Merge tag 'v5.10-rc6' into patchwork
authorMauro Carvalho Chehab <mchehab+huawei@kernel.org>
Tue, 1 Dec 2020 15:21:40 +0000 (16:21 +0100)
committerMauro Carvalho Chehab <mchehab+huawei@kernel.org>
Tue, 1 Dec 2020 15:21:40 +0000 (16:21 +0100)
Linux 5.10-rc6

* tag 'v5.10-rc6': (1815 commits)
  Linux 5.10-rc6
  sock: set sk_err to ee_errno on dequeue from errq
  mptcp: fix NULL ptr dereference on bad MPJ
  net: openvswitch: fix TTL decrement action netlink message format
  perf probe: Change function definition check due to broken DWARF
  perf probe: Fix to die_entrypc() returns error correctly
  perf stat: Use proper cpu for shadow stats
  perf record: Synthesize cgroup events only if needed
  perf diff: Fix error return value in __cmd_diff()
  perf tools: Update copy of libbpf's hashmap.c
  x86/mce: Do not overwrite no_way_out if mce_end() fails
  kvm: x86/mmu: Fix get_mmio_spte() on CPUs supporting 5-level PT
  KVM: x86: Fix split-irqchip vs interrupt injection window request
  KVM: x86: handle !lapic_in_kernel case in kvm_cpu_*_extint
  usb: typec: stusb160x: fix power-opmode property with typec-power-opmode
  printk: finalize records with trailing newlines
  can: af_can: can_rx_unregister(): remove WARN() statement from list operation sanity check
  can: m_can: m_can_dev_setup(): add support for bosch mcan version 3.3.0
  can: m_can: fix nominal bitiming tseg2 min for version >= 3.1
  can: m_can: m_can_open(): remove IRQF_TRIGGER_FALLING from request_threaded_irq()'s flags
  ...

280 files changed:
Documentation/devicetree/bindings/media/allwinner,sun4i-a10-video-engine.yaml
Documentation/devicetree/bindings/media/coda.txt [deleted file]
Documentation/devicetree/bindings/media/coda.yaml [new file with mode: 0644]
Documentation/devicetree/bindings/media/i2c/adv7604.txt [deleted file]
Documentation/devicetree/bindings/media/i2c/adv7604.yaml [new file with mode: 0644]
Documentation/devicetree/bindings/media/i2c/aptina,mt9v111.txt [deleted file]
Documentation/devicetree/bindings/media/i2c/aptina,mt9v111.yaml [new file with mode: 0644]
Documentation/devicetree/bindings/media/i2c/ov2680.txt [deleted file]
Documentation/devicetree/bindings/media/i2c/ov772x.txt [deleted file]
Documentation/devicetree/bindings/media/i2c/ovti,ov2680.yaml [new file with mode: 0644]
Documentation/devicetree/bindings/media/i2c/ovti,ov772x.yaml [new file with mode: 0644]
Documentation/devicetree/bindings/media/i2c/sony,imx214.txt [deleted file]
Documentation/devicetree/bindings/media/i2c/sony,imx214.yaml [new file with mode: 0644]
Documentation/devicetree/bindings/media/imx7-csi.txt [deleted file]
Documentation/devicetree/bindings/media/imx7-mipi-csi2.txt [deleted file]
Documentation/devicetree/bindings/media/nxp,imx7-csi.yaml [new file with mode: 0644]
Documentation/devicetree/bindings/media/nxp,imx7-mipi-csi2.yaml [new file with mode: 0644]
Documentation/devicetree/bindings/media/qcom,camss.txt
Documentation/devicetree/bindings/media/rc.yaml
Documentation/devicetree/bindings/media/rockchip-isp1.yaml [new file with mode: 0644]
Documentation/devicetree/bindings/media/st,stm32-dcmi.yaml
Documentation/driver-api/media/camera-sensor.rst
Documentation/driver-api/media/cec-core.rst
Documentation/driver-api/media/csi2.rst
Documentation/driver-api/media/dtv-frontend.rst
Documentation/driver-api/media/v4l2-controls.rst
Documentation/driver-api/media/v4l2-dev.rst
Documentation/userspace-api/media/cec/cec-ioc-g-mode.rst
Documentation/userspace-api/media/dvb/audio.rst
Documentation/userspace-api/media/dvb/ca.rst
Documentation/userspace-api/media/dvb/demux.rst
Documentation/userspace-api/media/dvb/dmx-qbuf.rst
Documentation/userspace-api/media/dvb/net.rst
Documentation/userspace-api/media/dvb/video.rst
Documentation/userspace-api/media/lirc.h.rst.exceptions
Documentation/userspace-api/media/rc/keytable.c.rst
Documentation/userspace-api/media/rc/lirc-dev-intro.rst
Documentation/userspace-api/media/rc/lirc-dev.rst
Documentation/userspace-api/media/rc/lirc-func.rst
Documentation/userspace-api/media/rc/lirc-get-features.rst
Documentation/userspace-api/media/rc/lirc-get-rec-mode.rst
Documentation/userspace-api/media/rc/lirc-get-rec-resolution.rst
Documentation/userspace-api/media/rc/lirc-get-send-mode.rst
Documentation/userspace-api/media/rc/lirc-get-timeout.rst
Documentation/userspace-api/media/rc/lirc-header.rst
Documentation/userspace-api/media/rc/lirc-read.rst
Documentation/userspace-api/media/rc/lirc-set-measure-carrier-mode.rst
Documentation/userspace-api/media/rc/lirc-set-rec-carrier-range.rst
Documentation/userspace-api/media/rc/lirc-set-rec-carrier.rst
Documentation/userspace-api/media/rc/lirc-set-rec-timeout-reports.rst
Documentation/userspace-api/media/rc/lirc-set-rec-timeout.rst
Documentation/userspace-api/media/rc/lirc-set-send-carrier.rst
Documentation/userspace-api/media/rc/lirc-set-send-duty-cycle.rst
Documentation/userspace-api/media/rc/lirc-set-transmitter-mask.rst
Documentation/userspace-api/media/rc/lirc-set-wideband-receiver.rst
Documentation/userspace-api/media/rc/lirc-write.rst
Documentation/userspace-api/media/rc/rc-intro.rst
Documentation/userspace-api/media/rc/rc-protos.rst
Documentation/userspace-api/media/rc/rc-sysfs-nodes.rst
Documentation/userspace-api/media/rc/rc-table-change.rst
Documentation/userspace-api/media/rc/rc-tables.rst
Documentation/userspace-api/media/rc/remote_controllers.rst
Documentation/userspace-api/media/v4l/biblio.rst
Documentation/userspace-api/media/v4l/buffer.rst
Documentation/userspace-api/media/v4l/colorspaces-details.rst
Documentation/userspace-api/media/v4l/pixfmt-meta-rkisp1.rst
Documentation/userspace-api/media/v4l/selection-api-configuration.rst
Documentation/userspace-api/media/v4l/subdev-formats.rst
Documentation/userspace-api/media/v4l/vidioc-g-ext-ctrls.rst
Documentation/userspace-api/media/v4l/vidioc-g-output.rst
Documentation/userspace-api/media/v4l/vidioc-qbuf.rst
MAINTAINERS
drivers/media/Kconfig
drivers/media/cec/core/cec-core.c
drivers/media/common/saa7146/saa7146_fops.c
drivers/media/common/saa7146/saa7146_video.c
drivers/media/common/siano/smsdvb-main.c
drivers/media/dvb-core/dvbdev.c
drivers/media/dvb-frontends/ascot2e.h
drivers/media/dvb-frontends/cxd2820r.h
drivers/media/dvb-frontends/drx39xyj/drxj.c
drivers/media/dvb-frontends/drxd_hard.c
drivers/media/dvb-frontends/drxk.h
drivers/media/dvb-frontends/dvb-pll.h
drivers/media/dvb-frontends/helene.h
drivers/media/dvb-frontends/horus3a.h
drivers/media/dvb-frontends/ix2505v.h
drivers/media/dvb-frontends/m88ds3103.c
drivers/media/dvb-frontends/m88ds3103.h
drivers/media/dvb-frontends/mb86a20s.h
drivers/media/dvb-frontends/nxt200x.c
drivers/media/dvb-frontends/rtl2832.c
drivers/media/dvb-frontends/si2165.c
drivers/media/dvb-frontends/si2165.h
drivers/media/dvb-frontends/si21xx.c
drivers/media/dvb-frontends/stb6000.h
drivers/media/dvb-frontends/tda826x.h
drivers/media/dvb-frontends/ts2020.c
drivers/media/dvb-frontends/zl10036.h
drivers/media/i2c/Kconfig
drivers/media/i2c/Makefile
drivers/media/i2c/ad5820.c
drivers/media/i2c/adp1653.c
drivers/media/i2c/adv7180.c
drivers/media/i2c/adv748x/adv748x-core.c
drivers/media/i2c/ak7375.c
drivers/media/i2c/dw9768.c
drivers/media/i2c/et8ek8/et8ek8_driver.c
drivers/media/i2c/hi556.c
drivers/media/i2c/imx214.c
drivers/media/i2c/imx219.c
drivers/media/i2c/imx258.c
drivers/media/i2c/imx274.c
drivers/media/i2c/imx290.c
drivers/media/i2c/imx319.c
drivers/media/i2c/imx355.c
drivers/media/i2c/max2175.c
drivers/media/i2c/msp3400-kthreads.c
drivers/media/i2c/mt9p031.c
drivers/media/i2c/ov13858.c
drivers/media/i2c/ov2680.c
drivers/media/i2c/ov2685.c
drivers/media/i2c/ov2740.c
drivers/media/i2c/ov5640.c
drivers/media/i2c/ov5670.c
drivers/media/i2c/ov5675.c
drivers/media/i2c/ov5695.c
drivers/media/i2c/ov7670.c
drivers/media/i2c/ov772x.c
drivers/media/i2c/ov7740.c
drivers/media/i2c/ov8856.c
drivers/media/i2c/ov9734.c [new file with mode: 0644]
drivers/media/i2c/smiapp/smiapp-core.c
drivers/media/i2c/tvp5150.c
drivers/media/pci/b2c2/flexcop-dma.c
drivers/media/pci/bt8xx/bt878.c
drivers/media/pci/bt8xx/btcx-risc.c
drivers/media/pci/bt8xx/bttv-cards.c
drivers/media/pci/bt8xx/bttv-driver.c
drivers/media/pci/bt8xx/bttv-risc.c
drivers/media/pci/cx23885/cx23885-core.c
drivers/media/pci/cx25821/cx25821-core.c
drivers/media/pci/dm1105/dm1105.c
drivers/media/pci/intel/ipu3/ipu3-cio2.c
drivers/media/pci/intel/ipu3/ipu3-cio2.h
drivers/media/pci/mantis/hopper_vp3028.c
drivers/media/pci/saa7134/saa7134-video.c
drivers/media/pci/saa7164/saa7164-core.c
drivers/media/pci/solo6x10/solo6x10-g723.c
drivers/media/platform/Kconfig
drivers/media/platform/Makefile
drivers/media/platform/coda/coda-bit.c
drivers/media/platform/coda/coda-common.c
drivers/media/platform/coda/coda.h
drivers/media/platform/davinci/isif.c
drivers/media/platform/exynos4-is/fimc-core.c
drivers/media/platform/fsl-viu.c
drivers/media/platform/marvell-ccic/mmp-driver.c
drivers/media/platform/mtk-jpeg/mtk_jpeg_core.c
drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c
drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.c
drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_drv.c
drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_pm.c
drivers/media/platform/pxa_camera.c
drivers/media/platform/qcom/camss/camss-csid.c
drivers/media/platform/qcom/camss/camss-csiphy-3ph-1-0.c
drivers/media/platform/qcom/camss/camss-csiphy.c
drivers/media/platform/qcom/camss/camss-csiphy.h
drivers/media/platform/qcom/camss/camss-ispif.c
drivers/media/platform/qcom/camss/camss-ispif.h
drivers/media/platform/qcom/camss/camss-vfe-4-7.c
drivers/media/platform/qcom/camss/camss-vfe.c
drivers/media/platform/qcom/camss/camss-vfe.h
drivers/media/platform/qcom/camss/camss-video.c
drivers/media/platform/qcom/camss/camss.c
drivers/media/platform/qcom/camss/camss.h
drivers/media/platform/qcom/venus/core.c
drivers/media/platform/qcom/venus/core.h
drivers/media/platform/qcom/venus/firmware.c
drivers/media/platform/qcom/venus/hfi.c
drivers/media/platform/qcom/venus/pm_helpers.c
drivers/media/platform/qcom/venus/vdec.c
drivers/media/platform/qcom/venus/venc.c
drivers/media/platform/rcar-vin/rcar-core.c
drivers/media/platform/rcar-vin/rcar-csi2.c
drivers/media/platform/rcar-vin/rcar-dma.c
drivers/media/platform/rcar-vin/rcar-vin.h
drivers/media/platform/rockchip/rkisp1/Makefile [new file with mode: 0644]
drivers/media/platform/rockchip/rkisp1/rkisp1-capture.c [new file with mode: 0644]
drivers/media/platform/rockchip/rkisp1/rkisp1-common.c [new file with mode: 0644]
drivers/media/platform/rockchip/rkisp1/rkisp1-common.h [new file with mode: 0644]
drivers/media/platform/rockchip/rkisp1/rkisp1-dev.c [new file with mode: 0644]
drivers/media/platform/rockchip/rkisp1/rkisp1-isp.c [new file with mode: 0644]
drivers/media/platform/rockchip/rkisp1/rkisp1-params.c [new file with mode: 0644]
drivers/media/platform/rockchip/rkisp1/rkisp1-regs.h [new file with mode: 0644]
drivers/media/platform/rockchip/rkisp1/rkisp1-resizer.c [new file with mode: 0644]
drivers/media/platform/rockchip/rkisp1/rkisp1-stats.c [new file with mode: 0644]
drivers/media/platform/s3c-camif/camif-core.c
drivers/media/platform/sti/c8sectpfe/c8sectpfe-core.c
drivers/media/platform/stm32/stm32-dcmi.c
drivers/media/platform/sunxi/sun4i-csi/sun4i_v4l2.c
drivers/media/radio/radio-sf16fmr2.c
drivers/media/rc/keymaps/Makefile
drivers/media/rc/keymaps/rc-khamsin.c [new file with mode: 0644]
drivers/media/rc/lirc_dev.c
drivers/media/rc/sunxi-cir.c
drivers/media/test-drivers/vim2m.c
drivers/media/test-drivers/vivid/vivid-kthread-cap.c
drivers/media/test-drivers/vivid/vivid-kthread-out.c
drivers/media/test-drivers/vivid/vivid-kthread-touch.c
drivers/media/test-drivers/vivid/vivid-sdr-cap.c
drivers/media/test-drivers/vivid/vivid-vid-cap.c
drivers/media/test-drivers/vivid/vivid-vid-out.c
drivers/media/tuners/mt2060.c
drivers/media/tuners/mt2063.c
drivers/media/tuners/mxl5005s.c
drivers/media/usb/au0828/au0828-video.c
drivers/media/usb/cx231xx/cx231xx-audio.c
drivers/media/usb/cx231xx/cx231xx-core.c
drivers/media/usb/cx231xx/cx231xx-vbi.c
drivers/media/usb/dvb-usb-v2/dvbsky.c
drivers/media/usb/dvb-usb-v2/rtl28xxu.c
drivers/media/usb/dvb-usb-v2/zd1301.c
drivers/media/usb/dvb-usb/dib0700_devices.c
drivers/media/usb/dvb-usb/dw2102.c
drivers/media/usb/dvb-usb/gp8psk.c
drivers/media/usb/em28xx/em28xx-audio.c
drivers/media/usb/gspca/ov534.c
drivers/media/usb/msi2500/msi2500.c
drivers/media/usb/pvrusb2/pvrusb2-devattr.c
drivers/media/usb/tm6000/tm6000-video.c
drivers/media/usb/uvc/uvc_ctrl.c
drivers/media/usb/zr364xx/zr364xx.c
drivers/media/v4l2-core/v4l2-common.c
drivers/media/v4l2-core/v4l2-compat-ioctl32.c
drivers/media/v4l2-core/v4l2-ctrls.c
drivers/media/v4l2-core/v4l2-fwnode.c
drivers/media/v4l2-core/v4l2-ioctl.c
drivers/media/v4l2-core/v4l2-subdev.c
drivers/staging/media/Kconfig
drivers/staging/media/Makefile
drivers/staging/media/imx/imx-media-csi.c
drivers/staging/media/ipu3/include/intel-ipu3.h
drivers/staging/media/rkisp1/Documentation/devicetree/bindings/media/rockchip-isp1.yaml [deleted file]
drivers/staging/media/rkisp1/Kconfig [deleted file]
drivers/staging/media/rkisp1/Makefile [deleted file]
drivers/staging/media/rkisp1/TODO [deleted file]
drivers/staging/media/rkisp1/rkisp1-capture.c [deleted file]
drivers/staging/media/rkisp1/rkisp1-common.c [deleted file]
drivers/staging/media/rkisp1/rkisp1-common.h [deleted file]
drivers/staging/media/rkisp1/rkisp1-dev.c [deleted file]
drivers/staging/media/rkisp1/rkisp1-isp.c [deleted file]
drivers/staging/media/rkisp1/rkisp1-params.c [deleted file]
drivers/staging/media/rkisp1/rkisp1-regs.h [deleted file]
drivers/staging/media/rkisp1/rkisp1-resizer.c [deleted file]
drivers/staging/media/rkisp1/rkisp1-stats.c [deleted file]
drivers/staging/media/rkisp1/uapi/rkisp1-config.h [deleted file]
drivers/staging/media/rkvdec/rkvdec.c
drivers/staging/media/sunxi/cedrus/cedrus.c
drivers/staging/media/sunxi/cedrus/cedrus_video.c
drivers/staging/media/zoran/zoran_driver.c
include/media/dvbdev.h
include/media/h264-ctrls.h
include/media/rc-map.h
include/media/v4l2-async.h
include/media/v4l2-common.h
include/media/v4l2-ctrls.h
include/media/v4l2-dev.h
include/media/v4l2-device.h
include/media/v4l2-dv-timings.h
include/media/v4l2-fwnode.h
include/media/v4l2-ioctl.h
include/media/v4l2-mediabus.h
include/media/v4l2-subdev.h
include/media/videobuf2-core.h
include/uapi/linux/lirc.h
include/uapi/linux/media-bus-format.h
include/uapi/linux/rkisp1-config.h [new file with mode: 0644]
include/uapi/linux/v4l2-controls.h
include/uapi/linux/videodev2.h

index 4cc1a67..0d58bbc 100644 (file)
@@ -18,6 +18,7 @@ properties:
       - allwinner,sun7i-a20-video-engine
       - allwinner,sun8i-a33-video-engine
       - allwinner,sun8i-h3-video-engine
+      - allwinner,sun8i-r40-video-engine
       - allwinner,sun50i-a64-video-engine
       - allwinner,sun50i-h5-video-engine
       - allwinner,sun50i-h6-video-engine
diff --git a/Documentation/devicetree/bindings/media/coda.txt b/Documentation/devicetree/bindings/media/coda.txt
deleted file mode 100644 (file)
index 90eb74c..0000000
+++ /dev/null
@@ -1,31 +0,0 @@
-Chips&Media Coda multi-standard codec IP
-========================================
-
-Coda codec IPs are present in i.MX SoCs in various versions,
-called VPU (Video Processing Unit).
-
-Required properties:
-- compatible : should be "fsl,<chip>-src" for i.MX SoCs:
-  (a) "fsl,imx27-vpu" for CodaDx6 present in i.MX27
-  (b) "fsl,imx51-vpu" for CodaHx4 present in i.MX51
-  (c) "fsl,imx53-vpu" for CODA7541 present in i.MX53
-  (d) "fsl,imx6q-vpu" for CODA960 present in i.MX6q
-- reg: should be register base and length as documented in the
-  SoC reference manual
-- interrupts : Should contain the VPU interrupt. For CODA960,
-  a second interrupt is needed for the MJPEG unit.
-- clocks : Should contain the ahb and per clocks, in the order
-  determined by the clock-names property.
-- clock-names : Should be "ahb", "per"
-- iram : phandle pointing to the SRAM device node
-
-Example:
-
-vpu: vpu@63ff4000 {
-       compatible = "fsl,imx53-vpu";
-       reg = <0x63ff4000 0x1000>;
-       interrupts = <9>;
-       clocks = <&clks 63>, <&clks 63>;
-       clock-names = "ahb", "per";
-       iram = <&ocram>;
-};
diff --git a/Documentation/devicetree/bindings/media/coda.yaml b/Documentation/devicetree/bindings/media/coda.yaml
new file mode 100644 (file)
index 0000000..7bac005
--- /dev/null
@@ -0,0 +1,108 @@
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/media/coda.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Chips&Media Coda multi-standard codec IP
+
+maintainers:
+  - Philipp Zabel <p.zabel@pengutronix.de>
+
+description: |-
+  Coda codec IPs are present in i.MX SoCs in various versions,
+  called VPU (Video Processing Unit).
+
+properties:
+  compatible:
+    oneOf:
+      - items:
+          - const: fsl,imx27-vpu
+          - const: cnm,codadx6
+      - items:
+          - const: fsl,imx51-vpu
+          - const: cnm,codahx4
+      - items:
+          - const: fsl,imx53-vpu
+          - const: cnm,coda7541
+      - items:
+          - enum:
+              - fsl,imx6dl-vpu
+              - fsl,imx6q-vpu
+          - const: cnm,coda960
+
+  reg:
+    maxItems: 1
+
+  clocks:
+    items:
+      - description: PER clock
+      - description: AHB interface clock
+
+  clock-names:
+    items:
+      - const: per
+      - const: ahb
+
+  resets:
+    maxItems: 1
+
+  iram:
+    $ref: /schemas/types.yaml#/definitions/phandle
+    description: phandle pointing to the SRAM device node
+    maxItems: 1
+
+required:
+  - compatible
+  - reg
+  - interrupts
+  - clocks
+  - clock-names
+
+allOf:
+  - if:
+      properties:
+        compatible:
+          contains:
+            const: cnm,coda960
+    then:
+      properties:
+        interrupts:
+          items:
+            - description: BIT processor interrupt
+            - description: JPEG unit interrupt
+
+        interrupt-names:
+          items:
+            - const: bit
+            - const: jpeg
+    else:
+      properties:
+        interrupts:
+          items:
+            - description: BIT processor interrupt
+
+  - if:
+      properties:
+        compatible:
+          contains:
+            enum:
+              - fsl,imx6dl-vpu
+              - fsl,imx6q-vpu
+    then:
+      properties:
+        power-domains:
+          $ref: /schemas/types.yaml#/definitions/phandle
+          description: phandle pointing to the PU power domain
+          maxItems: 1
+
+examples:
+  - |
+    vpu: video-codec@63ff4000 {
+        compatible = "fsl,imx53-vpu", "cnm,coda7541";
+        reg = <0x63ff4000 0x1000>;
+        interrupts = <9>;
+        clocks = <&clks 63>, <&clks 63>;
+        clock-names = "per", "ahb";
+        iram = <&ocram>;
+    };
diff --git a/Documentation/devicetree/bindings/media/i2c/adv7604.txt b/Documentation/devicetree/bindings/media/i2c/adv7604.txt
deleted file mode 100644 (file)
index b3e688b..0000000
+++ /dev/null
@@ -1,88 +0,0 @@
-* Analog Devices ADV7604/11/12 video decoder with HDMI receiver
-
-The ADV7604 and ADV7611/12 are multiformat video decoders with an integrated
-HDMI receiver. The ADV7604 has four multiplexed HDMI inputs and one analog
-input, and the ADV7611 has one HDMI input and no analog input. The 7612 is
-similar to the 7611 but has 2 HDMI inputs.
-
-These device tree bindings support the ADV7611/12 only at the moment.
-
-Required Properties:
-
-  - compatible: Must contain one of the following
-    - "adi,adv7611" for the ADV7611
-    - "adi,adv7612" for the ADV7612
-
-  - reg: I2C slave addresses
-    The ADV76xx has up to thirteen 256-byte maps that can be accessed via the
-    main I2C ports. Each map has it own I2C address and acts as a standard
-    slave device on the I2C bus. The main address is mandatory, others are
-    optional and revert to defaults if not specified.
-
-  - hpd-gpios: References to the GPIOs that control the HDMI hot-plug
-    detection pins, one per HDMI input. The active flag indicates the GPIO
-    level that enables hot-plug detection.
-
-The device node must contain one 'port' child node per device input and output
-port, in accordance with the video interface bindings defined in
-Documentation/devicetree/bindings/media/video-interfaces.txt. The port nodes
-are numbered as follows.
-
-  Port                 ADV7611    ADV7612
-------------------------------------------------------------
-  HDMI                 0             0, 1
-  Digital output       1                2
-
-The digital output port node must contain at least one endpoint.
-
-Optional Properties:
-
-  - reset-gpios: Reference to the GPIO connected to the device's reset pin.
-  - default-input: Select which input is selected after reset.
-  - reg-names : Names of maps with programmable addresses.
-               It can contain any map needing a non-default address.
-               Possible maps names are :
-                 "main", "avlink", "cec", "infoframe", "esdp", "dpp", "afe",
-                 "rep", "edid", "hdmi", "test", "cp", "vdp"
-
-Optional Endpoint Properties:
-
-  The following three properties are defined in video-interfaces.txt and are
-  valid for source endpoints only.
-
-  - hsync-active: Horizontal synchronization polarity. Defaults to active low.
-  - vsync-active: Vertical synchronization polarity. Defaults to active low.
-  - pclk-sample: Pixel clock polarity. Defaults to output on the falling edge.
-
-  If none of hsync-active, vsync-active and pclk-sample is specified the
-  endpoint will use embedded BT.656 synchronization.
-
-Example:
-
-       hdmi_receiver@4c {
-               compatible = "adi,adv7611";
-               /*
-                * The edid page will be accessible @ 0x66 on the I2C bus. All
-                * other maps will retain their default addresses.
-                */
-               reg = <0x4c>, <0x66>;
-               reg-names = "main", "edid";
-
-               reset-gpios = <&ioexp 0 GPIO_ACTIVE_LOW>;
-               hpd-gpios = <&ioexp 2 GPIO_ACTIVE_HIGH>;
-
-               #address-cells = <1>;
-               #size-cells = <0>;
-
-               default-input = <0>;
-
-               port@0 {
-                       reg = <0>;
-               };
-               port@1 {
-                       reg = <1>;
-                       hdmi_in: endpoint {
-                               remote-endpoint = <&ccdc_in>;
-                       };
-               };
-       };
diff --git a/Documentation/devicetree/bindings/media/i2c/adv7604.yaml b/Documentation/devicetree/bindings/media/i2c/adv7604.yaml
new file mode 100644 (file)
index 0000000..3897af5
--- /dev/null
@@ -0,0 +1,178 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/media/i2c/adv7604.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Analog Devices ADV7604/11/12 video decoder with HDMI receiver
+
+maintainers:
+  - Hans Verkuil <hverkuil-cisco@xs4all.nl>
+
+description:
+  The ADV7604 and ADV7611/12 are multiformat video decoders with an integrated
+  HDMI receiver. The ADV7604 has four multiplexed HDMI inputs and one analog
+  input, and the ADV7611 has one HDMI input and no analog input. The 7612 is
+  similar to the 7611 but has 2 HDMI inputs.
+
+  These device tree bindings support the ADV7611/12 only at the moment.
+
+properties:
+  compatible:
+    items:
+      - enum:
+        - adi,adv7611
+        - adi,adv7612
+
+  reg:
+    minItems: 1
+    maxItems: 13
+
+  reg-names:
+    minItems: 1
+    maxItems: 13
+    items:
+      - const: main
+      - enum: [ avlink, cec, infoframe, esdp, dpp, afe, rep, edid, hdmi, test, cp, vdp ]
+      - enum: [ avlink, cec, infoframe, esdp, dpp, afe, rep, edid, hdmi, test, cp, vdp ]
+      - enum: [ avlink, cec, infoframe, esdp, dpp, afe, rep, edid, hdmi, test, cp, vdp ]
+      - enum: [ avlink, cec, infoframe, esdp, dpp, afe, rep, edid, hdmi, test, cp, vdp ]
+      - enum: [ avlink, cec, infoframe, esdp, dpp, afe, rep, edid, hdmi, test, cp, vdp ]
+      - enum: [ avlink, cec, infoframe, esdp, dpp, afe, rep, edid, hdmi, test, cp, vdp ]
+      - enum: [ avlink, cec, infoframe, esdp, dpp, afe, rep, edid, hdmi, test, cp, vdp ]
+      - enum: [ avlink, cec, infoframe, esdp, dpp, afe, rep, edid, hdmi, test, cp, vdp ]
+      - enum: [ avlink, cec, infoframe, esdp, dpp, afe, rep, edid, hdmi, test, cp, vdp ]
+      - enum: [ avlink, cec, infoframe, esdp, dpp, afe, rep, edid, hdmi, test, cp, vdp ]
+      - enum: [ avlink, cec, infoframe, esdp, dpp, afe, rep, edid, hdmi, test, cp, vdp ]
+      - enum: [ avlink, cec, infoframe, esdp, dpp, afe, rep, edid, hdmi, test, cp, vdp ]
+
+  interrupts:
+    maxItems: 1
+
+  reset-gpios:
+    maxItems: 1
+
+  hpd-gpios:
+    minItems: 1
+    description:
+      References to the GPIOs that control the HDMI hot-plug detection pins,
+      one per HDMI input. The active flag indicates the GPIO level that
+      enables hot-plug detection.
+
+  default-input:
+    maxItems: 1
+    description:
+      Select which input is selected after reset.
+
+  ports:
+    type: object
+    description:
+      A node containing input and output port nodes with endpoint definitions
+      as documented in
+      Documentation/devicetree/bindings/media/video-interfaces.txt
+
+required:
+  - compatible
+  - reg
+
+additionalProperties: false
+
+allOf:
+  - if:
+      properties:
+        compatible:
+          contains:
+            const: adi,adv7611
+    then:
+      properties:
+        ports:
+          properties:
+            '#address-cells':
+              const: 1
+            '#size-cells':
+              const: 0
+            port@0:
+              type: object
+              description: Input port
+            port@1:
+              type: object
+              description: Output port
+
+          required:
+            - port@1
+
+          additionalProperties: false
+
+      required:
+        - ports
+
+  - if:
+      properties:
+        compatible:
+          contains:
+            const: adi,adv7612
+    then:
+      properties:
+        ports:
+          properties:
+            '#address-cells':
+              const: 1
+            '#size-cells':
+              const: 0
+            port@2:
+              type: object
+              description: Output port
+
+          patternProperties:
+            "^port@[0-1]$":
+              type: object
+              description: Input port
+
+          required:
+            - port@2
+
+          additionalProperties: false
+
+      required:
+        - ports
+
+examples:
+  - |
+    #include <dt-bindings/gpio/gpio.h>
+
+    i2c {
+            #address-cells = <1>;
+            #size-cells = <0>;
+
+            hdmi_receiver@4c {
+                    compatible = "adi,adv7611";
+                    /*
+                     * The edid page will be accessible @ 0x66 on the I2C bus. All
+                     * other maps will retain their default addresses.
+                     */
+                    reg = <0x4c>, <0x66>;
+                    reg-names = "main", "edid";
+
+                    reset-gpios = <&ioexp 0 GPIO_ACTIVE_LOW>;
+                    hpd-gpios = <&ioexp 2 GPIO_ACTIVE_HIGH>;
+                    default-input = <0>;
+
+                    ports {
+                            #address-cells = <1>;
+                            #size-cells = <0>;
+
+                            port@0 {
+                                    reg = <0>;
+                            };
+
+                            port@1 {
+                                    reg = <1>;
+                                    hdmi_in: endpoint {
+                                            remote-endpoint = <&ccdc_in>;
+                                    };
+                            };
+                    };
+
+
+            };
+    };
diff --git a/Documentation/devicetree/bindings/media/i2c/aptina,mt9v111.txt b/Documentation/devicetree/bindings/media/i2c/aptina,mt9v111.txt
deleted file mode 100644 (file)
index bd896e9..0000000
+++ /dev/null
@@ -1,46 +0,0 @@
-* Aptina MT9V111 CMOS sensor
-----------------------------
-
-The Aptina MT9V111 is a 1/4-Inch VGA-format digital image sensor with a core
-based on Aptina MT9V011 sensor and an integrated Image Flow Processor (IFP).
-
-The sensor has an active pixel array of 640x480 pixels and can output a number
-of image resolution and formats controllable through a simple two-wires
-interface.
-
-Required properties:
---------------------
-
-- compatible: shall be "aptina,mt9v111".
-- clocks: reference to the system clock input provider.
-
-Optional properties:
---------------------
-
-- enable-gpios: output enable signal, pin name "OE#". Active low.
-- standby-gpios: low power state control signal, pin name "STANDBY".
-  Active high.
-- reset-gpios: chip reset signal, pin name "RESET#". Active low.
-
-The device node must contain one 'port' child node with one 'endpoint' child
-sub-node for its digital output video port, in accordance with the video
-interface bindings defined in:
-Documentation/devicetree/bindings/media/video-interfaces.txt
-
-Example:
---------
-
-        &i2c1 {
-                camera@48 {
-                        compatible = "aptina,mt9v111";
-                        reg = <0x48>;
-
-                        clocks = <&camera_clk>;
-
-                        port {
-                                mt9v111_out: endpoint {
-                                        remote-endpoint = <&ceu_in>;
-                                };
-                        };
-                };
-        };
diff --git a/Documentation/devicetree/bindings/media/i2c/aptina,mt9v111.yaml b/Documentation/devicetree/bindings/media/i2c/aptina,mt9v111.yaml
new file mode 100644 (file)
index 0000000..ff9546e
--- /dev/null
@@ -0,0 +1,75 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/media/i2c/aptina,mt9v111.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Aptina MT9V111 CMOS sensor
+
+maintainers:
+  - Jacopo Mondi <jacopo@jmondi.org>
+
+description: |
+  The Aptina MT9V111 is a 1/4-Inch VGA-format digital image sensor with a core
+  based on Aptina MT9V011 sensor and an integrated Image Flow Processor (IFP).
+
+  The sensor has an active pixel array of 640x480 pixels and can output a number
+  of image resolutions and formats controllable through a simple two-wires
+  interface.
+
+properties:
+  compatible:
+    const: aptina,mt9v111
+
+  reg:
+    maxItems: 1
+
+  clocks:
+    maxItems: 1
+
+  enable-gpios:
+    description: Enable signal, pin name "OE#". Active low.
+    maxItems: 1
+
+  standby-gpios:
+    description: |
+      Low power state control signal, pin name "STANDBY". Active high.
+    maxItems: 1
+
+  reset-gpios:
+    description: Chip reset signal, pin name "RESET#". Active low.
+    maxItems: 1
+
+  port:
+    type: object
+    description: |
+      Output video port. See ../video-interfaces.txt.
+
+required:
+  - compatible
+  - reg
+  - clocks
+  - port
+
+additionalProperties: false
+
+examples:
+  - |
+    i2c0 {
+        #address-cells = <1>;
+        #size-cells = <0>;
+
+        camera@48 {
+            compatible = "aptina,mt9v111";
+            reg = <0x48>;
+            clocks = <&camera_clk>;
+
+            port {
+                mt9v111_out: endpoint {
+                    remote-endpoint = <&ceu_in>;
+                };
+            };
+        };
+    };
+
+...
diff --git a/Documentation/devicetree/bindings/media/i2c/ov2680.txt b/Documentation/devicetree/bindings/media/i2c/ov2680.txt
deleted file mode 100644 (file)
index 11e925e..0000000
+++ /dev/null
@@ -1,46 +0,0 @@
-* Omnivision OV2680 MIPI CSI-2 sensor
-
-Required Properties:
-- compatible: should be "ovti,ov2680".
-- clocks: reference to the xvclk input clock.
-- clock-names: should be "xvclk".
-- DOVDD-supply: Digital I/O voltage supply.
-- DVDD-supply: Digital core voltage supply.
-- AVDD-supply: Analog voltage supply.
-
-Optional Properties:
-- reset-gpios: reference to the GPIO connected to the powerdown/reset pin,
-               if any. This is an active low signal to the OV2680.
-
-The device node must contain one 'port' child node for its digital output
-video port, and this port must have a single endpoint in accordance with
- the video interface bindings defined in
-Documentation/devicetree/bindings/media/video-interfaces.txt.
-
-Endpoint node required properties for CSI-2 connection are:
-- remote-endpoint: a phandle to the bus receiver's endpoint node.
-- clock-lanes: should be set to <0> (clock lane on hardware lane 0).
-- data-lanes: should be set to <1> (one CSI-2 lane supported).
-
-Example:
-
-&i2c2 {
-       ov2680: camera-sensor@36 {
-               compatible = "ovti,ov2680";
-               reg = <0x36>;
-               clocks = <&osc>;
-               clock-names = "xvclk";
-               reset-gpios = <&gpio1 3 GPIO_ACTIVE_LOW>;
-               DOVDD-supply = <&sw2_reg>;
-               DVDD-supply = <&sw2_reg>;
-               AVDD-supply = <&reg_peri_3p15v>;
-
-               port {
-                       ov2680_to_mipi: endpoint {
-                               remote-endpoint = <&mipi_from_sensor>;
-                               clock-lanes = <0>;
-                               data-lanes = <1>;
-                       };
-               };
-       };
-};
diff --git a/Documentation/devicetree/bindings/media/i2c/ov772x.txt b/Documentation/devicetree/bindings/media/i2c/ov772x.txt
deleted file mode 100644 (file)
index 0b3ede5..0000000
+++ /dev/null
@@ -1,40 +0,0 @@
-* Omnivision OV7720/OV7725 CMOS sensor
-
-The Omnivision OV7720/OV7725 sensor supports multiple resolutions output,
-such as VGA, QVGA, and any size scaling down from CIF to 40x30. It also can
-support the YUV422, RGB565/555/444, GRB422 or raw RGB output formats.
-
-Required Properties:
-- compatible: shall be one of
-       "ovti,ov7720"
-       "ovti,ov7725"
-- clocks: reference to the xclk input clock.
-
-Optional Properties:
-- reset-gpios: reference to the GPIO connected to the RSTB pin which is
-  active low, if any.
-- powerdown-gpios: reference to the GPIO connected to the PWDN pin which is
-  active high, if any.
-
-The device node shall contain one 'port' child node with one child 'endpoint'
-subnode for its digital output video port, in accordance with the video
-interface bindings defined in Documentation/devicetree/bindings/media/
-video-interfaces.txt.
-
-Example:
-
-&i2c0 {
-       ov772x: camera@21 {
-               compatible = "ovti,ov7725";
-               reg = <0x21>;
-               reset-gpios = <&axi_gpio_0 0 GPIO_ACTIVE_LOW>;
-               powerdown-gpios = <&axi_gpio_0 1 GPIO_ACTIVE_LOW>;
-               clocks = <&xclk>;
-
-               port {
-                       ov772x_0: endpoint {
-                               remote-endpoint = <&vcap1_in0>;
-                       };
-               };
-       };
-};
diff --git a/Documentation/devicetree/bindings/media/i2c/ovti,ov2680.yaml b/Documentation/devicetree/bindings/media/i2c/ovti,ov2680.yaml
new file mode 100644 (file)
index 0000000..43bf749
--- /dev/null
@@ -0,0 +1,99 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/media/i2c/ovti,ov2680.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Omnivision OV2680 CMOS Sensor
+
+maintainers:
+  - Rui Miguel Silva <rmfrfs@gmail.com>
+
+description: |-
+  The OV2680 color sensor is a low voltage, high performance 1/5 inch UXGA (2
+  megapixel) CMOS image sensor that provides a single-chip UXGA (1600 x 1200)
+  camera. It provides full-frame, sub-sampled, or windowed 10-bit images in
+  various formats via the control of the Serial Camera Control Bus (SCCB)
+  interface. The OV2680 has an image array capable of operating at up to 30
+  frames per second (fps) in UXGA resolution.
+
+properties:
+  compatible:
+    const: ovti,ov2680
+
+  reg:
+    maxItems: 1
+
+  clocks:
+    maxItems: 1
+
+  clock-names:
+    const: xvclk
+
+  reset-gpios:
+    description:
+      The phandle and specifier for the GPIO that controls sensor reset.
+      This corresponds to the hardware pin XSHUTDOWN which is physically
+      active low.
+    maxItems: 1
+
+  dovdd-supply:
+    description:
+      Definition of the regulator used as interface power supply.
+
+  avdd-supply:
+    description:
+      Definition of the regulator used as analog power supply.
+
+  dvdd-supply:
+    description:
+      Definition of the regulator used as digital power supply.
+
+  port:
+    type: object
+    description:
+      A node containing an output port node with an endpoint definition
+      as documented in
+      Documentation/devicetree/bindings/media/video-interfaces.txt
+
+required:
+  - compatible
+  - reg
+  - clocks
+  - clock-names
+  - dovdd-supply
+  - avdd-supply
+  - dvdd-supply
+  - reset-gpios
+  - port
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/gpio/gpio.h>
+
+    i2c {
+        #address-cells = <1>;
+        #size-cells = <0>;
+
+        ov2680: camera-sensor@36 {
+                compatible = "ovti,ov2680";
+                reg = <0x36>;
+                clocks = <&osc>;
+                clock-names = "xvclk";
+                reset-gpios = <&gpio1 3 GPIO_ACTIVE_LOW>;
+
+                dovdd-supply = <&sw2_reg>;
+                dvdd-supply = <&sw2_reg>;
+                avdd-supply = <&reg_peri_3p15v>;
+
+                port {
+                        ov2680_to_mipi: endpoint {
+                                remote-endpoint = <&mipi_from_sensor>;
+                        };
+                };
+        };
+    };
+
+...
diff --git a/Documentation/devicetree/bindings/media/i2c/ovti,ov772x.yaml b/Documentation/devicetree/bindings/media/i2c/ovti,ov772x.yaml
new file mode 100644 (file)
index 0000000..63b3779
--- /dev/null
@@ -0,0 +1,134 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/media/i2c/ovti,ov772x.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Omnivision OV7720/OV7725 CMOS sensor
+
+maintainers:
+  - Jacopo Mondi <jacopo@jmondi.org>
+
+description: |
+  The Omnivision OV7720/OV7725 sensor supports multiple resolutions output,
+  such as VGA, QVGA, and any size scaling down from CIF to 40x30. It also can
+  support the YUV422, RGB565/555/444, GRB422 or raw RGB output formats.
+
+properties:
+  compatible:
+    enum:
+      - ovti,ov7720
+      - ovti,ov7725
+
+  reg:
+    maxItems: 1
+
+  clocks:
+    maxItems: 1
+
+  reset-gpios:
+    description: |
+      Reference to the GPIO connected to the RSTB pin which is active low.
+    maxItems: 1
+
+  powerdown-gpios:
+    description: |
+      Reference to the GPIO connected to the PWDN pin which is active high.
+    maxItems: 1
+
+  port:
+    type: object
+    description: |
+      Video output port. See ../video-interfaces.txt.
+
+    properties:
+      endpoint:
+        type: object
+
+        properties:
+          bus-type:
+            enum: [5, 6]
+
+          bus-width:
+            enum: [8, 10]
+            default: 10
+
+          data-shift:
+            enum: [0, 2]
+            default: 0
+
+          hsync-active:
+            enum: [0, 1]
+            default: 1
+
+          vsync-active:
+            enum: [0, 1]
+            default: 1
+
+          pclk-sample:
+            enum: [0, 1]
+            default: 1
+
+        allOf:
+          - if:
+              properties:
+                bus-type:
+                  const: 6
+            then:
+                properties:
+                  hsync-active: false
+                  vsync-active: false
+
+          - if:
+              properties:
+                bus-width:
+                  const: 10
+            then:
+                properties:
+                  data-shift:
+                    const: 0
+
+        required:
+          - bus-type
+
+        unevaluatedProperties: false
+
+    additionalProperties: false
+
+required:
+  - compatible
+  - reg
+  - clocks
+  - port
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/gpio/gpio.h>
+
+    i2c0 {
+        #address-cells = <1>;
+        #size-cells = <0>;
+        ov772x: camera@21 {
+            compatible = "ovti,ov7725";
+            reg = <0x21>;
+            reset-gpios = <&axi_gpio_0 0 GPIO_ACTIVE_LOW>;
+            powerdown-gpios = <&axi_gpio_0 1 GPIO_ACTIVE_LOW>;
+            clocks = <&xclk>;
+
+            port {
+                ov772x_0: endpoint {
+                    bus-type = <5>;
+                    vsync-active = <0>;
+                    hsync-active = <0>;
+                    pclk-sample = <0>;
+                    bus-width = <8>;
+                    data-shift = <0>;
+                    remote-endpoint = <&vcap1_in0>;
+                };
+            };
+        };
+    };
+
+...
diff --git a/Documentation/devicetree/bindings/media/i2c/sony,imx214.txt b/Documentation/devicetree/bindings/media/i2c/sony,imx214.txt
deleted file mode 100644 (file)
index f11f28a..0000000
+++ /dev/null
@@ -1,53 +0,0 @@
-* Sony 1/3.06-Inch 13.13Mp CMOS Digital Image Sensor
-
-The Sony imx214 is a 1/3.06-inch CMOS active pixel digital image sensor with
-an active array size of 4224H x 3200V. It is programmable through an I2C
-interface.
-Image data is sent through MIPI CSI-2, through 2 or 4 lanes at a maximum
-throughput of 1.2Gbps/lane.
-
-
-Required Properties:
-- compatible: Shall be "sony,imx214".
-- reg: I2C bus address of the device. Depending on how the sensor is wired,
-       it shall be <0x10> or <0x1a>;
-- enable-gpios: GPIO descriptor for the enable pin.
-- vdddo-supply: Chip digital IO regulator (1.8V).
-- vdda-supply: Chip analog regulator (2.7V).
-- vddd-supply: Chip digital core regulator (1.12V).
-- clocks: Reference to the xclk clock.
-- clock-frequency: Frequency of the xclk clock.
-
-Optional Properties:
-- flash-leds: See ../video-interfaces.txt
-- lens-focus: See ../video-interfaces.txt
-
-The imx214 device node shall contain one 'port' child node with
-an 'endpoint' subnode. For further reading on port node refer to
-Documentation/devicetree/bindings/media/video-interfaces.txt.
-
-Required Properties on endpoint:
-- data-lanes: check ../video-interfaces.txt
-- link-frequencies: check ../video-interfaces.txt
-- remote-endpoint: check ../video-interfaces.txt
-
-Example:
-
-       camera-sensor@1a {
-               compatible = "sony,imx214";
-               reg = <0x1a>;
-               vdddo-supply = <&pm8994_lvs1>;
-               vddd-supply = <&camera_vddd_1v12>;
-               vdda-supply = <&pm8994_l17>;
-               lens-focus = <&ad5820>;
-               enable-gpios = <&msmgpio 25 GPIO_ACTIVE_HIGH>;
-               clocks = <&mmcc CAMSS_MCLK0_CLK>;
-               clock-frequency = <24000000>;
-               port {
-                       imx214_ep: endpoint {
-                               data-lanes = <1 2 3 4>;
-                               link-frequencies = /bits/ 64 <480000000>;
-                               remote-endpoint = <&csiphy0_ep>;
-                       };
-               };
-       };
diff --git a/Documentation/devicetree/bindings/media/i2c/sony,imx214.yaml b/Documentation/devicetree/bindings/media/i2c/sony,imx214.yaml
new file mode 100644 (file)
index 0000000..0f5e25f
--- /dev/null
@@ -0,0 +1,133 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/media/i2c/sony,imx214.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Sony 1/3.06-Inch 13.13MP CMOS Digital Image Sensor
+
+maintainers:
+  - Ricardo Ribalda <ribalda@kernel.org>
+
+description: |
+  The Sony IMX214 is a 1/3.06-inch CMOS active pixel digital image sensor with
+  an active array size of 4224H x 3200V. It is programmable through an I2C
+  interface. Image data is sent through MIPI CSI-2, through 2 or 4 lanes at a
+  maximum throughput of 1.2Gbps/lane.
+
+properties:
+  compatible:
+    const: sony,imx214
+
+  reg:
+    enum:
+      - 0x10
+      - 0x1a
+
+  clocks:
+    description: Reference to the xclk clock.
+    maxItems: 1
+
+  clock-frequency:
+    description: Frequency of the xclk clock in Hz.
+
+  enable-gpios:
+    description: GPIO descriptor for the enable pin.
+    maxItems: 1
+
+  vdddo-supply:
+    description: Chip digital IO regulator (1.8V).
+    maxItems: 1
+
+  vdda-supply:
+    description: Chip analog regulator (2.7V).
+    maxItems: 1
+
+  vddd-supply:
+    description: Chip digital core regulator (1.12V).
+    maxItems: 1
+
+  flash-leds:
+    description: See ../video-interfaces.txt
+
+  lens-focus:
+    description: See ../video-interfaces.txt
+
+  port:
+    type: object
+    description: |
+      Video output port. See ../video-interfaces.txt.
+
+    properties:
+      endpoint:
+        type: object
+
+        properties:
+          data-lanes:
+            $ref: /schemas/types.yaml#/definitions/uint32-array
+            description: See ../video-interfaces.txt
+            anyOf:
+              - items:
+                - const: 1
+                - const: 2
+              - items:
+                - const: 1
+                - const: 2
+                - const: 3
+                - const: 4
+
+          link-frequencies:
+            $ref: /schemas/types.yaml#/definitions/uint64-array
+            description: See ../video-interfaces.txt
+
+        required:
+          - data-lanes
+          - link-frequencies
+
+        unevaluatedProperties: false
+
+    additionalProperties: false
+
+required:
+  - compatible
+  - reg
+  - clocks
+  - clock-frequency
+  - enable-gpios
+  - vdddo-supply
+  - vdda-supply
+  - vddd-supply
+  - port
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/gpio/gpio.h>
+
+    i2c0 {
+        #address-cells = <1>;
+        #size-cells = <0>;
+
+        camera-sensor@1a {
+            compatible = "sony,imx214";
+            reg = <0x1a>;
+            vdddo-supply = <&pm8994_lvs1>;
+            vddd-supply = <&camera_vddd_1v12>;
+            vdda-supply = <&pm8994_l17>;
+            lens-focus = <&ad5820>;
+            enable-gpios = <&msmgpio 25 GPIO_ACTIVE_HIGH>;
+            clocks = <&camera_clk>;
+            clock-frequency = <24000000>;
+
+            port {
+                imx214_ep: endpoint {
+                    data-lanes = <1 2 3 4>;
+                    link-frequencies = /bits/ 64 <480000000>;
+                    remote-endpoint = <&csiphy0_ep>;
+                };
+            };
+        };
+    };
+
+...
diff --git a/Documentation/devicetree/bindings/media/imx7-csi.txt b/Documentation/devicetree/bindings/media/imx7-csi.txt
deleted file mode 100644 (file)
index d80ceef..0000000
+++ /dev/null
@@ -1,42 +0,0 @@
-Freescale i.MX7 CMOS Sensor Interface
-=====================================
-
-csi node
---------
-
-This is device node for the CMOS Sensor Interface (CSI) which enables the chip
-to connect directly to external CMOS image sensors.
-
-Required properties:
-
-- compatible    : "fsl,imx7-csi" or "fsl,imx6ul-csi";
-- reg           : base address and length of the register set for the device;
-- interrupts    : should contain CSI interrupt;
-- clocks        : list of clock specifiers, see
-        Documentation/devicetree/bindings/clock/clock-bindings.txt for details;
-- clock-names   : must contain "mclk";
-
-The device node shall contain one 'port' child node with one child 'endpoint'
-node, according to the bindings defined in:
-Documentation/devicetree/bindings/media/video-interfaces.txt.
-
-In the following example a remote endpoint is a video multiplexer.
-
-example:
-
-                csi: csi@30710000 {
-                        #address-cells = <1>;
-                        #size-cells = <0>;
-
-                        compatible = "fsl,imx7-csi";
-                        reg = <0x30710000 0x10000>;
-                        interrupts = <GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH>;
-                        clocks = <&clks IMX7D_CSI_MCLK_ROOT_CLK>;
-                        clock-names = "mclk";
-
-                        port {
-                                csi_from_csi_mux: endpoint {
-                                        remote-endpoint = <&csi_mux_to_csi>;
-                                };
-                        };
-                };
diff --git a/Documentation/devicetree/bindings/media/imx7-mipi-csi2.txt b/Documentation/devicetree/bindings/media/imx7-mipi-csi2.txt
deleted file mode 100644 (file)
index 71fd74e..0000000
+++ /dev/null
@@ -1,90 +0,0 @@
-Freescale i.MX7 Mipi CSI2
-=========================
-
-mipi_csi2 node
---------------
-
-This is the device node for the MIPI CSI-2 receiver core in i.MX7 SoC. It is
-compatible with previous version of Samsung D-phy.
-
-Required properties:
-
-- compatible    : "fsl,imx7-mipi-csi2";
-- reg           : base address and length of the register set for the device;
-- interrupts    : should contain MIPI CSIS interrupt;
-- clocks        : list of clock specifiers, see
-        Documentation/devicetree/bindings/clock/clock-bindings.txt for details;
-- clock-names   : must contain "pclk", "wrap" and "phy" entries, matching
-                  entries in the clock property;
-- power-domains : a phandle to the power domain, see
-          Documentation/devicetree/bindings/power/power_domain.txt for details.
-- reset-names   : should include following entry "mrst";
-- resets        : a list of phandle, should contain reset entry of
-                  reset-names;
-- phy-supply    : from the generic phy bindings, a phandle to a regulator that
-                 provides power to MIPI CSIS core;
-
-Optional properties:
-
-- clock-frequency : The IP's main (system bus) clock frequency in Hz, default
-                   value when this property is not specified is 166 MHz;
-- fsl,csis-hs-settle : differential receiver (HS-RX) settle time;
-
-The device node should contain two 'port' child nodes with one child 'endpoint'
-node, according to the bindings defined in:
- Documentation/devicetree/bindings/ media/video-interfaces.txt.
- The following are properties specific to those nodes.
-
-port node
----------
-
-- reg            : (required) can take the values 0 or 1, where 0 shall be
-                     related to the sink port and port 1 shall be the source
-                     one;
-
-endpoint node
--------------
-
-- data-lanes    : (required) an array specifying active physical MIPI-CSI2
-                   data input lanes and their mapping to logical lanes; this
-                    shall only be applied to port 0 (sink port), the array's
-                    content is unused only its length is meaningful,
-                    in this case the maximum length supported is 2;
-
-example:
-
-        mipi_csi: mipi-csi@30750000 {
-                #address-cells = <1>;
-                #size-cells = <0>;
-
-                compatible = "fsl,imx7-mipi-csi2";
-                reg = <0x30750000 0x10000>;
-                interrupts = <GIC_SPI 25 IRQ_TYPE_LEVEL_HIGH>;
-                clocks = <&clks IMX7D_IPG_ROOT_CLK>,
-                                <&clks IMX7D_MIPI_CSI_ROOT_CLK>,
-                                <&clks IMX7D_MIPI_DPHY_ROOT_CLK>;
-                clock-names = "pclk", "wrap", "phy";
-                clock-frequency = <166000000>;
-                power-domains = <&pgc_mipi_phy>;
-                phy-supply = <&reg_1p0d>;
-                resets = <&src IMX7_RESET_MIPI_PHY_MRST>;
-                reset-names = "mrst";
-                fsl,csis-hs-settle = <3>;
-
-                port@0 {
-                        reg = <0>;
-
-                        mipi_from_sensor: endpoint {
-                                remote-endpoint = <&ov2680_to_mipi>;
-                                data-lanes = <1>;
-                        };
-                };
-
-                port@1 {
-                        reg = <1>;
-
-                        mipi_vc0_to_csi_mux: endpoint {
-                                remote-endpoint = <&csi_mux_from_mipi_vc0>;
-                        };
-                };
-        };
diff --git a/Documentation/devicetree/bindings/media/nxp,imx7-csi.yaml b/Documentation/devicetree/bindings/media/nxp,imx7-csi.yaml
new file mode 100644 (file)
index 0000000..4e81a47
--- /dev/null
@@ -0,0 +1,71 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/media/nxp,imx7-csi.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: i.MX7 CMOS Sensor Interface
+
+maintainers:
+  - Rui Miguel Silva <rmfrfs@gmail.com>
+
+description: |
+  This is device node for the CMOS Sensor Interface (CSI) which enables the
+  chip to connect directly to external CMOS image sensors.
+
+properties:
+  compatible:
+    enum:
+      - fsl,imx7-csi
+      - fsl,imx6ul-csi
+
+  reg:
+    maxItems: 1
+
+  interrupts:
+    maxItems: 1
+
+  clocks:
+    maxItems: 1
+
+  clock-names:
+    items:
+      - const: mclk
+
+  port:
+    type: object
+    description:
+      A node containing input port nodes with endpoint definitions as documented
+      in Documentation/devicetree/bindings/media/video-interfaces.txt
+
+required:
+  - compatible
+  - reg
+  - interrupts
+  - clocks
+  - clock-names
+  - port
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/clock/imx7d-clock.h>
+    #include <dt-bindings/interrupt-controller/arm-gic.h>
+    #include <dt-bindings/interrupt-controller/irq.h>
+
+    csi: csi@30710000 {
+            compatible = "fsl,imx7-csi";
+            reg = <0x30710000 0x10000>;
+            interrupts = <GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH>;
+            clocks = <&clks IMX7D_CSI_MCLK_ROOT_CLK>;
+            clock-names = "mclk";
+
+            port {
+                    csi_from_csi_mux: endpoint {
+                            remote-endpoint = <&csi_mux_to_csi>;
+                    };
+            };
+    };
+
+...
diff --git a/Documentation/devicetree/bindings/media/nxp,imx7-mipi-csi2.yaml b/Documentation/devicetree/bindings/media/nxp,imx7-mipi-csi2.yaml
new file mode 100644 (file)
index 0000000..0668332
--- /dev/null
@@ -0,0 +1,173 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/media/nxp,imx7-mipi-csi2.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: NXP i.MX7 Mipi CSI2
+
+maintainers:
+  - Rui Miguel Silva <rmfrfs@gmail.com>
+
+description: |
+  This is the device node for the MIPI CSI-2 receiver core in i.MX7 soc. It is
+  compatible with previous version of samsung d-phy.
+
+properties:
+  compatible:
+    const: fsl,imx7-mipi-csi2
+
+  reg:
+    maxItems: 1
+
+  interrupts:
+    maxItems: 1
+
+  clocks:
+    minItems: 3
+    maxItems: 3
+
+  clock-names:
+    items:
+      - const: pclk
+      - const: wrap
+      - const: phy
+
+  power-domains:
+    maxItems: 1
+
+  phy-supply:
+    description:
+      Phandle to a regulator that provides power to the PHY. This
+      regulator will be managed during the PHY power on/off sequence.
+
+  resets:
+    maxItems: 1
+
+  reset-names:
+    const: mrst
+
+  clock-frequency:
+    description:
+      The IP main (system bus) clock frequency in Hertz
+    default: 166000000
+
+  fsl,csis-hs-settle:
+    $ref: /schemas/types.yaml#/definitions/uint32
+    description:
+      Differential receiver (HS-RX) settle time
+
+  ports:
+    type: object
+    description:
+      A node containing input and output port nodes with endpoint definitions
+      as documented in
+      Documentation/devicetree/bindings/media/video-interfaces.txt
+
+    properties:
+      '#address-cells':
+        const: 1
+
+      '#size-cells':
+        const: 0
+
+      port@0:
+        type: object
+        description:
+          Input port node, single endpoint describing the CSI-2 transmitter.
+
+        properties:
+          reg:
+            const: 0
+
+          endpoint:
+            type: object
+
+            properties:
+              data-lanes:
+                $ref: /schemas/types.yaml#/definitions/uint32-array
+                description: See ../video-interfaces.txt
+                oneOf:
+                  - items:
+                      - const: 1
+                  - items:
+                      - const: 1
+                      - const: 2
+
+              remote-endpoint: true
+
+            required:
+              - data-lanes
+              - remote-endpoint
+
+            additionalProperties: false
+
+        additionalProperties: false
+
+      port@1:
+        type: object
+        description:
+          Output port node
+
+required:
+  - compatible
+  - reg
+  - interrupts
+  - clocks
+  - clock-names
+  - power-domains
+  - phy-supply
+  - resets
+  - reset-names
+  - ports
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/clock/imx7d-clock.h>
+    #include <dt-bindings/interrupt-controller/arm-gic.h>
+    #include <dt-bindings/interrupt-controller/irq.h>
+    #include <dt-bindings/reset/imx7-reset.h>
+
+    mipi_csi: mipi-csi@30750000 {
+            compatible = "fsl,imx7-mipi-csi2";
+            reg = <0x30750000 0x10000>;
+            interrupts = <GIC_SPI 25 IRQ_TYPE_LEVEL_HIGH>;
+
+            clocks = <&clks IMX7D_IPG_ROOT_CLK>,
+                     <&clks IMX7D_MIPI_CSI_ROOT_CLK>,
+                     <&clks IMX7D_MIPI_DPHY_ROOT_CLK>;
+            clock-names = "pclk", "wrap", "phy";
+            clock-frequency = <166000000>;
+
+            power-domains = <&pgc_mipi_phy>;
+            phy-supply = <&reg_1p0d>;
+            resets = <&src IMX7_RESET_MIPI_PHY_MRST>;
+            reset-names = "mrst";
+            fsl,csis-hs-settle = <3>;
+
+            ports {
+                    #address-cells = <1>;
+                    #size-cells = <0>;
+
+                    port@0 {
+                            reg = <0>;
+
+                            mipi_from_sensor: endpoint {
+                                    remote-endpoint = <&ov2680_to_mipi>;
+                                    data-lanes = <1>;
+                            };
+                    };
+
+                    port@1 {
+                            reg = <1>;
+
+                            mipi_vc0_to_csi_mux: endpoint {
+                                    remote-endpoint = <&csi_mux_from_mipi_vc0>;
+                            };
+                    };
+            };
+    };
+
+...
index 09eb6ed..4982346 100644 (file)
@@ -8,6 +8,7 @@ Qualcomm Camera Subsystem
        Definition: Should contain one of:
                - "qcom,msm8916-camss"
                - "qcom,msm8996-camss"
+               - "qcom,sdm660-camss"
 - reg:
        Usage: required
        Value type: <prop-encoded-array>
@@ -64,30 +65,36 @@ Qualcomm Camera Subsystem
        Value type: <stringlist>
        Definition: Should contain the following entries:
                - "top_ahb"
+               - "throttle_axi"        (660 only)
                - "ispif_ahb"
                - "csiphy0_timer"
                - "csiphy1_timer"
                - "csiphy2_timer"       (8996 only)
+               - "csiphy_ahb2crif"     (660 only)
                - "csi0_ahb"
                - "csi0"
                - "csi0_phy"
                - "csi0_pix"
                - "csi0_rdi"
+               - "cphy_csid0"          (660 only)
                - "csi1_ahb"
                - "csi1"
                - "csi1_phy"
                - "csi1_pix"
                - "csi1_rdi"
+               - "cphy_csid1"          (660 only)
                - "csi2_ahb"            (8996 only)
                - "csi2"                (8996 only)
                - "csi2_phy"            (8996 only)
                - "csi2_pix"            (8996 only)
                - "csi2_rdi"            (8996 only)
+               - "cphy_csid2"          (660 only)
                - "csi3_ahb"            (8996 only)
                - "csi3"                (8996 only)
                - "csi3_phy"            (8996 only)
                - "csi3_pix"            (8996 only)
                - "csi3_rdi"            (8996 only)
+               - "cphy_csid3"          (660 only)
                - "ahb"
                - "vfe0"
                - "csi_vfe0"
index 8ad2cba..03cf40f 100644 (file)
@@ -83,6 +83,7 @@ properties:
       - rc-it913x-v2
       - rc-kaiomy
       - rc-khadas
+      - rc-khamsin
       - rc-kworld-315u
       - rc-kworld-pc150u
       - rc-kworld-plus-tv-analog
diff --git a/Documentation/devicetree/bindings/media/rockchip-isp1.yaml b/Documentation/devicetree/bindings/media/rockchip-isp1.yaml
new file mode 100644 (file)
index 0000000..2004c05
--- /dev/null
@@ -0,0 +1,215 @@
+# SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/media/rockchip-isp1.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Rockchip SoC Image Signal Processing unit v1
+
+maintainers:
+  - Helen Koike <helen.koike@collabora.com>
+
+description: |
+  Rockchip ISP1 is the Camera interface for the Rockchip series of SoCs
+  which contains image processing, scaling, and compression functions.
+
+properties:
+  compatible:
+    const: rockchip,rk3399-cif-isp
+
+  reg:
+    maxItems: 1
+
+  interrupts:
+    maxItems: 1
+
+  clocks:
+    minItems: 3
+    items:
+      # isp0 and isp1
+      - description: ISP clock
+      - description: ISP AXI clock
+      - description: ISP AHB clock
+      # only for isp1
+      - description: ISP Pixel clock
+
+  clock-names:
+    minItems: 3
+    items:
+      # isp0 and isp1
+      - const: isp
+      - const: aclk
+      - const: hclk
+      # only for isp1
+      - const: pclk_isp
+
+  iommus:
+    maxItems: 1
+
+  phys:
+    maxItems: 1
+    description: phandle for the PHY port
+
+  phy-names:
+    const: dphy
+
+  power-domains:
+    maxItems: 1
+
+  # See ./video-interfaces.txt for details
+  ports:
+    type: object
+    additionalProperties: false
+
+    properties:
+      "#address-cells":
+        const: 1
+
+      "#size-cells":
+        const: 0
+
+      port@0:
+        type: object
+        description: connection point for sensors at MIPI-DPHY RX0
+        additionalProperties: false
+
+        properties:
+          "#address-cells":
+            const: 1
+
+          "#size-cells":
+            const: 0
+
+          reg:
+            const: 0
+
+        patternProperties:
+          endpoint:
+            type: object
+            additionalProperties: false
+
+            properties:
+              reg:
+                maxItems: 1
+
+              data-lanes:
+                minItems: 1
+                maxItems: 4
+
+              remote-endpoint: true
+
+        required:
+          - reg
+          - "#address-cells"
+          - "#size-cells"
+
+    required:
+      - "#address-cells"
+      - "#size-cells"
+      - port@0
+
+required:
+  - compatible
+  - reg
+  - interrupts
+  - clocks
+  - clock-names
+  - iommus
+  - phys
+  - phy-names
+  - power-domains
+  - ports
+
+if:
+  properties:
+    compatible:
+      contains:
+        const: rockchip,rk3399-cif-isp
+then:
+  properties:
+    clocks:
+      minItems: 3
+      maxItems: 4
+    clock-names:
+      minItems: 3
+      maxItems: 4
+
+additionalProperties: false
+
+examples:
+  - |
+
+    #include <dt-bindings/clock/rk3399-cru.h>
+    #include <dt-bindings/interrupt-controller/arm-gic.h>
+    #include <dt-bindings/power/rk3399-power.h>
+
+    parent0: parent {
+        #address-cells = <2>;
+        #size-cells = <2>;
+
+        isp0: isp0@ff910000 {
+            compatible = "rockchip,rk3399-cif-isp";
+            reg = <0x0 0xff910000 0x0 0x4000>;
+            interrupts = <GIC_SPI 43 IRQ_TYPE_LEVEL_HIGH 0>;
+            clocks = <&cru SCLK_ISP0>,
+                     <&cru ACLK_ISP0_WRAPPER>,
+                     <&cru HCLK_ISP0_WRAPPER>;
+            clock-names = "isp", "aclk", "hclk";
+            iommus = <&isp0_mmu>;
+            phys = <&dphy>;
+            phy-names = "dphy";
+            power-domains = <&power RK3399_PD_ISP0>;
+
+            ports {
+                #address-cells = <1>;
+                #size-cells = <0>;
+
+                port@0 {
+                    reg = <0>;
+                    #address-cells = <1>;
+                    #size-cells = <0>;
+
+                    mipi_in_wcam: endpoint@0 {
+                        reg = <0>;
+                        remote-endpoint = <&wcam_out>;
+                        data-lanes = <1 2>;
+                    };
+
+                    mipi_in_ucam: endpoint@1 {
+                        reg = <1>;
+                        remote-endpoint = <&ucam_out>;
+                        data-lanes = <1>;
+                    };
+                };
+            };
+        };
+
+        i2c7: i2c {
+            #address-cells = <1>;
+            #size-cells = <0>;
+
+            wcam: camera@36 {
+                compatible = "ovti,ov5695";
+                reg = <0x36>;
+
+                port {
+                    wcam_out: endpoint {
+                        remote-endpoint = <&mipi_in_wcam>;
+                        data-lanes = <1 2>;
+                    };
+                };
+            };
+
+            ucam: camera@3c {
+                compatible = "ovti,ov2685";
+                reg = <0x3c>;
+
+                  port {
+                      ucam_out: endpoint {
+                          remote-endpoint = <&mipi_in_ucam>;
+                          data-lanes = <1>;
+                      };
+                  };
+            };
+        };
+    };
index 3fe778c..c18574b 100644 (file)
@@ -44,6 +44,43 @@ properties:
       bindings defined in
       Documentation/devicetree/bindings/media/video-interfaces.txt.
 
+    properties:
+      endpoint:
+        type: object
+
+        properties:
+          bus-type:
+            enum: [5, 6]
+            default: 5
+
+          bus-width:
+            enum: [8, 10, 12, 14]
+            default: 8
+
+          remote-endpoint: true
+
+        allOf:
+          - if:
+              properties:
+                bus-type:
+                  const: 6
+
+            then:
+              properties:
+                hsync-active: false
+                vsync-active: false
+                bus-width:
+                  enum: [8]
+
+        required:
+          - remote-endpoint
+          - bus-type
+          - pclk-sample
+
+        unevaluatedProperties: false
+
+    additionalProperties: false
+
 required:
   - compatible
   - reg
@@ -75,6 +112,7 @@ examples:
         port {
              dcmi_0: endpoint {
                    remote-endpoint = <&ov5640_0>;
+                   bus-type = <5>;
                    bus-width = <8>;
                    hsync-active = <0>;
                    vsync-active = <0>;
index 4d1ae12..ffb0cad 100644 (file)
@@ -132,3 +132,16 @@ used to obtain device's power state after the power state transition:
 The function returns a non-zero value if it succeeded getting the power count or
 runtime PM was disabled, in either of which cases the driver may proceed to
 access the device.
+
+Controls
+--------
+
+For camera sensors that are connected to a bus where transmitter and receiver
+require common configuration set by drivers, such as CSI-2 or parallel (BT.601
+or BT.656) bus, the ``V4L2_CID_LINK_FREQ`` control is mandatory on transmitter
+drivers. Receiver drivers can use the ``V4L2_CID_LINK_FREQ`` to query the
+frequency used on the bus.
+
+The transmitter drivers should also implement ``V4L2_CID_PIXEL_RATE`` control in
+order to tell the maximum pixel rate to the receiver. This is required on raw
+camera sensors.
index bc42982..a26dc87 100644 (file)
@@ -143,7 +143,7 @@ To enable/disable the 'monitor all' mode::
        int (*adap_monitor_all_enable)(struct cec_adapter *adap, bool enable);
 
 If enabled, then the adapter should be put in a mode to also monitor messages
-that not for us. Not all hardware supports this and this function is only
+that are not for us. Not all hardware supports this and this function is only
 called if the CEC_CAP_MONITOR_ALL capability is set. This callback is optional
 (some hardware may always be in 'monitor all' mode).
 
@@ -335,7 +335,7 @@ So this must work:
        $ cat einj.txt >error-inj
 
 The first callback is called when this file is read and it should show the
-the current error injection state::
+current error injection state::
 
        int (*error_inj_show)(struct cec_adapter *adap, struct seq_file *sf);
 
index e1b8380..e3bbc6b 100644 (file)
@@ -28,10 +28,9 @@ interface elements must be present on the sub-device represents the
 CSI-2 transmitter.
 
 The V4L2_CID_LINK_FREQ control is used to tell the receiver driver the
-frequency (and not the symbol rate) of the link. The
-V4L2_CID_PIXEL_RATE is may be used by the receiver to obtain the pixel
-rate the transmitter uses. The
-:c:type:`v4l2_subdev_video_ops`->s_stream() callback provides an
+frequency (and not the symbol rate) of the link. The V4L2_CID_PIXEL_RATE
+control may be used by the receiver to obtain the pixel rate the transmitter
+uses. The :c:type:`v4l2_subdev_video_ops`->s_stream() callback provides an
 ability to start and stop the stream.
 
 The value of the V4L2_CID_PIXEL_RATE is calculated as follows::
index 91f77fe..ea43cdb 100644 (file)
@@ -244,7 +244,7 @@ Carrier Signal to Noise ratio (:ref:`DTV-STAT-CNR`)
     Having it available after inner FEC is more common.
 
 Bit counts post-FEC (:ref:`DTV-STAT-POST-ERROR-BIT-COUNT` and :ref:`DTV-STAT-POST-TOTAL-BIT-COUNT`)
-  - Those counters measure the number of bits and bit errors errors after
+  - Those counters measure the number of bits and bit errors after
     the forward error correction (FEC) on the inner coding block
     (after Viterbi, LDPC or other inner code).
 
@@ -253,7 +253,7 @@ Bit counts post-FEC (:ref:`DTV-STAT-POST-ERROR-BIT-COUNT` and :ref:`DTV-STAT-POS
     see :c:type:`fe_status`).
 
 Bit counts pre-FEC (:ref:`DTV-STAT-PRE-ERROR-BIT-COUNT` and :ref:`DTV-STAT-PRE-TOTAL-BIT-COUNT`)
-  - Those counters measure the number of bits and bit errors errors before
+  - Those counters measure the number of bits and bit errors before
     the forward error correction (FEC) on the inner coding block
     (before Viterbi, LDPC or other inner code).
 
@@ -263,7 +263,7 @@ Bit counts pre-FEC (:ref:`DTV-STAT-PRE-ERROR-BIT-COUNT` and :ref:`DTV-STAT-PRE-T
     after ``FE_HAS_VITERBI``, see :c:type:`fe_status`).
 
 Block counts (:ref:`DTV-STAT-ERROR-BLOCK-COUNT` and :ref:`DTV-STAT-TOTAL-BLOCK-COUNT`)
-  - Those counters measure the number of blocks and block errors errors after
+  - Those counters measure the number of blocks and block errors after
     the forward error correction (FEC) on the inner coding block
     (before Viterbi, LDPC or other inner code).
 
index 77f42ea..b2e9180 100644 (file)
@@ -335,7 +335,7 @@ current and new values:
        union v4l2_ctrl_ptr p_new;
        union v4l2_ctrl_ptr p_cur;
 
-If the control has a simple s32 type type, then:
+If the control has a simple s32 type, then:
 
 .. code-block:: c
 
@@ -349,7 +349,7 @@ Within the control ops you can freely use these. The val and cur.val speak for
 themselves. The p_char pointers point to character buffers of length
 ctrl->maximum + 1, and are always 0-terminated.
 
-Unless the control is marked volatile the p_cur field points to the the
+Unless the control is marked volatile the p_cur field points to the
 current cached control value. When you create a new control this value is made
 identical to the default value. After calling v4l2_ctrl_handler_setup() this
 value is passed to the hardware. It is generally a good idea to call this
index 666330a..99e3b5f 100644 (file)
@@ -212,7 +212,7 @@ types exist:
 ========================== ====================         ==============================
 
 The last argument gives you a certain amount of control over the device
-device node number used (i.e. the X in ``videoX``). Normally you will pass -1
+node number used (i.e. the X in ``videoX``). Normally you will pass -1
 to let the v4l2 framework pick the first free number. But sometimes users
 want to select a specific node number. It is common that drivers allow
 the user to select a specific device node number through a driver module
index d3387b1..663bdef 100644 (file)
@@ -188,7 +188,7 @@ Available follower modes are:
        in combination with :ref:`CEC_MODE_NO_INITIATOR <CEC-MODE-NO-INITIATOR>`, otherwise
        the ``EINVAL`` error code will be returned. In 'monitor all' mode all messages
        this CEC device transmits and all messages it receives, including
-       directed messages for other CEC devices will be reported. This is
+       directed messages for other CEC devices, will be reported. This is
        very useful for debugging, but not all devices support this. This
        mode requires that the :ref:`CEC_CAP_MONITOR_ALL <CEC-CAP-MONITOR-ALL>` capability is set,
        otherwise the ``EINVAL`` error code is returned. This is only allowed if
index 071abac..eaae567 100644 (file)
@@ -8,7 +8,7 @@ Digital TV Audio Device
 
 The Digital TV audio device controls the MPEG2 audio decoder of the Digital
 TV hardware. It can be accessed through ``/dev/dvb/adapter?/audio?``. Data
-types and and ioctl definitions can be accessed by including
+types and ioctl definitions can be accessed by including
 ``linux/dvb/audio.h`` in your application.
 
 Please note that some Digital TV cards don’t have their own MPEG decoder, which
index 6f6821e..0dc00e5 100644 (file)
@@ -7,7 +7,7 @@ Digital TV CA Device
 ####################
 
 The Digital TV CA device controls the conditional access hardware. It
-can be accessed through ``/dev/dvb/adapter?/ca?``. Data types and and ioctl
+can be accessed through ``/dev/dvb/adapter?/ca?``. Data types and ioctl
 definitions can be accessed by including ``linux/dvb/ca.h`` in your
 application.
 
index 364ef48..ef05abc 100644 (file)
@@ -11,7 +11,7 @@ digital TV. If the driver and hardware supports, those filters are
 implemented at the hardware. Otherwise, the Kernel provides a software
 emulation.
 
-It can be accessed through ``/dev/adapter?/demux?``. Data types and and
+It can be accessed through ``/dev/adapter?/demux?``. Data types and
 ioctl definitions can be accessed by including ``linux/dvb/dmx.h`` in
 your application.
 
index 17e7014..1a13a33 100644 (file)
@@ -50,7 +50,7 @@ by a :ref:`DMX_QUERYBUF` ioctl will do as well.
 When ``DMX_QBUF`` is called with a pointer to this structure, it locks the
 memory pages of the buffer in physical memory, so they cannot be swapped
 out to disk. Buffers remain locked until dequeued, until the
-the device is closed.
+device is closed.
 
 Applications call the ``DMX_DQBUF`` ioctl to dequeue a filled
 (capturing) buffer from the driver's outgoing queue.
index 33368f5..020a023 100644 (file)
@@ -23,7 +23,7 @@ types that are present on the transport stream. This is done through
 virtual ``dvb?_?`` network interfaces, and will be controlled/routed via
 the standard ip tools (like ip, route, netstat, ifconfig, etc).
 
-Data types and and ioctl definitions are defined via ``linux/dvb/net.h``
+Data types and ioctl definitions are defined via ``linux/dvb/net.h``
 header.
 
 
index 3ed1bbf..38a8d39 100644 (file)
@@ -8,7 +8,7 @@ Digital TV Video Device
 
 The Digital TV video device controls the MPEG2 video decoder of the Digital
 TV hardware. It can be accessed through **/dev/dvb/adapter0/video0**. Data
-types and and ioctl definitions can be accessed by including
+types and ioctl definitions can be accessed by including
 **linux/dvb/video.h** in your application.
 
 Note that the Digital TV video device only controls decoding of the MPEG video
index ac768d7..e74b73c 100644 (file)
@@ -64,6 +64,7 @@ ignore symbol RC_PROTO_RCMM12
 ignore symbol RC_PROTO_RCMM24
 ignore symbol RC_PROTO_RCMM32
 ignore symbol RC_PROTO_XBOX_DVD
+ignore symbol RC_PROTO_MAX
 
 # Undocumented macros
 
index 0b50cfa..243e02d 100644 (file)
@@ -1,4 +1,4 @@
-.. SPDX-License-Identifier: GFDL-1.1-no-invariants-or-later
+.. SPDX-License-Identifier: GPL-2.0 OR GFDL-1.1-no-invariants-or-later
 
 file: uapi/v4l/keytable.c
 =========================
index 167b354..c889737 100644 (file)
@@ -1,4 +1,4 @@
-.. SPDX-License-Identifier: GFDL-1.1-no-invariants-or-later
+.. SPDX-License-Identifier: GPL-2.0 OR GFDL-1.1-no-invariants-or-later
 
 .. _lirc_dev_intro:
 
@@ -57,12 +57,12 @@ on the following table.
 
     This mode is for both sending and receiving IR.
 
-    For transmitting (aka sending), create a ``struct lirc_scancode`` with
+    For transmitting (aka sending), create a struct lirc_scancode with
     the desired scancode set in the ``scancode`` member, :c:type:`rc_proto`
     set to the :ref:`IR protocol <Remote_controllers_Protocols>`, and all other
     members set to 0. Write this struct to the lirc device.
 
-    For receiving, you read ``struct lirc_scancode`` from the LIRC device.
+    For receiving, you read struct lirc_scancode from the LIRC device.
     The ``scancode`` field is set to the received scancode and the
     :ref:`IR protocol <Remote_controllers_Protocols>` is set in
     :c:type:`rc_proto`. If the scancode maps to a valid key code, this is set
@@ -136,6 +136,13 @@ on the following table.
 
     This mode is used only for IR send.
 
+*************************************
+Data types used by LIRC_MODE_SCANCODE
+*************************************
+
+.. kernel-doc:: include/uapi/linux/lirc.h
+    :identifiers: lirc_scancode rc_proto
+
 ********************
 BPF based IR decoder
 ********************
index 5510dc0..978f86d 100644 (file)
@@ -1,4 +1,4 @@
-.. SPDX-License-Identifier: GFDL-1.1-no-invariants-or-later
+.. SPDX-License-Identifier: GPL-2.0 OR GFDL-1.1-no-invariants-or-later
 
 .. _lirc_dev:
 
index 420a3db..793f295 100644 (file)
@@ -1,4 +1,4 @@
-.. SPDX-License-Identifier: GFDL-1.1-no-invariants-or-later
+.. SPDX-License-Identifier: GPL-2.0 OR GFDL-1.1-no-invariants-or-later
 
 .. _lirc_func:
 
index 66a243d..4bf2586 100644 (file)
@@ -1,4 +1,4 @@
-.. SPDX-License-Identifier: GFDL-1.1-no-invariants-or-later
+.. SPDX-License-Identifier: GPL-2.0 OR GFDL-1.1-no-invariants-or-later
 .. c:namespace:: RC
 
 .. _lirc_get_features:
index 188478e..628fe31 100644 (file)
@@ -1,4 +1,4 @@
-.. SPDX-License-Identifier: GFDL-1.1-no-invariants-or-later
+.. SPDX-License-Identifier: GPL-2.0 OR GFDL-1.1-no-invariants-or-later
 .. c:namespace:: RC
 
 .. _lirc_get_rec_mode:
index e29445c..4dfa9c2 100644 (file)
@@ -1,4 +1,4 @@
-.. SPDX-License-Identifier: GFDL-1.1-no-invariants-or-later
+.. SPDX-License-Identifier: GPL-2.0 OR GFDL-1.1-no-invariants-or-later
 .. c:namespace:: RC
 
 .. _lirc_get_rec_resolution:
index 77472fb..6378718 100644 (file)
@@ -1,4 +1,4 @@
-.. SPDX-License-Identifier: GFDL-1.1-no-invariants-or-later
+.. SPDX-License-Identifier: GPL-2.0 OR GFDL-1.1-no-invariants-or-later
 .. c:namespace:: RC
 
 .. _lirc_get_send_mode:
index f5f3e06..597c328 100644 (file)
@@ -1,4 +1,4 @@
-.. SPDX-License-Identifier: GFDL-1.1-no-invariants-or-later
+.. SPDX-License-Identifier: GPL-2.0 OR GFDL-1.1-no-invariants-or-later
 .. c:namespace:: RC
 
 .. _lirc_get_min_timeout:
index 8bd0acc..54cb40b 100644 (file)
@@ -1,4 +1,4 @@
-.. SPDX-License-Identifier: GFDL-1.1-no-invariants-or-later
+.. SPDX-License-Identifier: GPL-2.0 OR GFDL-1.1-no-invariants-or-later
 
 .. _lirc_header:
 
index d589560..ce34318 100644 (file)
@@ -1,4 +1,4 @@
-.. SPDX-License-Identifier: GFDL-1.1-no-invariants-or-later
+.. SPDX-License-Identifier: GPL-2.0 OR GFDL-1.1-no-invariants-or-later
 .. c:namespace:: RC
 
 .. _lirc-read:
index 9bf9811..04ced1a 100644 (file)
@@ -1,4 +1,4 @@
-.. SPDX-License-Identifier: GFDL-1.1-no-invariants-or-later
+.. SPDX-License-Identifier: GPL-2.0 OR GFDL-1.1-no-invariants-or-later
 .. c:namespace:: RC
 
 .. _lirc_set_measure_carrier_mode:
index 530bc22..7512dc8 100644 (file)
@@ -1,4 +1,4 @@
-.. SPDX-License-Identifier: GFDL-1.1-no-invariants-or-later
+.. SPDX-License-Identifier: GPL-2.0 OR GFDL-1.1-no-invariants-or-later
 .. c:namespace:: RC
 
 .. _lirc_set_rec_carrier_range:
index 28c928f..60e3214 100644 (file)
@@ -1,4 +1,4 @@
-.. SPDX-License-Identifier: GFDL-1.1-no-invariants-or-later
+.. SPDX-License-Identifier: GPL-2.0 OR GFDL-1.1-no-invariants-or-later
 .. c:namespace:: RC
 
 .. _lirc_set_rec_carrier:
index 83e7155..aebe810 100644 (file)
@@ -1,4 +1,4 @@
-.. SPDX-License-Identifier: GFDL-1.1-no-invariants-or-later
+.. SPDX-License-Identifier: GPL-2.0 OR GFDL-1.1-no-invariants-or-later
 .. c:namespace:: RC
 
 .. _lirc_set_rec_timeout_reports:
index 8f3f9ad..bf9fb2c 100644 (file)
@@ -1,4 +1,4 @@
-.. SPDX-License-Identifier: GFDL-1.1-no-invariants-or-later
+.. SPDX-License-Identifier: GPL-2.0 OR GFDL-1.1-no-invariants-or-later
 .. c:namespace:: RC
 
 .. _lirc_set_rec_timeout:
index e3810ba..a003f94 100644 (file)
@@ -1,4 +1,4 @@
-.. SPDX-License-Identifier: GFDL-1.1-no-invariants-or-later
+.. SPDX-License-Identifier: GPL-2.0 OR GFDL-1.1-no-invariants-or-later
 .. c:namespace:: RC
 
 .. _lirc_set_send_carrier:
index 52a0725..2979752 100644 (file)
@@ -1,4 +1,4 @@
-.. SPDX-License-Identifier: GFDL-1.1-no-invariants-or-later
+.. SPDX-License-Identifier: GPL-2.0 OR GFDL-1.1-no-invariants-or-later
 .. c:namespace:: RC
 
 .. _lirc_set_send_duty_cycle:
index 68f4cc2..38acbcd 100644 (file)
@@ -1,4 +1,4 @@
-.. SPDX-License-Identifier: GFDL-1.1-no-invariants-or-later
+.. SPDX-License-Identifier: GPL-2.0 OR GFDL-1.1-no-invariants-or-later
 .. c:namespace:: RC
 
 .. _lirc_set_transmitter_mask:
index be5321c..c9d578e 100644 (file)
@@ -1,4 +1,4 @@
-.. SPDX-License-Identifier: GFDL-1.1-no-invariants-or-later
+.. SPDX-License-Identifier: GPL-2.0 OR GFDL-1.1-no-invariants-or-later
 .. c:namespace:: RC
 
 .. _lirc_set_wideband_receiver:
index c1c3230..970a8b3 100644 (file)
@@ -1,4 +1,4 @@
-.. SPDX-License-Identifier: GFDL-1.1-no-invariants-or-later
+.. SPDX-License-Identifier: GPL-2.0 OR GFDL-1.1-no-invariants-or-later
 .. c:namespace:: RC
 
 .. _lirc-write:
index 1338478..2ba62cd 100644 (file)
@@ -1,4 +1,4 @@
-.. SPDX-License-Identifier: GFDL-1.1-no-invariants-or-later
+.. SPDX-License-Identifier: GPL-2.0 OR GFDL-1.1-no-invariants-or-later
 
 .. _Remote_controllers_Intro:
 
index 2e29058..a2eab3b 100644 (file)
@@ -1,4 +1,4 @@
-.. SPDX-License-Identifier: GFDL-1.1-no-invariants-or-later
+.. SPDX-License-Identifier: GPL-2.0 OR GFDL-1.1-no-invariants-or-later
 
 .. _Remote_controllers_Protocols:
 
index 43c4426..34d6a0a 100644 (file)
@@ -1,4 +1,4 @@
-.. SPDX-License-Identifier: GFDL-1.1-no-invariants-or-later
+.. SPDX-License-Identifier: GPL-2.0 OR GFDL-1.1-no-invariants-or-later
 
 .. _remote_controllers_sysfs_nodes:
 
index 61c77b0..d7de8a5 100644 (file)
@@ -1,4 +1,4 @@
-.. SPDX-License-Identifier: GFDL-1.1-no-invariants-or-later
+.. SPDX-License-Identifier: GPL-2.0 OR GFDL-1.1-no-invariants-or-later
 
 .. _Remote_controllers_table_change:
 
index 8dc1165..aafbfda 100644 (file)
@@ -1,4 +1,4 @@
-.. SPDX-License-Identifier: GFDL-1.1-no-invariants-or-later
+.. SPDX-License-Identifier: GPL-2.0 OR GFDL-1.1-no-invariants-or-later
 
 .. _Remote_controllers_tables:
 
index 2d9078a..f892918 100644 (file)
@@ -1,4 +1,4 @@
-.. SPDX-License-Identifier: GFDL-1.1-no-invariants-or-later
+.. SPDX-License-Identifier: GPL-2.0 OR GFDL-1.1-no-invariants-or-later
 .. include:: <isonum.txt>
 
 .. _remote_controllers:
index 7869b6f..64d241d 100644 (file)
@@ -270,7 +270,17 @@ EBU Tech 3213
 =============
 
 
-:title:     E.B.U. Standard for Chromaticity Tolerances for Studio Monitors"
+:title:     E.B.U. Standard for Chromaticity Tolerances for Studio Monitors
+
+:author:    European Broadcast Union (http://www.ebu.ch)
+
+.. _tech3321:
+
+EBU Tech 3321
+=============
+
+
+:title:     E.B.U. guidelines for Consumer Flat Panel Displays (FPDs)
 
 :author:    European Broadcast Union (http://www.ebu.ch)
 
index 7dbdfbb..1b0fdc1 100644 (file)
@@ -604,7 +604,7 @@ Buffer Flags
        :ref:`VIDIOC_DQBUF <VIDIOC_QBUF>` ioctl is called. Due to
        hardware limitations, the last buffer may be empty. In this case
        the driver will set the ``bytesused`` field to 0, regardless of
-       the format. Any Any subsequent call to the
+       the format. Any subsequent call to the
        :ref:`VIDIOC_DQBUF <VIDIOC_QBUF>` ioctl will not block anymore,
        but return an ``EPIPE`` error code.
     * .. _`V4L2-BUF-FLAG-REQUEST-FD`:
index 014e7c9..126f664 100644 (file)
@@ -674,8 +674,9 @@ Colorspace EBU Tech. 3213 (V4L2_COLORSPACE_470_SYSTEM_BG)
 =========================================================
 
 The :ref:`tech3213` standard defines the colorspace used by PAL/SECAM
-in 1975. In practice this colorspace is obsolete and SMPTE 170M should
-be used instead. The default transfer function is
+in 1975. Note that this colorspace is not supported by the HDMI interface.
+Instead :ref:`tech3321` recommends that Rec. 709 is used instead for HDMI.
+The default transfer function is
 ``V4L2_XFER_FUNC_709``. The default Y'CbCr encoding is
 ``V4L2_YCBCR_ENC_601``. The default Y'CbCr quantization is limited
 range. The chromaticities of the primary colors and the white reference
index 7e43837..f367147 100644 (file)
@@ -46,4 +46,4 @@ important tuning tools using software control loop.
 rkisp1 uAPI data types
 ======================
 
-.. kernel-doc:: drivers/staging/media/rkisp1/uapi/rkisp1-config.h
+.. kernel-doc:: include/uapi/linux/rkisp1-config.h
index 37617ed..fee49bf 100644 (file)
@@ -94,7 +94,7 @@ specified using :ref:`VIDIOC_S_FMT <VIDIOC_G_FMT>` ioctl.
 
 The top left corner, width and height of the source rectangle, that is
 the area from which image date are processed by the hardware, is given
-by the ``V4L2_SEL_TGT_CROP``. Its coordinates are expressed in in the
+by the ``V4L2_SEL_TGT_CROP``. Its coordinates are expressed in the
 same coordinate system as the bounds rectangle. The active cropping area
 must lie completely inside the crop boundaries and the driver may
 further adjust the requested size and/or position according to hardware
index c9b7bb3..7f16cbe 100644 (file)
@@ -7899,3 +7899,30 @@ formats.
       - 0x5001
       - Interleaved raw UYVY and JPEG image format with embedded meta-data
        used by Samsung S3C73MX camera sensors.
+
+.. _v4l2-mbus-metadata-fmts:
+
+Metadata Formats
+^^^^^^^^^^^^^^^^
+
+This section lists all metadata formats.
+
+The following table lists the existing metadata formats.
+
+.. tabularcolumns:: |p{8.0cm}|p{1.4cm}|p{7.7cm}|
+
+.. flat-table:: Metadata formats
+    :header-rows:  1
+    :stub-columns: 0
+
+    * - Identifier
+      - Code
+      - Comments
+    * .. _MEDIA-BUS-FMT-METADATA-FIXED:
+
+      - MEDIA_BUS_FMT_METADATA_FIXED
+      - 0x7001
+      - This format should be used when the same driver handles
+       both sides of the link and the bus format is a fixed
+       metadata format that is not configurable from userspace.
+       Width and height will be set to 0 for this format.
index f2173e3..a8d12bd 100644 (file)
@@ -53,7 +53,7 @@ by the ``controls`` fields.
 To get the current value of a set of controls applications initialize
 the ``id``, ``size`` and ``reserved2`` fields of each struct
 :c:type:`v4l2_ext_control` and call the
-:ref:`VIDIOC_G_EXT_CTRLS <VIDIOC_G_EXT_CTRLS>` ioctl. String controls controls must also set the
+:ref:`VIDIOC_G_EXT_CTRLS <VIDIOC_G_EXT_CTRLS>` ioctl. String controls must also set the
 ``string`` field. Controls of compound types
 (``V4L2_CTRL_FLAG_HAS_PAYLOAD`` is set) must set the ``ptr`` field.
 
index 3138c4c..dbcdd51 100644 (file)
@@ -46,7 +46,7 @@ To select a video output applications store the number of the desired
 output in an integer and call the :ref:`VIDIOC_S_OUTPUT <VIDIOC_G_OUTPUT>` ioctl with a
 pointer to this integer. Side effects are possible. For example outputs
 may support different video standards, so the driver may implicitly
-switch the current standard. standard. Because of these possible side
+switch the current standard. Because of these possible side
 effects applications must select an output before querying or
 negotiating any other parameters.
 
index fbf8c59..77e0747 100644 (file)
@@ -163,7 +163,7 @@ EINVAL
     The buffer ``type`` is not supported, or the ``index`` is out of
     bounds, or no buffers have been allocated yet, or the ``userptr`` or
     ``length`` are invalid, or the ``V4L2_BUF_FLAG_REQUEST_FD`` flag was
-    set but the the given ``request_fd`` was invalid, or ``m.fd`` was
+    set but the given ``request_fd`` was invalid, or ``m.fd`` was
     an invalid DMABUF file descriptor.
 
 EIO
index 2daa6ee..a223929 100644 (file)
@@ -1073,6 +1073,7 @@ M:        Hans Verkuil <hverkuil-cisco@xs4all.nl>
 L:     linux-media@vger.kernel.org
 S:     Maintained
 F:     drivers/media/i2c/adv7604*
+F:     Documentation/devicetree/bindings/media/i2c/adv7604.yaml
 
 ANALOG DEVICES INC ADV7842 DRIVER
 M:     Hans Verkuil <hverkuil-cisco@xs4all.nl>
@@ -4343,7 +4344,7 @@ CODA V4L2 MEM2MEM DRIVER
 M:     Philipp Zabel <p.zabel@pengutronix.de>
 L:     linux-media@vger.kernel.org
 S:     Maintained
-F:     Documentation/devicetree/bindings/media/coda.txt
+F:     Documentation/devicetree/bindings/media/coda.yaml
 F:     drivers/media/platform/coda/
 
 CODE OF CONDUCT
@@ -10816,8 +10817,8 @@ L:      linux-media@vger.kernel.org
 S:     Maintained
 T:     git git://linuxtv.org/media_tree.git
 F:     Documentation/admin-guide/media/imx7.rst
-F:     Documentation/devicetree/bindings/media/imx7-csi.txt
-F:     Documentation/devicetree/bindings/media/imx7-mipi-csi2.txt
+F:     Documentation/devicetree/bindings/media/nxp,imx7-csi.yaml
+F:     Documentation/devicetree/bindings/media/nxp,imx7-mipi-csi2.yaml
 F:     drivers/staging/media/imx/imx7-media-csi.c
 F:     drivers/staging/media/imx/imx7-mipi-csis.c
 
@@ -11899,7 +11900,7 @@ M:      Jacopo Mondi <jacopo@jmondi.org>
 L:     linux-media@vger.kernel.org
 S:     Maintained
 T:     git git://linuxtv.org/media_tree.git
-F:     Documentation/devicetree/bindings/media/i2c/aptina,mt9v111.txt
+F:     Documentation/devicetree/bindings/media/i2c/aptina,mt9v111.yaml
 F:     drivers/media/i2c/mt9v111.c
 
 MULTIFUNCTION DEVICES (MFD)
@@ -12856,7 +12857,7 @@ M:      Rui Miguel Silva <rmfrfs@gmail.com>
 L:     linux-media@vger.kernel.org
 S:     Maintained
 T:     git git://linuxtv.org/media_tree.git
-F:     Documentation/devicetree/bindings/media/i2c/ov2680.txt
+F:     Documentation/devicetree/bindings/media/i2c/ov2680.yaml
 F:     drivers/media/i2c/ov2680.c
 
 OMNIVISION OV2685 SENSOR DRIVER
@@ -12926,7 +12927,7 @@ M:      Jacopo Mondi <jacopo@jmondi.org>
 L:     linux-media@vger.kernel.org
 S:     Odd fixes
 T:     git git://linuxtv.org/media_tree.git
-F:     Documentation/devicetree/bindings/media/i2c/ov772x.txt
+F:     Documentation/devicetree/bindings/media/i2c/ovti,ov772x.yaml
 F:     drivers/media/i2c/ov772x.c
 F:     include/media/i2c/ov772x.h
 
@@ -12962,6 +12963,14 @@ T:     git git://linuxtv.org/media_tree.git
 F:     Documentation/devicetree/bindings/media/i2c/ov9650.txt
 F:     drivers/media/i2c/ov9650.c
 
+OMNIVISION OV9734 SENSOR DRIVER
+M:     Tianshu Qiu <tian.shu.qiu@intel.com>
+R:     Bingbu Cao <bingbu.cao@intel.com>
+L:     linux-media@vger.kernel.org
+S:     Maintained
+T:     git git://linuxtv.org/media_tree.git
+F:     drivers/media/i2c/ov9734.c
+
 ONENAND FLASH DRIVER
 M:     Kyungmin Park <kyungmin.park@samsung.com>
 L:     linux-mtd@lists.infradead.org
@@ -14435,6 +14444,7 @@ W:      https://wireless.wiki.kernel.org/en/users/Drivers/ath9k
 F:     drivers/net/wireless/ath/ath9k/
 
 QUALCOMM CAMERA SUBSYSTEM DRIVER
+M:     Robert Foss <robert.foss@linaro.org>
 M:     Todor Tomov <todor.too@gmail.com>
 L:     linux-media@vger.kernel.org
 S:     Maintained
@@ -15008,10 +15018,13 @@ ROCKCHIP ISP V1 DRIVER
 M:     Helen Koike <helen.koike@collabora.com>
 M:     Dafna Hirschfeld <dafna.hirschfeld@collabora.com>
 L:     linux-media@vger.kernel.org
+L:     linux-rockchip@lists.infradead.org
 S:     Maintained
 F:     Documentation/admin-guide/media/rkisp1.rst
+F:     Documentation/devicetree/bindings/media/rockchip-isp1.yaml
 F:     Documentation/userspace-api/media/v4l/pixfmt-meta-rkisp1.rst
-F:     drivers/staging/media/rkisp1/
+F:     drivers/media/platform/rockchip/rkisp1
+F:     include/uapi/linux/rkisp1-config.h
 
 ROCKCHIP RASTER 2D GRAPHIC ACCELERATION UNIT DRIVER
 M:     Jacob Chen <jacob-chen@iotwrt.com>
@@ -16262,7 +16275,7 @@ M:      Ricardo Ribalda <ribalda@kernel.org>
 L:     linux-media@vger.kernel.org
 S:     Maintained
 T:     git git://linuxtv.org/media_tree.git
-F:     Documentation/devicetree/bindings/media/i2c/sony,imx214.txt
+F:     Documentation/devicetree/bindings/media/i2c/sony,imx214.yaml
 F:     drivers/media/i2c/imx214.c
 
 SONY IMX219 SENSOR DRIVER
@@ -19398,6 +19411,13 @@ T:     git git://git.kernel.org/pub/scm/linux/kernel/git/dlemoal/zonefs.git
 F:     Documentation/filesystems/zonefs.rst
 F:     fs/zonefs/
 
+ZPOOL COMPRESSED PAGE STORAGE API
+M:     Dan Streetman <ddstreet@ieee.org>
+L:     linux-mm@kvack.org
+S:     Maintained
+F:     include/linux/zpool.h
+F:     mm/zpool.c
+
 ZR36067 VIDEO FOR LINUX DRIVER
 M:     Corentin Labbe <clabbe@baylibre.com>
 L:     mjpeg-users@lists.sourceforge.net
@@ -19408,13 +19428,6 @@ Q:     https://patchwork.linuxtv.org/project/linux-media/list/
 F:     Documentation/driver-api/media/drivers/zoran.rst
 F:     drivers/staging/media/zoran/
 
-ZPOOL COMPRESSED PAGE STORAGE API
-M:     Dan Streetman <ddstreet@ieee.org>
-L:     linux-mm@kvack.org
-S:     Maintained
-F:     include/linux/zpool.h
-F:     mm/zpool.c
-
 ZRAM COMPRESSED RAM BLOCK DEVICE DRVIER
 M:     Minchan Kim <minchan@kernel.org>
 M:     Nitin Gupta <ngupta@vflare.org>
index a6d073f..6222b3a 100644 (file)
@@ -24,7 +24,6 @@ if MEDIA_SUPPORT
 
 config MEDIA_SUPPORT_FILTER
        bool "Filter media drivers"
-       depends on MEDIA_SUPPORT
        default y if !EMBEDDED && !EXPERT
        help
           Configuring the media subsystem can be complex, as there are
index ece2362..551689d 100644 (file)
@@ -166,12 +166,12 @@ static void cec_devnode_unregister(struct cec_adapter *adap)
                mutex_unlock(&devnode->lock);
                return;
        }
+       devnode->registered = false;
+       devnode->unregistered = true;
 
        list_for_each_entry(fh, &devnode->fhs, list)
                wake_up_interruptible(&fh->wait);
 
-       devnode->registered = false;
-       devnode->unregistered = true;
        mutex_unlock(&devnode->lock);
 
        mutex_lock(&adap->lock);
index d653187..e936c56 100644 (file)
@@ -55,8 +55,6 @@ void saa7146_dma_free(struct saa7146_dev *dev,struct videobuf_queue *q,
        struct videobuf_dmabuf *dma=videobuf_to_dma(&buf->vb);
        DEB_EE("dev:%p, buf:%p\n", dev, buf);
 
-       BUG_ON(in_interrupt());
-
        videobuf_waiton(q, &buf->vb, 0, 0);
        videobuf_dma_unmap(q->dev, dma);
        videobuf_dma_free(dma);
index ccd15b4..7b8795e 100644 (file)
@@ -771,10 +771,8 @@ static int vidioc_s_fmt_vid_overlay(struct file *file, void *__fh, struct v4l2_f
        vv->ov.nclips = f->fmt.win.clipcount;
        if (vv->ov.nclips > 16)
                vv->ov.nclips = 16;
-       if (copy_from_user(vv->ov.clips, f->fmt.win.clips,
-                               sizeof(struct v4l2_clip) * vv->ov.nclips)) {
-               return -EFAULT;
-       }
+       memcpy(vv->ov.clips, f->fmt.win.clips,
+              sizeof(struct v4l2_clip) * vv->ov.nclips);
 
        /* vv->ov.fh is used to indicate that we have valid overlay information, too */
        vv->ov.fh = fh;
index 88f90df..ae17407 100644 (file)
@@ -1169,12 +1169,15 @@ static int smsdvb_hotplug(struct smscore_device_t *coredev,
        rc = dvb_create_media_graph(&client->adapter, true);
        if (rc < 0) {
                pr_err("dvb_create_media_graph failed %d\n", rc);
-               goto client_error;
+               goto media_graph_error;
        }
 
        pr_info("DVB interface registered.\n");
        return 0;
 
+media_graph_error:
+       smsdvb_debugfs_release(client);
+
 client_error:
        dvb_unregister_frontend(&client->frontend);
 
index 959fa28..5ff7bed 100644 (file)
@@ -539,6 +539,9 @@ int dvb_register_device(struct dvb_adapter *adap, struct dvb_device **pdvbdev,
        if (IS_ERR(clsdev)) {
                pr_err("%s: failed to create device dvb%d.%s%d (%ld)\n",
                       __func__, adap->num, dnames[type], id, PTR_ERR(clsdev));
+               dvb_media_device_free(dvbdev);
+               kfree(dvbdevfops);
+               kfree(dvbdev);
                return PTR_ERR(clsdev);
        }
        dprintk("DVB: register adapter%d/%s%d @ minor: %i (0x%02x)\n",
index f886fab..d86b3de 100644 (file)
@@ -33,7 +33,7 @@ struct ascot2e_config {
 
 #if IS_REACHABLE(CONFIG_DVB_ASCOT2E)
 /**
- * Attach an ascot2e tuner
+ * ascot2e_attach - Attach an ascot2e tuner
  *
  * @fe: frontend to be attached
  * @config: pointer to &struct ascot2e_config with tuner configuration.
index a28b875..4aa6cf4 100644 (file)
@@ -96,7 +96,7 @@ struct cxd2820r_config {
 
 #if IS_REACHABLE(CONFIG_DVB_CXD2820R)
 /**
- * Attach a cxd2820r demod
+ * cxd2820r_attach - Attach a cxd2820r demod
  *
  * @config: pointer to &struct cxd2820r_config with demod configuration.
  * @i2c: i2c adapter to use.
index 237b9d0..37b32d9 100644 (file)
@@ -2325,7 +2325,6 @@ hi_command(struct i2c_device_addr *dev_addr, const struct drxj_hi_cmd *cmd, u16
 
        default:
                return -EINVAL;
-               break;
        }
 
        /* Write command */
@@ -3594,7 +3593,6 @@ static int ctrl_set_uio_cfg(struct drx_demod_instance *demod, struct drxuio_cfg
                        break;
                default:
                        return -EINVAL;
-                       break;
                }               /* switch ( uio_cfg->mode ) */
                break;
       /*====================================================================*/
@@ -3618,7 +3616,6 @@ static int ctrl_set_uio_cfg(struct drx_demod_instance *demod, struct drxuio_cfg
                        break;
                default:
                        return -EINVAL;
-                       break;
                }               /* switch ( uio_cfg->mode ) */
                break;
       /*====================================================================*/
@@ -3642,7 +3639,6 @@ static int ctrl_set_uio_cfg(struct drx_demod_instance *demod, struct drxuio_cfg
                case DRX_UIO_MODE_FIRMWARE0:
                default:
                        return -EINVAL;
-                       break;
                }               /* switch ( uio_cfg->mode ) */
                break;
       /*====================================================================*/
@@ -10953,7 +10949,6 @@ ctrl_set_standard(struct drx_demod_instance *demod, enum drx_standard *standard)
        default:
                ext_attr->standard = DRX_STANDARD_UNKNOWN;
                return -EINVAL;
-               break;
        }
 
        return 0;
@@ -11074,7 +11069,6 @@ ctrl_power_mode(struct drx_demod_instance *demod, enum drx_power_mode *mode)
        default:
                /* Unknow sleep mode */
                return -EINVAL;
-               break;
        }
 
        /* Check if device needs to be powered up */
@@ -11896,7 +11890,6 @@ static int drx_ctrl_u_code(struct drx_demod_instance *demod,
                }
                default:
                        return -EINVAL;
-                       break;
 
                }
                mc_data += mc_block_nr_bytes;
index 45f9828..a7eb81d 100644 (file)
@@ -1622,7 +1622,6 @@ static int CorrectSysClockDeviation(struct drxd_state *state)
                        break;
                default:
                        return -1;
-                       break;
                }
 
                /* Compute new sysclock value
index ee06e89..69fdca0 100644 (file)
@@ -54,7 +54,7 @@ struct drxk_config {
 
 #if IS_REACHABLE(CONFIG_DVB_DRXK)
 /**
- * Attach a drxk demod
+ * drxk_attach - Attach a drxk demod
  *
  * @config: pointer to &struct drxk_config with demod configuration.
  * @i2c: i2c adapter to use.
index 973a66a..7183888 100644 (file)
@@ -38,7 +38,7 @@ struct dvb_pll_config {
 
 #if IS_REACHABLE(CONFIG_DVB_PLL)
 /**
- * Attach a dvb-pll to the supplied frontend structure.
+ * dvb_pll_attach - Attach a dvb-pll to the supplied frontend structure.
  *
  * @fe: Frontend to attach to.
  * @pll_addr: i2c address of the PLL (if used).
index c026bdc..32e0b1f 100644 (file)
@@ -44,7 +44,7 @@ struct helene_config {
 
 #if IS_REACHABLE(CONFIG_DVB_HELENE)
 /**
- * Attach a helene tuner (terrestrial and cable standards)
+ * helene_attach - Attach a helene tuner (terrestrial and cable standards)
  *
  * @fe: frontend to be attached
  * @config: pointer to &struct helene_config with tuner configuration.
@@ -57,7 +57,7 @@ extern struct dvb_frontend *helene_attach(struct dvb_frontend *fe,
                                        struct i2c_adapter *i2c);
 
 /**
- * Attach a helene tuner (satellite standards)
+ * helene_attach_s - Attach a helene tuner (satellite standards)
  *
  * @fe: frontend to be attached
  * @config: pointer to &struct helene_config with tuner configuration.
index 366c399..91dbe20 100644 (file)
@@ -33,7 +33,7 @@ struct horus3a_config {
 
 #if IS_REACHABLE(CONFIG_DVB_HORUS3A)
 /**
- * Attach a horus3a tuner
+ * horus3a_attach - Attach a horus3a tuner
  *
  * @fe: frontend to be attached
  * @config: pointer to &struct helene_config with tuner configuration.
index 671c0e0..1755691 100644 (file)
@@ -1,5 +1,5 @@
 /* SPDX-License-Identifier: GPL-2.0-only */
-/**
+/*
  * Driver for Sharp IX2505V (marked B0017) DVB-S silicon tuner
  *
  * Copyright (C) 2010 Malcolm Priestley
@@ -31,7 +31,7 @@ struct ix2505v_config {
 
 #if IS_REACHABLE(CONFIG_DVB_IX2505V)
 /**
- * Attach a ix2505v tuner to the supplied frontend structure.
+ * ix2505v_attach - Attach a ix2505v tuner to the supplied frontend structure.
  *
  * @fe: Frontend to attach to.
  * @config: pointer to &struct ix2505v_config
index ad6d9d5..cfa4cdd 100644 (file)
@@ -1793,9 +1793,9 @@ static int m88ds3103_probe(struct i2c_client *client,
        dev->config.lnb_en_pol = pdata->lnb_en_pol;
        dev->cfg = &dev->config;
        /* create regmap */
-       dev->regmap_config.reg_bits = 8,
-       dev->regmap_config.val_bits = 8,
-       dev->regmap_config.lock_arg = dev,
+       dev->regmap_config.reg_bits = 8;
+       dev->regmap_config.val_bits = 8;
+       dev->regmap_config.lock_arg = dev;
        dev->regmap = devm_regmap_init_i2c(client, &dev->regmap_config);
        if (IS_ERR(dev->regmap)) {
                ret = PTR_ERR(dev->regmap);
index 46b7224..e32b68c 100644 (file)
@@ -128,7 +128,7 @@ struct m88ds3103_config {
 #if defined(CONFIG_DVB_M88DS3103) || \
                (defined(CONFIG_DVB_M88DS3103_MODULE) && defined(MODULE))
 /**
- * Attach a m88ds3103 demod
+ * m88ds3103_attach - Attach a m88ds3103 demod
  *
  * @config: pointer to &struct m88ds3103_config with demod configuration.
  * @i2c: i2c adapter to use.
index 00a6b6e..d20d22b 100644 (file)
@@ -26,7 +26,7 @@ struct mb86a20s_config {
 
 #if IS_REACHABLE(CONFIG_DVB_MB86A20S)
 /**
- * Attach a mb86a20s demod
+ * mb86a20s_attach - Attach a mb86a20s demod
  *
  * @config: pointer to &struct mb86a20s_config with demod configuration.
  * @i2c: i2c adapter to use.
index 35b83b1..200b6db 100644 (file)
@@ -168,7 +168,6 @@ static int nxt200x_writereg_multibyte (struct nxt200x_state* state, u8 reg, u8*
                        break;
                default:
                        return -EINVAL;
-                       break;
        }
 
        /* set multi register length */
@@ -190,7 +189,6 @@ static int nxt200x_writereg_multibyte (struct nxt200x_state* state, u8 reg, u8*
                        break;
                default:
                        return -EINVAL;
-                       break;
        }
 
        pr_warn("Error writing multireg register 0x%02X\n", reg);
@@ -216,7 +214,6 @@ static int nxt200x_readreg_multibyte (struct nxt200x_state* state, u8 reg, u8* d
                        /* read the actual data */
                        nxt200x_readbytes(state, reg, data, len);
                        return 0;
-                       break;
                case NXT2004:
                        /* probably not right, but gives correct values */
                        attr = 0x02;
@@ -239,10 +236,8 @@ static int nxt200x_readreg_multibyte (struct nxt200x_state* state, u8 reg, u8* d
                                nxt200x_readbytes(state, 0x36 + i, &data[i], 1);
                        }
                        return 0;
-                       break;
                default:
                        return -EINVAL;
-                       break;
        }
 }
 
@@ -374,7 +369,6 @@ static int nxt200x_writetuner (struct nxt200x_state* state, u8* data)
                        break;
                default:
                        return -EINVAL;
-                       break;
        }
        return 0;
 }
@@ -555,7 +549,6 @@ static int nxt200x_setup_frontend_parameters(struct dvb_frontend *fe)
                        break;
                default:
                        return -EINVAL;
-                       break;
        }
 
        if (fe->ops.tuner_ops.calc_regs) {
@@ -580,7 +573,6 @@ static int nxt200x_setup_frontend_parameters(struct dvb_frontend *fe)
                        break;
                default:
                        return -EINVAL;
-                       break;
        }
        nxt200x_writebytes(state, 0x42, buf, 1);
 
@@ -594,7 +586,6 @@ static int nxt200x_setup_frontend_parameters(struct dvb_frontend *fe)
                        break;
                default:
                        return -EINVAL;
-                       break;
        }
        nxt200x_writebytes(state, 0x57, buf, 1);
 
@@ -610,7 +601,6 @@ static int nxt200x_setup_frontend_parameters(struct dvb_frontend *fe)
                        break;
                default:
                        return -EINVAL;
-                       break;
        }
 
        /* write sdmx input */
@@ -626,7 +616,6 @@ static int nxt200x_setup_frontend_parameters(struct dvb_frontend *fe)
                                break;
                default:
                                return -EINVAL;
-                               break;
        }
        buf[1] = 0x00;
        switch (state->demod_chip) {
@@ -638,7 +627,6 @@ static int nxt200x_setup_frontend_parameters(struct dvb_frontend *fe)
                        break;
                default:
                        return -EINVAL;
-                       break;
        }
 
        /* write adc power lpf fc */
@@ -664,7 +652,6 @@ static int nxt200x_setup_frontend_parameters(struct dvb_frontend *fe)
                        break;
                default:
                        return -EINVAL;
-                       break;
        }
 
        /* write kg1 */
@@ -720,7 +707,6 @@ static int nxt200x_setup_frontend_parameters(struct dvb_frontend *fe)
                                break;
                default:
                                return -EINVAL;
-                               break;
        }
        nxt200x_writebytes(state, 0x30, buf, 1);
 
@@ -742,7 +728,6 @@ static int nxt200x_setup_frontend_parameters(struct dvb_frontend *fe)
                        break;
                default:
                        return -EINVAL;
-                       break;
        }
 
        /* write agc control reg */
@@ -1114,7 +1099,6 @@ static int nxt200x_init(struct dvb_frontend* fe)
                                break;
                        default:
                                return -EINVAL;
-                               break;
                }
                state->initialised = 1;
        }
index e5bffaa..01dcc7f 100644 (file)
@@ -1056,13 +1056,13 @@ static int rtl2832_probe(struct i2c_client *client,
        dev->sleeping = true;
        INIT_DELAYED_WORK(&dev->i2c_gate_work, rtl2832_i2c_gate_work);
        /* create regmap */
-       dev->regmap_config.reg_bits =  8,
-       dev->regmap_config.val_bits =  8,
-       dev->regmap_config.volatile_reg = rtl2832_volatile_reg,
-       dev->regmap_config.max_register = 5 * 0x100,
-       dev->regmap_config.ranges = regmap_range_cfg,
-       dev->regmap_config.num_ranges = ARRAY_SIZE(regmap_range_cfg),
-       dev->regmap_config.cache_type = REGCACHE_NONE,
+       dev->regmap_config.reg_bits =  8;
+       dev->regmap_config.val_bits =  8;
+       dev->regmap_config.volatile_reg = rtl2832_volatile_reg;
+       dev->regmap_config.max_register = 5 * 0x100;
+       dev->regmap_config.ranges = regmap_range_cfg;
+       dev->regmap_config.num_ranges = ARRAY_SIZE(regmap_range_cfg);
+       dev->regmap_config.cache_type = REGCACHE_NONE;
        dev->regmap = regmap_init_i2c(client, &dev->regmap_config);
        if (IS_ERR(dev->regmap)) {
                ret = PTR_ERR(dev->regmap);
index 3fdaef1..ebee230 100644 (file)
@@ -5,7 +5,7 @@
  *  Copyright (C) 2013-2017 Matthias Schwarzott <zzam@gentoo.org>
  *
  *  References:
- *  http://www.silabs.com/Support%20Documents/TechnicalDocs/Si2165-short.pdf
+ *  https://www.silabs.com/Support%20Documents/TechnicalDocs/Si2165-short.pdf
  */
 
 #include <linux/delay.h>
index 0b19317..adc5e18 100644 (file)
@@ -5,7 +5,7 @@
  * Copyright (C) 2013-2017 Matthias Schwarzott <zzam@gentoo.org>
  *
  * References:
- *   http://www.silabs.com/Support%20Documents/TechnicalDocs/Si2165-short.pdf
+ *   https://www.silabs.com/Support%20Documents/TechnicalDocs/Si2165-short.pdf
  */
 
 #ifndef _DVB_SI2165_H
index a116eff..e31eb2c 100644 (file)
@@ -464,10 +464,8 @@ static int si21xx_set_voltage(struct dvb_frontend *fe, enum fe_sec_voltage volt)
        switch (volt) {
        case SEC_VOLTAGE_18:
                return si21_writereg(state, LNB_CTRL_REG_1, val | 0x40);
-               break;
        case SEC_VOLTAGE_13:
                return si21_writereg(state, LNB_CTRL_REG_1, (val & ~0x40));
-               break;
        default:
                return -EINVAL;
        }
index 570a4b1..38da55a 100644 (file)
@@ -15,7 +15,7 @@
 
 #if IS_REACHABLE(CONFIG_DVB_STB6000)
 /**
- * Attach a stb6000 tuner to the supplied frontend structure.
+ * stb6000_attach - Attach a stb6000 tuner to the supplied frontend structure.
  *
  * @fe: Frontend to attach to.
  * @addr: i2c address of the tuner.
index bb575a2..e1d33ed 100644 (file)
@@ -14,7 +14,7 @@
 #include <media/dvb_frontend.h>
 
 /**
- * Attach a tda826x tuner to the supplied frontend structure.
+ * tda826x_attach - Attach a tda826x tuner to the supplied frontend structure.
  *
  * @fe: Frontend to attach to.
  * @addr: i2c address of the tuner.
index 234607b..3e38391 100644 (file)
@@ -569,11 +569,11 @@ static int ts2020_probe(struct i2c_client *client,
 
        /* create regmap */
        mutex_init(&dev->regmap_mutex);
-       dev->regmap_config.reg_bits = 8,
-       dev->regmap_config.val_bits = 8,
-       dev->regmap_config.lock = ts2020_regmap_lock,
-       dev->regmap_config.unlock = ts2020_regmap_unlock,
-       dev->regmap_config.lock_arg = dev,
+       dev->regmap_config.reg_bits = 8;
+       dev->regmap_config.val_bits = 8;
+       dev->regmap_config.lock = ts2020_regmap_lock;
+       dev->regmap_config.unlock = ts2020_regmap_unlock;
+       dev->regmap_config.lock_arg = dev;
        dev->regmap = regmap_init_i2c(client, &dev->regmap_config);
        if (IS_ERR(dev->regmap)) {
                ret = PTR_ERR(dev->regmap);
index 91eea77..ad83e63 100644 (file)
@@ -1,5 +1,5 @@
 /* SPDX-License-Identifier: GPL-2.0-only */
-/**
+/*
  * Driver for Zarlink ZL10036 DVB-S silicon tuner
  *
  * Copyright (C) 2006 Tino Reichardt
@@ -19,7 +19,7 @@ struct zl10036_config {
 
 #if IS_REACHABLE(CONFIG_DVB_ZL10036)
 /**
- * Attach a zl10036 tuner to the supplied frontend structure.
+ * zl10036_attach - Attach a zl10036 tuner to the supplied frontend structure.
  *
  * @fe: Frontend to attach to.
  * @config: zl10036_config structure.
index 878f66e..369b6d8 100644 (file)
@@ -877,6 +877,7 @@ config VIDEO_OV2740
        select MEDIA_CONTROLLER
        select VIDEO_V4L2_SUBDEV_API
        select V4L2_FWNODE
+       select REGMAP_I2C
        help
          This is a Video4Linux2 sensor driver for the OmniVision
          OV2740 camera.
@@ -1050,6 +1051,20 @@ config VIDEO_OV9650
          This is a V4L2 sensor driver for the Omnivision
          OV9650 and OV9652 camera sensors.
 
+config VIDEO_OV9734
+       tristate "OmniVision OV9734 sensor support"
+       depends on VIDEO_V4L2 && I2C
+       depends on ACPI || COMPILE_TEST
+       select MEDIA_CONTROLLER
+       select VIDEO_V4L2_SUBDEV_API
+       select V4L2_FWNODE
+       help
+         This is a Video4Linux2 sensor driver for the OmniVision
+         OV9734 camera.
+
+         To compile this driver as a module, choose M here: the
+         module's name is ov9734.
+
 config VIDEO_OV13858
        tristate "OmniVision OV13858 sensor support"
        depends on I2C && VIDEO_V4L2
index f0a7747..b448506 100644 (file)
@@ -83,6 +83,7 @@ obj-$(CONFIG_VIDEO_OV7740) += ov7740.o
 obj-$(CONFIG_VIDEO_OV8856) += ov8856.o
 obj-$(CONFIG_VIDEO_OV9640) += ov9640.o
 obj-$(CONFIG_VIDEO_OV9650) += ov9650.o
+obj-$(CONFIG_VIDEO_OV9734) += ov9734.o
 obj-$(CONFIG_VIDEO_OV13858) += ov13858.o
 obj-$(CONFIG_VIDEO_MT9M001) += mt9m001.o
 obj-$(CONFIG_VIDEO_MT9M032) += mt9m032.o
index 19c74db..2958a46 100644 (file)
@@ -270,8 +270,7 @@ static const struct v4l2_subdev_internal_ops ad5820_internal_ops = {
  */
 static int __maybe_unused ad5820_suspend(struct device *dev)
 {
-       struct i2c_client *client = container_of(dev, struct i2c_client, dev);
-       struct v4l2_subdev *subdev = i2c_get_clientdata(client);
+       struct v4l2_subdev *subdev = dev_get_drvdata(dev);
        struct ad5820_device *coil = to_ad5820_device(subdev);
 
        if (!coil->power_count)
@@ -282,8 +281,7 @@ static int __maybe_unused ad5820_suspend(struct device *dev)
 
 static int __maybe_unused ad5820_resume(struct device *dev)
 {
-       struct i2c_client *client = container_of(dev, struct i2c_client, dev);
-       struct v4l2_subdev *subdev = i2c_get_clientdata(client);
+       struct v4l2_subdev *subdev = dev_get_drvdata(dev);
        struct ad5820_device *coil = to_ad5820_device(subdev);
 
        if (!coil->power_count)
index 694125a..522a0b1 100644 (file)
@@ -379,8 +379,7 @@ static const struct v4l2_subdev_internal_ops adp1653_internal_ops = {
 
 static int adp1653_suspend(struct device *dev)
 {
-       struct i2c_client *client = to_i2c_client(dev);
-       struct v4l2_subdev *subdev = i2c_get_clientdata(client);
+       struct v4l2_subdev *subdev = dev_get_drvdata(dev);
        struct adp1653_flash *flash = to_adp1653_flash(subdev);
 
        if (!flash->power_count)
@@ -391,8 +390,7 @@ static int adp1653_suspend(struct device *dev)
 
 static int adp1653_resume(struct device *dev)
 {
-       struct i2c_client *client = to_i2c_client(dev);
-       struct v4l2_subdev *subdev = i2c_get_clientdata(client);
+       struct v4l2_subdev *subdev = dev_get_drvdata(dev);
        struct adp1653_flash *flash = to_adp1653_flash(subdev);
 
        if (!flash->power_count)
index 4498d14..44bb6fe 100644 (file)
@@ -1454,8 +1454,7 @@ MODULE_DEVICE_TABLE(i2c, adv7180_id);
 #ifdef CONFIG_PM_SLEEP
 static int adv7180_suspend(struct device *dev)
 {
-       struct i2c_client *client = to_i2c_client(dev);
-       struct v4l2_subdev *sd = i2c_get_clientdata(client);
+       struct v4l2_subdev *sd = dev_get_drvdata(dev);
        struct adv7180_state *state = to_state(sd);
 
        return adv7180_set_power(state, false);
@@ -1463,8 +1462,7 @@ static int adv7180_suspend(struct device *dev)
 
 static int adv7180_resume(struct device *dev)
 {
-       struct i2c_client *client = to_i2c_client(dev);
-       struct v4l2_subdev *sd = i2c_get_clientdata(client);
+       struct v4l2_subdev *sd = dev_get_drvdata(dev);
        struct adv7180_state *state = to_state(sd);
        int ret;
 
index 1fe7f97..ae8b7eb 100644 (file)
@@ -589,14 +589,13 @@ static int adv748x_parse_csi2_lanes(struct adv748x_state *state,
                                    unsigned int port,
                                    struct device_node *ep)
 {
-       struct v4l2_fwnode_endpoint vep;
+       struct v4l2_fwnode_endpoint vep = { .bus_type = V4L2_MBUS_CSI2_DPHY };
        unsigned int num_lanes;
        int ret;
 
        if (port != ADV748X_PORT_TXA && port != ADV748X_PORT_TXB)
                return 0;
 
-       vep.bus_type = V4L2_MBUS_CSI2_DPHY;
        ret = v4l2_fwnode_endpoint_parse(of_fwnode_handle(ep), &vep);
        if (ret)
                return ret;
index 7b14b11..e1f94ee 100644 (file)
@@ -196,9 +196,7 @@ static int ak7375_remove(struct i2c_client *client)
  */
 static int __maybe_unused ak7375_vcm_suspend(struct device *dev)
 {
-
-       struct i2c_client *client = to_i2c_client(dev);
-       struct v4l2_subdev *sd = i2c_get_clientdata(client);
+       struct v4l2_subdev *sd = dev_get_drvdata(dev);
        struct ak7375_device *ak7375_dev = sd_to_ak7375_vcm(sd);
        int ret, val;
 
@@ -233,8 +231,7 @@ static int __maybe_unused ak7375_vcm_suspend(struct device *dev)
  */
 static int __maybe_unused ak7375_vcm_resume(struct device *dev)
 {
-       struct i2c_client *client = to_i2c_client(dev);
-       struct v4l2_subdev *sd = i2c_get_clientdata(client);
+       struct v4l2_subdev *sd = dev_get_drvdata(dev);
        struct ak7375_device *ak7375_dev = sd_to_ak7375_vcm(sd);
        int ret, val;
 
index 45cdd92..8b8cb4b 100644 (file)
@@ -315,8 +315,7 @@ static int dw9768_release(struct dw9768 *dw9768)
 
 static int dw9768_runtime_suspend(struct device *dev)
 {
-       struct i2c_client *client = to_i2c_client(dev);
-       struct v4l2_subdev *sd = i2c_get_clientdata(client);
+       struct v4l2_subdev *sd = dev_get_drvdata(dev);
        struct dw9768 *dw9768 = sd_to_dw9768(sd);
 
        dw9768_release(dw9768);
@@ -328,8 +327,7 @@ static int dw9768_runtime_suspend(struct device *dev)
 
 static int dw9768_runtime_resume(struct device *dev)
 {
-       struct i2c_client *client = to_i2c_client(dev);
-       struct v4l2_subdev *sd = i2c_get_clientdata(client);
+       struct v4l2_subdev *sd = dev_get_drvdata(dev);
        struct dw9768 *dw9768 = sd_to_dw9768(sd);
        int ret;
 
index 256acf7..122af76 100644 (file)
@@ -1237,7 +1237,7 @@ static ssize_t
 et8ek8_priv_mem_read(struct device *dev, struct device_attribute *attr,
                     char *buf)
 {
-       struct v4l2_subdev *subdev = i2c_get_clientdata(to_i2c_client(dev));
+       struct v4l2_subdev *subdev = dev_get_drvdata(dev);
        struct et8ek8_sensor *sensor = to_et8ek8_sensor(subdev);
 
 #if PAGE_SIZE < ET8EK8_PRIV_MEM_SIZE
@@ -1374,8 +1374,7 @@ static const struct v4l2_subdev_internal_ops et8ek8_internal_ops = {
  */
 static int __maybe_unused et8ek8_suspend(struct device *dev)
 {
-       struct i2c_client *client = to_i2c_client(dev);
-       struct v4l2_subdev *subdev = i2c_get_clientdata(client);
+       struct v4l2_subdev *subdev = dev_get_drvdata(dev);
        struct et8ek8_sensor *sensor = to_et8ek8_sensor(subdev);
 
        if (!sensor->power_count)
@@ -1386,8 +1385,7 @@ static int __maybe_unused et8ek8_suspend(struct device *dev)
 
 static int __maybe_unused et8ek8_resume(struct device *dev)
 {
-       struct i2c_client *client = to_i2c_client(dev);
-       struct v4l2_subdev *subdev = i2c_get_clientdata(client);
+       struct v4l2_subdev *subdev = dev_get_drvdata(dev);
        struct et8ek8_sensor *sensor = to_et8ek8_sensor(subdev);
 
        if (!sensor->power_count)
index c66cd14..c747368 100644 (file)
@@ -839,8 +839,7 @@ static int hi556_set_stream(struct v4l2_subdev *sd, int enable)
 
 static int __maybe_unused hi556_suspend(struct device *dev)
 {
-       struct i2c_client *client = to_i2c_client(dev);
-       struct v4l2_subdev *sd = i2c_get_clientdata(client);
+       struct v4l2_subdev *sd = dev_get_drvdata(dev);
        struct hi556 *hi556 = to_hi556(sd);
 
        mutex_lock(&hi556->mutex);
@@ -854,8 +853,7 @@ static int __maybe_unused hi556_suspend(struct device *dev)
 
 static int __maybe_unused hi556_resume(struct device *dev)
 {
-       struct i2c_client *client = to_i2c_client(dev);
-       struct v4l2_subdev *sd = i2c_get_clientdata(client);
+       struct v4l2_subdev *sd = dev_get_drvdata(dev);
        struct hi556 *hi556 = to_hi556(sd);
        int ret;
 
index 1ef5af9..cee1a48 100644 (file)
@@ -786,7 +786,7 @@ static int imx214_s_stream(struct v4l2_subdev *subdev, int enable)
                if (ret < 0)
                        goto err_rpm_put;
        } else {
-               ret = imx214_start_streaming(imx214);
+               ret = imx214_stop_streaming(imx214);
                if (ret < 0)
                        goto err_rpm_put;
                pm_runtime_put(imx214->dev);
index 1cee45e..982828d 100644 (file)
@@ -262,8 +262,6 @@ static const struct imx219_reg mode_1920_1080_regs[] = {
        {0x4793, 0x10},
        {0x4797, 0x0e},
        {0x479b, 0x0e},
-       {0x0162, 0x0d},
-       {0x0163, 0x78},
 };
 
 static const struct imx219_reg mode_1640_1232_regs[] = {
@@ -1114,22 +1112,21 @@ err_unlock:
 /* Power/clock management functions */
 static int imx219_power_on(struct device *dev)
 {
-       struct i2c_client *client = to_i2c_client(dev);
-       struct v4l2_subdev *sd = i2c_get_clientdata(client);
+       struct v4l2_subdev *sd = dev_get_drvdata(dev);
        struct imx219 *imx219 = to_imx219(sd);
        int ret;
 
        ret = regulator_bulk_enable(IMX219_NUM_SUPPLIES,
                                    imx219->supplies);
        if (ret) {
-               dev_err(&client->dev, "%s: failed to enable regulators\n",
+               dev_err(dev, "%s: failed to enable regulators\n",
                        __func__);
                return ret;
        }
 
        ret = clk_prepare_enable(imx219->xclk);
        if (ret) {
-               dev_err(&client->dev, "%s: failed to enable clock\n",
+               dev_err(dev, "%s: failed to enable clock\n",
                        __func__);
                goto reg_off;
        }
@@ -1148,8 +1145,7 @@ reg_off:
 
 static int imx219_power_off(struct device *dev)
 {
-       struct i2c_client *client = to_i2c_client(dev);
-       struct v4l2_subdev *sd = i2c_get_clientdata(client);
+       struct v4l2_subdev *sd = dev_get_drvdata(dev);
        struct imx219 *imx219 = to_imx219(sd);
 
        gpiod_set_value_cansleep(imx219->reset_gpio, 0);
@@ -1161,8 +1157,7 @@ static int imx219_power_off(struct device *dev)
 
 static int __maybe_unused imx219_suspend(struct device *dev)
 {
-       struct i2c_client *client = to_i2c_client(dev);
-       struct v4l2_subdev *sd = i2c_get_clientdata(client);
+       struct v4l2_subdev *sd = dev_get_drvdata(dev);
        struct imx219 *imx219 = to_imx219(sd);
 
        if (imx219->streaming)
@@ -1173,8 +1168,7 @@ static int __maybe_unused imx219_suspend(struct device *dev)
 
 static int __maybe_unused imx219_resume(struct device *dev)
 {
-       struct i2c_client *client = to_i2c_client(dev);
-       struct v4l2_subdev *sd = i2c_get_clientdata(client);
+       struct v4l2_subdev *sd = dev_get_drvdata(dev);
        struct imx219 *imx219 = to_imx219(sd);
        int ret;
 
@@ -1498,7 +1492,8 @@ static int imx219_probe(struct i2c_client *client)
 
        /* Initialize subdev */
        imx219->sd.internal_ops = &imx219_internal_ops;
-       imx219->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
+       imx219->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE |
+                           V4L2_SUBDEV_FL_HAS_EVENTS;
        imx219->sd.entity.function = MEDIA_ENT_F_CAM_SENSOR;
 
        /* Initialize source pad */
index ccb55fd..df62c69 100644 (file)
@@ -1305,6 +1305,6 @@ module_i2c_driver(imx258_i2c_driver);
 
 MODULE_AUTHOR("Yeh, Andy <andy.yeh@intel.com>");
 MODULE_AUTHOR("Chiang, Alan");
-MODULE_AUTHOR("Chen, Jason <jasonx.z.chen@intel.com>");
+MODULE_AUTHOR("Chen, Jason");
 MODULE_DESCRIPTION("Sony IMX258 sensor driver");
 MODULE_LICENSE("GPL v2");
index e6aa9f3..54642d5 100644 (file)
@@ -18,7 +18,9 @@
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/of_gpio.h>
+#include <linux/pm_runtime.h>
 #include <linux/regmap.h>
+#include <linux/regulator/consumer.h>
 #include <linux/slab.h>
 #include <linux/v4l2-mediabus.h>
 #include <linux/videodev2.h>
@@ -65,7 +67,6 @@
  */
 #define IMX274_MIN_EXPOSURE_TIME               (4 * 260 / 72)
 
-#define IMX274_DEFAULT_BINNING                 IMX274_BINNING_OFF
 #define IMX274_MAX_WIDTH                       (3840)
 #define IMX274_MAX_HEIGHT                      (2160)
 #define IMX274_MAX_FRAME_RATE                  (120)
 #define IMX274_TABLE_WAIT_MS                   0
 #define IMX274_TABLE_END                       1
 
+/* regulator supplies */
+static const char * const imx274_supply_names[] = {
+       "vddl",  /* IF (1.2V) supply */
+       "vdig",  /* Digital Core (1.8V) supply */
+       "vana",  /* Analog (2.8V) supply */
+};
+
+#define IMX274_NUM_SUPPLIES ARRAY_SIZE(imx274_supply_names)
+
 /*
  * imx274 I2C operation related structure
  */
@@ -145,12 +155,6 @@ static const struct regmap_config imx274_regmap_config = {
        .cache_type = REGCACHE_RBTREE,
 };
 
-enum imx274_binning {
-       IMX274_BINNING_OFF,
-       IMX274_BINNING_2_1,
-       IMX274_BINNING_3_1,
-};
-
 /*
  * Parameters for each imx274 readout mode.
  *
@@ -158,7 +162,8 @@ enum imx274_binning {
  * implemented modes.
  *
  * @init_regs: registers to initialize the mode
- * @bin_ratio: downscale factor (e.g. 3 for 3:1 binning)
+ * @wbin_ratio: width downscale factor (e.g. 3 for 1280; 3 = 3840/1280)
+ * @hbin_ratio: height downscale factor (e.g. 3 for 720; 3 = 2160/720)
  * @min_frame_len: Minimum frame length for each mode (see "Frame Rate
  *                 Adjustment (CSI-2)" in the datasheet)
  * @min_SHR: Minimum SHR register value (see "Shutter Setting (CSI-2)" in the
@@ -169,7 +174,8 @@ enum imx274_binning {
  */
 struct imx274_mode {
        const struct reg_8 *init_regs;
-       unsigned int bin_ratio;
+       u8 wbin_ratio;
+       u8 hbin_ratio;
        int min_frame_len;
        int min_SHR;
        int max_fps;
@@ -332,6 +338,46 @@ static const struct reg_8 imx274_mode5_1280x720_raw10[] = {
        {IMX274_TABLE_END, 0x00}
 };
 
+/*
+ * Vertical 2/8 subsampling horizontal 3 binning
+ * imx274 mode6(refer to datasheet) register configuration with
+ * 1280x540 resolution, raw10 data and mipi four lane output
+ */
+static const struct reg_8 imx274_mode6_1280x540_raw10[] = {
+       {0x3004, 0x04}, /* mode setting */
+       {0x3005, 0x31},
+       {0x3006, 0x00},
+       {0x3007, 0x02}, /* mode setting */
+
+       {0x3018, 0xA2}, /* output XVS, HVS */
+
+       {0x306B, 0x05},
+       {0x30E2, 0x04}, /* mode setting */
+
+       {0x30EE, 0x01},
+       {0x3342, 0x0A},
+       {0x3343, 0x00},
+       {0x3344, 0x16},
+       {0x3345, 0x00},
+       {0x33A6, 0x01},
+       {0x3528, 0x0E},
+       {0x3554, 0x1F},
+       {0x3555, 0x01},
+       {0x3556, 0x01},
+       {0x3557, 0x01},
+       {0x3558, 0x01},
+       {0x3559, 0x00},
+       {0x355A, 0x00},
+       {0x35BA, 0x0E},
+       {0x366A, 0x1B},
+       {0x366B, 0x1A},
+       {0x366C, 0x19},
+       {0x366D, 0x17},
+       {0x3A41, 0x04},
+
+       {IMX274_TABLE_END, 0x00}
+};
+
 /*
  * imx274 first step register configuration for
  * starting stream
@@ -445,7 +491,8 @@ static const struct reg_8 imx274_tp_regs[] = {
 static const struct imx274_mode imx274_modes[] = {
        {
                /* mode 1, 4K */
-               .bin_ratio = 1,
+               .wbin_ratio = 1, /* 3840 */
+               .hbin_ratio = 1, /* 2160 */
                .init_regs = imx274_mode1_3840x2160_raw10,
                .min_frame_len = 4550,
                .min_SHR = 12,
@@ -454,7 +501,8 @@ static const struct imx274_mode imx274_modes[] = {
        },
        {
                /* mode 3, 1080p */
-               .bin_ratio = 2,
+               .wbin_ratio = 2, /* 1920 */
+               .hbin_ratio = 2, /* 1080 */
                .init_regs = imx274_mode3_1920x1080_raw10,
                .min_frame_len = 2310,
                .min_SHR = 8,
@@ -463,13 +511,24 @@ static const struct imx274_mode imx274_modes[] = {
        },
        {
                /* mode 5, 720p */
-               .bin_ratio = 3,
+               .wbin_ratio = 3, /* 1280 */
+               .hbin_ratio = 3, /* 720 */
                .init_regs = imx274_mode5_1280x720_raw10,
                .min_frame_len = 2310,
                .min_SHR = 8,
                .max_fps = 120,
                .nocpiop = 112,
        },
+       {
+               /* mode 6, 540p */
+               .wbin_ratio = 3, /* 1280 */
+               .hbin_ratio = 4, /* 540 */
+               .init_regs = imx274_mode6_1280x540_raw10,
+               .min_frame_len = 2310,
+               .min_SHR = 4,
+               .max_fps = 120,
+               .nocpiop = 112,
+       },
 };
 
 /*
@@ -501,6 +560,8 @@ struct imx274_ctrls {
  * @frame_rate: V4L2 frame rate structure
  * @regmap: Pointer to regmap structure
  * @reset_gpio: Pointer to reset gpio
+ * @supplies: List of analog and digital supply regulators
+ * @inck: Pointer to sensor input clock
  * @lock: Mutex structure
  * @mode: Parameters for the selected readout mode
  */
@@ -514,6 +575,8 @@ struct stimx274 {
        struct v4l2_fract frame_interval;
        struct regmap *regmap;
        struct gpio_desc *reset_gpio;
+       struct regulator_bulk_data supplies[IMX274_NUM_SUPPLIES];
+       struct clk *inck;
        struct mutex lock; /* mutex lock for operations */
        const struct imx274_mode *mode;
 };
@@ -726,6 +789,12 @@ static int imx274_start_stream(struct stimx274 *priv)
 {
        int err = 0;
 
+       err = __v4l2_ctrl_handler_setup(&priv->ctrls.handler);
+       if (err) {
+               dev_err(&priv->client->dev, "Error %d setup controls\n", err);
+               return err;
+       }
+
        /*
         * Refer to "Standby Cancel Sequence when using CSI-2" in
         * imx274 datasheet, it should wait 10ms or more here.
@@ -767,6 +836,66 @@ static void imx274_reset(struct stimx274 *priv, int rst)
        usleep_range(IMX274_RESET_DELAY1, IMX274_RESET_DELAY2);
 }
 
+static int imx274_power_on(struct device *dev)
+{
+       struct i2c_client *client = to_i2c_client(dev);
+       struct v4l2_subdev *sd = i2c_get_clientdata(client);
+       struct stimx274 *imx274 = to_imx274(sd);
+       int ret;
+
+       /* keep sensor in reset before power on */
+       imx274_reset(imx274, 0);
+
+       ret = clk_prepare_enable(imx274->inck);
+       if (ret) {
+               dev_err(&imx274->client->dev,
+                       "Failed to enable input clock: %d\n", ret);
+               return ret;
+       }
+
+       ret = regulator_bulk_enable(IMX274_NUM_SUPPLIES, imx274->supplies);
+       if (ret) {
+               dev_err(&imx274->client->dev,
+                       "Failed to enable regulators: %d\n", ret);
+               goto fail_reg;
+       }
+
+       udelay(2);
+       imx274_reset(imx274, 1);
+
+       return 0;
+
+fail_reg:
+       clk_disable_unprepare(imx274->inck);
+       return ret;
+}
+
+static int imx274_power_off(struct device *dev)
+{
+       struct i2c_client *client = to_i2c_client(dev);
+       struct v4l2_subdev *sd = i2c_get_clientdata(client);
+       struct stimx274 *imx274 = to_imx274(sd);
+
+       imx274_reset(imx274, 0);
+
+       regulator_bulk_disable(IMX274_NUM_SUPPLIES, imx274->supplies);
+
+       clk_disable_unprepare(imx274->inck);
+
+       return 0;
+}
+
+static int imx274_regulators_get(struct device *dev, struct stimx274 *imx274)
+{
+       unsigned int i;
+
+       for (i = 0; i < IMX274_NUM_SUPPLIES; i++)
+               imx274->supplies[i].supply = imx274_supply_names[i];
+
+       return devm_regulator_bulk_get(dev, IMX274_NUM_SUPPLIES,
+                                       imx274->supplies);
+}
+
 /**
  * imx274_s_ctrl - This is used to set the imx274 V4L2 controls
  * @ctrl: V4L2 control to be set
@@ -781,6 +910,9 @@ static int imx274_s_ctrl(struct v4l2_ctrl *ctrl)
        struct stimx274 *imx274 = to_imx274(sd);
        int ret = -EINVAL;
 
+       if (!pm_runtime_get_if_in_use(&imx274->client->dev))
+               return 0;
+
        dev_dbg(&imx274->client->dev,
                "%s : s_ctrl: %s, value: %d\n", __func__,
                ctrl->name, ctrl->val);
@@ -811,6 +943,8 @@ static int imx274_s_ctrl(struct v4l2_ctrl *ctrl)
                break;
        }
 
+       pm_runtime_put(&imx274->client->dev);
+
        return ret;
 }
 
@@ -892,12 +1026,13 @@ static int __imx274_change_compose(struct stimx274 *imx274,
        }
 
        for (i = 0; i < ARRAY_SIZE(imx274_modes); i++) {
-               unsigned int ratio = imx274_modes[i].bin_ratio;
+               u8 wratio = imx274_modes[i].wbin_ratio;
+               u8 hratio = imx274_modes[i].hbin_ratio;
 
                int goodness = imx274_binning_goodness(
                        imx274,
-                       cur_crop->width / ratio, *width,
-                       cur_crop->height / ratio, *height,
+                       cur_crop->width / wratio, *width,
+                       cur_crop->height / hratio, *height,
                        flags);
 
                if (goodness >= best_goodness) {
@@ -906,14 +1041,14 @@ static int __imx274_change_compose(struct stimx274 *imx274,
                }
        }
 
-       *width = cur_crop->width / best_mode->bin_ratio;
-       *height = cur_crop->height / best_mode->bin_ratio;
+       *width = cur_crop->width / best_mode->wbin_ratio;
+       *height = cur_crop->height / best_mode->hbin_ratio;
 
        if (which == V4L2_SUBDEV_FORMAT_ACTIVE)
                imx274->mode = best_mode;
 
-       dev_dbg(dev, "%s: selected %u:1 binning\n",
-               __func__, best_mode->bin_ratio);
+       dev_dbg(dev, "%s: selected %ux%u binning\n",
+               __func__, best_mode->wbin_ratio, best_mode->hbin_ratio);
 
        tgt_fmt->width = *width;
        tgt_fmt->height = *height;
@@ -1163,7 +1298,7 @@ static int imx274_apply_trimming(struct stimx274 *imx274)
                (-imx274->crop.top / 2) : (imx274->crop.top / 2);
        v_cut = (IMX274_MAX_HEIGHT - imx274->crop.height) / 2;
        write_v_size = imx274->crop.height + 22;
-       y_out_size   = imx274->crop.height + 14;
+       y_out_size   = imx274->crop.height;
 
        err = imx274_write_mbreg(imx274, IMX274_HMAX_REG_LSB, hmax, 2);
        if (!err)
@@ -1271,10 +1406,8 @@ unlock:
  *
  * Return: 0 on success, errors otherwise
  */
-static int imx274_load_default(struct stimx274 *priv)
+static void imx274_load_default(struct stimx274 *priv)
 {
-       int ret;
-
        /* load default control values */
        priv->frame_interval.numerator = 1;
        priv->frame_interval.denominator = IMX274_DEF_FRAME_RATE;
@@ -1282,29 +1415,6 @@ static int imx274_load_default(struct stimx274 *priv)
        priv->ctrls.gain->val = IMX274_DEF_GAIN;
        priv->ctrls.vflip->val = 0;
        priv->ctrls.test_pattern->val = TEST_PATTERN_DISABLED;
-
-       /* update frame rate */
-       ret = imx274_set_frame_interval(priv,
-                                       priv->frame_interval);
-       if (ret)
-               return ret;
-
-       /* update exposure time */
-       ret = v4l2_ctrl_s_ctrl(priv->ctrls.exposure, priv->ctrls.exposure->val);
-       if (ret)
-               return ret;
-
-       /* update gain */
-       ret = v4l2_ctrl_s_ctrl(priv->ctrls.gain, priv->ctrls.gain->val);
-       if (ret)
-               return ret;
-
-       /* update vflip */
-       ret = v4l2_ctrl_s_ctrl(priv->ctrls.vflip, priv->ctrls.vflip->val);
-       if (ret)
-               return ret;
-
-       return 0;
 }
 
 /**
@@ -1329,6 +1439,13 @@ static int imx274_s_stream(struct v4l2_subdev *sd, int on)
        mutex_lock(&imx274->lock);
 
        if (on) {
+               ret = pm_runtime_get_sync(&imx274->client->dev);
+               if (ret < 0) {
+                       pm_runtime_put_noidle(&imx274->client->dev);
+                       mutex_unlock(&imx274->lock);
+                       return ret;
+               }
+
                /* load mode registers */
                ret = imx274_mode_regs(imx274);
                if (ret)
@@ -1349,12 +1466,6 @@ static int imx274_s_stream(struct v4l2_subdev *sd, int on)
                if (ret)
                        goto fail;
 
-               /* update exposure time */
-               ret = __v4l2_ctrl_s_ctrl(imx274->ctrls.exposure,
-                                        imx274->ctrls.exposure->val);
-               if (ret)
-                       goto fail;
-
                /* start stream */
                ret = imx274_start_stream(imx274);
                if (ret)
@@ -1364,6 +1475,8 @@ static int imx274_s_stream(struct v4l2_subdev *sd, int on)
                ret = imx274_write_table(imx274, imx274_stop);
                if (ret)
                        goto fail;
+
+               pm_runtime_put(&imx274->client->dev);
        }
 
        mutex_unlock(&imx274->lock);
@@ -1371,6 +1484,7 @@ static int imx274_s_stream(struct v4l2_subdev *sd, int on)
        return 0;
 
 fail:
+       pm_runtime_put(&imx274->client->dev);
        mutex_unlock(&imx274->lock);
        dev_err(&imx274->client->dev, "s_stream failed\n");
        return ret;
@@ -1836,12 +1950,23 @@ static int imx274_probe(struct i2c_client *client)
 
        mutex_init(&imx274->lock);
 
+       imx274->inck = devm_clk_get_optional(&client->dev, "inck");
+       if (IS_ERR(imx274->inck))
+               return PTR_ERR(imx274->inck);
+
+       ret = imx274_regulators_get(&client->dev, imx274);
+       if (ret) {
+               dev_err(&client->dev,
+                       "Failed to get power regulators, err: %d\n", ret);
+               return ret;
+       }
+
        /* initialize format */
-       imx274->mode = &imx274_modes[IMX274_DEFAULT_BINNING];
+       imx274->mode = &imx274_modes[0];
        imx274->crop.width = IMX274_MAX_WIDTH;
        imx274->crop.height = IMX274_MAX_HEIGHT;
-       imx274->format.width = imx274->crop.width / imx274->mode->bin_ratio;
-       imx274->format.height = imx274->crop.height / imx274->mode->bin_ratio;
+       imx274->format.width = imx274->crop.width / imx274->mode->wbin_ratio;
+       imx274->format.height = imx274->crop.height / imx274->mode->hbin_ratio;
        imx274->format.field = V4L2_FIELD_NONE;
        imx274->format.code = MEDIA_BUS_FMT_SRGGB10_1X10;
        imx274->format.colorspace = V4L2_COLORSPACE_SRGB;
@@ -1883,15 +2008,20 @@ static int imx274_probe(struct i2c_client *client)
                goto err_me;
        }
 
-       /* pull sensor out of reset */
-       imx274_reset(imx274, 1);
+       /* power on the sensor */
+       ret = imx274_power_on(&client->dev);
+       if (ret < 0) {
+               dev_err(&client->dev,
+                       "%s : imx274 power on failed\n", __func__);
+               goto err_me;
+       }
 
        /* initialize controls */
        ret = v4l2_ctrl_handler_init(&imx274->ctrls.handler, 4);
        if (ret < 0) {
                dev_err(&client->dev,
                        "%s : ctrl handler init Failed\n", __func__);
-               goto err_me;
+               goto err_power_off;
        }
 
        imx274->ctrls.handler.lock = &imx274->lock;
@@ -1927,22 +2057,8 @@ static int imx274_probe(struct i2c_client *client)
                goto err_ctrls;
        }
 
-       /* setup default controls */
-       ret = v4l2_ctrl_handler_setup(&imx274->ctrls.handler);
-       if (ret) {
-               dev_err(&client->dev,
-                       "Error %d setup default controls\n", ret);
-               goto err_ctrls;
-       }
-
        /* load default control values */
-       ret = imx274_load_default(imx274);
-       if (ret) {
-               dev_err(&client->dev,
-                       "%s : imx274_load_default failed %d\n",
-                       __func__, ret);
-               goto err_ctrls;
-       }
+       imx274_load_default(imx274);
 
        /* register subdevice */
        ret = v4l2_async_register_subdev(sd);
@@ -1953,11 +2069,17 @@ static int imx274_probe(struct i2c_client *client)
                goto err_ctrls;
        }
 
+       pm_runtime_set_active(&client->dev);
+       pm_runtime_enable(&client->dev);
+       pm_runtime_idle(&client->dev);
+
        dev_info(&client->dev, "imx274 : imx274 probe success !\n");
        return 0;
 
 err_ctrls:
        v4l2_ctrl_handler_free(&imx274->ctrls.handler);
+err_power_off:
+       imx274_power_off(&client->dev);
 err_me:
        media_entity_cleanup(&sd->entity);
 err_regmap:
@@ -1970,19 +2092,27 @@ static int imx274_remove(struct i2c_client *client)
        struct v4l2_subdev *sd = i2c_get_clientdata(client);
        struct stimx274 *imx274 = to_imx274(sd);
 
-       /* stop stream */
-       imx274_write_table(imx274, imx274_stop);
+       pm_runtime_disable(&client->dev);
+       if (!pm_runtime_status_suspended(&client->dev))
+               imx274_power_off(&client->dev);
+       pm_runtime_set_suspended(&client->dev);
 
        v4l2_async_unregister_subdev(sd);
        v4l2_ctrl_handler_free(&imx274->ctrls.handler);
+
        media_entity_cleanup(&sd->entity);
        mutex_destroy(&imx274->lock);
        return 0;
 }
 
+static const struct dev_pm_ops imx274_pm_ops = {
+       SET_RUNTIME_PM_OPS(imx274_power_off, imx274_power_on, NULL)
+};
+
 static struct i2c_driver imx274_i2c_driver = {
        .driver = {
                .name   = DRIVER_NAME,
+               .pm = &imx274_pm_ops,
                .of_match_table = imx274_of_id_table,
        },
        .probe_new      = imx274_probe,
index adcddf3..6319a42 100644 (file)
@@ -842,20 +842,19 @@ exit:
 
 static int imx290_power_on(struct device *dev)
 {
-       struct i2c_client *client = to_i2c_client(dev);
-       struct v4l2_subdev *sd = i2c_get_clientdata(client);
+       struct v4l2_subdev *sd = dev_get_drvdata(dev);
        struct imx290 *imx290 = to_imx290(sd);
        int ret;
 
        ret = clk_prepare_enable(imx290->xclk);
        if (ret) {
-               dev_err(imx290->dev, "Failed to enable clock\n");
+               dev_err(dev, "Failed to enable clock\n");
                return ret;
        }
 
        ret = regulator_bulk_enable(IMX290_NUM_SUPPLIES, imx290->supplies);
        if (ret) {
-               dev_err(imx290->dev, "Failed to enable regulators\n");
+               dev_err(dev, "Failed to enable regulators\n");
                clk_disable_unprepare(imx290->xclk);
                return ret;
        }
@@ -872,8 +871,7 @@ static int imx290_power_on(struct device *dev)
 
 static int imx290_power_off(struct device *dev)
 {
-       struct i2c_client *client = to_i2c_client(dev);
-       struct v4l2_subdev *sd = i2c_get_clientdata(client);
+       struct v4l2_subdev *sd = dev_get_drvdata(dev);
        struct imx290 *imx290 = to_imx290(sd);
 
        clk_disable_unprepare(imx290->xclk);
index 17c2e4b..8473c0b 100644 (file)
@@ -2179,8 +2179,7 @@ err_unlock:
 
 static int __maybe_unused imx319_suspend(struct device *dev)
 {
-       struct i2c_client *client = to_i2c_client(dev);
-       struct v4l2_subdev *sd = i2c_get_clientdata(client);
+       struct v4l2_subdev *sd = dev_get_drvdata(dev);
        struct imx319 *imx319 = to_imx319(sd);
 
        if (imx319->streaming)
@@ -2191,8 +2190,7 @@ static int __maybe_unused imx319_suspend(struct device *dev)
 
 static int __maybe_unused imx319_resume(struct device *dev)
 {
-       struct i2c_client *client = to_i2c_client(dev);
-       struct v4l2_subdev *sd = i2c_get_clientdata(client);
+       struct v4l2_subdev *sd = dev_get_drvdata(dev);
        struct imx319 *imx319 = to_imx319(sd);
        int ret;
 
@@ -2535,7 +2533,7 @@ static const struct dev_pm_ops imx319_pm_ops = {
        SET_SYSTEM_SLEEP_PM_OPS(imx319_suspend, imx319_resume)
 };
 
-static const struct acpi_device_id imx319_acpi_ids[] = {
+static const struct acpi_device_id imx319_acpi_ids[] __maybe_unused = {
        { "SONY319A" },
        { /* sentinel */ }
 };
index bed293b..700f746 100644 (file)
@@ -1480,8 +1480,7 @@ err_unlock:
 
 static int __maybe_unused imx355_suspend(struct device *dev)
 {
-       struct i2c_client *client = to_i2c_client(dev);
-       struct v4l2_subdev *sd = i2c_get_clientdata(client);
+       struct v4l2_subdev *sd = dev_get_drvdata(dev);
        struct imx355 *imx355 = to_imx355(sd);
 
        if (imx355->streaming)
@@ -1492,8 +1491,7 @@ static int __maybe_unused imx355_suspend(struct device *dev)
 
 static int __maybe_unused imx355_resume(struct device *dev)
 {
-       struct i2c_client *client = to_i2c_client(dev);
-       struct v4l2_subdev *sd = i2c_get_clientdata(client);
+       struct v4l2_subdev *sd = dev_get_drvdata(dev);
        struct imx355 *imx355 = to_imx355(sd);
        int ret;
 
@@ -1835,7 +1833,7 @@ static const struct dev_pm_ops imx355_pm_ops = {
        SET_SYSTEM_SLEEP_PM_OPS(imx355_suspend, imx355_resume)
 };
 
-static const struct acpi_device_id imx355_acpi_ids[] = {
+static const struct acpi_device_id imx355_acpi_ids[] __maybe_unused = {
        { "SONY355A" },
        { /* sentinel */ }
 };
index 03b4ed3..661208c 100644 (file)
@@ -503,7 +503,7 @@ static void max2175_set_bbfilter(struct max2175 *ctx)
        }
 }
 
-static bool max2175_set_csm_mode(struct max2175 *ctx,
+static int max2175_set_csm_mode(struct max2175 *ctx,
                          enum max2175_csm_mode new_mode)
 {
        int ret = max2175_poll_csm_ready(ctx);
index 52e506f..ecabc0e 100644 (file)
@@ -549,8 +549,10 @@ restart:
                        val = msp_read_dsp(client, 0x1b);
                        if (val > 32767)
                                val -= 65536;
-                       if (val1 < val)
-                               val1 = val, max1 = i;
+                       if (val1 < val) {
+                               val1 = val;
+                               max1 = i;
+                       }
                        dev_dbg_lvl(&client->dev, 1, msp_debug,
                                "carrier1 val: %5d / %s\n", val, cd[i].name);
                }
@@ -586,8 +588,10 @@ restart:
                        val = msp_read_dsp(client, 0x1b);
                        if (val > 32767)
                                val -= 65536;
-                       if (val2 < val)
-                               val2 = val, max2 = i;
+                       if (val2 < val) {
+                               val2 = val;
+                               max2 = i;
+                       }
                        dev_dbg_lvl(&client->dev, 1, msp_debug,
                                "carrier2 val: %5d / %s\n", val, cd[i].name);
                }
index dc23b9e..a633b93 100644 (file)
@@ -346,8 +346,7 @@ static void mt9p031_power_off(struct mt9p031 *mt9p031)
        regulator_bulk_disable(ARRAY_SIZE(mt9p031->regulators),
                               mt9p031->regulators);
 
-       if (mt9p031->clk)
-               clk_disable_unprepare(mt9p031->clk);
+       clk_disable_unprepare(mt9p031->clk);
 }
 
 static int __mt9p031_set_power(struct mt9p031 *mt9p031, bool on)
index 236ad2c..2f3be7a 100644 (file)
@@ -1505,8 +1505,7 @@ err_unlock:
 
 static int __maybe_unused ov13858_suspend(struct device *dev)
 {
-       struct i2c_client *client = to_i2c_client(dev);
-       struct v4l2_subdev *sd = i2c_get_clientdata(client);
+       struct v4l2_subdev *sd = dev_get_drvdata(dev);
        struct ov13858 *ov13858 = to_ov13858(sd);
 
        if (ov13858->streaming)
@@ -1517,8 +1516,7 @@ static int __maybe_unused ov13858_suspend(struct device *dev)
 
 static int __maybe_unused ov13858_resume(struct device *dev)
 {
-       struct i2c_client *client = to_i2c_client(dev);
-       struct v4l2_subdev *sd = i2c_get_clientdata(client);
+       struct v4l2_subdev *sd = dev_get_drvdata(dev);
        struct ov13858 *ov13858 = to_ov13858(sd);
        int ret;
 
index 59cdbc3..178dfe9 100644 (file)
@@ -1111,8 +1111,7 @@ static int ov2680_remove(struct i2c_client *client)
 
 static int __maybe_unused ov2680_suspend(struct device *dev)
 {
-       struct i2c_client *client = to_i2c_client(dev);
-       struct v4l2_subdev *sd = i2c_get_clientdata(client);
+       struct v4l2_subdev *sd = dev_get_drvdata(dev);
        struct ov2680_dev *sensor = to_ov2680_dev(sd);
 
        if (sensor->is_streaming)
@@ -1123,8 +1122,7 @@ static int __maybe_unused ov2680_suspend(struct device *dev)
 
 static int __maybe_unused ov2680_resume(struct device *dev)
 {
-       struct i2c_client *client = to_i2c_client(dev);
-       struct v4l2_subdev *sd = i2c_get_clientdata(client);
+       struct v4l2_subdev *sd = dev_get_drvdata(dev);
        struct ov2680_dev *sensor = to_ov2680_dev(sd);
        int ret;
 
index 6814583..49a2dce 100644 (file)
@@ -506,8 +506,7 @@ static int ov2685_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
 
 static int __maybe_unused ov2685_runtime_resume(struct device *dev)
 {
-       struct i2c_client *client = to_i2c_client(dev);
-       struct v4l2_subdev *sd = i2c_get_clientdata(client);
+       struct v4l2_subdev *sd = dev_get_drvdata(dev);
        struct ov2685 *ov2685 = to_ov2685(sd);
 
        return __ov2685_power_on(ov2685);
@@ -515,8 +514,7 @@ static int __maybe_unused ov2685_runtime_resume(struct device *dev)
 
 static int __maybe_unused ov2685_runtime_suspend(struct device *dev)
 {
-       struct i2c_client *client = to_i2c_client(dev);
-       struct v4l2_subdev *sd = i2c_get_clientdata(client);
+       struct v4l2_subdev *sd = dev_get_drvdata(dev);
        struct ov2685 *ov2685 = to_ov2685(sd);
 
        __ov2685_power_off(ov2685);
index bd0d45b..9901654 100644 (file)
@@ -37,7 +37,7 @@
 
 /* Exposure controls from sensor */
 #define OV2740_REG_EXPOSURE            0x3500
-#define OV2740_EXPOSURE_MIN            8
+#define OV2740_EXPOSURE_MIN            4
 #define OV2740_EXPOSURE_MAX_MARGIN     8
 #define OV2740_EXPOSURE_STEP           1
 
 #define OV2740_REG_OTP_CUSTOMER                0x7010
 
 struct nvm_data {
-       char *nvm_buffer;
+       struct i2c_client *client;
        struct nvmem_device *nvmem;
        struct regmap *regmap;
+       char *nvm_buffer;
 };
 
 enum {
@@ -335,6 +336,9 @@ struct ov2740 {
 
        /* Streaming on/off */
        bool streaming;
+
+       /* NVM data inforamtion */
+       struct nvm_data *nvm;
 };
 
 static inline struct ov2740 *to_ov2740(struct v4l2_subdev *subdev)
@@ -594,13 +598,109 @@ static void ov2740_update_pad_format(const struct ov2740_mode *mode,
        fmt->field = V4L2_FIELD_NONE;
 }
 
+static int ov2740_load_otp_data(struct nvm_data *nvm)
+{
+       struct i2c_client *client = nvm->client;
+       struct ov2740 *ov2740 = to_ov2740(i2c_get_clientdata(client));
+       u32 isp_ctrl00 = 0;
+       u32 isp_ctrl01 = 0;
+       int ret;
+
+       if (!nvm)
+               return -EINVAL;
+
+       if (nvm->nvm_buffer)
+               return 0;
+
+       nvm->nvm_buffer = kzalloc(CUSTOMER_USE_OTP_SIZE, GFP_KERNEL);
+       if (!nvm->nvm_buffer)
+               return -ENOMEM;
+
+       ret = ov2740_read_reg(ov2740, OV2740_REG_ISP_CTRL00, 1, &isp_ctrl00);
+       if (ret) {
+               dev_err(&client->dev, "failed to read ISP CTRL00\n");
+               goto err;
+       }
+
+       ret = ov2740_read_reg(ov2740, OV2740_REG_ISP_CTRL01, 1, &isp_ctrl01);
+       if (ret) {
+               dev_err(&client->dev, "failed to read ISP CTRL01\n");
+               goto err;
+       }
+
+       /* Clear bit 5 of ISP CTRL00 */
+       ret = ov2740_write_reg(ov2740, OV2740_REG_ISP_CTRL00, 1,
+                              isp_ctrl00 & ~BIT(5));
+       if (ret) {
+               dev_err(&client->dev, "failed to set ISP CTRL00\n");
+               goto err;
+       }
+
+       /* Clear bit 7 of ISP CTRL01 */
+       ret = ov2740_write_reg(ov2740, OV2740_REG_ISP_CTRL01, 1,
+                              isp_ctrl01 & ~BIT(7));
+       if (ret) {
+               dev_err(&client->dev, "failed to set ISP CTRL01\n");
+               goto err;
+       }
+
+       ret = ov2740_write_reg(ov2740, OV2740_REG_MODE_SELECT, 1,
+                              OV2740_MODE_STREAMING);
+       if (ret) {
+               dev_err(&client->dev, "failed to set streaming mode\n");
+               goto err;
+       }
+
+       /*
+        * Users are not allowed to access OTP-related registers and memory
+        * during the 20 ms period after streaming starts (0x100 = 0x01).
+        */
+       msleep(20);
+
+       ret = regmap_bulk_read(nvm->regmap, OV2740_REG_OTP_CUSTOMER,
+                              nvm->nvm_buffer, CUSTOMER_USE_OTP_SIZE);
+       if (ret) {
+               dev_err(&client->dev, "failed to read OTP data, ret %d\n", ret);
+               goto err;
+       }
+
+       ret = ov2740_write_reg(ov2740, OV2740_REG_MODE_SELECT, 1,
+                              OV2740_MODE_STANDBY);
+       if (ret) {
+               dev_err(&client->dev, "failed to set streaming mode\n");
+               goto err;
+       }
+
+       ret = ov2740_write_reg(ov2740, OV2740_REG_ISP_CTRL01, 1, isp_ctrl01);
+       if (ret) {
+               dev_err(&client->dev, "failed to set ISP CTRL01\n");
+               goto err;
+       }
+
+       ret = ov2740_write_reg(ov2740, OV2740_REG_ISP_CTRL00, 1, isp_ctrl00);
+       if (ret) {
+               dev_err(&client->dev, "failed to set ISP CTRL00\n");
+               goto err;
+       }
+
+       return 0;
+err:
+       kfree(nvm->nvm_buffer);
+       nvm->nvm_buffer = NULL;
+
+       return ret;
+}
+
 static int ov2740_start_streaming(struct ov2740 *ov2740)
 {
        struct i2c_client *client = v4l2_get_subdevdata(&ov2740->sd);
+       struct nvm_data *nvm = ov2740->nvm;
        const struct ov2740_reg_list *reg_list;
        int link_freq_index;
        int ret = 0;
 
+       ov2740_load_otp_data(nvm);
+
        link_freq_index = ov2740->cur_mode->link_freq_index;
        reg_list = &link_freq_configs[link_freq_index].reg_list;
        ret = ov2740_write_reg_list(ov2740, reg_list);
@@ -674,8 +774,7 @@ static int ov2740_set_stream(struct v4l2_subdev *sd, int enable)
 
 static int __maybe_unused ov2740_suspend(struct device *dev)
 {
-       struct i2c_client *client = to_i2c_client(dev);
-       struct v4l2_subdev *sd = i2c_get_clientdata(client);
+       struct v4l2_subdev *sd = dev_get_drvdata(dev);
        struct ov2740 *ov2740 = to_ov2740(sd);
 
        mutex_lock(&ov2740->mutex);
@@ -689,8 +788,7 @@ static int __maybe_unused ov2740_suspend(struct device *dev)
 
 static int __maybe_unused ov2740_resume(struct device *dev)
 {
-       struct i2c_client *client = to_i2c_client(dev);
-       struct v4l2_subdev *sd = i2c_get_clientdata(client);
+       struct v4l2_subdev *sd = dev_get_drvdata(dev);
        struct ov2740 *ov2740 = to_ov2740(sd);
        int ret = 0;
 
@@ -932,96 +1030,52 @@ static int ov2740_remove(struct i2c_client *client)
        return 0;
 }
 
-static int ov2740_load_otp_data(struct i2c_client *client, struct nvm_data *nvm)
+static int ov2740_nvmem_read(void *priv, unsigned int off, void *val,
+                            size_t count)
 {
-       struct ov2740 *ov2740 = to_ov2740(i2c_get_clientdata(client));
-       u32 isp_ctrl00 = 0;
-       u32 isp_ctrl01 = 0;
-       int ret;
-
-       ret = ov2740_read_reg(ov2740, OV2740_REG_ISP_CTRL00, 1, &isp_ctrl00);
-       if (ret) {
-               dev_err(&client->dev, "failed to read ISP CTRL00\n");
-               goto exit;
-       }
-       ret = ov2740_read_reg(ov2740, OV2740_REG_ISP_CTRL01, 1, &isp_ctrl01);
-       if (ret) {
-               dev_err(&client->dev, "failed to read ISP CTRL01\n");
-               goto exit;
-       }
-
-       /* Clear bit 5 of ISP CTRL00 */
-       ret = ov2740_write_reg(ov2740, OV2740_REG_ISP_CTRL00, 1,
-                              isp_ctrl00 & ~BIT(5));
-       if (ret) {
-               dev_err(&client->dev, "failed to write ISP CTRL00\n");
-               goto exit;
-       }
+       struct nvm_data *nvm = priv;
+       struct v4l2_subdev *sd = i2c_get_clientdata(nvm->client);
+       struct device *dev = &nvm->client->dev;
+       struct ov2740 *ov2740 = to_ov2740(sd);
+       int ret = 0;
 
-       /* Clear bit 7 of ISP CTRL01 */
-       ret = ov2740_write_reg(ov2740, OV2740_REG_ISP_CTRL01, 1,
-                              isp_ctrl01 & ~BIT(7));
-       if (ret) {
-               dev_err(&client->dev, "failed to write ISP CTRL01\n");
-               goto exit;
-       }
+       mutex_lock(&ov2740->mutex);
 
-       ret = ov2740_write_reg(ov2740, OV2740_REG_MODE_SELECT, 1,
-                              OV2740_MODE_STREAMING);
-       if (ret) {
-               dev_err(&client->dev, "failed to start streaming\n");
+       if (nvm->nvm_buffer) {
+               memcpy(val, nvm->nvm_buffer + off, count);
                goto exit;
        }
 
-       /*
-        * Users are not allowed to access OTP-related registers and memory
-        * during the 20 ms period after streaming starts (0x100 = 0x01).
-        */
-       msleep(20);
-
-       ret = regmap_bulk_read(nvm->regmap, OV2740_REG_OTP_CUSTOMER,
-                              nvm->nvm_buffer, CUSTOMER_USE_OTP_SIZE);
-       if (ret) {
-               dev_err(&client->dev, "failed to read OTP data, ret %d\n", ret);
+       ret = pm_runtime_get_sync(dev);
+       if (ret < 0) {
+               pm_runtime_put_noidle(dev);
                goto exit;
        }
 
-       ov2740_write_reg(ov2740, OV2740_REG_MODE_SELECT, 1,
-                        OV2740_MODE_STANDBY);
-       ov2740_write_reg(ov2740, OV2740_REG_ISP_CTRL01, 1, isp_ctrl01);
-       ov2740_write_reg(ov2740, OV2740_REG_ISP_CTRL00, 1, isp_ctrl00);
+       ret = ov2740_load_otp_data(nvm);
+       if (!ret)
+               memcpy(val, nvm->nvm_buffer + off, count);
 
+       pm_runtime_put(dev);
 exit:
+       mutex_unlock(&ov2740->mutex);
        return ret;
 }
 
-static int ov2740_nvmem_read(void *priv, unsigned int off, void *val,
-                            size_t count)
-{
-       struct nvm_data *nvm = priv;
-
-       memcpy(val, nvm->nvm_buffer + off, count);
-
-       return 0;
-}
-
-static int ov2740_register_nvmem(struct i2c_client *client)
+static int ov2740_register_nvmem(struct i2c_client *client,
+                                struct ov2740 *ov2740)
 {
        struct nvm_data *nvm;
        struct regmap_config regmap_config = { };
        struct nvmem_config nvmem_config = { };
        struct regmap *regmap;
        struct device *dev = &client->dev;
-       int ret = 0;
+       int ret;
 
        nvm = devm_kzalloc(dev, sizeof(*nvm), GFP_KERNEL);
        if (!nvm)
                return -ENOMEM;
 
-       nvm->nvm_buffer = devm_kzalloc(dev, CUSTOMER_USE_OTP_SIZE, GFP_KERNEL);
-       if (!nvm->nvm_buffer)
-               return -ENOMEM;
-
        regmap_config.val_bits = 8;
        regmap_config.reg_bits = 16;
        regmap_config.disable_locking = true;
@@ -1030,12 +1084,7 @@ static int ov2740_register_nvmem(struct i2c_client *client)
                return PTR_ERR(regmap);
 
        nvm->regmap = regmap;
-
-       ret = ov2740_load_otp_data(client, nvm);
-       if (ret) {
-               dev_err(dev, "failed to load OTP data, ret %d\n", ret);
-               return ret;
-       }
+       nvm->client = client;
 
        nvmem_config.name = dev_name(dev);
        nvmem_config.dev = dev;
@@ -1053,7 +1102,11 @@ static int ov2740_register_nvmem(struct i2c_client *client)
 
        nvm->nvmem = devm_nvmem_register(dev, &nvmem_config);
 
-       return PTR_ERR_OR_ZERO(nvm->nvmem);
+       ret = PTR_ERR_OR_ZERO(nvm->nvmem);
+       if (!ret)
+               ov2740->nvm = nvm;
+
+       return ret;
 }
 
 static int ov2740_probe(struct i2c_client *client)
@@ -1105,7 +1158,7 @@ static int ov2740_probe(struct i2c_client *client)
                goto probe_error_media_entity_cleanup;
        }
 
-       ret = ov2740_register_nvmem(client);
+       ret = ov2740_register_nvmem(client, ov2740);
        if (ret)
                dev_warn(&client->dev, "register nvmem failed, ret %d\n", ret);
 
index 8d0254d..14f3afa 100644 (file)
@@ -98,7 +98,8 @@
 #define OV5640_REG_AVG_READOUT         0x56a1
 
 enum ov5640_mode_id {
-       OV5640_MODE_QCIF_176_144 = 0,
+       OV5640_MODE_QQVGA_160_120 = 0,
+       OV5640_MODE_QCIF_176_144,
        OV5640_MODE_QVGA_320_240,
        OV5640_MODE_VGA_640_480,
        OV5640_MODE_NTSC_720_480,
@@ -416,6 +417,24 @@ static const struct reg_value ov5640_setting_QVGA_320_240[] = {
        {0x3824, 0x02, 0, 0}, {0x5001, 0xa3, 0, 0},
 };
 
+static const struct reg_value ov5640_setting_QQVGA_160_120[] = {
+       {0x3c07, 0x08, 0, 0},
+       {0x3c09, 0x1c, 0, 0}, {0x3c0a, 0x9c, 0, 0}, {0x3c0b, 0x40, 0, 0},
+       {0x3814, 0x31, 0, 0},
+       {0x3815, 0x31, 0, 0}, {0x3800, 0x00, 0, 0}, {0x3801, 0x00, 0, 0},
+       {0x3802, 0x00, 0, 0}, {0x3803, 0x04, 0, 0}, {0x3804, 0x0a, 0, 0},
+       {0x3805, 0x3f, 0, 0}, {0x3806, 0x07, 0, 0}, {0x3807, 0x9b, 0, 0},
+       {0x3810, 0x00, 0, 0},
+       {0x3811, 0x10, 0, 0}, {0x3812, 0x00, 0, 0}, {0x3813, 0x06, 0, 0},
+       {0x3618, 0x00, 0, 0}, {0x3612, 0x29, 0, 0}, {0x3708, 0x64, 0, 0},
+       {0x3709, 0x52, 0, 0}, {0x370c, 0x03, 0, 0}, {0x3a02, 0x03, 0, 0},
+       {0x3a03, 0xd8, 0, 0}, {0x3a08, 0x01, 0, 0}, {0x3a09, 0x27, 0, 0},
+       {0x3a0a, 0x00, 0, 0}, {0x3a0b, 0xf6, 0, 0}, {0x3a0e, 0x03, 0, 0},
+       {0x3a0d, 0x04, 0, 0}, {0x3a14, 0x03, 0, 0}, {0x3a15, 0xd8, 0, 0},
+       {0x4001, 0x02, 0, 0}, {0x4004, 0x02, 0, 0},
+       {0x4407, 0x04, 0, 0}, {0x5001, 0xa3, 0, 0},
+};
+
 static const struct reg_value ov5640_setting_QCIF_176_144[] = {
        {0x3c07, 0x08, 0, 0},
        {0x3c09, 0x1c, 0, 0}, {0x3c0a, 0x9c, 0, 0}, {0x3c0b, 0x40, 0, 0},
@@ -552,6 +571,11 @@ static const struct ov5640_mode_info ov5640_mode_init_data = {
 
 static const struct ov5640_mode_info
 ov5640_mode_data[OV5640_NUM_MODES] = {
+       {OV5640_MODE_QQVGA_160_120, SUBSAMPLING,
+        160, 1896, 120, 984,
+        ov5640_setting_QQVGA_160_120,
+        ARRAY_SIZE(ov5640_setting_QQVGA_160_120),
+        OV5640_30_FPS},
        {OV5640_MODE_QCIF_176_144, SUBSAMPLING,
         176, 1896, 144, 984,
         ov5640_setting_QCIF_176_144,
@@ -1216,20 +1240,6 @@ static int ov5640_set_autogain(struct ov5640_dev *sensor, bool on)
                              BIT(1), on ? 0 : BIT(1));
 }
 
-static int ov5640_set_stream_bt656(struct ov5640_dev *sensor, bool on)
-{
-       int ret;
-
-       ret = ov5640_write_reg(sensor, OV5640_REG_CCIR656_CTRL00,
-                              on ? 0x1 : 0x00);
-       if (ret)
-               return ret;
-
-       return ov5640_write_reg(sensor, OV5640_REG_SYS_CTRL0, on ?
-                               OV5640_REG_SYS_CTRL0_SW_PWUP :
-                               OV5640_REG_SYS_CTRL0_SW_PWDN);
-}
-
 static int ov5640_set_stream_dvp(struct ov5640_dev *sensor, bool on)
 {
        return ov5640_write_reg(sensor, OV5640_REG_SYS_CTRL0, on ?
@@ -1994,13 +2004,13 @@ static int ov5640_set_power_mipi(struct ov5640_dev *sensor, bool on)
 static int ov5640_set_power_dvp(struct ov5640_dev *sensor, bool on)
 {
        unsigned int flags = sensor->ep.bus.parallel.flags;
-       u8 pclk_pol = 0;
-       u8 hsync_pol = 0;
-       u8 vsync_pol = 0;
+       bool bt656 = sensor->ep.bus_type == V4L2_MBUS_BT656;
+       u8 polarities = 0;
        int ret;
 
        if (!on) {
                /* Reset settings to their default values. */
+               ov5640_write_reg(sensor, OV5640_REG_CCIR656_CTRL00, 0x00);
                ov5640_write_reg(sensor, OV5640_REG_IO_MIPI_CTRL00, 0x58);
                ov5640_write_reg(sensor, OV5640_REG_POLARITY_CTRL00, 0x20);
                ov5640_write_reg(sensor, OV5640_REG_PAD_OUTPUT_ENABLE01, 0x00);
@@ -2024,7 +2034,35 @@ static int ov5640_set_power_dvp(struct ov5640_dev *sensor, bool on)
         * - VSYNC:     active high
         * - HREF:      active low
         * - PCLK:      active low
+        *
+        * VSYNC & HREF are not configured if BT656 bus mode is selected
         */
+
+       /*
+        * BT656 embedded synchronization configuration
+        *
+        * CCIR656 CTRL00
+        * - [7]:       SYNC code selection (0: auto generate sync code,
+        *              1: sync code from regs 0x4732-0x4735)
+        * - [6]:       f value in CCIR656 SYNC code when fixed f value
+        * - [5]:       Fixed f value
+        * - [4:3]:     Blank toggle data options (00: data=1'h040/1'h200,
+        *              01: data from regs 0x4736-0x4738, 10: always keep 0)
+        * - [1]:       Clip data disable
+        * - [0]:       CCIR656 mode enable
+        *
+        * Default CCIR656 SAV/EAV mode with default codes
+        * SAV=0xff000080 & EAV=0xff00009d is enabled here with settings:
+        * - CCIR656 mode enable
+        * - auto generation of sync codes
+        * - blank toggle data 1'h040/1'h200
+        * - clip reserved data (0x00 & 0xff changed to 0x01 & 0xfe)
+        */
+       ret = ov5640_write_reg(sensor, OV5640_REG_CCIR656_CTRL00,
+                              bt656 ? 0x01 : 0x00);
+       if (ret)
+               return ret;
+
        /*
         * configure parallel port control lines polarity
         *
@@ -2035,29 +2073,26 @@ static int ov5640_set_power_dvp(struct ov5640_dev *sensor, bool on)
         *              datasheet and hardware, 0 is active high
         *              and 1 is active low...)
         */
-       if (sensor->ep.bus_type == V4L2_MBUS_PARALLEL) {
-               if (flags & V4L2_MBUS_PCLK_SAMPLE_RISING)
-                       pclk_pol = 1;
+       if (!bt656) {
                if (flags & V4L2_MBUS_HSYNC_ACTIVE_HIGH)
-                       hsync_pol = 1;
+                       polarities |= BIT(1);
                if (flags & V4L2_MBUS_VSYNC_ACTIVE_LOW)
-                       vsync_pol = 1;
-
-               ret = ov5640_write_reg(sensor, OV5640_REG_POLARITY_CTRL00,
-                                      (pclk_pol << 5) | (hsync_pol << 1) |
-                                      vsync_pol);
-
-               if (ret)
-                       return ret;
+                       polarities |= BIT(0);
        }
+       if (flags & V4L2_MBUS_PCLK_SAMPLE_RISING)
+               polarities |= BIT(5);
+
+       ret = ov5640_write_reg(sensor, OV5640_REG_POLARITY_CTRL00, polarities);
+       if (ret)
+               return ret;
 
        /*
-        * powerdown MIPI TX/RX PHY & disable MIPI
+        * powerdown MIPI TX/RX PHY & enable DVP
         *
         * MIPI CONTROL 00
-        * 4:    PWDN PHY TX
-        * 3:    PWDN PHY RX
-        * 2:    MIPI enable
+        * [4] = 1      : Power down MIPI HS Tx
+        * [3] = 1      : Power down MIPI LS Rx
+        * [2] = 0      : DVP enable (MIPI disable)
         */
        ret = ov5640_write_reg(sensor, OV5640_REG_IO_MIPI_CTRL00, 0x18);
        if (ret)
@@ -2074,8 +2109,7 @@ static int ov5640_set_power_dvp(struct ov5640_dev *sensor, bool on)
         * - [3:0]:     D[9:6] output enable
         */
        ret = ov5640_write_reg(sensor, OV5640_REG_PAD_OUTPUT_ENABLE01,
-                              sensor->ep.bus_type == V4L2_MBUS_PARALLEL ?
-                              0x7f : 0x1f);
+                              bt656 ? 0x1f : 0x7f);
        if (ret)
                return ret;
 
@@ -2925,8 +2959,6 @@ static int ov5640_s_stream(struct v4l2_subdev *sd, int enable)
 
                if (sensor->ep.bus_type == V4L2_MBUS_CSI2_DPHY)
                        ret = ov5640_set_stream_mipi(sensor, enable);
-               else if (sensor->ep.bus_type == V4L2_MBUS_BT656)
-                       ret = ov5640_set_stream_bt656(sensor, enable);
                else
                        ret = ov5640_set_stream_dvp(sensor, enable);
 
index f26252e..148fd4e 100644 (file)
@@ -2373,8 +2373,7 @@ unlock_and_return:
 
 static int __maybe_unused ov5670_suspend(struct device *dev)
 {
-       struct i2c_client *client = to_i2c_client(dev);
-       struct v4l2_subdev *sd = i2c_get_clientdata(client);
+       struct v4l2_subdev *sd = dev_get_drvdata(dev);
        struct ov5670 *ov5670 = to_ov5670(sd);
 
        if (ov5670->streaming)
@@ -2385,8 +2384,7 @@ static int __maybe_unused ov5670_suspend(struct device *dev)
 
 static int __maybe_unused ov5670_resume(struct device *dev)
 {
-       struct i2c_client *client = to_i2c_client(dev);
-       struct v4l2_subdev *sd = i2c_get_clientdata(client);
+       struct v4l2_subdev *sd = dev_get_drvdata(dev);
        struct ov5670 *ov5670 = to_ov5670(sd);
        int ret;
 
index 9540ce8..5e35808 100644 (file)
@@ -889,8 +889,7 @@ static int ov5675_set_stream(struct v4l2_subdev *sd, int enable)
 
 static int __maybe_unused ov5675_suspend(struct device *dev)
 {
-       struct i2c_client *client = to_i2c_client(dev);
-       struct v4l2_subdev *sd = i2c_get_clientdata(client);
+       struct v4l2_subdev *sd = dev_get_drvdata(dev);
        struct ov5675 *ov5675 = to_ov5675(sd);
 
        mutex_lock(&ov5675->mutex);
@@ -904,8 +903,7 @@ static int __maybe_unused ov5675_suspend(struct device *dev)
 
 static int __maybe_unused ov5675_resume(struct device *dev)
 {
-       struct i2c_client *client = to_i2c_client(dev);
-       struct v4l2_subdev *sd = i2c_get_clientdata(client);
+       struct v4l2_subdev *sd = dev_get_drvdata(dev);
        struct ov5675 *ov5675 = to_ov5675(sd);
        int ret;
 
index cc678d9..bbccb6f 100644 (file)
@@ -1033,8 +1033,7 @@ static void __ov5695_power_off(struct ov5695 *ov5695)
 
 static int __maybe_unused ov5695_runtime_resume(struct device *dev)
 {
-       struct i2c_client *client = to_i2c_client(dev);
-       struct v4l2_subdev *sd = i2c_get_clientdata(client);
+       struct v4l2_subdev *sd = dev_get_drvdata(dev);
        struct ov5695 *ov5695 = to_ov5695(sd);
 
        return __ov5695_power_on(ov5695);
@@ -1042,8 +1041,7 @@ static int __maybe_unused ov5695_runtime_resume(struct device *dev)
 
 static int __maybe_unused ov5695_runtime_suspend(struct device *dev)
 {
-       struct i2c_client *client = to_i2c_client(dev);
-       struct v4l2_subdev *sd = i2c_get_clientdata(client);
+       struct v4l2_subdev *sd = dev_get_drvdata(dev);
        struct ov5695 *ov5695 = to_ov5695(sd);
 
        __ov5695_power_off(ov5695);
index b42b289..d2df811 100644 (file)
@@ -561,6 +561,7 @@ static int ov7670_read(struct v4l2_subdev *sd, unsigned char reg,
                unsigned char *value)
 {
        struct ov7670_info *info = to_state(sd);
+
        if (info->use_smbus)
                return ov7670_read_smbus(sd, reg, value);
        else
@@ -571,6 +572,7 @@ static int ov7670_write(struct v4l2_subdev *sd, unsigned char reg,
                unsigned char value)
 {
        struct ov7670_info *info = to_state(sd);
+
        if (info->use_smbus)
                return ov7670_write_smbus(sd, reg, value);
        else
@@ -597,6 +599,7 @@ static int ov7670_write_array(struct v4l2_subdev *sd, struct regval_list *vals)
 {
        while (vals->reg_num != 0xff || vals->value != 0xff) {
                int ret = ov7670_write(sd, vals->reg_num, vals->value);
+
                if (ret < 0)
                        return ret;
                vals++;
@@ -921,27 +924,38 @@ static int ov7670_set_hw(struct v4l2_subdev *sd, int hstart, int hstop,
 {
        int ret;
        unsigned char v;
-/*
- * Horizontal: 11 bits, top 8 live in hstart and hstop.  Bottom 3 of
- * hstart are in href[2:0], bottom 3 of hstop in href[5:3].  There is
- * a mystery "edge offset" value in the top two bits of href.
- */
-       ret =  ov7670_write(sd, REG_HSTART, (hstart >> 3) & 0xff);
-       ret += ov7670_write(sd, REG_HSTOP, (hstop >> 3) & 0xff);
-       ret += ov7670_read(sd, REG_HREF, &v);
+       /*
+        * Horizontal: 11 bits, top 8 live in hstart and hstop.  Bottom 3 of
+        * hstart are in href[2:0], bottom 3 of hstop in href[5:3].  There is
+        * a mystery "edge offset" value in the top two bits of href.
+        */
+       ret = ov7670_write(sd, REG_HSTART, (hstart >> 3) & 0xff);
+       if (ret)
+               return ret;
+       ret = ov7670_write(sd, REG_HSTOP, (hstop >> 3) & 0xff);
+       if (ret)
+               return ret;
+       ret = ov7670_read(sd, REG_HREF, &v);
+       if (ret)
+               return ret;
        v = (v & 0xc0) | ((hstop & 0x7) << 3) | (hstart & 0x7);
        msleep(10);
-       ret += ov7670_write(sd, REG_HREF, v);
-/*
- * Vertical: similar arrangement, but only 10 bits.
- */
-       ret += ov7670_write(sd, REG_VSTART, (vstart >> 2) & 0xff);
-       ret += ov7670_write(sd, REG_VSTOP, (vstop >> 2) & 0xff);
-       ret += ov7670_read(sd, REG_VREF, &v);
+       ret = ov7670_write(sd, REG_HREF, v);
+       if (ret)
+               return ret;
+       /* Vertical: similar arrangement, but only 10 bits. */
+       ret = ov7670_write(sd, REG_VSTART, (vstart >> 2) & 0xff);
+       if (ret)
+               return ret;
+       ret = ov7670_write(sd, REG_VSTOP, (vstop >> 2) & 0xff);
+       if (ret)
+               return ret;
+       ret = ov7670_read(sd, REG_VREF, &v);
+       if (ret)
+               return ret;
        v = (v & 0xf0) | ((vstop & 0x3) << 2) | (vstart & 0x3);
        msleep(10);
-       ret += ov7670_write(sd, REG_VREF, v);
-       return ret;
+       return ov7670_write(sd, REG_VREF, v);
 }
 
 
@@ -1245,6 +1259,7 @@ static int ov7670_enum_frame_size(struct v4l2_subdev *sd,
         */
        for (i = 0; i < n_win_sizes; i++) {
                struct ov7670_win_size *win = &info->devtype->win_sizes[i];
+
                if (info->min_width && win->width < info->min_width)
                        continue;
                if (info->min_height && win->height < info->min_height)
@@ -1285,17 +1300,17 @@ static int ov7670_store_cmatrix(struct v4l2_subdev *sd,
                                raw = 0xff;
                        else
                                raw = (-1 * matrix[i]) & 0xff;
-               }
-               else {
+               } else {
                        if (matrix[i] > 255)
                                raw = 0xff;
                        else
                                raw = matrix[i] & 0xff;
                }
-               ret += ov7670_write(sd, REG_CMATRIX_BASE + i, raw);
+               ret = ov7670_write(sd, REG_CMATRIX_BASE + i, raw);
+               if (ret)
+                       return ret;
        }
-       ret += ov7670_write(sd, REG_CMATRIX_SIGN, signbits);
-       return ret;
+       return ov7670_write(sd, REG_CMATRIX_SIGN, signbits);
 }
 
 
@@ -1381,11 +1396,9 @@ static int ov7670_s_sat_hue(struct v4l2_subdev *sd, int sat, int hue)
 {
        struct ov7670_info *info = to_state(sd);
        int matrix[CMATRIX_LEN];
-       int ret;
 
        ov7670_calc_cmatrix(info, matrix, sat, hue);
-       ret = ov7670_store_cmatrix(sd, matrix);
-       return ret;
+       return ov7670_store_cmatrix(sd, matrix);
 }
 
 
@@ -1403,14 +1416,12 @@ static unsigned char ov7670_abs_to_sm(unsigned char v)
 static int ov7670_s_brightness(struct v4l2_subdev *sd, int value)
 {
        unsigned char com8 = 0, v;
-       int ret;
 
        ov7670_read(sd, REG_COM8, &com8);
        com8 &= ~COM8_AEC;
        ov7670_write(sd, REG_COM8, com8);
        v = ov7670_abs_to_sm(value);
-       ret = ov7670_write(sd, REG_BRIGHT, v);
-       return ret;
+       return ov7670_write(sd, REG_BRIGHT, v);
 }
 
 static int ov7670_s_contrast(struct v4l2_subdev *sd, int value)
@@ -1424,13 +1435,14 @@ static int ov7670_s_hflip(struct v4l2_subdev *sd, int value)
        int ret;
 
        ret = ov7670_read(sd, REG_MVFP, &v);
+       if (ret)
+               return ret;
        if (value)
                v |= MVFP_MIRROR;
        else
                v &= ~MVFP_MIRROR;
        msleep(10);  /* FIXME */
-       ret += ov7670_write(sd, REG_MVFP, v);
-       return ret;
+       return ov7670_write(sd, REG_MVFP, v);
 }
 
 static int ov7670_s_vflip(struct v4l2_subdev *sd, int value)
@@ -1439,13 +1451,14 @@ static int ov7670_s_vflip(struct v4l2_subdev *sd, int value)
        int ret;
 
        ret = ov7670_read(sd, REG_MVFP, &v);
+       if (ret)
+               return ret;
        if (value)
                v |= MVFP_FLIP;
        else
                v &= ~MVFP_FLIP;
        msleep(10);  /* FIXME */
-       ret += ov7670_write(sd, REG_MVFP, v);
-       return ret;
+       return ov7670_write(sd, REG_MVFP, v);
 }
 
 /*
@@ -1460,8 +1473,10 @@ static int ov7670_g_gain(struct v4l2_subdev *sd, __s32 *value)
        unsigned char gain;
 
        ret = ov7670_read(sd, REG_GAIN, &gain);
+       if (ret)
+               return ret;
        *value = gain;
-       return ret;
+       return 0;
 }
 
 static int ov7670_s_gain(struct v4l2_subdev *sd, int value)
@@ -1470,12 +1485,13 @@ static int ov7670_s_gain(struct v4l2_subdev *sd, int value)
        unsigned char com8;
 
        ret = ov7670_write(sd, REG_GAIN, value & 0xff);
+       if (ret)
+               return ret;
        /* Have to turn off AGC as well */
-       if (ret == 0) {
-               ret = ov7670_read(sd, REG_COM8, &com8);
-               ret = ov7670_write(sd, REG_COM8, com8 & ~COM8_AGC);
-       }
-       return ret;
+       ret = ov7670_read(sd, REG_COM8, &com8);
+       if (ret)
+               return ret;
+       return ov7670_write(sd, REG_COM8, com8 & ~COM8_AGC);
 }
 
 /*
@@ -1680,13 +1696,13 @@ static int ov7670_s_power(struct v4l2_subdev *sd, int on)
                return 0;
 
        if (on) {
-               ov7670_power_on (sd);
+               ov7670_power_on(sd);
                ov7670_init(sd, 0);
                ov7670_apply_fmt(sd);
                ov7675_apply_framerate(sd);
                v4l2_ctrl_handler_setup(&info->hdl);
        } else {
-               ov7670_power_off (sd);
+               ov7670_power_off(sd);
        }
 
        return 0;
index 2cc6a67..d94cf2d 100644 (file)
@@ -31,6 +31,7 @@
 #include <media/v4l2-ctrls.h>
 #include <media/v4l2-device.h>
 #include <media/v4l2-event.h>
+#include <media/v4l2-fwnode.h>
 #include <media/v4l2-image-sizes.h>
 #include <media/v4l2-subdev.h>
 
 
 /* COM3 */
 #define SWAP_MASK       (SWAP_RGB | SWAP_YUV | SWAP_ML)
-#define IMG_MASK        (VFLIP_IMG | HFLIP_IMG)
+#define IMG_MASK        (VFLIP_IMG | HFLIP_IMG | SCOLOR_TEST)
 
 #define VFLIP_IMG       0x80   /* Vertical flip image ON/OFF selection */
 #define HFLIP_IMG       0x40   /* Horizontal mirror image ON/OFF selection */
@@ -424,6 +425,7 @@ struct ov772x_priv {
        const struct ov772x_win_size     *win;
        struct v4l2_ctrl                 *vflip_ctrl;
        struct v4l2_ctrl                 *hflip_ctrl;
+       unsigned int                      test_pattern;
        /* band_filter = COM8[5] ? 256 - BDBASE : 0 */
        struct v4l2_ctrl                 *band_filter_ctrl;
        unsigned int                      fps;
@@ -434,6 +436,7 @@ struct ov772x_priv {
 #ifdef CONFIG_MEDIA_CONTROLLER
        struct media_pad pad;
 #endif
+       enum v4l2_mbus_type               bus_type;
 };
 
 /*
@@ -538,6 +541,11 @@ static const struct ov772x_win_size ov772x_win_sizes[] = {
        },
 };
 
+static const char * const ov772x_test_pattern_menu[] = {
+       "Disabled",
+       "Vertical Color Bar Type 1",
+};
+
 /*
  * frame rate settings lists
  */
@@ -581,6 +589,14 @@ static int ov772x_s_stream(struct v4l2_subdev *sd, int enable)
        if (priv->streaming == enable)
                goto done;
 
+       if (priv->bus_type == V4L2_MBUS_BT656) {
+               ret = regmap_update_bits(priv->regmap, COM7, ITU656_ON_OFF,
+                                        enable ?
+                                        ITU656_ON_OFF : ~ITU656_ON_OFF);
+               if (ret)
+                       goto done;
+       }
+
        ret = regmap_update_bits(priv->regmap, COM2, SOFT_SLEEP_MODE,
                                 enable ? 0 : SOFT_SLEEP_MODE);
        if (ret)
@@ -800,6 +816,9 @@ static int ov772x_s_ctrl(struct v4l2_ctrl *ctrl)
                }
 
                return ret;
+       case V4L2_CID_TEST_PATTERN:
+               priv->test_pattern = ctrl->val;
+               return 0;
        }
 
        return -EINVAL;
@@ -1098,6 +1117,8 @@ static int ov772x_set_params(struct ov772x_priv *priv,
                val ^= VFLIP_IMG;
        if (priv->hflip_ctrl->val)
                val ^= HFLIP_IMG;
+       if (priv->test_pattern)
+               val |= SCOLOR_TEST;
 
        ret = regmap_update_bits(priv->regmap, COM3, SWAP_MASK | IMG_MASK, val);
        if (ret < 0)
@@ -1348,6 +1369,46 @@ static const struct v4l2_subdev_ops ov772x_subdev_ops = {
        .pad    = &ov772x_subdev_pad_ops,
 };
 
+static int ov772x_parse_dt(struct i2c_client *client,
+                          struct ov772x_priv *priv)
+{
+       struct v4l2_fwnode_endpoint bus_cfg = {
+               .bus_type = V4L2_MBUS_PARALLEL
+       };
+       struct fwnode_handle *ep;
+       int ret;
+
+       ep = fwnode_graph_get_next_endpoint(dev_fwnode(&client->dev), NULL);
+       if (!ep) {
+               dev_err(&client->dev, "Endpoint node not found\n");
+               return -EINVAL;
+       }
+
+       /*
+        * For backward compatibility with older DTS where the
+        * bus-type property was not mandatory, assume
+        * V4L2_MBUS_PARALLEL as it was the only supported bus at the
+        * time. v4l2_fwnode_endpoint_alloc_parse() will not fail if
+        * 'bus-type' is not specified.
+        */
+       ret = v4l2_fwnode_endpoint_alloc_parse(ep, &bus_cfg);
+       if (ret) {
+               bus_cfg = (struct v4l2_fwnode_endpoint)
+                         { .bus_type = V4L2_MBUS_BT656 };
+               ret = v4l2_fwnode_endpoint_alloc_parse(ep, &bus_cfg);
+               if (ret)
+                       goto error_fwnode_put;
+       }
+
+       priv->bus_type = bus_cfg.bus_type;
+       v4l2_fwnode_endpoint_free(&bus_cfg);
+
+error_fwnode_put:
+       fwnode_handle_put(ep);
+
+       return ret;
+}
+
 /*
  * i2c_driver function
  */
@@ -1394,6 +1455,10 @@ static int ov772x_probe(struct i2c_client *client)
        priv->band_filter_ctrl = v4l2_ctrl_new_std(&priv->hdl, &ov772x_ctrl_ops,
                                                   V4L2_CID_BAND_STOP_FILTER,
                                                   0, 256, 1, 0);
+       v4l2_ctrl_new_std_menu_items(&priv->hdl, &ov772x_ctrl_ops,
+                                    V4L2_CID_TEST_PATTERN,
+                                    ARRAY_SIZE(ov772x_test_pattern_menu) - 1,
+                                    0, 0, ov772x_test_pattern_menu);
        priv->subdev.ctrl_handler = &priv->hdl;
        if (priv->hdl.error) {
                ret = priv->hdl.error;
@@ -1415,6 +1480,10 @@ static int ov772x_probe(struct i2c_client *client)
                goto error_clk_put;
        }
 
+       ret = ov772x_parse_dt(client, priv);
+       if (ret)
+               goto error_clk_put;
+
        ret = ov772x_video_probe(priv);
        if (ret < 0)
                goto error_gpio_put;
index 5832461..47a9003 100644 (file)
@@ -1176,8 +1176,7 @@ static int ov7740_remove(struct i2c_client *client)
 
 static int __maybe_unused ov7740_runtime_suspend(struct device *dev)
 {
-       struct i2c_client *client = to_i2c_client(dev);
-       struct v4l2_subdev *sd = i2c_get_clientdata(client);
+       struct v4l2_subdev *sd = dev_get_drvdata(dev);
        struct ov7740 *ov7740 = container_of(sd, struct ov7740, subdev);
 
        ov7740_set_power(ov7740, 0);
@@ -1187,8 +1186,7 @@ static int __maybe_unused ov7740_runtime_suspend(struct device *dev)
 
 static int __maybe_unused ov7740_runtime_resume(struct device *dev)
 {
-       struct i2c_client *client = to_i2c_client(dev);
-       struct v4l2_subdev *sd = i2c_get_clientdata(client);
+       struct v4l2_subdev *sd = dev_get_drvdata(dev);
        struct ov7740 *ov7740 = container_of(sd, struct ov7740, subdev);
 
        return ov7740_set_power(ov7740, 1);
index 2f4ceaa..d8cefd3 100644 (file)
@@ -1417,8 +1417,7 @@ static void __ov8856_power_off(struct ov8856 *ov8856)
 
 static int __maybe_unused ov8856_suspend(struct device *dev)
 {
-       struct i2c_client *client = to_i2c_client(dev);
-       struct v4l2_subdev *sd = i2c_get_clientdata(client);
+       struct v4l2_subdev *sd = dev_get_drvdata(dev);
        struct ov8856 *ov8856 = to_ov8856(sd);
 
        mutex_lock(&ov8856->mutex);
@@ -1433,8 +1432,7 @@ static int __maybe_unused ov8856_suspend(struct device *dev)
 
 static int __maybe_unused ov8856_resume(struct device *dev)
 {
-       struct i2c_client *client = to_i2c_client(dev);
-       struct v4l2_subdev *sd = i2c_get_clientdata(client);
+       struct v4l2_subdev *sd = dev_get_drvdata(dev);
        struct ov8856 *ov8856 = to_ov8856(sd);
        int ret;
 
diff --git a/drivers/media/i2c/ov9734.c b/drivers/media/i2c/ov9734.c
new file mode 100644 (file)
index 0000000..4b9a2e9
--- /dev/null
@@ -0,0 +1,1018 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (c) 2020 Intel Corporation.
+
+#include <asm/unaligned.h>
+#include <linux/acpi.h>
+#include <linux/delay.h>
+#include <linux/i2c.h>
+#include <linux/module.h>
+#include <linux/pm_runtime.h>
+#include <media/v4l2-ctrls.h>
+#include <media/v4l2-device.h>
+#include <media/v4l2-fwnode.h>
+
+#define OV9734_LINK_FREQ_180MHZ                180000000ULL
+#define OV9734_SCLK                    36000000LL
+#define OV9734_MCLK                    19200000
+/* ov9734 only support 1-lane mipi output */
+#define OV9734_DATA_LANES              1
+#define OV9734_RGB_DEPTH               10
+
+#define OV9734_REG_CHIP_ID             0x300a
+#define OV9734_CHIP_ID                 0x9734
+
+#define OV9734_REG_MODE_SELECT         0x0100
+#define OV9734_MODE_STANDBY            0x00
+#define OV9734_MODE_STREAMING          0x01
+
+/* vertical-timings from sensor */
+#define OV9734_REG_VTS                 0x380e
+#define OV9734_VTS_30FPS               0x0322
+#define OV9734_VTS_30FPS_MIN           0x0322
+#define OV9734_VTS_MAX                 0x7fff
+
+/* horizontal-timings from sensor */
+#define OV9734_REG_HTS                 0x380c
+
+/* Exposure controls from sensor */
+#define OV9734_REG_EXPOSURE            0x3500
+#define OV9734_EXPOSURE_MIN            4
+#define OV9734_EXPOSURE_MAX_MARGIN     4
+#define        OV9734_EXPOSURE_STEP            1
+
+/* Analog gain controls from sensor */
+#define OV9734_REG_ANALOG_GAIN         0x350a
+#define OV9734_ANAL_GAIN_MIN           16
+#define OV9734_ANAL_GAIN_MAX           248
+#define OV9734_ANAL_GAIN_STEP          1
+
+/* Digital gain controls from sensor */
+#define OV9734_REG_MWB_R_GAIN          0x5180
+#define OV9734_REG_MWB_G_GAIN          0x5182
+#define OV9734_REG_MWB_B_GAIN          0x5184
+#define OV9734_DGTL_GAIN_MIN           256
+#define OV9734_DGTL_GAIN_MAX           1023
+#define OV9734_DGTL_GAIN_STEP          1
+#define OV9734_DGTL_GAIN_DEFAULT       256
+
+/* Test Pattern Control */
+#define OV9734_REG_TEST_PATTERN                0x5080
+#define OV9734_TEST_PATTERN_ENABLE     BIT(7)
+#define OV9734_TEST_PATTERN_BAR_SHIFT  2
+
+enum {
+       OV9734_LINK_FREQ_180MHZ_INDEX,
+};
+
+struct ov9734_reg {
+       u16 address;
+       u8 val;
+};
+
+struct ov9734_reg_list {
+       u32 num_of_regs;
+       const struct ov9734_reg *regs;
+};
+
+struct ov9734_link_freq_config {
+       const struct ov9734_reg_list reg_list;
+};
+
+struct ov9734_mode {
+       /* Frame width in pixels */
+       u32 width;
+
+       /* Frame height in pixels */
+       u32 height;
+
+       /* Horizontal timining size */
+       u32 hts;
+
+       /* Default vertical timining size */
+       u32 vts_def;
+
+       /* Min vertical timining size */
+       u32 vts_min;
+
+       /* Link frequency needed for this resolution */
+       u32 link_freq_index;
+
+       /* Sensor register settings for this resolution */
+       const struct ov9734_reg_list reg_list;
+};
+
+static const struct ov9734_reg mipi_data_rate_360mbps[] = {
+       {0x3030, 0x19},
+       {0x3080, 0x02},
+       {0x3081, 0x4b},
+       {0x3082, 0x04},
+       {0x3083, 0x00},
+       {0x3084, 0x02},
+       {0x3085, 0x01},
+       {0x3086, 0x01},
+       {0x3089, 0x01},
+       {0x308a, 0x00},
+       {0x301e, 0x15},
+       {0x3103, 0x01},
+};
+
+static const struct ov9734_reg mode_1296x734_regs[] = {
+       {0x3001, 0x00},
+       {0x3002, 0x00},
+       {0x3007, 0x00},
+       {0x3010, 0x00},
+       {0x3011, 0x08},
+       {0x3014, 0x22},
+       {0x3600, 0x55},
+       {0x3601, 0x02},
+       {0x3605, 0x22},
+       {0x3611, 0xe7},
+       {0x3654, 0x10},
+       {0x3655, 0x77},
+       {0x3656, 0x77},
+       {0x3657, 0x07},
+       {0x3658, 0x22},
+       {0x3659, 0x22},
+       {0x365a, 0x02},
+       {0x3784, 0x05},
+       {0x3785, 0x55},
+       {0x37c0, 0x07},
+       {0x3800, 0x00},
+       {0x3801, 0x04},
+       {0x3802, 0x00},
+       {0x3803, 0x04},
+       {0x3804, 0x05},
+       {0x3805, 0x0b},
+       {0x3806, 0x02},
+       {0x3807, 0xdb},
+       {0x3808, 0x05},
+       {0x3809, 0x00},
+       {0x380a, 0x02},
+       {0x380b, 0xd0},
+       {0x380c, 0x05},
+       {0x380d, 0xc6},
+       {0x380e, 0x03},
+       {0x380f, 0x22},
+       {0x3810, 0x00},
+       {0x3811, 0x04},
+       {0x3812, 0x00},
+       {0x3813, 0x04},
+       {0x3816, 0x00},
+       {0x3817, 0x00},
+       {0x3818, 0x00},
+       {0x3819, 0x04},
+       {0x3820, 0x18},
+       {0x3821, 0x00},
+       {0x382c, 0x06},
+       {0x3500, 0x00},
+       {0x3501, 0x31},
+       {0x3502, 0x00},
+       {0x3503, 0x03},
+       {0x3504, 0x00},
+       {0x3505, 0x00},
+       {0x3509, 0x10},
+       {0x350a, 0x00},
+       {0x350b, 0x40},
+       {0x3d00, 0x00},
+       {0x3d01, 0x00},
+       {0x3d02, 0x00},
+       {0x3d03, 0x00},
+       {0x3d04, 0x00},
+       {0x3d05, 0x00},
+       {0x3d06, 0x00},
+       {0x3d07, 0x00},
+       {0x3d08, 0x00},
+       {0x3d09, 0x00},
+       {0x3d0a, 0x00},
+       {0x3d0b, 0x00},
+       {0x3d0c, 0x00},
+       {0x3d0d, 0x00},
+       {0x3d0e, 0x00},
+       {0x3d0f, 0x00},
+       {0x3d80, 0x00},
+       {0x3d81, 0x00},
+       {0x3d82, 0x38},
+       {0x3d83, 0xa4},
+       {0x3d84, 0x00},
+       {0x3d85, 0x00},
+       {0x3d86, 0x1f},
+       {0x3d87, 0x03},
+       {0x3d8b, 0x00},
+       {0x3d8f, 0x00},
+       {0x4001, 0xe0},
+       {0x4009, 0x0b},
+       {0x4300, 0x03},
+       {0x4301, 0xff},
+       {0x4304, 0x00},
+       {0x4305, 0x00},
+       {0x4309, 0x00},
+       {0x4600, 0x00},
+       {0x4601, 0x80},
+       {0x4800, 0x00},
+       {0x4805, 0x00},
+       {0x4821, 0x50},
+       {0x4823, 0x50},
+       {0x4837, 0x2d},
+       {0x4a00, 0x00},
+       {0x4f00, 0x80},
+       {0x4f01, 0x10},
+       {0x4f02, 0x00},
+       {0x4f03, 0x00},
+       {0x4f04, 0x00},
+       {0x4f05, 0x00},
+       {0x4f06, 0x00},
+       {0x4f07, 0x00},
+       {0x4f08, 0x00},
+       {0x4f09, 0x00},
+       {0x5000, 0x2f},
+       {0x500c, 0x00},
+       {0x500d, 0x00},
+       {0x500e, 0x00},
+       {0x500f, 0x00},
+       {0x5010, 0x00},
+       {0x5011, 0x00},
+       {0x5012, 0x00},
+       {0x5013, 0x00},
+       {0x5014, 0x00},
+       {0x5015, 0x00},
+       {0x5016, 0x00},
+       {0x5017, 0x00},
+       {0x5080, 0x00},
+       {0x5180, 0x01},
+       {0x5181, 0x00},
+       {0x5182, 0x01},
+       {0x5183, 0x00},
+       {0x5184, 0x01},
+       {0x5185, 0x00},
+       {0x5708, 0x06},
+       {0x380f, 0x2a},
+       {0x5780, 0x3e},
+       {0x5781, 0x0f},
+       {0x5782, 0x44},
+       {0x5783, 0x02},
+       {0x5784, 0x01},
+       {0x5785, 0x01},
+       {0x5786, 0x00},
+       {0x5787, 0x04},
+       {0x5788, 0x02},
+       {0x5789, 0x0f},
+       {0x578a, 0xfd},
+       {0x578b, 0xf5},
+       {0x578c, 0xf5},
+       {0x578d, 0x03},
+       {0x578e, 0x08},
+       {0x578f, 0x0c},
+       {0x5790, 0x08},
+       {0x5791, 0x04},
+       {0x5792, 0x00},
+       {0x5793, 0x52},
+       {0x5794, 0xa3},
+       {0x5000, 0x3f},
+       {0x3801, 0x00},
+       {0x3803, 0x00},
+       {0x3805, 0x0f},
+       {0x3807, 0xdf},
+       {0x3809, 0x10},
+       {0x380b, 0xde},
+       {0x3811, 0x00},
+       {0x3813, 0x01},
+};
+
+static const char * const ov9734_test_pattern_menu[] = {
+       "Disabled",
+       "Standard Color Bar",
+       "Top-Bottom Darker Color Bar",
+       "Right-Left Darker Color Bar",
+       "Bottom-Top Darker Color Bar",
+};
+
+static const s64 link_freq_menu_items[] = {
+       OV9734_LINK_FREQ_180MHZ,
+};
+
+static const struct ov9734_link_freq_config link_freq_configs[] = {
+       [OV9734_LINK_FREQ_180MHZ_INDEX] = {
+               .reg_list = {
+                       .num_of_regs = ARRAY_SIZE(mipi_data_rate_360mbps),
+                       .regs = mipi_data_rate_360mbps,
+               }
+       },
+};
+
+static const struct ov9734_mode supported_modes[] = {
+       {
+               .width = 1296,
+               .height = 734,
+               .hts = 0x5c6,
+               .vts_def = OV9734_VTS_30FPS,
+               .vts_min = OV9734_VTS_30FPS_MIN,
+               .reg_list = {
+                       .num_of_regs = ARRAY_SIZE(mode_1296x734_regs),
+                       .regs = mode_1296x734_regs,
+               },
+               .link_freq_index = OV9734_LINK_FREQ_180MHZ_INDEX,
+       },
+};
+
+struct ov9734 {
+       struct v4l2_subdev sd;
+       struct media_pad pad;
+       struct v4l2_ctrl_handler ctrl_handler;
+
+       /* V4L2 Controls */
+       struct v4l2_ctrl *link_freq;
+       struct v4l2_ctrl *pixel_rate;
+       struct v4l2_ctrl *vblank;
+       struct v4l2_ctrl *hblank;
+       struct v4l2_ctrl *exposure;
+
+       /* Current mode */
+       const struct ov9734_mode *cur_mode;
+
+       /* To serialize asynchronus callbacks */
+       struct mutex mutex;
+
+       /* Streaming on/off */
+       bool streaming;
+};
+
+static inline struct ov9734 *to_ov9734(struct v4l2_subdev *subdev)
+{
+       return container_of(subdev, struct ov9734, sd);
+}
+
+static u64 to_pixel_rate(u32 f_index)
+{
+       u64 pixel_rate = link_freq_menu_items[f_index] * 2 * OV9734_DATA_LANES;
+
+       do_div(pixel_rate, OV9734_RGB_DEPTH);
+
+       return pixel_rate;
+}
+
+static u64 to_pixels_per_line(u32 hts, u32 f_index)
+{
+       u64 ppl = hts * to_pixel_rate(f_index);
+
+       do_div(ppl, OV9734_SCLK);
+
+       return ppl;
+}
+
+static int ov9734_read_reg(struct ov9734 *ov9734, u16 reg, u16 len, u32 *val)
+{
+       struct i2c_client *client = v4l2_get_subdevdata(&ov9734->sd);
+       struct i2c_msg msgs[2];
+       u8 addr_buf[2];
+       u8 data_buf[4] = {0};
+       int ret;
+
+       if (len > sizeof(data_buf))
+               return -EINVAL;
+
+       put_unaligned_be16(reg, addr_buf);
+       msgs[0].addr = client->addr;
+       msgs[0].flags = 0;
+       msgs[0].len = sizeof(addr_buf);
+       msgs[0].buf = addr_buf;
+       msgs[1].addr = client->addr;
+       msgs[1].flags = I2C_M_RD;
+       msgs[1].len = len;
+       msgs[1].buf = &data_buf[sizeof(data_buf) - len];
+
+       ret = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs));
+       if (ret != ARRAY_SIZE(msgs))
+               return ret < 0 ? ret : -EIO;
+
+       *val = get_unaligned_be32(data_buf);
+
+       return 0;
+}
+
+static int ov9734_write_reg(struct ov9734 *ov9734, u16 reg, u16 len, u32 val)
+{
+       struct i2c_client *client = v4l2_get_subdevdata(&ov9734->sd);
+       u8 buf[6];
+       int ret = 0;
+
+       if (len > 4)
+               return -EINVAL;
+
+       put_unaligned_be16(reg, buf);
+       put_unaligned_be32(val << 8 * (4 - len), buf + 2);
+
+       ret = i2c_master_send(client, buf, len + 2);
+       if (ret != len + 2)
+               return ret < 0 ? ret : -EIO;
+
+       return 0;
+}
+
+static int ov9734_write_reg_list(struct ov9734 *ov9734,
+                                const struct ov9734_reg_list *r_list)
+{
+       struct i2c_client *client = v4l2_get_subdevdata(&ov9734->sd);
+       unsigned int i;
+       int ret;
+
+       for (i = 0; i < r_list->num_of_regs; i++) {
+               ret = ov9734_write_reg(ov9734, r_list->regs[i].address, 1,
+                                      r_list->regs[i].val);
+               if (ret) {
+                       dev_err_ratelimited(&client->dev,
+                                           "write reg 0x%4.4x return err = %d",
+                                           r_list->regs[i].address, ret);
+                       return ret;
+               }
+       }
+
+       return 0;
+}
+
+static int ov9734_update_digital_gain(struct ov9734 *ov9734, u32 d_gain)
+{
+       int ret;
+
+       ret = ov9734_write_reg(ov9734, OV9734_REG_MWB_R_GAIN, 2, d_gain);
+       if (ret)
+               return ret;
+
+       ret = ov9734_write_reg(ov9734, OV9734_REG_MWB_G_GAIN, 2, d_gain);
+       if (ret)
+               return ret;
+
+       return ov9734_write_reg(ov9734, OV9734_REG_MWB_B_GAIN, 2, d_gain);
+}
+
+static int ov9734_test_pattern(struct ov9734 *ov9734, u32 pattern)
+{
+       if (pattern)
+               pattern = (pattern - 1) << OV9734_TEST_PATTERN_BAR_SHIFT |
+                       OV9734_TEST_PATTERN_ENABLE;
+
+       return ov9734_write_reg(ov9734, OV9734_REG_TEST_PATTERN, 1, pattern);
+}
+
+static int ov9734_set_ctrl(struct v4l2_ctrl *ctrl)
+{
+       struct ov9734 *ov9734 = container_of(ctrl->handler,
+                                            struct ov9734, ctrl_handler);
+       struct i2c_client *client = v4l2_get_subdevdata(&ov9734->sd);
+       s64 exposure_max;
+       int ret = 0;
+
+       /* Propagate change of current control to all related controls */
+       if (ctrl->id == V4L2_CID_VBLANK) {
+               /* Update max exposure while meeting expected vblanking */
+               exposure_max = ov9734->cur_mode->height + ctrl->val -
+                       OV9734_EXPOSURE_MAX_MARGIN;
+               __v4l2_ctrl_modify_range(ov9734->exposure,
+                                        ov9734->exposure->minimum,
+                                        exposure_max, ov9734->exposure->step,
+                                        exposure_max);
+       }
+
+       /* V4L2 controls values will be applied only when power is already up */
+       if (!pm_runtime_get_if_in_use(&client->dev))
+               return 0;
+
+       switch (ctrl->id) {
+       case V4L2_CID_ANALOGUE_GAIN:
+               ret = ov9734_write_reg(ov9734, OV9734_REG_ANALOG_GAIN,
+                                      2, ctrl->val);
+               break;
+
+       case V4L2_CID_DIGITAL_GAIN:
+               ret = ov9734_update_digital_gain(ov9734, ctrl->val);
+               break;
+
+       case V4L2_CID_EXPOSURE:
+               /* 4 least significant bits of expsoure are fractional part */
+               ret = ov9734_write_reg(ov9734, OV9734_REG_EXPOSURE,
+                                      3, ctrl->val << 4);
+               break;
+
+       case V4L2_CID_VBLANK:
+               ret = ov9734_write_reg(ov9734, OV9734_REG_VTS, 2,
+                                      ov9734->cur_mode->height + ctrl->val);
+               break;
+
+       case V4L2_CID_TEST_PATTERN:
+               ret = ov9734_test_pattern(ov9734, ctrl->val);
+               break;
+
+       default:
+               ret = -EINVAL;
+               break;
+       }
+
+       pm_runtime_put(&client->dev);
+
+       return ret;
+}
+
+static const struct v4l2_ctrl_ops ov9734_ctrl_ops = {
+       .s_ctrl = ov9734_set_ctrl,
+};
+
+static int ov9734_init_controls(struct ov9734 *ov9734)
+{
+       struct v4l2_ctrl_handler *ctrl_hdlr;
+       const struct ov9734_mode *cur_mode;
+       s64 exposure_max, h_blank, pixel_rate;
+       u32 vblank_min, vblank_max, vblank_default;
+       int ret, size;
+
+       ctrl_hdlr = &ov9734->ctrl_handler;
+       ret = v4l2_ctrl_handler_init(ctrl_hdlr, 8);
+       if (ret)
+               return ret;
+
+       ctrl_hdlr->lock = &ov9734->mutex;
+       cur_mode = ov9734->cur_mode;
+       size = ARRAY_SIZE(link_freq_menu_items);
+       ov9734->link_freq = v4l2_ctrl_new_int_menu(ctrl_hdlr, &ov9734_ctrl_ops,
+                                                  V4L2_CID_LINK_FREQ,
+                                                  size - 1, 0,
+                                                  link_freq_menu_items);
+       if (ov9734->link_freq)
+               ov9734->link_freq->flags |= V4L2_CTRL_FLAG_READ_ONLY;
+
+       pixel_rate = to_pixel_rate(OV9734_LINK_FREQ_180MHZ_INDEX);
+       ov9734->pixel_rate = v4l2_ctrl_new_std(ctrl_hdlr, &ov9734_ctrl_ops,
+                                              V4L2_CID_PIXEL_RATE, 0,
+                                              pixel_rate, 1, pixel_rate);
+       vblank_min = cur_mode->vts_min - cur_mode->height;
+       vblank_max = OV9734_VTS_MAX - cur_mode->height;
+       vblank_default = cur_mode->vts_def - cur_mode->height;
+       ov9734->vblank = v4l2_ctrl_new_std(ctrl_hdlr, &ov9734_ctrl_ops,
+                                          V4L2_CID_VBLANK, vblank_min,
+                                          vblank_max, 1, vblank_default);
+       h_blank = to_pixels_per_line(cur_mode->hts, cur_mode->link_freq_index);
+       h_blank -= cur_mode->width;
+       ov9734->hblank = v4l2_ctrl_new_std(ctrl_hdlr, &ov9734_ctrl_ops,
+                                          V4L2_CID_HBLANK, h_blank, h_blank, 1,
+                                          h_blank);
+       if (ov9734->hblank)
+               ov9734->hblank->flags |= V4L2_CTRL_FLAG_READ_ONLY;
+
+       v4l2_ctrl_new_std(ctrl_hdlr, &ov9734_ctrl_ops, V4L2_CID_ANALOGUE_GAIN,
+                         OV9734_ANAL_GAIN_MIN, OV9734_ANAL_GAIN_MAX,
+                         OV9734_ANAL_GAIN_STEP, OV9734_ANAL_GAIN_MIN);
+       v4l2_ctrl_new_std(ctrl_hdlr, &ov9734_ctrl_ops, V4L2_CID_DIGITAL_GAIN,
+                         OV9734_DGTL_GAIN_MIN, OV9734_DGTL_GAIN_MAX,
+                         OV9734_DGTL_GAIN_STEP, OV9734_DGTL_GAIN_DEFAULT);
+       exposure_max = ov9734->cur_mode->vts_def - OV9734_EXPOSURE_MAX_MARGIN;
+       ov9734->exposure = v4l2_ctrl_new_std(ctrl_hdlr, &ov9734_ctrl_ops,
+                                            V4L2_CID_EXPOSURE,
+                                            OV9734_EXPOSURE_MIN, exposure_max,
+                                            OV9734_EXPOSURE_STEP,
+                                            exposure_max);
+       v4l2_ctrl_new_std_menu_items(ctrl_hdlr, &ov9734_ctrl_ops,
+                                    V4L2_CID_TEST_PATTERN,
+                                    ARRAY_SIZE(ov9734_test_pattern_menu) - 1,
+                                    0, 0, ov9734_test_pattern_menu);
+       if (ctrl_hdlr->error)
+               return ctrl_hdlr->error;
+
+       ov9734->sd.ctrl_handler = ctrl_hdlr;
+
+       return 0;
+}
+
+static void ov9734_update_pad_format(const struct ov9734_mode *mode,
+                                    struct v4l2_mbus_framefmt *fmt)
+{
+       fmt->width = mode->width;
+       fmt->height = mode->height;
+       fmt->code = MEDIA_BUS_FMT_SGRBG10_1X10;
+       fmt->field = V4L2_FIELD_NONE;
+}
+
+static int ov9734_start_streaming(struct ov9734 *ov9734)
+{
+       struct i2c_client *client = v4l2_get_subdevdata(&ov9734->sd);
+       const struct ov9734_reg_list *reg_list;
+       int link_freq_index, ret;
+
+       link_freq_index = ov9734->cur_mode->link_freq_index;
+       reg_list = &link_freq_configs[link_freq_index].reg_list;
+       ret = ov9734_write_reg_list(ov9734, reg_list);
+       if (ret) {
+               dev_err(&client->dev, "failed to set plls");
+               return ret;
+       }
+
+       reg_list = &ov9734->cur_mode->reg_list;
+       ret = ov9734_write_reg_list(ov9734, reg_list);
+       if (ret) {
+               dev_err(&client->dev, "failed to set mode");
+               return ret;
+       }
+
+       ret = __v4l2_ctrl_handler_setup(ov9734->sd.ctrl_handler);
+       if (ret)
+               return ret;
+
+       ret = ov9734_write_reg(ov9734, OV9734_REG_MODE_SELECT,
+                              1, OV9734_MODE_STREAMING);
+       if (ret)
+               dev_err(&client->dev, "failed to start stream");
+
+       return ret;
+}
+
+static void ov9734_stop_streaming(struct ov9734 *ov9734)
+{
+       struct i2c_client *client = v4l2_get_subdevdata(&ov9734->sd);
+
+       if (ov9734_write_reg(ov9734, OV9734_REG_MODE_SELECT,
+                            1, OV9734_MODE_STANDBY))
+               dev_err(&client->dev, "failed to stop stream");
+}
+
+static int ov9734_set_stream(struct v4l2_subdev *sd, int enable)
+{
+       struct ov9734 *ov9734 = to_ov9734(sd);
+       struct i2c_client *client = v4l2_get_subdevdata(sd);
+       int ret = 0;
+
+       if (ov9734->streaming == enable)
+               return 0;
+
+       mutex_lock(&ov9734->mutex);
+       if (enable) {
+               ret = pm_runtime_get_sync(&client->dev);
+               if (ret < 0) {
+                       pm_runtime_put_noidle(&client->dev);
+                       mutex_unlock(&ov9734->mutex);
+                       return ret;
+               }
+
+               ret = ov9734_start_streaming(ov9734);
+               if (ret) {
+                       enable = 0;
+                       ov9734_stop_streaming(ov9734);
+                       pm_runtime_put(&client->dev);
+               }
+       } else {
+               ov9734_stop_streaming(ov9734);
+               pm_runtime_put(&client->dev);
+       }
+
+       ov9734->streaming = enable;
+       mutex_unlock(&ov9734->mutex);
+
+       return ret;
+}
+
+static int __maybe_unused ov9734_suspend(struct device *dev)
+{
+       struct i2c_client *client = to_i2c_client(dev);
+       struct v4l2_subdev *sd = i2c_get_clientdata(client);
+       struct ov9734 *ov9734 = to_ov9734(sd);
+
+       mutex_lock(&ov9734->mutex);
+       if (ov9734->streaming)
+               ov9734_stop_streaming(ov9734);
+
+       mutex_unlock(&ov9734->mutex);
+
+       return 0;
+}
+
+static int __maybe_unused ov9734_resume(struct device *dev)
+{
+       struct i2c_client *client = to_i2c_client(dev);
+       struct v4l2_subdev *sd = i2c_get_clientdata(client);
+       struct ov9734 *ov9734 = to_ov9734(sd);
+       int ret = 0;
+
+       mutex_lock(&ov9734->mutex);
+       if (!ov9734->streaming)
+               goto exit;
+
+       ret = ov9734_start_streaming(ov9734);
+       if (ret) {
+               ov9734->streaming = false;
+               ov9734_stop_streaming(ov9734);
+       }
+
+exit:
+       mutex_unlock(&ov9734->mutex);
+       return ret;
+}
+
+static int ov9734_set_format(struct v4l2_subdev *sd,
+                            struct v4l2_subdev_pad_config *cfg,
+                            struct v4l2_subdev_format *fmt)
+{
+       struct ov9734 *ov9734 = to_ov9734(sd);
+       const struct ov9734_mode *mode;
+       s32 vblank_def, h_blank;
+
+       mode = v4l2_find_nearest_size(supported_modes,
+                                     ARRAY_SIZE(supported_modes), width,
+                                     height, fmt->format.width,
+                                     fmt->format.height);
+
+       mutex_lock(&ov9734->mutex);
+       ov9734_update_pad_format(mode, &fmt->format);
+       if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) {
+               *v4l2_subdev_get_try_format(sd, cfg, fmt->pad) = fmt->format;
+       } else {
+               ov9734->cur_mode = mode;
+               __v4l2_ctrl_s_ctrl(ov9734->link_freq, mode->link_freq_index);
+               __v4l2_ctrl_s_ctrl_int64(ov9734->pixel_rate,
+                                        to_pixel_rate(mode->link_freq_index));
+
+               /* Update limits and set FPS to default */
+               vblank_def = mode->vts_def - mode->height;
+               __v4l2_ctrl_modify_range(ov9734->vblank,
+                                        mode->vts_min - mode->height,
+                                        OV9734_VTS_MAX - mode->height, 1,
+                                        vblank_def);
+               __v4l2_ctrl_s_ctrl(ov9734->vblank, vblank_def);
+               h_blank = to_pixels_per_line(mode->hts, mode->link_freq_index) -
+                       mode->width;
+               __v4l2_ctrl_modify_range(ov9734->hblank, h_blank, h_blank, 1,
+                                        h_blank);
+       }
+
+       mutex_unlock(&ov9734->mutex);
+
+       return 0;
+}
+
+static int ov9734_get_format(struct v4l2_subdev *sd,
+                            struct v4l2_subdev_pad_config *cfg,
+                            struct v4l2_subdev_format *fmt)
+{
+       struct ov9734 *ov9734 = to_ov9734(sd);
+
+       mutex_lock(&ov9734->mutex);
+       if (fmt->which == V4L2_SUBDEV_FORMAT_TRY)
+               fmt->format = *v4l2_subdev_get_try_format(&ov9734->sd, cfg,
+                                                         fmt->pad);
+       else
+               ov9734_update_pad_format(ov9734->cur_mode, &fmt->format);
+
+       mutex_unlock(&ov9734->mutex);
+
+       return 0;
+}
+
+static int ov9734_enum_mbus_code(struct v4l2_subdev *sd,
+                                struct v4l2_subdev_pad_config *cfg,
+                                struct v4l2_subdev_mbus_code_enum *code)
+{
+       if (code->index > 0)
+               return -EINVAL;
+
+       code->code = MEDIA_BUS_FMT_SGRBG10_1X10;
+
+       return 0;
+}
+
+static int ov9734_enum_frame_size(struct v4l2_subdev *sd,
+                                 struct v4l2_subdev_pad_config *cfg,
+                                 struct v4l2_subdev_frame_size_enum *fse)
+{
+       if (fse->index >= ARRAY_SIZE(supported_modes))
+               return -EINVAL;
+
+       if (fse->code != MEDIA_BUS_FMT_SGRBG10_1X10)
+               return -EINVAL;
+
+       fse->min_width = supported_modes[fse->index].width;
+       fse->max_width = fse->min_width;
+       fse->min_height = supported_modes[fse->index].height;
+       fse->max_height = fse->min_height;
+
+       return 0;
+}
+
+static int ov9734_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
+{
+       struct ov9734 *ov9734 = to_ov9734(sd);
+
+       mutex_lock(&ov9734->mutex);
+       ov9734_update_pad_format(&supported_modes[0],
+                                v4l2_subdev_get_try_format(sd, fh->pad, 0));
+       mutex_unlock(&ov9734->mutex);
+
+       return 0;
+}
+
+static const struct v4l2_subdev_video_ops ov9734_video_ops = {
+       .s_stream = ov9734_set_stream,
+};
+
+static const struct v4l2_subdev_pad_ops ov9734_pad_ops = {
+       .set_fmt = ov9734_set_format,
+       .get_fmt = ov9734_get_format,
+       .enum_mbus_code = ov9734_enum_mbus_code,
+       .enum_frame_size = ov9734_enum_frame_size,
+};
+
+static const struct v4l2_subdev_ops ov9734_subdev_ops = {
+       .video = &ov9734_video_ops,
+       .pad = &ov9734_pad_ops,
+};
+
+static const struct media_entity_operations ov9734_subdev_entity_ops = {
+       .link_validate = v4l2_subdev_link_validate,
+};
+
+static const struct v4l2_subdev_internal_ops ov9734_internal_ops = {
+       .open = ov9734_open,
+};
+
+static int ov9734_identify_module(struct ov9734 *ov9734)
+{
+       struct i2c_client *client = v4l2_get_subdevdata(&ov9734->sd);
+       int ret;
+       u32 val;
+
+       ret = ov9734_read_reg(ov9734, OV9734_REG_CHIP_ID, 2, &val);
+       if (ret)
+               return ret;
+
+       if (val != OV9734_CHIP_ID) {
+               dev_err(&client->dev, "chip id mismatch: %x!=%x",
+                       OV9734_CHIP_ID, val);
+               return -ENXIO;
+       }
+
+       return 0;
+}
+
+static int ov9734_check_hwcfg(struct device *dev)
+{
+       struct fwnode_handle *ep;
+       struct fwnode_handle *fwnode = dev_fwnode(dev);
+       struct v4l2_fwnode_endpoint bus_cfg = {
+               .bus_type = V4L2_MBUS_CSI2_DPHY
+       };
+       u32 mclk;
+       int ret;
+       unsigned int i, j;
+
+       if (!fwnode)
+               return -ENXIO;
+
+       ret = fwnode_property_read_u32(fwnode, "clock-frequency", &mclk);
+       if (ret)
+               return ret;
+
+       if (mclk != OV9734_MCLK) {
+               dev_err(dev, "external clock %d is not supported", mclk);
+               return -EINVAL;
+       }
+
+       ep = fwnode_graph_get_next_endpoint(fwnode, NULL);
+       if (!ep)
+               return -ENXIO;
+
+       ret = v4l2_fwnode_endpoint_alloc_parse(ep, &bus_cfg);
+       fwnode_handle_put(ep);
+       if (ret)
+               return ret;
+
+       if (!bus_cfg.nr_of_link_frequencies) {
+               dev_err(dev, "no link frequencies defined");
+               ret = -EINVAL;
+               goto check_hwcfg_error;
+       }
+
+       for (i = 0; i < ARRAY_SIZE(link_freq_menu_items); i++) {
+               for (j = 0; j < bus_cfg.nr_of_link_frequencies; j++) {
+                       if (link_freq_menu_items[i] ==
+                           bus_cfg.link_frequencies[j])
+                               break;
+               }
+
+               if (j == bus_cfg.nr_of_link_frequencies) {
+                       dev_err(dev, "no link frequency %lld supported",
+                               link_freq_menu_items[i]);
+                       ret = -EINVAL;
+                       goto check_hwcfg_error;
+               }
+       }
+
+check_hwcfg_error:
+       v4l2_fwnode_endpoint_free(&bus_cfg);
+
+       return ret;
+}
+
+static int ov9734_remove(struct i2c_client *client)
+{
+       struct v4l2_subdev *sd = i2c_get_clientdata(client);
+       struct ov9734 *ov9734 = to_ov9734(sd);
+
+       v4l2_async_unregister_subdev(sd);
+       media_entity_cleanup(&sd->entity);
+       v4l2_ctrl_handler_free(sd->ctrl_handler);
+       pm_runtime_disable(&client->dev);
+       mutex_destroy(&ov9734->mutex);
+
+       return 0;
+}
+
+static int ov9734_probe(struct i2c_client *client)
+{
+       struct ov9734 *ov9734;
+       int ret;
+
+       ret = ov9734_check_hwcfg(&client->dev);
+       if (ret) {
+               dev_err(&client->dev, "failed to check HW configuration: %d",
+                       ret);
+               return ret;
+       }
+
+       ov9734 = devm_kzalloc(&client->dev, sizeof(*ov9734), GFP_KERNEL);
+       if (!ov9734)
+               return -ENOMEM;
+
+       v4l2_i2c_subdev_init(&ov9734->sd, client, &ov9734_subdev_ops);
+       ret = ov9734_identify_module(ov9734);
+       if (ret) {
+               dev_err(&client->dev, "failed to find sensor: %d", ret);
+               return ret;
+       }
+
+       mutex_init(&ov9734->mutex);
+       ov9734->cur_mode = &supported_modes[0];
+       ret = ov9734_init_controls(ov9734);
+       if (ret) {
+               dev_err(&client->dev, "failed to init controls: %d", ret);
+               goto probe_error_v4l2_ctrl_handler_free;
+       }
+
+       ov9734->sd.internal_ops = &ov9734_internal_ops;
+       ov9734->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
+       ov9734->sd.entity.ops = &ov9734_subdev_entity_ops;
+       ov9734->sd.entity.function = MEDIA_ENT_F_CAM_SENSOR;
+       ov9734->pad.flags = MEDIA_PAD_FL_SOURCE;
+       ret = media_entity_pads_init(&ov9734->sd.entity, 1, &ov9734->pad);
+       if (ret) {
+               dev_err(&client->dev, "failed to init entity pads: %d", ret);
+               goto probe_error_v4l2_ctrl_handler_free;
+       }
+
+       ret = v4l2_async_register_subdev_sensor_common(&ov9734->sd);
+       if (ret < 0) {
+               dev_err(&client->dev, "failed to register V4L2 subdev: %d",
+                       ret);
+               goto probe_error_media_entity_cleanup;
+       }
+
+       /*
+        * Device is already turned on by i2c-core with ACPI domain PM.
+        * Enable runtime PM and turn off the device.
+        */
+       pm_runtime_set_active(&client->dev);
+       pm_runtime_enable(&client->dev);
+       pm_runtime_idle(&client->dev);
+
+       return 0;
+
+probe_error_media_entity_cleanup:
+       media_entity_cleanup(&ov9734->sd.entity);
+
+probe_error_v4l2_ctrl_handler_free:
+       v4l2_ctrl_handler_free(ov9734->sd.ctrl_handler);
+       mutex_destroy(&ov9734->mutex);
+
+       return ret;
+}
+
+static const struct dev_pm_ops ov9734_pm_ops = {
+       SET_SYSTEM_SLEEP_PM_OPS(ov9734_suspend, ov9734_resume)
+};
+
+static const struct acpi_device_id ov9734_acpi_ids[] = {
+       { "OVTI9734", },
+       {}
+};
+
+MODULE_DEVICE_TABLE(acpi, ov9734_acpi_ids);
+
+static struct i2c_driver ov9734_i2c_driver = {
+       .driver = {
+               .name = "ov9734",
+               .pm = &ov9734_pm_ops,
+               .acpi_match_table = ov9734_acpi_ids,
+       },
+       .probe_new = ov9734_probe,
+       .remove = ov9734_remove,
+};
+
+module_i2c_driver(ov9734_i2c_driver);
+
+MODULE_AUTHOR("Qiu, Tianshu <tian.shu.qiu@intel.com>");
+MODULE_AUTHOR("Bingbu Cao <bingbu.cao@intel.com>");
+MODULE_DESCRIPTION("OmniVision OV9734 sensor driver");
+MODULE_LICENSE("GPL v2");
index 6fc0680..105ef29 100644 (file)
@@ -1185,8 +1185,7 @@ out:
 
 static int smiapp_power_on(struct device *dev)
 {
-       struct i2c_client *client = to_i2c_client(dev);
-       struct v4l2_subdev *subdev = i2c_get_clientdata(client);
+       struct v4l2_subdev *subdev = dev_get_drvdata(dev);
        struct smiapp_subdev *ssd = to_smiapp_subdev(subdev);
        /*
         * The sub-device related to the I2C device is always the
@@ -1199,14 +1198,14 @@ static int smiapp_power_on(struct device *dev)
 
        rval = regulator_enable(sensor->vana);
        if (rval) {
-               dev_err(&client->dev, "failed to enable vana regulator\n");
+               dev_err(dev, "failed to enable vana regulator\n");
                return rval;
        }
        usleep_range(1000, 1000);
 
        rval = clk_prepare_enable(sensor->ext_clk);
        if (rval < 0) {
-               dev_dbg(&client->dev, "failed to enable xclk\n");
+               dev_dbg(dev, "failed to enable xclk\n");
                goto out_xclk_fail;
        }
        usleep_range(1000, 1000);
@@ -1230,7 +1229,7 @@ static int smiapp_power_on(struct device *dev)
        if (sensor->hwcfg->i2c_addr_alt) {
                rval = smiapp_change_cci_addr(sensor);
                if (rval) {
-                       dev_err(&client->dev, "cci address change error\n");
+                       dev_err(dev, "cci address change error\n");
                        goto out_cci_addr_fail;
                }
        }
@@ -1238,14 +1237,14 @@ static int smiapp_power_on(struct device *dev)
        rval = smiapp_write(sensor, SMIAPP_REG_U8_SOFTWARE_RESET,
                            SMIAPP_SOFTWARE_RESET);
        if (rval < 0) {
-               dev_err(&client->dev, "software reset failed\n");
+               dev_err(dev, "software reset failed\n");
                goto out_cci_addr_fail;
        }
 
        if (sensor->hwcfg->i2c_addr_alt) {
                rval = smiapp_change_cci_addr(sensor);
                if (rval) {
-                       dev_err(&client->dev, "cci address change error\n");
+                       dev_err(dev, "cci address change error\n");
                        goto out_cci_addr_fail;
                }
        }
@@ -1253,7 +1252,7 @@ static int smiapp_power_on(struct device *dev)
        rval = smiapp_write(sensor, SMIAPP_REG_U16_COMPRESSION_MODE,
                            SMIAPP_COMPRESSION_MODE_SIMPLE_PREDICTOR);
        if (rval) {
-               dev_err(&client->dev, "compression mode set failed\n");
+               dev_err(dev, "compression mode set failed\n");
                goto out_cci_addr_fail;
        }
 
@@ -1261,28 +1260,28 @@ static int smiapp_power_on(struct device *dev)
                sensor, SMIAPP_REG_U16_EXTCLK_FREQUENCY_MHZ,
                sensor->hwcfg->ext_clk / (1000000 / (1 << 8)));
        if (rval) {
-               dev_err(&client->dev, "extclk frequency set failed\n");
+               dev_err(dev, "extclk frequency set failed\n");
                goto out_cci_addr_fail;
        }
 
        rval = smiapp_write(sensor, SMIAPP_REG_U8_CSI_LANE_MODE,
                            sensor->hwcfg->lanes - 1);
        if (rval) {
-               dev_err(&client->dev, "csi lane mode set failed\n");
+               dev_err(dev, "csi lane mode set failed\n");
                goto out_cci_addr_fail;
        }
 
        rval = smiapp_write(sensor, SMIAPP_REG_U8_FAST_STANDBY_CTRL,
                            SMIAPP_FAST_STANDBY_CTRL_IMMEDIATE);
        if (rval) {
-               dev_err(&client->dev, "fast standby set failed\n");
+               dev_err(dev, "fast standby set failed\n");
                goto out_cci_addr_fail;
        }
 
        rval = smiapp_write(sensor, SMIAPP_REG_U8_CSI_SIGNALLING_MODE,
                            sensor->hwcfg->csi_signalling_mode);
        if (rval) {
-               dev_err(&client->dev, "csi signalling mode set failed\n");
+               dev_err(dev, "csi signalling mode set failed\n");
                goto out_cci_addr_fail;
        }
 
@@ -1294,7 +1293,7 @@ static int smiapp_power_on(struct device *dev)
 
        rval = smiapp_call_quirk(sensor, post_poweron);
        if (rval) {
-               dev_err(&client->dev, "post_poweron quirks failed\n");
+               dev_err(dev, "post_poweron quirks failed\n");
                goto out_cci_addr_fail;
        }
 
@@ -1312,8 +1311,7 @@ out_xclk_fail:
 
 static int smiapp_power_off(struct device *dev)
 {
-       struct i2c_client *client = to_i2c_client(dev);
-       struct v4l2_subdev *subdev = i2c_get_clientdata(client);
+       struct v4l2_subdev *subdev = dev_get_drvdata(dev);
        struct smiapp_subdev *ssd = to_smiapp_subdev(subdev);
        struct smiapp_sensor *sensor =
                container_of(ssd, struct smiapp_sensor, ssds[0]);
index 7d94012..29f65bb 100644 (file)
@@ -1413,8 +1413,7 @@ static const struct media_entity_operations tvp5150_sd_media_ops = {
  ****************************************************************************/
 static int __maybe_unused tvp5150_runtime_suspend(struct device *dev)
 {
-       struct i2c_client *client = to_i2c_client(dev);
-       struct v4l2_subdev *sd = i2c_get_clientdata(client);
+       struct v4l2_subdev *sd = dev_get_drvdata(dev);
        struct tvp5150 *decoder = to_tvp5150(sd);
 
        if (decoder->irq)
@@ -1427,8 +1426,7 @@ static int __maybe_unused tvp5150_runtime_suspend(struct device *dev)
 
 static int __maybe_unused tvp5150_runtime_resume(struct device *dev)
 {
-       struct i2c_client *client = to_i2c_client(dev);
-       struct v4l2_subdev *sd = i2c_get_clientdata(client);
+       struct v4l2_subdev *sd = dev_get_drvdata(dev);
        struct tvp5150 *decoder = to_tvp5150(sd);
 
        if (decoder->irq)
index ba45b37..ff80585 100644 (file)
@@ -17,7 +17,7 @@ int flexcop_dma_allocate(struct pci_dev *pdev,
                return -EINVAL;
        }
 
-       tcpu = pci_alloc_consistent(pdev, size, &tdma);
+       tcpu = dma_alloc_coherent(&pdev->dev, size, &tdma, GFP_KERNEL);
        if (tcpu != NULL) {
                dma->pdev = pdev;
                dma->cpu_addr0 = tcpu;
@@ -33,8 +33,8 @@ EXPORT_SYMBOL(flexcop_dma_allocate);
 
 void flexcop_dma_free(struct flexcop_dma *dma)
 {
-       pci_free_consistent(dma->pdev, dma->size*2,
-                       dma->cpu_addr0, dma->dma_addr0);
+       dma_free_coherent(&dma->pdev->dev, dma->size * 2, dma->cpu_addr0,
+                         dma->dma_addr0);
        memset(dma, 0, sizeof(struct flexcop_dma));
 }
 EXPORT_SYMBOL(flexcop_dma_free);
index 79ba15a..78dd35c 100644 (file)
@@ -67,14 +67,14 @@ EXPORT_SYMBOL(bt878);
 static void bt878_mem_free(struct bt878 *bt)
 {
        if (bt->buf_cpu) {
-               pci_free_consistent(bt->dev, bt->buf_size, bt->buf_cpu,
-                                   bt->buf_dma);
+               dma_free_coherent(&bt->dev->dev, bt->buf_size, bt->buf_cpu,
+                                 bt->buf_dma);
                bt->buf_cpu = NULL;
        }
 
        if (bt->risc_cpu) {
-               pci_free_consistent(bt->dev, bt->risc_size, bt->risc_cpu,
-                                   bt->risc_dma);
+               dma_free_coherent(&bt->dev->dev, bt->risc_size, bt->risc_cpu,
+                                 bt->risc_dma);
                bt->risc_cpu = NULL;
        }
 }
@@ -84,16 +84,16 @@ static int bt878_mem_alloc(struct bt878 *bt)
        if (!bt->buf_cpu) {
                bt->buf_size = 128 * 1024;
 
-               bt->buf_cpu = pci_zalloc_consistent(bt->dev, bt->buf_size,
-                                                   &bt->buf_dma);
+               bt->buf_cpu = dma_alloc_coherent(&bt->dev->dev, bt->buf_size,
+                                                &bt->buf_dma, GFP_KERNEL);
                if (!bt->buf_cpu)
                        return -ENOMEM;
        }
 
        if (!bt->risc_cpu) {
                bt->risc_size = PAGE_SIZE;
-               bt->risc_cpu = pci_zalloc_consistent(bt->dev, bt->risc_size,
-                                                    &bt->risc_dma);
+               bt->risc_cpu = dma_alloc_coherent(&bt->dev->dev, bt->risc_size,
+                                                 &bt->risc_dma, GFP_KERNEL);
                if (!bt->risc_cpu) {
                        bt878_mem_free(bt);
                        return -ENOMEM;
index 5125798..b317903 100644 (file)
@@ -48,7 +48,7 @@ void btcx_riscmem_free(struct pci_dev *pci,
        dprintk("btcx: riscmem free [%d] dma=%lx\n",
                memcnt, (unsigned long)risc->dma);
 
-       pci_free_consistent(pci, risc->size, risc->cpu, risc->dma);
+       dma_free_coherent(&pci->dev, risc->size, risc->cpu, risc->dma);
        memset(risc,0,sizeof(*risc));
 }
 
@@ -62,7 +62,7 @@ int btcx_riscmem_alloc(struct pci_dev *pci,
        if (NULL != risc->cpu && risc->size < size)
                btcx_riscmem_free(pci,risc);
        if (NULL == risc->cpu) {
-               cpu = pci_alloc_consistent(pci, size, &dma);
+               cpu = dma_alloc_coherent(&pci->dev, size, &dma, GFP_KERNEL);
                if (NULL == cpu)
                        return -ENOMEM;
                risc->cpu  = cpu;
@@ -73,7 +73,6 @@ int btcx_riscmem_alloc(struct pci_dev *pci,
                dprintk("btcx: riscmem alloc [%d] dma=%lx cpu=%p size=%d\n",
                        memcnt, (unsigned long)dma, cpu, size);
        }
-       memset(risc->cpu,0,risc->size);
        return 0;
 }
 
index 1614880..ca20b80 100644 (file)
@@ -3934,8 +3934,10 @@ static void osprey_eeprom(struct bttv *btv, const u8 ee[256])
                        if (checksum != ee[21])
                                return;
                        cardid = BTTV_BOARD_OSPREY1x0_848;
-                       for (i = 12; i < 21; i++)
-                               serial *= 10, serial += ee[i] - '0';
+                       for (i = 12; i < 21; i++) {
+                               serial *= 10;
+                               serial += ee[i] - '0';
+                       }
                }
        } else {
                unsigned short type;
index 8824dd0..1f62a9d 100644 (file)
@@ -2058,7 +2058,6 @@ verify_window_lock(struct bttv_fh *fh, struct v4l2_window *win,
 {
        enum v4l2_field field;
        unsigned int width_mask;
-       int rc;
 
        if (win->w.width < 48)
                win->w.width = 48;
@@ -2111,13 +2110,10 @@ verify_window_lock(struct bttv_fh *fh, struct v4l2_window *win,
        win->w.width -= win->w.left & ~width_mask;
        win->w.left = (win->w.left - width_mask - 1) & width_mask;
 
-       rc = limit_scaled_size_lock(fh, &win->w.width, &win->w.height,
-                              field, width_mask,
-                              /* width_bias: round down */ 0,
-                              adjust_size, adjust_crop);
-       if (0 != rc)
-               return rc;
-       return 0;
+       return limit_scaled_size_lock(fh, &win->w.width, &win->w.height,
+                                     field, width_mask,
+                                     /* width_bias: round down */ 0,
+                                     adjust_size, adjust_crop);
 }
 
 static int setup_window_lock(struct bttv_fh *fh, struct bttv *btv,
@@ -2143,12 +2139,8 @@ static int setup_window_lock(struct bttv_fh *fh, struct bttv *btv,
        clips = kmalloc(size,GFP_KERNEL);
        if (NULL == clips)
                return -ENOMEM;
-       if (n > 0) {
-               if (copy_from_user(clips,win->clips,sizeof(struct v4l2_clip)*n)) {
-                       kfree(clips);
-                       return -EFAULT;
-               }
-       }
+       if (n > 0)
+               memcpy(clips, win->clips, sizeof(struct v4l2_clip) * n);
 
        /* clip against screen */
        if (NULL != btv->fbuf.base)
@@ -4016,7 +4008,7 @@ static int bttv_probe(struct pci_dev *dev, const struct pci_device_id *pci_id)
                result = -EIO;
                goto free_mem;
        }
-       if (pci_set_dma_mask(dev, DMA_BIT_MASK(32))) {
+       if (dma_set_mask(&dev->dev, DMA_BIT_MASK(32))) {
                pr_warn("%d: No suitable DMA available\n", btv->c.nr);
                result = -EIO;
                goto free_mem;
@@ -4270,15 +4262,14 @@ static void bttv_remove(struct pci_dev *pci_dev)
        return;
 }
 
-#ifdef CONFIG_PM
-static int bttv_suspend(struct pci_dev *pci_dev, pm_message_t state)
+static int __maybe_unused bttv_suspend(struct device *dev)
 {
-       struct v4l2_device *v4l2_dev = pci_get_drvdata(pci_dev);
+       struct v4l2_device *v4l2_dev = dev_get_drvdata(dev);
        struct bttv *btv = to_bttv(v4l2_dev);
        struct bttv_buffer_set idle;
        unsigned long flags;
 
-       dprintk("%d: suspend %d\n", btv->c.nr, state.event);
+       dprintk("%d: suspend\n", btv->c.nr);
 
        /* stop dma + irqs */
        spin_lock_irqsave(&btv->s_lock,flags);
@@ -4298,42 +4289,19 @@ static int bttv_suspend(struct pci_dev *pci_dev, pm_message_t state)
        btv->state.gpio_enable = btread(BT848_GPIO_OUT_EN);
        btv->state.gpio_data   = gpio_read();
 
-       /* save pci state */
-       pci_save_state(pci_dev);
-       if (0 != pci_set_power_state(pci_dev, pci_choose_state(pci_dev, state))) {
-               pci_disable_device(pci_dev);
-               btv->state.disabled = 1;
-       }
+       btv->state.disabled = 1;
        return 0;
 }
 
-static int bttv_resume(struct pci_dev *pci_dev)
+static int __maybe_unused bttv_resume(struct device *dev)
 {
-       struct v4l2_device *v4l2_dev = pci_get_drvdata(pci_dev);
+       struct v4l2_device *v4l2_dev = dev_get_drvdata(dev);
        struct bttv *btv = to_bttv(v4l2_dev);
        unsigned long flags;
-       int err;
 
        dprintk("%d: resume\n", btv->c.nr);
 
-       /* restore pci state */
-       if (btv->state.disabled) {
-               err=pci_enable_device(pci_dev);
-               if (err) {
-                       pr_warn("%d: Can't enable device\n", btv->c.nr);
-                       return err;
-               }
-               btv->state.disabled = 0;
-       }
-       err=pci_set_power_state(pci_dev, PCI_D0);
-       if (err) {
-               pci_disable_device(pci_dev);
-               pr_warn("%d: Can't enable device\n", btv->c.nr);
-               btv->state.disabled = 1;
-               return err;
-       }
-
-       pci_restore_state(pci_dev);
+       btv->state.disabled = 0;
 
        /* restore bt878 state */
        bttv_reinit_bt848(btv);
@@ -4351,7 +4319,6 @@ static int bttv_resume(struct pci_dev *pci_dev)
        spin_unlock_irqrestore(&btv->s_lock,flags);
        return 0;
 }
-#endif
 
 static const struct pci_device_id bttv_pci_tbl[] = {
        {PCI_VDEVICE(BROOKTREE, PCI_DEVICE_ID_BT848), 0},
@@ -4364,15 +4331,16 @@ static const struct pci_device_id bttv_pci_tbl[] = {
 
 MODULE_DEVICE_TABLE(pci, bttv_pci_tbl);
 
+static SIMPLE_DEV_PM_OPS(bttv_pm_ops,
+                        bttv_suspend,
+                        bttv_resume);
+
 static struct pci_driver bttv_pci_driver = {
-       .name     = "bttv",
-       .id_table = bttv_pci_tbl,
-       .probe    = bttv_probe,
-       .remove   = bttv_remove,
-#ifdef CONFIG_PM
-       .suspend  = bttv_suspend,
-       .resume   = bttv_resume,
-#endif
+       .name      = "bttv",
+       .id_table  = bttv_pci_tbl,
+       .probe     = bttv_probe,
+       .remove    = bttv_remove,
+       .driver.pm = &bttv_pm_ops,
 };
 
 static int __init bttv_init_module(void)
index 4af7282..32fa4a7 100644 (file)
@@ -572,7 +572,6 @@ bttv_dma_free(struct videobuf_queue *q,struct bttv *btv, struct bttv_buffer *buf
 {
        struct videobuf_dmabuf *dma=videobuf_to_dma(&buf->vb);
 
-       BUG_ON(in_interrupt());
        videobuf_waiton(q, &buf->vb, 0, 0);
        videobuf_dma_unmap(q->dev, dma);
        videobuf_dma_free(dma);
index 4b0c53f..16eb4ab 100644 (file)
@@ -1322,7 +1322,6 @@ void cx23885_free_buffer(struct cx23885_dev *dev, struct cx23885_buffer *buf)
 {
        struct cx23885_riscmem *risc = &buf->risc;
 
-       BUG_ON(in_interrupt());
        pci_free_consistent(dev->pci, risc->size, risc->cpu, risc->dma);
 }
 
index 55018d9..6f8ffab 100644 (file)
@@ -1198,7 +1198,6 @@ EXPORT_SYMBOL(cx25821_risc_databuffer_audio);
 
 void cx25821_free_buffer(struct cx25821_dev *dev, struct cx25821_buffer *buf)
 {
-       BUG_ON(in_interrupt());
        if (WARN_ON(buf->risc.size == 0))
                return;
        pci_free_consistent(dev->pci,
index 9dce31d..4ac645a 100644 (file)
@@ -604,19 +604,17 @@ static void dm1105_set_dma_addr(struct dm1105_dev *dev)
 
 static int dm1105_dma_map(struct dm1105_dev *dev)
 {
-       dev->ts_buf = pci_alloc_consistent(dev->pdev,
-                                       6 * DM1105_DMA_BYTES,
-                                       &dev->dma_addr);
+       dev->ts_buf = dma_alloc_coherent(&dev->pdev->dev,
+                                        6 * DM1105_DMA_BYTES, &dev->dma_addr,
+                                        GFP_KERNEL);
 
        return !dev->ts_buf;
 }
 
 static void dm1105_dma_unmap(struct dm1105_dev *dev)
 {
-       pci_free_consistent(dev->pdev,
-                       6 * DM1105_DMA_BYTES,
-                       dev->ts_buf,
-                       dev->dma_addr);
+       dma_free_coherent(&dev->pdev->dev, 6 * DM1105_DMA_BYTES, dev->ts_buf,
+                         dev->dma_addr);
 }
 
 static void dm1105_enable_irqs(struct dm1105_dev *dev)
@@ -1010,7 +1008,7 @@ static int dm1105_probe(struct pci_dev *pdev,
        if (ret < 0)
                goto err_kfree;
 
-       ret = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
+       ret = dma_set_mask(&pdev->dev, DMA_BIT_MASK(32));
        if (ret < 0)
                goto err_pci_disable_device;
 
index 4e598e9..36e354e 100644 (file)
@@ -14,6 +14,7 @@
 #include <linux/delay.h>
 #include <linux/interrupt.h>
 #include <linux/iopoll.h>
+#include <linux/mm.h>
 #include <linux/module.h>
 #include <linux/pci.h>
 #include <linux/pfn.h>
@@ -33,6 +34,7 @@ struct ipu3_cio2_fmt {
        u32 mbus_code;
        u32 fourcc;
        u8 mipicode;
+       u8 bpp;
 };
 
 /*
@@ -46,18 +48,22 @@ static const struct ipu3_cio2_fmt formats[] = {
                .mbus_code      = MEDIA_BUS_FMT_SGRBG10_1X10,
                .fourcc         = V4L2_PIX_FMT_IPU3_SGRBG10,
                .mipicode       = 0x2b,
+               .bpp            = 10,
        }, {
                .mbus_code      = MEDIA_BUS_FMT_SGBRG10_1X10,
                .fourcc         = V4L2_PIX_FMT_IPU3_SGBRG10,
                .mipicode       = 0x2b,
+               .bpp            = 10,
        }, {
                .mbus_code      = MEDIA_BUS_FMT_SBGGR10_1X10,
                .fourcc         = V4L2_PIX_FMT_IPU3_SBGGR10,
                .mipicode       = 0x2b,
+               .bpp            = 10,
        }, {
                .mbus_code      = MEDIA_BUS_FMT_SRGGB10_1X10,
                .fourcc         = V4L2_PIX_FMT_IPU3_SRGGB10,
                .mipicode       = 0x2b,
+               .bpp            = 10,
        },
 };
 
@@ -189,9 +195,8 @@ static void cio2_fbpt_entry_init_buf(struct cio2_device *cio2,
         * 4095 (PAGE_SIZE - 1) means every single byte in the last page
         * is available for DMA transfer.
         */
-       entry[1].second_entry.last_page_available_bytes =
-                       (remaining & ~PAGE_MASK) ?
-                               (remaining & ~PAGE_MASK) - 1 : PAGE_SIZE - 1;
+       remaining = offset_in_page(remaining) ?: PAGE_SIZE;
+       entry[1].second_entry.last_page_available_bytes = remaining - 1;
        /* Fill FBPT */
        remaining = length;
        i = 0;
@@ -286,37 +291,22 @@ static s32 cio2_rx_timing(s32 a, s32 b, s64 freq, int def)
        return r;
 };
 
-/* Calculate the the delay value for termination enable of clock lane HS Rx */
+/* Calculate the delay value for termination enable of clock lane HS Rx */
 static int cio2_csi2_calc_timing(struct cio2_device *cio2, struct cio2_queue *q,
-                                struct cio2_csi2_timing *timing)
+                                struct cio2_csi2_timing *timing,
+                                unsigned int bpp, unsigned int lanes)
 {
        struct device *dev = &cio2->pci_dev->dev;
-       struct v4l2_querymenu qm = { .id = V4L2_CID_LINK_FREQ };
-       struct v4l2_ctrl *link_freq;
        s64 freq;
-       int r;
 
        if (!q->sensor)
                return -ENODEV;
 
-       link_freq = v4l2_ctrl_find(q->sensor->ctrl_handler, V4L2_CID_LINK_FREQ);
-       if (!link_freq) {
-               dev_err(dev, "failed to find LINK_FREQ\n");
-               return -EPIPE;
-       }
-
-       qm.index = v4l2_ctrl_g_ctrl(link_freq);
-       r = v4l2_querymenu(q->sensor->ctrl_handler, &qm);
-       if (r) {
-               dev_err(dev, "failed to get menu item\n");
-               return r;
-       }
-
-       if (!qm.value) {
-               dev_err(dev, "error invalid link_freq\n");
-               return -EINVAL;
+       freq = v4l2_get_link_rate(q->sensor->ctrl_handler, bpp, lanes);
+       if (freq < 0) {
+               dev_err(dev, "error %lld, invalid link_freq\n", freq);
+               return freq;
        }
-       freq = qm.value;
 
        timing->clk_termen = cio2_rx_timing(CIO2_CSIRX_DLY_CNT_TERMEN_CLANE_A,
                                            CIO2_CSIRX_DLY_CNT_TERMEN_CLANE_B,
@@ -364,7 +354,7 @@ static int cio2_hw_init(struct cio2_device *cio2, struct cio2_queue *q)
 
        lanes = q->csi2.lanes;
 
-       r = cio2_csi2_calc_timing(cio2, q, &timing);
+       r = cio2_csi2_calc_timing(cio2, q, &timing, fmt->bpp, lanes);
        if (r)
                return r;
 
@@ -561,7 +551,9 @@ static void cio2_buffer_done(struct cio2_device *cio2, unsigned int dma_chan)
 
                b = q->bufs[q->bufs_first];
                if (b) {
-                       unsigned int bytes = entry[1].second_entry.num_of_bytes;
+                       unsigned int received = entry[1].second_entry.num_of_bytes;
+                       unsigned long payload =
+                               vb2_get_plane_payload(&b->vbb.vb2_buf, 0);
 
                        q->bufs[q->bufs_first] = NULL;
                        atomic_dec(&q->bufs_queued);
@@ -571,10 +563,10 @@ static void cio2_buffer_done(struct cio2_device *cio2, unsigned int dma_chan)
                        b->vbb.vb2_buf.timestamp = ns;
                        b->vbb.field = V4L2_FIELD_NONE;
                        b->vbb.sequence = atomic_read(&q->frame_sequence);
-                       if (b->vbb.vb2_buf.planes[0].length != bytes)
-                               dev_warn(dev, "buffer length is %d received %d\n",
-                                        b->vbb.vb2_buf.planes[0].length,
-                                        bytes);
+                       if (payload != received)
+                               dev_warn(dev,
+                                        "payload length is %lu, received %u\n",
+                                        payload, received);
                        vb2_buffer_done(&b->vbb.vb2_buf, VB2_BUF_STATE_DONE);
                }
                atomic_inc(&q->frame_sequence);
@@ -791,6 +783,7 @@ static void cio2_vb2_return_all_buffers(struct cio2_queue *q,
                        atomic_dec(&q->bufs_queued);
                        vb2_buffer_done(&q->bufs[i]->vbb.vb2_buf,
                                        state);
+                       q->bufs[i] = NULL;
                }
        }
 }
@@ -1094,8 +1087,8 @@ static int cio2_v4l2_try_fmt(struct file *file, void *fh, struct v4l2_format *f)
        /* Only supports up to 4224x3136 */
        if (mpix->width > CIO2_IMAGE_MAX_WIDTH)
                mpix->width = CIO2_IMAGE_MAX_WIDTH;
-       if (mpix->height > CIO2_IMAGE_MAX_LENGTH)
-               mpix->height = CIO2_IMAGE_MAX_LENGTH;
+       if (mpix->height > CIO2_IMAGE_MAX_HEIGHT)
+               mpix->height = CIO2_IMAGE_MAX_HEIGHT;
 
        mpix->num_planes = 1;
        mpix->pixelformat = fmt->fourcc;
@@ -1232,29 +1225,15 @@ static int cio2_subdev_get_fmt(struct v4l2_subdev *sd,
                               struct v4l2_subdev_format *fmt)
 {
        struct cio2_queue *q = container_of(sd, struct cio2_queue, subdev);
-       struct v4l2_subdev_format format;
-       int ret;
 
-       if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) {
-               fmt->format = *v4l2_subdev_get_try_format(sd, cfg, fmt->pad);
-               return 0;
-       }
-
-       if (fmt->pad == CIO2_PAD_SINK) {
-               format.which = V4L2_SUBDEV_FORMAT_ACTIVE;
-               ret = v4l2_subdev_call(sd, pad, get_fmt, NULL,
-                                      &format);
+       mutex_lock(&q->subdev_lock);
 
-               if (ret)
-                       return ret;
-               /* update colorspace etc */
-               q->subdev_fmt.colorspace = format.format.colorspace;
-               q->subdev_fmt.ycbcr_enc = format.format.ycbcr_enc;
-               q->subdev_fmt.quantization = format.format.quantization;
-               q->subdev_fmt.xfer_func = format.format.xfer_func;
-       }
+       if (fmt->which == V4L2_SUBDEV_FORMAT_TRY)
+               fmt->format = *v4l2_subdev_get_try_format(sd, cfg, fmt->pad);
+       else
+               fmt->format = q->subdev_fmt;
 
-       fmt->format = q->subdev_fmt;
+       mutex_unlock(&q->subdev_lock);
 
        return 0;
 }
@@ -1271,6 +1250,9 @@ static int cio2_subdev_set_fmt(struct v4l2_subdev *sd,
                               struct v4l2_subdev_format *fmt)
 {
        struct cio2_queue *q = container_of(sd, struct cio2_queue, subdev);
+       struct v4l2_mbus_framefmt *mbus;
+       u32 mbus_code = fmt->format.code;
+       unsigned int i;
 
        /*
         * Only allow setting sink pad format;
@@ -1279,16 +1261,28 @@ static int cio2_subdev_set_fmt(struct v4l2_subdev *sd,
        if (fmt->pad == CIO2_PAD_SOURCE)
                return cio2_subdev_get_fmt(sd, cfg, fmt);
 
-       if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) {
-               *v4l2_subdev_get_try_format(sd, cfg, fmt->pad) = fmt->format;
-       } else {
-               /* It's the sink, allow changing frame size */
-               q->subdev_fmt.width = fmt->format.width;
-               q->subdev_fmt.height = fmt->format.height;
-               q->subdev_fmt.code = fmt->format.code;
-               fmt->format = q->subdev_fmt;
+       if (fmt->which == V4L2_SUBDEV_FORMAT_TRY)
+               mbus = v4l2_subdev_get_try_format(sd, cfg, fmt->pad);
+       else
+               mbus = &q->subdev_fmt;
+
+       fmt->format.code = formats[0].mbus_code;
+
+       for (i = 0; i < ARRAY_SIZE(formats); i++) {
+               if (formats[i].mbus_code == fmt->format.code) {
+                       fmt->format.code = mbus_code;
+                       break;
+               }
        }
 
+       fmt->format.width = min(fmt->format.width, CIO2_IMAGE_MAX_WIDTH);
+       fmt->format.height = min(fmt->format.height, CIO2_IMAGE_MAX_HEIGHT);
+       fmt->format.field = V4L2_FIELD_NONE;
+
+       mutex_lock(&q->subdev_lock);
+       *mbus = fmt->format;
+       mutex_unlock(&q->subdev_lock);
+
        return 0;
 }
 
@@ -1547,6 +1541,7 @@ static int cio2_queue_init(struct cio2_device *cio2, struct cio2_queue *q)
 
        /* Initialize miscellaneous variables */
        mutex_init(&q->lock);
+       mutex_init(&q->subdev_lock);
 
        /* Initialize formats to default values */
        fmt = &q->subdev_fmt;
@@ -1663,6 +1658,7 @@ fail_vdev_media_entity:
 fail_subdev_media_entity:
        cio2_fbpt_exit(q, &cio2->pci_dev->dev);
 fail_fbpt:
+       mutex_destroy(&q->subdev_lock);
        mutex_destroy(&q->lock);
 
        return r;
@@ -1675,6 +1671,7 @@ static void cio2_queue_exit(struct cio2_device *cio2, struct cio2_queue *q)
        v4l2_device_unregister_subdev(&q->subdev);
        media_entity_cleanup(&q->subdev.entity);
        cio2_fbpt_exit(q, &cio2->pci_dev->dev);
+       mutex_destroy(&q->subdev_lock);
        mutex_destroy(&q->lock);
 }
 
index 549b08f..ccf0b85 100644 (file)
 #define CIO2_PCI_BAR                                   0
 #define CIO2_DMA_MASK                                  DMA_BIT_MASK(39)
 
-#define CIO2_IMAGE_MAX_WIDTH                           4224
-#define CIO2_IMAGE_MAX_LENGTH                          3136
+#define CIO2_IMAGE_MAX_WIDTH                           4224U
+#define CIO2_IMAGE_MAX_HEIGHT                          3136U
 
 /* 32MB = 8xFBPT_entry */
 #define CIO2_MAX_LOPS                                  8
 #define CIO2_MAX_BUFFERS                       (PAGE_SIZE / 16 / CIO2_MAX_LOPS)
 #define CIO2_LOP_ENTRIES                       (PAGE_SIZE / sizeof(u32))
 
-#define CIO2_PAD_SINK                                  0
-#define CIO2_PAD_SOURCE                                        1
-#define CIO2_PADS                                      2
+#define CIO2_PAD_SINK                                  0U
+#define CIO2_PAD_SOURCE                                        1U
+#define CIO2_PADS                                      2U
 
-#define CIO2_NUM_DMA_CHAN                              20
-#define CIO2_NUM_PORTS                                 4 /* DPHYs */
+#define CIO2_NUM_DMA_CHAN                              20U
+#define CIO2_NUM_PORTS                                 4U /* DPHYs */
 
 /* 1 for each sensor */
 #define CIO2_QUEUES                                    CIO2_NUM_PORTS
 #define CIO2_REG_MIPIBE_FORCE_RAW8     (CIO2_REG_MIPIBE_BASE + 0x20)
 #define CIO2_REG_MIPIBE_FORCE_RAW8_ENABLE              BIT(0)
 #define CIO2_REG_MIPIBE_FORCE_RAW8_USE_TYPEID          BIT(1)
-#define CIO2_REG_MIPIBE_FORCE_RAW8_TYPEID_SHIFT                2
+#define CIO2_REG_MIPIBE_FORCE_RAW8_TYPEID_SHIFT                2U
 
 #define CIO2_REG_MIPIBE_IRQ_STATUS     (CIO2_REG_MIPIBE_BASE + 0x24)
 #define CIO2_REG_MIPIBE_IRQ_CLEAR      (CIO2_REG_MIPIBE_BASE + 0x28)
 #define CIO2_REG_MIPIBE_GLOBAL_LUT_DISREGARD (CIO2_REG_MIPIBE_BASE + 0x68)
-#define CIO2_MIPIBE_GLOBAL_LUT_DISREGARD               1
+#define CIO2_MIPIBE_GLOBAL_LUT_DISREGARD               1U
 #define CIO2_REG_MIPIBE_PKT_STALL_STATUS (CIO2_REG_MIPIBE_BASE + 0x6c)
 #define CIO2_REG_MIPIBE_PARSE_GSP_THROUGH_LP_LUT_REG_IDX \
                                        (CIO2_REG_MIPIBE_BASE + 0x70)
                                       (CIO2_REG_MIPIBE_BASE + 0x74 + 4 * (vc))
 #define CIO2_REG_MIPIBE_LP_LUT_ENTRY(m)        /* m = 0..15 */ \
                                        (CIO2_REG_MIPIBE_BASE + 0x84 + 4 * (m))
-#define CIO2_MIPIBE_LP_LUT_ENTRY_DISREGARD             1
-#define CIO2_MIPIBE_LP_LUT_ENTRY_SID_SHIFT             1
-#define CIO2_MIPIBE_LP_LUT_ENTRY_VC_SHIFT              5
-#define CIO2_MIPIBE_LP_LUT_ENTRY_FORMAT_TYPE_SHIFT     7
+#define CIO2_MIPIBE_LP_LUT_ENTRY_DISREGARD             1U
+#define CIO2_MIPIBE_LP_LUT_ENTRY_SID_SHIFT             1U
+#define CIO2_MIPIBE_LP_LUT_ENTRY_VC_SHIFT              5U
+#define CIO2_MIPIBE_LP_LUT_ENTRY_FORMAT_TYPE_SHIFT     7U
 
 /* base register: CIO2_REG_PIPE_BASE(pipe) * CIO2_REG_IRQCTRL_BASE */
 /* IRQ registers are 18-bit wide, see cio2_irq_error for bit definitions */
 #define CIO2_CGC_ROSC_DCGE                             BIT(12)
 #define CIO2_CGC_XOSC_DCGE                             BIT(13)
 #define CIO2_CGC_FLIS_DCGE                             BIT(14)
-#define CIO2_CGC_CLKGATE_HOLDOFF_SHIFT                 20
-#define CIO2_CGC_CSI_CLKGATE_HOLDOFF_SHIFT             24
+#define CIO2_CGC_CLKGATE_HOLDOFF_SHIFT                 20U
+#define CIO2_CGC_CSI_CLKGATE_HOLDOFF_SHIFT             24U
 #define CIO2_REG_D0I3C                                 0x1408
 #define CIO2_D0I3C_I3                                  BIT(2)  /* Set D0I3 */
 #define CIO2_D0I3C_RR                                  BIT(3)  /* Restore? */
 #define CIO2_REG_SWRESET                               0x140c
-#define CIO2_SWRESET_SWRESET                           1
+#define CIO2_SWRESET_SWRESET                           1U
 #define CIO2_REG_SENSOR_ACTIVE                         0x1410
 #define CIO2_REG_INT_STS                               0x1414
 #define CIO2_REG_INT_STS_EXT_OE                                0x1418
-#define CIO2_INT_EXT_OE_DMAOE_SHIFT                    0
+#define CIO2_INT_EXT_OE_DMAOE_SHIFT                    0U
 #define CIO2_INT_EXT_OE_DMAOE_MASK                     0x7ffff
-#define CIO2_INT_EXT_OE_OES_SHIFT                      24
+#define CIO2_INT_EXT_OE_OES_SHIFT                      24U
 #define CIO2_INT_EXT_OE_OES_MASK       (0xf << CIO2_INT_EXT_OE_OES_SHIFT)
 #define CIO2_REG_INT_EN                                        0x1420
 #define CIO2_REG_INT_EN_IRQ                            (1 << 24)
-#define CIO2_REG_INT_EN_IOS(dma)       (1 << (((dma) >> 1) + 12))
+#define CIO2_REG_INT_EN_IOS(dma)       (1U << (((dma) >> 1U) + 12U))
 /*
  * Interrupt on completion bit, Eg. DMA 0-3 maps to bit 0-3,
  * DMA4 & DMA5 map to bit 4 ... DMA18 & DMA19 map to bit 11 Et cetera
  */
-#define CIO2_INT_IOC(dma)      (1 << ((dma) < 4 ? (dma) : ((dma) >> 1) + 2))
+#define CIO2_INT_IOC(dma)      (1U << ((dma) < 4U ? (dma) : ((dma) >> 1U) + 2U))
 #define CIO2_INT_IOC_SHIFT                             0
 #define CIO2_INT_IOC_MASK              (0x7ff << CIO2_INT_IOC_SHIFT)
-#define CIO2_INT_IOS_IOLN(dma)         (1 << (((dma) >> 1) + 12))
+#define CIO2_INT_IOS_IOLN(dma)         (1U << (((dma) >> 1U) + 12U))
 #define CIO2_INT_IOS_IOLN_SHIFT                                12
 #define CIO2_INT_IOS_IOLN_MASK         (0x3ff << CIO2_INT_IOS_IOLN_SHIFT)
 #define CIO2_INT_IOIE                                  BIT(22)
 #define CIO2_INT_IOIRQ                                 BIT(24)
 #define CIO2_REG_INT_EN_EXT_OE                         0x1424
 #define CIO2_REG_DMA_DBG                               0x1448
-#define CIO2_REG_DMA_DBG_DMA_INDEX_SHIFT               0
+#define CIO2_REG_DMA_DBG_DMA_INDEX_SHIFT               0U
 #define CIO2_REG_PBM_ARB_CTRL                          0x1460
-#define CIO2_PBM_ARB_CTRL_LANES_DIV                    0 /* 4-4-2-2 lanes */
-#define CIO2_PBM_ARB_CTRL_LANES_DIV_SHIFT              0
+#define CIO2_PBM_ARB_CTRL_LANES_DIV                    0U /* 4-4-2-2 lanes */
+#define CIO2_PBM_ARB_CTRL_LANES_DIV_SHIFT              0U
 #define CIO2_PBM_ARB_CTRL_LE_EN                                BIT(7)
-#define CIO2_PBM_ARB_CTRL_PLL_POST_SHTDN               2
-#define CIO2_PBM_ARB_CTRL_PLL_POST_SHTDN_SHIFT         8
-#define CIO2_PBM_ARB_CTRL_PLL_AHD_WK_UP                        480
-#define CIO2_PBM_ARB_CTRL_PLL_AHD_WK_UP_SHIFT          16
+#define CIO2_PBM_ARB_CTRL_PLL_POST_SHTDN               2U
+#define CIO2_PBM_ARB_CTRL_PLL_POST_SHTDN_SHIFT         8U
+#define CIO2_PBM_ARB_CTRL_PLL_AHD_WK_UP                        480U
+#define CIO2_PBM_ARB_CTRL_PLL_AHD_WK_UP_SHIFT          16U
 #define CIO2_REG_PBM_WMCTRL1                           0x1464
-#define CIO2_PBM_WMCTRL1_MIN_2CK_SHIFT                 0
-#define CIO2_PBM_WMCTRL1_MID1_2CK_SHIFT                        8
-#define CIO2_PBM_WMCTRL1_MID2_2CK_SHIFT                        16
+#define CIO2_PBM_WMCTRL1_MIN_2CK_SHIFT                 0U
+#define CIO2_PBM_WMCTRL1_MID1_2CK_SHIFT                        8U
+#define CIO2_PBM_WMCTRL1_MID2_2CK_SHIFT                        16U
 #define CIO2_PBM_WMCTRL1_TS_COUNT_DISABLE              BIT(31)
 #define CIO2_PBM_WMCTRL1_MIN_2CK       (4 << CIO2_PBM_WMCTRL1_MIN_2CK_SHIFT)
 #define CIO2_PBM_WMCTRL1_MID1_2CK      (16 << CIO2_PBM_WMCTRL1_MID1_2CK_SHIFT)
 #define CIO2_PBM_WMCTRL1_MID2_2CK      (21 << CIO2_PBM_WMCTRL1_MID2_2CK_SHIFT)
 #define CIO2_REG_PBM_WMCTRL2                           0x1468
-#define CIO2_PBM_WMCTRL2_HWM_2CK                       40
-#define CIO2_PBM_WMCTRL2_HWM_2CK_SHIFT                 0
-#define CIO2_PBM_WMCTRL2_LWM_2CK                       22
-#define CIO2_PBM_WMCTRL2_LWM_2CK_SHIFT                 8
-#define CIO2_PBM_WMCTRL2_OBFFWM_2CK                    2
-#define CIO2_PBM_WMCTRL2_OBFFWM_2CK_SHIFT              16
-#define CIO2_PBM_WMCTRL2_TRANSDYN                      1
-#define CIO2_PBM_WMCTRL2_TRANSDYN_SHIFT                        24
+#define CIO2_PBM_WMCTRL2_HWM_2CK                       40U
+#define CIO2_PBM_WMCTRL2_HWM_2CK_SHIFT                 0U
+#define CIO2_PBM_WMCTRL2_LWM_2CK                       22U
+#define CIO2_PBM_WMCTRL2_LWM_2CK_SHIFT                 8U
+#define CIO2_PBM_WMCTRL2_OBFFWM_2CK                    2U
+#define CIO2_PBM_WMCTRL2_OBFFWM_2CK_SHIFT              16U
+#define CIO2_PBM_WMCTRL2_TRANSDYN                      1U
+#define CIO2_PBM_WMCTRL2_TRANSDYN_SHIFT                        24U
 #define CIO2_PBM_WMCTRL2_DYNWMEN                       BIT(28)
 #define CIO2_PBM_WMCTRL2_OBFF_MEM_EN                   BIT(29)
 #define CIO2_PBM_WMCTRL2_OBFF_CPU_EN                   BIT(30)
 #define CIO2_REG_PBM_TS_COUNT                          0x146c
 #define CIO2_REG_PBM_FOPN_ABORT                                0x1474
 /* below n = 0..3 */
-#define CIO2_PBM_FOPN_ABORT(n)                         (0x1 << 8 * (n))
-#define CIO2_PBM_FOPN_FORCE_ABORT(n)                   (0x2 << 8 * (n))
-#define CIO2_PBM_FOPN_FRAMEOPEN(n)                     (0x8 << 8 * (n))
+#define CIO2_PBM_FOPN_ABORT(n)                         (0x1 << 8U * (n))
+#define CIO2_PBM_FOPN_FORCE_ABORT(n)                   (0x2 << 8U * (n))
+#define CIO2_PBM_FOPN_FRAMEOPEN(n)                     (0x8 << 8U * (n))
 #define CIO2_REG_LTRCTRL                               0x1480
 #define CIO2_LTRCTRL_LTRDYNEN                          BIT(16)
-#define CIO2_LTRCTRL_LTRSTABLETIME_SHIFT               8
+#define CIO2_LTRCTRL_LTRSTABLETIME_SHIFT               8U
 #define CIO2_LTRCTRL_LTRSTABLETIME_MASK                        0xff
 #define CIO2_LTRCTRL_LTRSEL1S3                         BIT(7)
 #define CIO2_LTRCTRL_LTRSEL1S2                         BIT(6)
 #define CIO2_LTRCTRL_LTRSEL2S0                         BIT(0)
 #define CIO2_REG_LTRVAL23                              0x1484
 #define CIO2_REG_LTRVAL01                              0x1488
-#define CIO2_LTRVAL02_VAL_SHIFT                                0
-#define CIO2_LTRVAL02_SCALE_SHIFT                      10
-#define CIO2_LTRVAL13_VAL_SHIFT                                16
-#define CIO2_LTRVAL13_SCALE_SHIFT                      26
+#define CIO2_LTRVAL02_VAL_SHIFT                                0U
+#define CIO2_LTRVAL02_SCALE_SHIFT                      10U
+#define CIO2_LTRVAL13_VAL_SHIFT                                16U
+#define CIO2_LTRVAL13_SCALE_SHIFT                      26U
 
-#define CIO2_LTRVAL0_VAL                               175
+#define CIO2_LTRVAL0_VAL                               175U
 /* Value times 1024 ns */
-#define CIO2_LTRVAL0_SCALE                             2
-#define CIO2_LTRVAL1_VAL                               90
-#define CIO2_LTRVAL1_SCALE                             2
-#define CIO2_LTRVAL2_VAL                               90
-#define CIO2_LTRVAL2_SCALE                             2
-#define CIO2_LTRVAL3_VAL                               90
-#define CIO2_LTRVAL3_SCALE                             2
+#define CIO2_LTRVAL0_SCALE                             2U
+#define CIO2_LTRVAL1_VAL                               90U
+#define CIO2_LTRVAL1_SCALE                             2U
+#define CIO2_LTRVAL2_VAL                               90U
+#define CIO2_LTRVAL2_SCALE                             2U
+#define CIO2_LTRVAL3_VAL                               90U
+#define CIO2_LTRVAL3_SCALE                             2U
 
 #define CIO2_REG_CDMABA(n)             (0x1500 + 0x10 * (n))   /* n = 0..19 */
 #define CIO2_REG_CDMARI(n)             (0x1504 + 0x10 * (n))
-#define CIO2_CDMARI_FBPT_RP_SHIFT                      0
+#define CIO2_CDMARI_FBPT_RP_SHIFT                      0U
 #define CIO2_CDMARI_FBPT_RP_MASK                       0xff
 #define CIO2_REG_CDMAC0(n)             (0x1508 + 0x10 * (n))
-#define CIO2_CDMAC0_FBPT_LEN_SHIFT                     0
-#define CIO2_CDMAC0_FBPT_WIDTH_SHIFT                   8
+#define CIO2_CDMAC0_FBPT_LEN_SHIFT                     0U
+#define CIO2_CDMAC0_FBPT_WIDTH_SHIFT                   8U
 #define CIO2_CDMAC0_FBPT_NS                            BIT(25)
 #define CIO2_CDMAC0_DMA_INTR_ON_FS                     BIT(26)
 #define CIO2_CDMAC0_DMA_INTR_ON_FE                     BIT(27)
 #define CIO2_CDMAC0_DMA_EN                             BIT(30)
 #define CIO2_CDMAC0_DMA_HALTED                         BIT(31)
 #define CIO2_REG_CDMAC1(n)             (0x150c + 0x10 * (n))
-#define CIO2_CDMAC1_LINENUMINT_SHIFT                   0
-#define CIO2_CDMAC1_LINENUMUPDATE_SHIFT                        16
+#define CIO2_CDMAC1_LINENUMINT_SHIFT                   0U
+#define CIO2_CDMAC1_LINENUMUPDATE_SHIFT                        16U
 /* n = 0..3 */
 #define CIO2_REG_PXM_PXF_FMT_CFG0(n)   (0x1700 + 0x30 * (n))
-#define CIO2_PXM_PXF_FMT_CFG_SID0_SHIFT                        0
-#define CIO2_PXM_PXF_FMT_CFG_SID1_SHIFT                        16
+#define CIO2_PXM_PXF_FMT_CFG_SID0_SHIFT                        0U
+#define CIO2_PXM_PXF_FMT_CFG_SID1_SHIFT                        16U
 #define CIO2_PXM_PXF_FMT_CFG_PCK_64B                   (0 << 0)
 #define CIO2_PXM_PXF_FMT_CFG_PCK_32B                   (1 << 0)
 #define CIO2_PXM_PXF_FMT_CFG_BPP_08                    (0 << 2)
 #define CIO2_PXM_PXF_FMT_CFG_PSWAP4_2ND_BD             (1 << 10)
 #define CIO2_REG_INT_STS_EXT_IE                                0x17e4
 #define CIO2_REG_INT_EN_EXT_IE                         0x17e8
-#define CIO2_INT_EXT_IE_ECC_RE(n)                      (0x01 << (8 * (n)))
-#define CIO2_INT_EXT_IE_DPHY_NR(n)                     (0x02 << (8 * (n)))
-#define CIO2_INT_EXT_IE_ECC_NR(n)                      (0x04 << (8 * (n)))
-#define CIO2_INT_EXT_IE_CRCERR(n)                      (0x08 << (8 * (n)))
-#define CIO2_INT_EXT_IE_INTERFRAMEDATA(n)              (0x10 << (8 * (n)))
-#define CIO2_INT_EXT_IE_PKT2SHORT(n)                   (0x20 << (8 * (n)))
-#define CIO2_INT_EXT_IE_PKT2LONG(n)                    (0x40 << (8 * (n)))
-#define CIO2_INT_EXT_IE_IRQ(n)                         (0x80 << (8 * (n)))
+#define CIO2_INT_EXT_IE_ECC_RE(n)                      (0x01 << (8U * (n)))
+#define CIO2_INT_EXT_IE_DPHY_NR(n)                     (0x02 << (8U * (n)))
+#define CIO2_INT_EXT_IE_ECC_NR(n)                      (0x04 << (8U * (n)))
+#define CIO2_INT_EXT_IE_CRCERR(n)                      (0x08 << (8U * (n)))
+#define CIO2_INT_EXT_IE_INTERFRAMEDATA(n)              (0x10 << (8U * (n)))
+#define CIO2_INT_EXT_IE_PKT2SHORT(n)                   (0x20 << (8U * (n)))
+#define CIO2_INT_EXT_IE_PKT2LONG(n)                    (0x40 << (8U * (n)))
+#define CIO2_INT_EXT_IE_IRQ(n)                         (0x80 << (8U * (n)))
 #define CIO2_REG_PXM_FRF_CFG(n)                                (0x1720 + 0x30 * (n))
 #define CIO2_PXM_FRF_CFG_FNSEL                         BIT(0)
 #define CIO2_PXM_FRF_CFG_FN_RST                                BIT(1)
 #define CIO2_PXM_FRF_CFG_ABORT                         BIT(2)
-#define CIO2_PXM_FRF_CFG_CRC_TH_SHIFT                  3
+#define CIO2_PXM_FRF_CFG_CRC_TH_SHIFT                  3U
 #define CIO2_PXM_FRF_CFG_MSK_ECC_DPHY_NR               BIT(8)
 #define CIO2_PXM_FRF_CFG_MSK_ECC_RE                    BIT(9)
 #define CIO2_PXM_FRF_CFG_MSK_ECC_DPHY_NE               BIT(10)
-#define CIO2_PXM_FRF_CFG_EVEN_ODD_MODE_SHIFT           11
+#define CIO2_PXM_FRF_CFG_EVEN_ODD_MODE_SHIFT           11U
 #define CIO2_PXM_FRF_CFG_MASK_CRC_THRES                        BIT(13)
 #define CIO2_PXM_FRF_CFG_MASK_CSI_ACCEPT               BIT(14)
 #define CIO2_PXM_FRF_CFG_CIOHC_FS_MODE                 BIT(15)
-#define CIO2_PXM_FRF_CFG_CIOHC_FRST_FRM_SHIFT          16
+#define CIO2_PXM_FRF_CFG_CIOHC_FRST_FRM_SHIFT          16U
 #define CIO2_REG_PXM_SID2BID0(n)                       (0x1724 + 0x30 * (n))
 #define CIO2_FB_HPLL_FREQ                              0x2
 #define CIO2_ISCLK_RATIO                               0xc
 
 #define CIO2_INT_EN_EXT_OE_MASK                                0x8f0fffff
 
-#define CIO2_CGC_CLKGATE_HOLDOFF                       3
-#define CIO2_CGC_CSI_CLKGATE_HOLDOFF                   5
+#define CIO2_CGC_CLKGATE_HOLDOFF                       3U
+#define CIO2_CGC_CSI_CLKGATE_HOLDOFF                   5U
 
 #define CIO2_PXM_FRF_CFG_CRC_TH                                16
 
 #define CIO2_INT_EN_EXT_IE_MASK                                0xffffffff
 
-#define CIO2_DMA_CHAN                                  0
+#define CIO2_DMA_CHAN                                  0U
 
 #define CIO2_CSIRX_DLY_CNT_CLANE_IDX                   -1
 
 #define CIO2_CSIRX_DLY_CNT_TERMEN_DEFAULT              0x4
 #define CIO2_CSIRX_DLY_CNT_SETTLE_DEFAULT              0x570
 
-#define CIO2_PMCSR_OFFSET                              4
-#define CIO2_PMCSR_D0D3_SHIFT                          2
+#define CIO2_PMCSR_OFFSET                              4U
+#define CIO2_PMCSR_D0D3_SHIFT                          2U
 #define CIO2_PMCSR_D3                                  0x3
 
 struct cio2_csi2_timing {
@@ -335,6 +335,7 @@ struct cio2_queue {
 
        /* Subdev, /dev/v4l-subdevX */
        struct v4l2_subdev subdev;
+       struct mutex subdev_lock; /* Serialise acces to subdev_fmt field */
        struct media_pad subdev_pads[CIO2_PADS];
        struct v4l2_mbus_framefmt subdev_fmt;
        atomic_t frame_sequence;
index 37bd386..ce1e873 100644 (file)
@@ -33,7 +33,7 @@ static int vp3028_frontend_init(struct mantis_pci *mantis, struct dvb_frontend *
 {
        struct i2c_adapter *adapter     = &mantis->adapter;
        struct mantis_hwconfig *config  = mantis->hwconfig;
-       int err = 0;
+       int err;
 
        mantis_gpio_set_bits(mantis, config->reset, 0);
        msleep(100);
index 9a6a6b6..0f9d6b9 100644 (file)
@@ -868,8 +868,11 @@ static int buffer_activate(struct saa7134_dev *dev,
                lines_uv = dev->height >> dev->fmt->vshift;
                base2    = base + bpl * dev->height;
                base3    = base2 + bpl_uv * lines_uv;
-               if (dev->fmt->uvswap)
-                       tmp = base2, base2 = base3, base3 = tmp;
+               if (dev->fmt->uvswap) {
+                       tmp = base2;
+                       base2 = base3;
+                       base3 = tmp;
+               }
                video_dbg("uv: bpl=%ld lines=%ld base2/3=%ld/%ld\n",
                        bpl_uv,lines_uv,base2,base3);
                if (V4L2_FIELD_HAS_BOTH(dev->field)) {
@@ -1265,9 +1268,7 @@ static int saa7134_g_fmt_vid_overlay(struct file *file, void *priv,
                                struct v4l2_format *f)
 {
        struct saa7134_dev *dev = video_drvdata(file);
-       struct v4l2_clip __user *clips = f->fmt.win.clips;
        u32 clipcount = f->fmt.win.clipcount;
-       int err = 0;
        int i;
 
        if (saa7134_no_overlay > 0) {
@@ -1275,20 +1276,20 @@ static int saa7134_g_fmt_vid_overlay(struct file *file, void *priv,
                return -EINVAL;
        }
        f->fmt.win = dev->win;
-       f->fmt.win.clips = clips;
-       if (clips == NULL)
-               clipcount = 0;
+       if (!f->fmt.win.clips) {
+               f->fmt.win.clipcount = 0;
+               return 0;
+       }
        if (dev->nclips < clipcount)
                clipcount = dev->nclips;
        f->fmt.win.clipcount = clipcount;
 
-       for (i = 0; !err && i < clipcount; i++) {
-               if (copy_to_user(&f->fmt.win.clips[i].c, &dev->clips[i].c,
-                                       sizeof(struct v4l2_rect)))
-                       err = -EFAULT;
+       for (i = 0; i < clipcount; i++) {
+               memcpy(&f->fmt.win.clips[i].c, &dev->clips[i].c,
+                      sizeof(struct v4l2_rect));
        }
 
-       return err;
+       return 0;
 }
 
 static int saa7134_try_fmt_vid_cap(struct file *file, void *priv,
@@ -1396,9 +1397,8 @@ static int saa7134_s_fmt_vid_overlay(struct file *file, void *priv,
        dev->win    = f->fmt.win;
        dev->nclips = f->fmt.win.clipcount;
 
-       if (copy_from_user(dev->clips, f->fmt.win.clips,
-                          sizeof(struct v4l2_clip) * dev->nclips))
-               return -EFAULT;
+       memcpy(dev->clips, f->fmt.win.clips,
+              sizeof(struct v4l2_clip) * dev->nclips);
 
        if (priv == dev->overlay_owner) {
                spin_lock_irqsave(&dev->slock, flags);
index 6c08b77..f3a4e57 100644 (file)
@@ -1139,32 +1139,21 @@ static int saa7164_seq_show(struct seq_file *m, void *v)
        return 0;
 }
 
-static const struct seq_operations saa7164_seq_ops = {
+static const struct seq_operations saa7164_sops = {
        .start = saa7164_seq_start,
        .next = saa7164_seq_next,
        .stop = saa7164_seq_stop,
        .show = saa7164_seq_show,
 };
 
-static int saa7164_open(struct inode *inode, struct file *file)
-{
-       return seq_open(file, &saa7164_seq_ops);
-}
-
-static const struct file_operations saa7164_operations = {
-       .owner          = THIS_MODULE,
-       .open           = saa7164_open,
-       .read           = seq_read,
-       .llseek         = seq_lseek,
-       .release        = seq_release,
-};
+DEFINE_SEQ_ATTRIBUTE(saa7164);
 
 static struct dentry *saa7614_dentry;
 
 static void __init saa7164_debugfs_create(void)
 {
        saa7614_dentry = debugfs_create_file("saa7164", 0444, NULL, NULL,
-                                            &saa7164_operations);
+                                            &saa7164_fops);
 }
 
 static void __exit saa7164_debugfs_remove(void)
index 906ce86..d137b94 100644 (file)
@@ -385,7 +385,7 @@ int solo_g723_init(struct solo_dev *solo_dev)
 
        ret = snd_ctl_add(card, snd_ctl_new1(&kctl, solo_dev));
        if (ret < 0)
-               return ret;
+               goto snd_error;
 
        ret = solo_snd_pcm_init(solo_dev);
        if (ret < 0)
index 7e152bb..ffffef2 100644 (file)
@@ -147,6 +147,24 @@ config VIDEO_RENESAS_CEU
        help
          This is a v4l2 driver for the Renesas CEU Interface
 
+config VIDEO_ROCKCHIP_ISP1
+       tristate "Rockchip Image Signal Processing v1 Unit driver"
+       depends on VIDEO_V4L2 && OF
+       depends on ARCH_ROCKCHIP || COMPILE_TEST
+       select MEDIA_CONTROLLER
+       select VIDEO_V4L2_SUBDEV_API
+       select VIDEOBUF2_DMA_CONTIG
+       select VIDEOBUF2_VMALLOC
+       select V4L2_FWNODE
+       select GENERIC_PHY_MIPI_DPHY
+       default n
+       help
+         Enable this to support the Image Signal Processing (ISP) module
+         present in RK3399 SoCs.
+
+         To compile this driver as a module, choose M here: the module
+         will be called rockchip-isp1.
+
 source "drivers/media/platform/exynos4-is/Kconfig"
 source "drivers/media/platform/am437x/Kconfig"
 source "drivers/media/platform/xilinx/Kconfig"
index 62b6cdc..b342714 100644 (file)
@@ -52,6 +52,7 @@ obj-$(CONFIG_VIDEO_RENESAS_FDP1)      += rcar_fdp1.o
 obj-$(CONFIG_VIDEO_RENESAS_JPU)                += rcar_jpu.o
 obj-$(CONFIG_VIDEO_RENESAS_VSP1)       += vsp1/
 
+obj-$(CONFIG_VIDEO_ROCKCHIP_ISP1)      += rockchip/rkisp1/
 obj-$(CONFIG_VIDEO_ROCKCHIP_RGA)       += rockchip/rga/
 
 obj-y  += omap/
index bf75927..2f42808 100644 (file)
@@ -13,6 +13,7 @@
 #include <linux/kernel.h>
 #include <linux/log2.h>
 #include <linux/platform_device.h>
+#include <linux/ratelimit.h>
 #include <linux/reset.h>
 #include <linux/slab.h>
 #include <linux/videodev2.h>
@@ -293,12 +294,11 @@ static bool coda_bitstream_try_queue(struct coda_ctx *ctx,
                        coda_dbg(1, ctx,
                                 "could not parse header, sequence initialization might fail\n");
                }
-       }
 
-       /* Add padding before the first buffer, if it is too small */
-       if (ctx->qsequence == 0 && payload < 512 &&
-           ctx->codec->src_fourcc == V4L2_PIX_FMT_H264)
-               coda_h264_bitstream_pad(ctx, 512 - payload);
+               /* Add padding before the first buffer, if it is too small */
+               if (ctx->codec->src_fourcc == V4L2_PIX_FMT_H264)
+                       coda_h264_bitstream_pad(ctx, 512 - payload);
+       }
 
        ret = coda_bitstream_queue(ctx, vaddr, payload);
        if (ret < 0) {
@@ -1837,6 +1837,29 @@ static bool coda_reorder_enable(struct coda_ctx *ctx)
        return profile > V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE;
 }
 
+static void coda_decoder_drop_used_metas(struct coda_ctx *ctx)
+{
+       struct coda_buffer_meta *meta, *tmp;
+
+       /*
+        * All metas that end at or before the RD pointer (fifo out),
+        * are now consumed by the VPU and should be released.
+        */
+       spin_lock(&ctx->buffer_meta_lock);
+       list_for_each_entry_safe(meta, tmp, &ctx->buffer_meta_list, list) {
+               if (ctx->bitstream_fifo.kfifo.out >= meta->end) {
+                       coda_dbg(2, ctx, "releasing meta: seq=%d start=%d end=%d\n",
+                                meta->sequence, meta->start, meta->end);
+
+                       list_del(&meta->list);
+                       ctx->num_metas--;
+                       ctx->first_frame_sequence++;
+                       kfree(meta);
+               }
+       }
+       spin_unlock(&ctx->buffer_meta_lock);
+}
+
 static int __coda_decoder_seq_init(struct coda_ctx *ctx)
 {
        struct coda_q_data *q_data_src, *q_data_dst;
@@ -1922,10 +1945,17 @@ static int __coda_decoder_seq_init(struct coda_ctx *ctx)
        }
        ctx->sequence_offset = ~0U;
        ctx->initialized = 1;
+       ctx->first_frame_sequence = 0;
 
        /* Update kfifo out pointer from coda bitstream read pointer */
        coda_kfifo_sync_from_device(ctx);
 
+       /*
+        * After updating the read pointer, we need to check if
+        * any metas are consumed and should be released.
+        */
+       coda_decoder_drop_used_metas(ctx);
+
        if (coda_read(dev, CODA_RET_DEC_SEQ_SUCCESS) == 0) {
                v4l2_err(&dev->v4l2_dev,
                        "CODA_COMMAND_SEQ_INIT failed, error code = 0x%x\n",
@@ -2005,21 +2035,13 @@ static void coda_dec_seq_init_work(struct work_struct *work)
        struct coda_ctx *ctx = container_of(work,
                                            struct coda_ctx, seq_init_work);
        struct coda_dev *dev = ctx->dev;
-       int ret;
 
        mutex_lock(&ctx->buffer_mutex);
        mutex_lock(&dev->coda_mutex);
 
-       if (ctx->initialized == 1)
-               goto out;
-
-       ret = __coda_decoder_seq_init(ctx);
-       if (ret < 0)
-               goto out;
-
-       ctx->initialized = 1;
+       if (!ctx->initialized)
+               __coda_decoder_seq_init(ctx);
 
-out:
        mutex_unlock(&dev->coda_mutex);
        mutex_unlock(&ctx->buffer_mutex);
 }
@@ -2348,9 +2370,12 @@ static void coda_finish_decode(struct coda_ctx *ctx)
        }
 
        err_mb = coda_read(dev, CODA_RET_DEC_PIC_ERR_MB);
-       if (err_mb > 0)
-               v4l2_err(&dev->v4l2_dev,
-                        "errors in %d macroblocks\n", err_mb);
+       if (err_mb > 0) {
+               if (__ratelimit(&dev->mb_err_rs))
+                       coda_dbg(1, ctx, "errors in %d macroblocks\n", err_mb);
+               v4l2_ctrl_s_ctrl(ctx->mb_err_cnt_ctrl,
+                                v4l2_ctrl_g_ctrl(ctx->mb_err_cnt_ctrl) + err_mb);
+       }
 
        if (dev->devtype->product == CODA_HX4 ||
            dev->devtype->product == CODA_7541) {
@@ -2404,12 +2429,16 @@ static void coda_finish_decode(struct coda_ctx *ctx)
                v4l2_err(&dev->v4l2_dev,
                         "decoded frame index out of range: %d\n", decoded_idx);
        } else {
+               int sequence;
+
                decoded_frame = &ctx->internal_frames[decoded_idx];
 
                val = coda_read(dev, CODA_RET_DEC_PIC_FRAME_NUM);
                if (ctx->sequence_offset == -1)
                        ctx->sequence_offset = val;
-               val -= ctx->sequence_offset;
+
+               sequence = val + ctx->first_frame_sequence
+                              - ctx->sequence_offset;
                spin_lock(&ctx->buffer_meta_lock);
                if (!list_empty(&ctx->buffer_meta_list)) {
                        meta = list_first_entry(&ctx->buffer_meta_list,
@@ -2424,10 +2453,10 @@ static void coda_finish_decode(struct coda_ctx *ctx)
                         * should be enough to detect most errors and saves us
                         * from doing different things based on the format.
                         */
-                       if ((val & 0xffff) != (meta->sequence & 0xffff)) {
+                       if ((sequence & 0xffff) != (meta->sequence & 0xffff)) {
                                v4l2_err(&dev->v4l2_dev,
                                         "sequence number mismatch (%d(%d) != %d)\n",
-                                        val, ctx->sequence_offset,
+                                        sequence, ctx->sequence_offset,
                                         meta->sequence);
                        }
                        decoded_frame->meta = *meta;
@@ -2437,7 +2466,7 @@ static void coda_finish_decode(struct coda_ctx *ctx)
                        v4l2_err(&dev->v4l2_dev, "empty timestamp list!\n");
                        memset(&decoded_frame->meta, 0,
                               sizeof(struct coda_buffer_meta));
-                       decoded_frame->meta.sequence = val;
+                       decoded_frame->meta.sequence = sequence;
                        decoded_frame->meta.last = false;
                        ctx->sequence_offset++;
                }
index 87a2c70..d30eafe 100644 (file)
@@ -26,6 +26,7 @@
 #include <linux/videodev2.h>
 #include <linux/of.h>
 #include <linux/platform_data/media/coda.h>
+#include <linux/ratelimit.h>
 #include <linux/reset.h>
 
 #include <media/v4l2-ctrls.h>
@@ -172,7 +173,7 @@ struct coda_video_device {
 };
 
 static const struct coda_video_device coda_bit_encoder = {
-       .name = "coda-encoder",
+       .name = "coda-video-encoder",
        .type = CODA_INST_ENCODER,
        .ops = &coda_bit_encode_ops,
        .src_formats = {
@@ -202,7 +203,7 @@ static const struct coda_video_device coda_bit_jpeg_encoder = {
 };
 
 static const struct coda_video_device coda_bit_decoder = {
-       .name = "coda-decoder",
+       .name = "coda-video-decoder",
        .type = CODA_INST_DECODER,
        .ops = &coda_bit_decode_ops,
        .src_formats = {
@@ -2062,6 +2063,7 @@ static int coda_start_streaming(struct vb2_queue *q, unsigned int count)
        if (q_data_dst->fourcc == V4L2_PIX_FMT_JPEG)
                ctx->params.gop_size = 1;
        ctx->gopcounter = ctx->params.gop_size - 1;
+       v4l2_ctrl_s_ctrl(ctx->mb_err_cnt_ctrl, 0);
 
        ret = ctx->ops->start_streaming(ctx);
        if (ctx->inst_type == CODA_INST_DECODER) {
@@ -2462,6 +2464,15 @@ static void coda_decode_ctrls(struct coda_ctx *ctx)
                ctx->mpeg4_level_ctrl->flags |= V4L2_CTRL_FLAG_READ_ONLY;
 }
 
+static const struct v4l2_ctrl_config coda_mb_err_cnt_ctrl_config = {
+       .id     = V4L2_CID_CODA_MB_ERR_CNT,
+       .name   = "Macroblocks Error Count",
+       .type   = V4L2_CTRL_TYPE_INTEGER,
+       .min    = 0,
+       .max    = 0x7fffffff,
+       .step   = 1,
+};
+
 static int coda_ctrls_setup(struct coda_ctx *ctx)
 {
        v4l2_ctrl_handler_init(&ctx->ctrls, 2);
@@ -2484,6 +2495,12 @@ static int coda_ctrls_setup(struct coda_ctx *ctx)
                                  1, 1, 1, 1);
                if (ctx->cvd->src_formats[0] == V4L2_PIX_FMT_H264)
                        coda_decode_ctrls(ctx);
+
+               ctx->mb_err_cnt_ctrl = v4l2_ctrl_new_custom(&ctx->ctrls,
+                                               &coda_mb_err_cnt_ctrl_config,
+                                               NULL);
+               if (ctx->mb_err_cnt_ctrl)
+                       ctx->mb_err_cnt_ctrl->flags |= V4L2_CTRL_FLAG_READ_ONLY;
        }
 
        if (ctx->ctrls.error) {
@@ -2851,17 +2868,17 @@ err_clk_per:
 static int coda_register_device(struct coda_dev *dev, int i)
 {
        struct video_device *vfd = &dev->vfd[i];
-       enum coda_inst_type type;
+       const char *name;
        int ret;
 
        if (i >= dev->devtype->num_vdevs)
                return -EINVAL;
-       type = dev->devtype->vdevs[i]->type;
+       name = dev->devtype->vdevs[i]->name;
 
        strscpy(vfd->name, dev->devtype->vdevs[i]->name, sizeof(vfd->name));
        vfd->fops       = &coda_fops;
        vfd->ioctl_ops  = &coda_ioctl_ops;
-       vfd->release    = video_device_release_empty,
+       vfd->release    = video_device_release_empty;
        vfd->lock       = &dev->dev_mutex;
        vfd->v4l2_dev   = &dev->v4l2_dev;
        vfd->vfl_dir    = VFL_DIR_M2M;
@@ -2876,8 +2893,7 @@ static int coda_register_device(struct coda_dev *dev, int i)
        ret = video_register_device(vfd, VFL_TYPE_VIDEO, 0);
        if (!ret)
                v4l2_info(&dev->v4l2_dev, "%s registered as %s\n",
-                         type == CODA_INST_ENCODER ? "encoder" : "decoder",
-                         video_device_node_name(vfd));
+                         name, video_device_node_name(vfd));
        return ret;
 }
 
@@ -3154,7 +3170,7 @@ static int coda_probe(struct platform_device *pdev)
                return irq;
 
        ret = devm_request_irq(&pdev->dev, irq, coda_irq_handler, 0,
-                              dev_name(&pdev->dev), dev);
+                              CODA_NAME "-video", dev);
        if (ret < 0) {
                dev_err(&pdev->dev, "failed to request irq: %d\n", ret);
                return ret;
@@ -3168,7 +3184,7 @@ static int coda_probe(struct platform_device *pdev)
 
                ret = devm_request_threaded_irq(&pdev->dev, irq, NULL,
                                                coda9_jpeg_irq_handler,
-                                               IRQF_ONESHOT, CODA_NAME " jpeg",
+                                               IRQF_ONESHOT, CODA_NAME "-jpeg",
                                                dev);
                if (ret < 0) {
                        dev_err(&pdev->dev, "failed to request jpeg irq\n");
@@ -3203,6 +3219,7 @@ static int coda_probe(struct platform_device *pdev)
        if (ret)
                return ret;
 
+       ratelimit_default_init(&dev->mb_err_rs);
        mutex_init(&dev->dev_mutex);
        mutex_init(&dev->coda_mutex);
        ida_init(&dev->ida);
index b81f3ac..dcf3564 100644 (file)
@@ -17,6 +17,7 @@
 #include <linux/mutex.h>
 #include <linux/kfifo.h>
 #include <linux/videodev2.h>
+#include <linux/ratelimit.h>
 
 #include <media/v4l2-ctrls.h>
 #include <media/v4l2-device.h>
 #define CODA_MAX_FRAMEBUFFERS  19
 #define FMO_SLICE_SAVE_BUF_SIZE        (32)
 
+/*
+ * This control allows applications to read the per-stream
+ * (i.e. per-context) Macroblocks Error Count. This value
+ * is CODA specific.
+ */
+#define V4L2_CID_CODA_MB_ERR_CNT (V4L2_CID_USER_CODA_BASE + 0)
+
 enum {
        V4L2_M2M_SRC = 0,
        V4L2_M2M_DST = 1,
@@ -92,6 +100,7 @@ struct coda_dev {
        struct v4l2_m2m_dev     *m2m_dev;
        struct ida              ida;
        struct dentry           *debugfs_root;
+       struct ratelimit_state  mb_err_rs;
 };
 
 struct coda_codec {
@@ -242,6 +251,7 @@ struct coda_ctx {
        struct v4l2_ctrl                *mpeg2_level_ctrl;
        struct v4l2_ctrl                *mpeg4_profile_ctrl;
        struct v4l2_ctrl                *mpeg4_level_ctrl;
+       struct v4l2_ctrl                *mb_err_cnt_ctrl;
        struct v4l2_fh                  fh;
        int                             gopcounter;
        int                             runcounter;
@@ -259,6 +269,7 @@ struct coda_ctx {
        struct list_head                buffer_meta_list;
        spinlock_t                      buffer_meta_lock;
        int                             num_metas;
+       unsigned int                    first_frame_sequence;
        struct coda_aux_buf             workbuf;
        int                             num_internal_frames;
        int                             idx;
index c98edb6..c53cecd 100644 (file)
@@ -1075,10 +1075,14 @@ fail_base_iomap:
        release_mem_region(res->start, resource_size(res));
        i--;
 fail_nobase_res:
-       if (isif_cfg.base_addr)
+       if (isif_cfg.base_addr) {
                iounmap(isif_cfg.base_addr);
-       if (isif_cfg.linear_tbl0_addr)
+               isif_cfg.base_addr = NULL;
+       }
+       if (isif_cfg.linear_tbl0_addr) {
                iounmap(isif_cfg.linear_tbl0_addr);
+               isif_cfg.linear_tbl0_addr = NULL;
+       }
 
        while (i >= 0) {
                res = platform_get_resource(pdev, IORESOURCE_MEM, i);
@@ -1096,8 +1100,11 @@ static int isif_remove(struct platform_device *pdev)
        int i = 0;
 
        iounmap(isif_cfg.base_addr);
+       isif_cfg.base_addr = NULL;
        iounmap(isif_cfg.linear_tbl0_addr);
+       isif_cfg.linear_tbl0_addr = NULL;
        iounmap(isif_cfg.linear_tbl1_addr);
+       isif_cfg.linear_tbl1_addr = NULL;
        while (i < 3) {
                res = platform_get_resource(pdev, IORESOURCE_MEM, i);
                if (res)
index 08d1f39..db6e548 100644 (file)
@@ -214,11 +214,13 @@ static int fimc_get_scaler_factor(u32 src, u32 tar, u32 *ratio, u32 *shift)
        while (sh--) {
                u32 tmp = 1 << sh;
                if (src >= tar * tmp) {
-                       *shift = sh, *ratio = tmp;
+                       *shift = sh;
+                       *ratio = tmp;
                        return 0;
                }
        }
-       *shift = 0, *ratio = 1;
+       *shift = 0;
+       *ratio = 1;
        return 0;
 }
 
index 4f2a0f9..ff62530 100644 (file)
@@ -381,8 +381,6 @@ static void free_buffer(struct videobuf_queue *vq, struct viu_buf *buf)
        struct videobuf_buffer *vb = &buf->vb;
        void *vaddr = NULL;
 
-       BUG_ON(in_interrupt());
-
        videobuf_waiton(vq, &buf->vb, 0, 0);
 
        if (vq->int_ops && vq->int_ops->vaddr)
index 63fce1b..032fddd 100644 (file)
@@ -307,8 +307,7 @@ static int mmpcam_platform_remove(struct platform_device *pdev)
  * Suspend/resume support.
  */
 
-#ifdef CONFIG_PM
-static int mmpcam_runtime_resume(struct device *dev)
+static int __maybe_unused mmpcam_runtime_resume(struct device *dev)
 {
        struct mmp_camera *cam = dev_get_drvdata(dev);
        struct mcam_camera *mcam = &cam->mcam;
@@ -322,7 +321,7 @@ static int mmpcam_runtime_resume(struct device *dev)
        return 0;
 }
 
-static int mmpcam_runtime_suspend(struct device *dev)
+static int __maybe_unused mmpcam_runtime_suspend(struct device *dev)
 {
        struct mmp_camera *cam = dev_get_drvdata(dev);
        struct mcam_camera *mcam = &cam->mcam;
@@ -353,7 +352,6 @@ static int __maybe_unused mmpcam_resume(struct device *dev)
                return mccic_resume(&cam->mcam);
        return 0;
 }
-#endif
 
 static const struct dev_pm_ops mmpcam_pm_ops = {
        SET_RUNTIME_PM_OPS(mmpcam_runtime_suspend, mmpcam_runtime_resume, NULL)
index 227245c..88a23bc 100644 (file)
@@ -1306,6 +1306,7 @@ static int mtk_jpeg_clk_init(struct mtk_jpeg_dev *jpeg)
                                jpeg->variant->clks);
        if (ret) {
                dev_err(&pdev->dev, "failed to get jpeg clock:%d\n", ret);
+               put_device(&pdev->dev);
                return ret;
        }
 
@@ -1331,6 +1332,12 @@ static void mtk_jpeg_job_timeout_work(struct work_struct *work)
        v4l2_m2m_buf_done(dst_buf, VB2_BUF_STATE_ERROR);
        v4l2_m2m_job_finish(jpeg->m2m_dev, ctx->fh.m2m_ctx);
 }
+
+static inline void mtk_jpeg_clk_release(struct mtk_jpeg_dev *jpeg)
+{
+       put_device(jpeg->larb);
+}
+
 static int mtk_jpeg_probe(struct platform_device *pdev)
 {
        struct mtk_jpeg_dev *jpeg;
@@ -1435,6 +1442,7 @@ err_m2m_init:
        v4l2_device_unregister(&jpeg->v4l2_dev);
 
 err_dev_register:
+       mtk_jpeg_clk_release(jpeg);
 
 err_clk_init:
 
@@ -1452,6 +1460,7 @@ static int mtk_jpeg_remove(struct platform_device *pdev)
        video_device_release(jpeg->vdev);
        v4l2_m2m_release(jpeg->m2m_dev);
        v4l2_device_unregister(&jpeg->v4l2_dev);
+       mtk_jpeg_clk_release(jpeg);
 
        return 0;
 }
index 145686d..147dfef 100644 (file)
@@ -232,14 +232,7 @@ static int mtk_vcodec_probe(struct platform_device *pdev)
                mtk_v4l2_err("Could not get vdec IPI device");
                return -ENODEV;
        }
-       if (!pdev->dev.dma_parms) {
-               pdev->dev.dma_parms = devm_kzalloc(&pdev->dev,
-                                               sizeof(*pdev->dev.dma_parms),
-                                               GFP_KERNEL);
-               if (!pdev->dev.dma_parms)
-                       return -ENOMEM;
-       }
-       dma_set_max_seg_size(&pdev->dev, DMA_BIT_MASK(32));
+       dma_set_max_seg_size(&pdev->dev, UINT_MAX);
 
        dev->fw_handler = mtk_vcodec_fw_select(dev, fw_type, DECODER);
        if (IS_ERR(dev->fw_handler))
index 36dfe3f..ddee704 100644 (file)
@@ -47,11 +47,14 @@ int mtk_vcodec_init_dec_pm(struct mtk_vcodec_dev *mtkdev)
                dec_clk->clk_info = devm_kcalloc(&pdev->dev,
                        dec_clk->clk_num, sizeof(*clk_info),
                        GFP_KERNEL);
-               if (!dec_clk->clk_info)
-                       return -ENOMEM;
+               if (!dec_clk->clk_info) {
+                       ret = -ENOMEM;
+                       goto put_device;
+               }
        } else {
                mtk_v4l2_err("Failed to get vdec clock count");
-               return -EINVAL;
+               ret = -EINVAL;
+               goto put_device;
        }
 
        for (i = 0; i < dec_clk->clk_num; i++) {
@@ -60,25 +63,29 @@ int mtk_vcodec_init_dec_pm(struct mtk_vcodec_dev *mtkdev)
                        "clock-names", i, &clk_info->clk_name);
                if (ret) {
                        mtk_v4l2_err("Failed to get clock name id = %d", i);
-                       return ret;
+                       goto put_device;
                }
                clk_info->vcodec_clk = devm_clk_get(&pdev->dev,
                        clk_info->clk_name);
                if (IS_ERR(clk_info->vcodec_clk)) {
                        mtk_v4l2_err("devm_clk_get (%d)%s fail", i,
                                clk_info->clk_name);
-                       return PTR_ERR(clk_info->vcodec_clk);
+                       ret = PTR_ERR(clk_info->vcodec_clk);
+                       goto put_device;
                }
        }
 
        pm_runtime_enable(&pdev->dev);
-
+       return 0;
+put_device:
+       put_device(pm->larbvdec);
        return ret;
 }
 
 void mtk_vcodec_release_dec_pm(struct mtk_vcodec_dev *dev)
 {
        pm_runtime_disable(dev->pm.dev);
+       put_device(dev->pm.larbvdec);
 }
 
 void mtk_vcodec_dec_pw_on(struct mtk_vcodec_pm *pm)
index 3be8a04..dfb42e1 100644 (file)
@@ -284,14 +284,7 @@ static int mtk_vcodec_probe(struct platform_device *pdev)
                mtk_v4l2_err("Could not get venc IPI device");
                return -ENODEV;
        }
-       if (!pdev->dev.dma_parms) {
-               pdev->dev.dma_parms = devm_kzalloc(&pdev->dev,
-                                               sizeof(*pdev->dev.dma_parms),
-                                               GFP_KERNEL);
-               if (!pdev->dev.dma_parms)
-                       return -ENOMEM;
-       }
-       dma_set_max_seg_size(&pdev->dev, DMA_BIT_MASK(32));
+       dma_set_max_seg_size(&pdev->dev, UINT_MAX);
 
        dev->fw_handler = mtk_vcodec_fw_select(dev, fw_type, ENCODER);
        if (IS_ERR(dev->fw_handler))
index ee22902..3b7c54d 100644 (file)
@@ -47,14 +47,16 @@ int mtk_vcodec_init_enc_pm(struct mtk_vcodec_dev *mtkdev)
        node = of_parse_phandle(dev->of_node, "mediatek,larb", 1);
        if (!node) {
                mtk_v4l2_err("no mediatek,larb found");
-               return -ENODEV;
+               ret = -ENODEV;
+               goto put_larbvenc;
        }
 
        pdev = of_find_device_by_node(node);
        of_node_put(node);
        if (!pdev) {
                mtk_v4l2_err("no mediatek,larb device found");
-               return -ENODEV;
+               ret = -ENODEV;
+               goto put_larbvenc;
        }
 
        pm->larbvenclt = &pdev->dev;
@@ -67,11 +69,14 @@ int mtk_vcodec_init_enc_pm(struct mtk_vcodec_dev *mtkdev)
                enc_clk->clk_info = devm_kcalloc(&pdev->dev,
                        enc_clk->clk_num, sizeof(*clk_info),
                        GFP_KERNEL);
-               if (!enc_clk->clk_info)
-                       return -ENOMEM;
+               if (!enc_clk->clk_info) {
+                       ret = -ENOMEM;
+                       goto put_larbvenclt;
+               }
        } else {
                mtk_v4l2_err("Failed to get venc clock count");
-               return -EINVAL;
+               ret = -EINVAL;
+               goto put_larbvenclt;
        }
 
        for (i = 0; i < enc_clk->clk_num; i++) {
@@ -80,22 +85,31 @@ int mtk_vcodec_init_enc_pm(struct mtk_vcodec_dev *mtkdev)
                        "clock-names", i, &clk_info->clk_name);
                if (ret) {
                        mtk_v4l2_err("venc failed to get clk name %d", i);
-                       return ret;
+                       goto put_larbvenclt;
                }
                clk_info->vcodec_clk = devm_clk_get(&pdev->dev,
                        clk_info->clk_name);
                if (IS_ERR(clk_info->vcodec_clk)) {
                        mtk_v4l2_err("venc devm_clk_get (%d)%s fail", i,
                                clk_info->clk_name);
-                       return PTR_ERR(clk_info->vcodec_clk);
+                       ret = PTR_ERR(clk_info->vcodec_clk);
+                       goto put_larbvenclt;
                }
        }
 
+       return 0;
+
+put_larbvenclt:
+       put_device(pm->larbvenclt);
+put_larbvenc:
+       put_device(pm->larbvenc);
        return ret;
 }
 
 void mtk_vcodec_release_enc_pm(struct mtk_vcodec_dev *mtkdev)
 {
+       put_device(mtkdev->pm.larbvenclt);
+       put_device(mtkdev->pm.larbvenc);
 }
 
 
index e47520f..b664ce7 100644 (file)
@@ -1256,7 +1256,7 @@ static void pxa_camera_setup_cicr(struct pxa_camera_dev *pcdev,
                 * transformation. Note that UYVY is the only format that
                 * should be used if pxa framebuffer Overlay2 is used.
                 */
-               /* fall through */
+               fallthrough;
        case V4L2_PIX_FMT_UYVY:
        case V4L2_PIX_FMT_VYUY:
        case V4L2_PIX_FMT_YUYV:
@@ -1667,7 +1667,7 @@ static int pxa_camera_get_formats(struct v4l2_device *v4l2_dev,
                                "Providing format %s using code %d\n",
                                pxa_camera_formats[0].name, code.code);
                }
-       /* fall through */
+               fallthrough;
        case MEDIA_BUS_FMT_VYUY8_2X8:
        case MEDIA_BUS_FMT_YUYV8_2X8:
        case MEDIA_BUS_FMT_YVYU8_2X8:
index 2ffcda0..be3fe76 100644 (file)
@@ -383,7 +383,8 @@ static u32 csid_src_pad_code(struct csid_device *csid, u32 sink_code,
                        return 0;
 
                return sink_code;
-       } else if (csid->camss->version == CAMSS_8x96) {
+       } else if (csid->camss->version == CAMSS_8x96 ||
+                  csid->camss->version == CAMSS_660) {
                switch (sink_code) {
                case MEDIA_BUS_FMT_SBGGR10_1X10:
                {
@@ -718,7 +719,8 @@ static int csid_set_stream(struct v4l2_subdev *sd, int enable)
                val |= df << CAMSS_CSID_CID_n_CFG_DECODE_FORMAT_SHIFT;
                val |= CAMSS_CSID_CID_n_CFG_RDI_MODE_RAW_DUMP;
 
-               if (csid->camss->version == CAMSS_8x96) {
+               if (csid->camss->version == CAMSS_8x96 ||
+                   csid->camss->version == CAMSS_660) {
                        u32 sink_code = csid->fmt[MSM_CSID_PAD_SINK].code;
                        u32 src_code = csid->fmt[MSM_CSID_PAD_SRC].code;
 
@@ -1098,7 +1100,8 @@ int msm_csid_subdev_init(struct camss *camss, struct csid_device *csid,
                csid->formats = csid_formats_8x16;
                csid->nformats =
                                ARRAY_SIZE(csid_formats_8x16);
-       } else if (camss->version == CAMSS_8x96) {
+       } else if (camss->version == CAMSS_8x96 ||
+                  camss->version == CAMSS_660) {
                csid->formats = csid_formats_8x96;
                csid->nformats =
                                ARRAY_SIZE(csid_formats_8x96);
index 2e65caf..97cb9de 100644 (file)
@@ -8,6 +8,7 @@
  * Copyright (C) 2016-2018 Linaro Ltd.
  */
 
+#include "camss.h"
 #include "camss-csiphy.h"
 
 #include <linux/delay.h>
@@ -21,6 +22,7 @@
 #define CSIPHY_3PH_LNn_CFG3(n)                 (0x008 + 0x100 * (n))
 #define CSIPHY_3PH_LNn_CFG4(n)                 (0x00c + 0x100 * (n))
 #define CSIPHY_3PH_LNn_CFG4_T_HS_CLK_MISS      0xa4
+#define CSIPHY_3PH_LNn_CFG4_T_HS_CLK_MISS_660  0xa5
 #define CSIPHY_3PH_LNn_CFG5(n)                 (0x010 + 0x100 * (n))
 #define CSIPHY_3PH_LNn_CFG5_T_HS_DTERM         0x02
 #define CSIPHY_3PH_LNn_CFG5_HS_REC_EQ_FQ_INT   0x50
@@ -198,7 +200,10 @@ static void csiphy_lanes_enable(struct csiphy_device *csiphy,
        val = CSIPHY_3PH_LNn_CFG1_SWI_REC_DLY_PRG;
        writel_relaxed(val, csiphy->base + CSIPHY_3PH_LNn_CFG1(l));
 
-       val = CSIPHY_3PH_LNn_CFG4_T_HS_CLK_MISS;
+       if (csiphy->camss->version == CAMSS_660)
+               val = CSIPHY_3PH_LNn_CFG4_T_HS_CLK_MISS_660;
+       else
+               val = CSIPHY_3PH_LNn_CFG4_T_HS_CLK_MISS;
        writel_relaxed(val, csiphy->base + CSIPHY_3PH_LNn_CFG4(l));
 
        val = CSIPHY_3PH_LNn_MISC1_IS_CLKLANE;
index 85b2405..509c9a5 100644 (file)
@@ -113,9 +113,7 @@ static int csiphy_set_clock_rates(struct csiphy_device *csiphy)
        for (i = 0; i < csiphy->nclocks; i++) {
                struct camss_clock *clock = &csiphy->clock[i];
 
-               if (!strcmp(clock->name, "csiphy0_timer") ||
-                   !strcmp(clock->name, "csiphy1_timer") ||
-                   !strcmp(clock->name, "csiphy2_timer")) {
+               if (csiphy->rate_set[i]) {
                        u8 bpp = csiphy_get_bpp(csiphy->formats,
                                        csiphy->nformats,
                                        csiphy->fmt[MSM_CSIPHY_PAD_SINK].code);
@@ -554,7 +552,8 @@ int msm_csiphy_subdev_init(struct camss *camss,
                csiphy->ops = &csiphy_ops_2ph_1_0;
                csiphy->formats = csiphy_formats_8x16;
                csiphy->nformats = ARRAY_SIZE(csiphy_formats_8x16);
-       } else if (camss->version == CAMSS_8x96) {
+       } else if (camss->version == CAMSS_8x96 ||
+                  camss->version == CAMSS_660) {
                csiphy->ops = &csiphy_ops_3ph_1_0;
                csiphy->formats = csiphy_formats_8x96;
                csiphy->nformats = ARRAY_SIZE(csiphy_formats_8x96);
@@ -612,6 +611,13 @@ int msm_csiphy_subdev_init(struct camss *camss,
        if (!csiphy->clock)
                return -ENOMEM;
 
+       csiphy->rate_set = devm_kcalloc(dev,
+                                       csiphy->nclocks,
+                                       sizeof(*csiphy->rate_set),
+                                       GFP_KERNEL);
+       if (!csiphy->rate_set)
+               return -ENOMEM;
+
        for (i = 0; i < csiphy->nclocks; i++) {
                struct camss_clock *clock = &csiphy->clock[i];
 
@@ -639,6 +645,17 @@ int msm_csiphy_subdev_init(struct camss *camss,
 
                for (j = 0; j < clock->nfreqs; j++)
                        clock->freq[j] = res->clock_rate[i][j];
+
+               if (!strcmp(clock->name, "csiphy0_timer") ||
+                   !strcmp(clock->name, "csiphy1_timer") ||
+                   !strcmp(clock->name, "csiphy2_timer"))
+                       csiphy->rate_set[i] = true;
+
+               if (camss->version == CAMSS_660 &&
+                   (!strcmp(clock->name, "csi0_phy") ||
+                    !strcmp(clock->name, "csi1_phy") ||
+                    !strcmp(clock->name, "csi2_phy")))
+                       csiphy->rate_set[i] = true;
        }
 
        return 0;
index 376f865..f7967ef 100644 (file)
@@ -66,6 +66,7 @@ struct csiphy_device {
        u32 irq;
        char irq_name[30];
        struct camss_clock *clock;
+       bool *rate_set;
        int nclocks;
        u32 timer_clk_rate;
        struct csiphy_config cfg;
index db94cfd..adeb928 100644 (file)
@@ -26,6 +26,7 @@
 #define MSM_ISPIF_NAME "msm_ispif"
 
 #define ISPIF_RST_CMD_0                        0x008
+#define ISPIF_RST_CMD_1                        0x00c
 #define ISPIF_RST_CMD_0_STROBED_RST_EN         (1 << 0)
 #define ISPIF_RST_CMD_0_MISC_LOGIC_RST         (1 << 1)
 #define ISPIF_RST_CMD_0_SW_REG_RST             (1 << 2)
@@ -179,7 +180,10 @@ static irqreturn_t ispif_isr_8x96(int irq, void *dev)
        writel(0x1, ispif->base + ISPIF_IRQ_GLOBAL_CLEAR_CMD);
 
        if ((value0 >> 27) & 0x1)
-               complete(&ispif->reset_complete);
+               complete(&ispif->reset_complete[0]);
+
+       if ((value3 >> 27) & 0x1)
+               complete(&ispif->reset_complete[1]);
 
        if (unlikely(value0 & ISPIF_VFE_m_IRQ_STATUS_0_PIX0_OVERFLOW))
                dev_err_ratelimited(to_device(ispif), "VFE0 pix0 overflow\n");
@@ -237,7 +241,7 @@ static irqreturn_t ispif_isr_8x16(int irq, void *dev)
        writel(0x1, ispif->base + ISPIF_IRQ_GLOBAL_CLEAR_CMD);
 
        if ((value0 >> 27) & 0x1)
-               complete(&ispif->reset_complete);
+               complete(&ispif->reset_complete[0]);
 
        if (unlikely(value0 & ISPIF_VFE_m_IRQ_STATUS_0_PIX0_OVERFLOW))
                dev_err_ratelimited(to_device(ispif), "VFE0 pix0 overflow\n");
@@ -257,33 +261,18 @@ static irqreturn_t ispif_isr_8x16(int irq, void *dev)
        return IRQ_HANDLED;
 }
 
-/*
- * ispif_reset - Trigger reset on ISPIF module and wait to complete
- * @ispif: ISPIF device
- *
- * Return 0 on success or a negative error code otherwise
- */
-static int ispif_reset(struct ispif_device *ispif)
+static int ispif_vfe_reset(struct ispif_device *ispif, u8 vfe_id)
 {
        unsigned long time;
        u32 val;
-       int ret;
-
-       ret = camss_pm_domain_on(to_camss(ispif), PM_DOMAIN_VFE0);
-       if (ret < 0)
-               return ret;
 
-       ret = camss_pm_domain_on(to_camss(ispif), PM_DOMAIN_VFE1);
-       if (ret < 0)
-               return ret;
-
-       ret = camss_enable_clocks(ispif->nclocks_for_reset,
-                                 ispif->clock_for_reset,
-                                 to_device(ispif));
-       if (ret < 0)
-               return ret;
+       if (vfe_id > (to_camss(ispif)->vfe_num - 1)) {
+               dev_err(to_device(ispif),
+                       "Error: asked reset for invalid VFE%d\n", vfe_id);
+               return -ENOENT;
+       }
 
-       reinit_completion(&ispif->reset_complete);
+       reinit_completion(&ispif->reset_complete[vfe_id]);
 
        val = ISPIF_RST_CMD_0_STROBED_RST_EN |
                ISPIF_RST_CMD_0_MISC_LOGIC_RST |
@@ -303,15 +292,50 @@ static int ispif_reset(struct ispif_device *ispif)
                ISPIF_RST_CMD_0_RDI_OUTPUT_1_MISR_RST |
                ISPIF_RST_CMD_0_RDI_OUTPUT_2_MISR_RST;
 
-       writel_relaxed(val, ispif->base + ISPIF_RST_CMD_0);
+       if (vfe_id == 1)
+               writel_relaxed(val, ispif->base + ISPIF_RST_CMD_1);
+       else
+               writel_relaxed(val, ispif->base + ISPIF_RST_CMD_0);
 
-       time = wait_for_completion_timeout(&ispif->reset_complete,
+       time = wait_for_completion_timeout(&ispif->reset_complete[vfe_id],
                msecs_to_jiffies(ISPIF_RESET_TIMEOUT_MS));
        if (!time) {
-               dev_err(to_device(ispif), "ISPIF reset timeout\n");
-               ret = -EIO;
+               dev_err(to_device(ispif),
+                       "ISPIF for VFE%d reset timeout\n", vfe_id);
+               return -EIO;
        }
 
+       return 0;
+}
+
+/*
+ * ispif_reset - Trigger reset on ISPIF module and wait to complete
+ * @ispif: ISPIF device
+ *
+ * Return 0 on success or a negative error code otherwise
+ */
+static int ispif_reset(struct ispif_device *ispif, u8 vfe_id)
+{
+       int ret;
+
+       ret = camss_pm_domain_on(to_camss(ispif), PM_DOMAIN_VFE0);
+       if (ret < 0)
+               return ret;
+
+       ret = camss_pm_domain_on(to_camss(ispif), PM_DOMAIN_VFE1);
+       if (ret < 0)
+               return ret;
+
+       ret = camss_enable_clocks(ispif->nclocks_for_reset,
+                                 ispif->clock_for_reset,
+                                 to_device(ispif));
+       if (ret < 0)
+               return ret;
+
+       ret = ispif_vfe_reset(ispif, vfe_id);
+       if (ret)
+               dev_dbg(to_device(ispif), "ISPIF Reset failed\n");
+
        camss_disable_clocks(ispif->nclocks_for_reset, ispif->clock_for_reset);
 
        camss_pm_domain_off(to_camss(ispif), PM_DOMAIN_VFE0);
@@ -355,7 +379,7 @@ static int ispif_set_power(struct v4l2_subdev *sd, int on)
                        goto exit;
                }
 
-               ret = ispif_reset(ispif);
+               ret = ispif_reset(ispif, line->vfe_id);
                if (ret < 0) {
                        pm_runtime_put_sync(dev);
                        camss_disable_clocks(ispif->nclocks, ispif->clock);
@@ -801,7 +825,8 @@ static int ispif_set_stream(struct v4l2_subdev *sd, int enable)
                ispif_select_csid(ispif, intf, csid, vfe, 1);
                ispif_select_cid(ispif, intf, cid, vfe, 1);
                ispif_config_irq(ispif, intf, vfe, 1);
-               if (to_camss(ispif)->version == CAMSS_8x96)
+               if (to_camss(ispif)->version == CAMSS_8x96 ||
+                   to_camss(ispif)->version == CAMSS_660)
                        ispif_config_pack(ispif,
                                          line->fmt[MSM_ISPIF_PAD_SINK].code,
                                          intf, cid, vfe, 1);
@@ -818,7 +843,8 @@ static int ispif_set_stream(struct v4l2_subdev *sd, int enable)
                        return ret;
 
                mutex_lock(&ispif->config_lock);
-               if (to_camss(ispif)->version == CAMSS_8x96)
+               if (to_camss(ispif)->version == CAMSS_8x96 ||
+                   to_camss(ispif)->version == CAMSS_660)
                        ispif_config_pack(ispif,
                                          line->fmt[MSM_ISPIF_PAD_SINK].code,
                                          intf, cid, vfe, 0);
@@ -1074,7 +1100,8 @@ int msm_ispif_subdev_init(struct ispif_device *ispif,
        /* Number of ISPIF lines - same as number of CSID hardware modules */
        if (to_camss(ispif)->version == CAMSS_8x16)
                ispif->line_num = 2;
-       else if (to_camss(ispif)->version == CAMSS_8x96)
+       else if (to_camss(ispif)->version == CAMSS_8x96 ||
+                to_camss(ispif)->version == CAMSS_660)
                ispif->line_num = 4;
        else
                return -EINVAL;
@@ -1092,7 +1119,8 @@ int msm_ispif_subdev_init(struct ispif_device *ispif,
                        ispif->line[i].formats = ispif_formats_8x16;
                        ispif->line[i].nformats =
                                        ARRAY_SIZE(ispif_formats_8x16);
-               } else if (to_camss(ispif)->version == CAMSS_8x96) {
+               } else if (to_camss(ispif)->version == CAMSS_8x96 ||
+                          to_camss(ispif)->version == CAMSS_660) {
                        ispif->line[i].formats = ispif_formats_8x96;
                        ispif->line[i].nformats =
                                        ARRAY_SIZE(ispif_formats_8x96);
@@ -1132,7 +1160,8 @@ int msm_ispif_subdev_init(struct ispif_device *ispif,
        if (to_camss(ispif)->version == CAMSS_8x16)
                ret = devm_request_irq(dev, ispif->irq, ispif_isr_8x16,
                               IRQF_TRIGGER_RISING, ispif->irq_name, ispif);
-       else if (to_camss(ispif)->version == CAMSS_8x96)
+       else if (to_camss(ispif)->version == CAMSS_8x96 ||
+                to_camss(ispif)->version == CAMSS_660)
                ret = devm_request_irq(dev, ispif->irq, ispif_isr_8x96,
                               IRQF_TRIGGER_RISING, ispif->irq_name, ispif);
        else
@@ -1192,7 +1221,8 @@ int msm_ispif_subdev_init(struct ispif_device *ispif,
 
        mutex_init(&ispif->config_lock);
 
-       init_completion(&ispif->reset_complete);
+       for (i = 0; i < MSM_ISPIF_VFE_NUM; i++)
+               init_completion(&ispif->reset_complete[i]);
 
        return 0;
 }
index 1a5ba24..4132174 100644 (file)
@@ -56,7 +56,7 @@ struct ispif_device {
        int nclocks;
        struct camss_clock  *clock_for_reset;
        int nclocks_for_reset;
-       struct completion reset_complete;
+       struct completion reset_complete[MSM_ISPIF_VFE_NUM];
        int power_count;
        struct mutex power_lock;
        struct ispif_intf_cmd_reg intf_cmd[MSM_ISPIF_VFE_NUM];
index 0dca8bf..b5704a2 100644 (file)
 #define VFE_0_BUS_BDG_QOS_CFG_7                0x420
 #define VFE_0_BUS_BDG_QOS_CFG_7_CFG    0x0001aaa9
 
+#define VFE48_0_BUS_BDG_QOS_CFG_0_CFG  0xaaa5aaa5
+#define VFE48_0_BUS_BDG_QOS_CFG_3_CFG  0xaa55aaa5
+#define VFE48_0_BUS_BDG_QOS_CFG_4_CFG  0xaa55aa55
+#define VFE48_0_BUS_BDG_QOS_CFG_7_CFG  0x0005aa55
+
 #define VFE_0_BUS_BDG_DS_CFG_0         0x424
 #define VFE_0_BUS_BDG_DS_CFG_0_CFG     0xcccc0011
 #define VFE_0_BUS_BDG_DS_CFG_1         0x428
 #define VFE_0_BUS_BDG_DS_CFG_16                0x464
 #define VFE_0_BUS_BDG_DS_CFG_16_CFG    0x40000103
 
+#define VFE48_0_BUS_BDG_DS_CFG_0_CFG   0xcccc1111
+#define VFE48_0_BUS_BDG_DS_CFG_16_CFG  0x00000110
+
 #define VFE_0_RDI_CFG_x(x)             (0x46c + (0x4 * (x)))
 #define VFE_0_RDI_CFG_x_RDI_STREAM_SEL_SHIFT   28
 #define VFE_0_RDI_CFG_x_RDI_STREAM_SEL_MASK    (0xf << 28)
 #define VFE_0_REALIGN_BUF_CFG_CR_ODD_PIXEL     BIT(3)
 #define VFE_0_REALIGN_BUF_CFG_HSUB_ENABLE      BIT(4)
 
+#define VFE48_0_BUS_IMAGE_MASTER_CMD           0xcec
+#define VFE48_0_BUS_IMAGE_MASTER_n_SHIFT(x)    (2 * (x))
+
 #define CAMIF_TIMEOUT_SLEEP_US 1000
 #define CAMIF_TIMEOUT_ALL_US 1000000
 
@@ -246,7 +257,7 @@ static void vfe_hw_version_read(struct vfe_device *vfe, struct device *dev)
        dev_err(dev, "VFE HW Version = 0x%08x\n", hw_version);
 }
 
-static u16 vfe_get_ub_size(u8 vfe_id)
+static u16 vfe47_get_ub_size(u8 vfe_id)
 {
        if (vfe_id == 0)
                return MSM_VFE_VFE0_UB_SIZE_RDI;
@@ -299,7 +310,7 @@ static void vfe_halt_clear(struct vfe_device *vfe)
        writel_relaxed(0x0, vfe->base + VFE_0_BUS_BDG_CMD);
 }
 
-static void vfe_wm_enable(struct vfe_device *vfe, u8 wm, u8 enable)
+static void vfe47_wm_enable(struct vfe_device *vfe, u8 wm, u8 enable)
 {
        if (enable)
                vfe_reg_set(vfe, VFE_0_BUS_IMAGE_MASTER_n_WR_CFG(wm),
@@ -883,7 +894,7 @@ static void vfe_set_clamp_cfg(struct vfe_device *vfe)
        writel_relaxed(val, vfe->base + VFE_0_CLAMP_ENC_MIN_CFG);
 }
 
-static void vfe_set_qos(struct vfe_device *vfe)
+static void vfe47_set_qos(struct vfe_device *vfe)
 {
        u32 val = VFE_0_BUS_BDG_QOS_CFG_0_CFG;
        u32 val7 = VFE_0_BUS_BDG_QOS_CFG_7_CFG;
@@ -898,7 +909,7 @@ static void vfe_set_qos(struct vfe_device *vfe)
        writel_relaxed(val7, vfe->base + VFE_0_BUS_BDG_QOS_CFG_7);
 }
 
-static void vfe_set_ds(struct vfe_device *vfe)
+static void vfe47_set_ds(struct vfe_device *vfe)
 {
        u32 val = VFE_0_BUS_BDG_DS_CFG_0_CFG;
        u32 val16 = VFE_0_BUS_BDG_DS_CFG_16_CFG;
@@ -1098,11 +1109,115 @@ static irqreturn_t vfe_isr(int irq, void *dev)
 
 const struct vfe_hw_ops vfe_ops_4_7 = {
        .hw_version_read = vfe_hw_version_read,
-       .get_ub_size = vfe_get_ub_size,
+       .get_ub_size = vfe47_get_ub_size,
+       .global_reset = vfe_global_reset,
+       .halt_request = vfe_halt_request,
+       .halt_clear = vfe_halt_clear,
+       .wm_enable = vfe47_wm_enable,
+       .wm_frame_based = vfe_wm_frame_based,
+       .wm_line_based = vfe_wm_line_based,
+       .wm_set_framedrop_period = vfe_wm_set_framedrop_period,
+       .wm_set_framedrop_pattern = vfe_wm_set_framedrop_pattern,
+       .wm_set_ub_cfg = vfe_wm_set_ub_cfg,
+       .bus_reload_wm = vfe_bus_reload_wm,
+       .wm_set_ping_addr = vfe_wm_set_ping_addr,
+       .wm_set_pong_addr = vfe_wm_set_pong_addr,
+       .wm_get_ping_pong_status = vfe_wm_get_ping_pong_status,
+       .bus_enable_wr_if = vfe_bus_enable_wr_if,
+       .bus_connect_wm_to_rdi = vfe_bus_connect_wm_to_rdi,
+       .wm_set_subsample = vfe_wm_set_subsample,
+       .bus_disconnect_wm_from_rdi = vfe_bus_disconnect_wm_from_rdi,
+       .set_xbar_cfg = vfe_set_xbar_cfg,
+       .set_realign_cfg = vfe_set_realign_cfg,
+       .set_rdi_cid = vfe_set_rdi_cid,
+       .reg_update = vfe_reg_update,
+       .reg_update_clear = vfe_reg_update_clear,
+       .enable_irq_wm_line = vfe_enable_irq_wm_line,
+       .enable_irq_pix_line = vfe_enable_irq_pix_line,
+       .enable_irq_common = vfe_enable_irq_common,
+       .set_demux_cfg = vfe_set_demux_cfg,
+       .set_scale_cfg = vfe_set_scale_cfg,
+       .set_crop_cfg = vfe_set_crop_cfg,
+       .set_clamp_cfg = vfe_set_clamp_cfg,
+       .set_qos = vfe47_set_qos,
+       .set_ds = vfe47_set_ds,
+       .set_cgc_override = vfe_set_cgc_override,
+       .set_camif_cfg = vfe_set_camif_cfg,
+       .set_camif_cmd = vfe_set_camif_cmd,
+       .set_module_cfg = vfe_set_module_cfg,
+       .camif_wait_for_stop = vfe_camif_wait_for_stop,
+       .isr_read = vfe_isr_read,
+       .violation_read = vfe_violation_read,
+       .isr = vfe_isr,
+};
+
+static u16 vfe48_get_ub_size(u8 vfe_id)
+{
+       /* On VFE4.8 the ub-size is the same on both instances */
+       return MSM_VFE_VFE0_UB_SIZE_RDI;
+}
+
+static void vfe48_wm_enable(struct vfe_device *vfe, u8 wm, u8 enable)
+{
+       if (enable)
+               writel_relaxed(2 << VFE48_0_BUS_IMAGE_MASTER_n_SHIFT(wm),
+                              vfe->base + VFE48_0_BUS_IMAGE_MASTER_CMD);
+       else
+               writel_relaxed(1 << VFE48_0_BUS_IMAGE_MASTER_n_SHIFT(wm),
+                              vfe->base + VFE48_0_BUS_IMAGE_MASTER_CMD);
+
+       /* The WM must be enabled before sending other commands */
+       wmb();
+}
+
+static void vfe48_set_qos(struct vfe_device *vfe)
+{
+       u32 val = VFE48_0_BUS_BDG_QOS_CFG_0_CFG;
+       u32 val3 = VFE48_0_BUS_BDG_QOS_CFG_3_CFG;
+       u32 val4 = VFE48_0_BUS_BDG_QOS_CFG_4_CFG;
+       u32 val7 = VFE48_0_BUS_BDG_QOS_CFG_7_CFG;
+
+       writel_relaxed(val, vfe->base + VFE_0_BUS_BDG_QOS_CFG_0);
+       writel_relaxed(val, vfe->base + VFE_0_BUS_BDG_QOS_CFG_1);
+       writel_relaxed(val, vfe->base + VFE_0_BUS_BDG_QOS_CFG_2);
+       writel_relaxed(val3, vfe->base + VFE_0_BUS_BDG_QOS_CFG_3);
+       writel_relaxed(val4, vfe->base + VFE_0_BUS_BDG_QOS_CFG_4);
+       writel_relaxed(val4, vfe->base + VFE_0_BUS_BDG_QOS_CFG_5);
+       writel_relaxed(val4, vfe->base + VFE_0_BUS_BDG_QOS_CFG_6);
+       writel_relaxed(val7, vfe->base + VFE_0_BUS_BDG_QOS_CFG_7);
+}
+
+static void vfe48_set_ds(struct vfe_device *vfe)
+{
+       u32 val = VFE48_0_BUS_BDG_DS_CFG_0_CFG;
+       u32 val16 = VFE48_0_BUS_BDG_DS_CFG_16_CFG;
+
+       writel_relaxed(val, vfe->base + VFE_0_BUS_BDG_DS_CFG_0);
+       writel_relaxed(val, vfe->base + VFE_0_BUS_BDG_DS_CFG_1);
+       writel_relaxed(val, vfe->base + VFE_0_BUS_BDG_DS_CFG_2);
+       writel_relaxed(val, vfe->base + VFE_0_BUS_BDG_DS_CFG_3);
+       writel_relaxed(val, vfe->base + VFE_0_BUS_BDG_DS_CFG_4);
+       writel_relaxed(val, vfe->base + VFE_0_BUS_BDG_DS_CFG_5);
+       writel_relaxed(val, vfe->base + VFE_0_BUS_BDG_DS_CFG_6);
+       writel_relaxed(val, vfe->base + VFE_0_BUS_BDG_DS_CFG_7);
+       writel_relaxed(val, vfe->base + VFE_0_BUS_BDG_DS_CFG_8);
+       writel_relaxed(val, vfe->base + VFE_0_BUS_BDG_DS_CFG_9);
+       writel_relaxed(val, vfe->base + VFE_0_BUS_BDG_DS_CFG_10);
+       writel_relaxed(val, vfe->base + VFE_0_BUS_BDG_DS_CFG_11);
+       writel_relaxed(val, vfe->base + VFE_0_BUS_BDG_DS_CFG_12);
+       writel_relaxed(val, vfe->base + VFE_0_BUS_BDG_DS_CFG_13);
+       writel_relaxed(val, vfe->base + VFE_0_BUS_BDG_DS_CFG_14);
+       writel_relaxed(val, vfe->base + VFE_0_BUS_BDG_DS_CFG_15);
+       writel_relaxed(val16, vfe->base + VFE_0_BUS_BDG_DS_CFG_16);
+}
+
+const struct vfe_hw_ops vfe_ops_4_8 = {
+       .hw_version_read = vfe_hw_version_read,
+       .get_ub_size = vfe48_get_ub_size,
        .global_reset = vfe_global_reset,
        .halt_request = vfe_halt_request,
        .halt_clear = vfe_halt_clear,
-       .wm_enable = vfe_wm_enable,
+       .wm_enable = vfe48_wm_enable,
        .wm_frame_based = vfe_wm_frame_based,
        .wm_line_based = vfe_wm_line_based,
        .wm_set_framedrop_period = vfe_wm_set_framedrop_period,
@@ -1128,8 +1243,8 @@ const struct vfe_hw_ops vfe_ops_4_7 = {
        .set_scale_cfg = vfe_set_scale_cfg,
        .set_crop_cfg = vfe_set_crop_cfg,
        .set_clamp_cfg = vfe_set_clamp_cfg,
-       .set_qos = vfe_set_qos,
-       .set_ds = vfe_set_ds,
+       .set_qos = vfe48_set_qos,
+       .set_ds = vfe48_set_ds,
        .set_cgc_override = vfe_set_cgc_override,
        .set_camif_cfg = vfe_set_camif_cfg,
        .set_camif_cmd = vfe_set_camif_cmd,
index b7d2293..fae2b51 100644 (file)
@@ -205,7 +205,8 @@ static u32 vfe_src_pad_code(struct vfe_line *line, u32 sink_code,
 
                        return sink_code;
                }
-       else if (vfe->camss->version == CAMSS_8x96)
+       else if (vfe->camss->version == CAMSS_8x96 ||
+                vfe->camss->version == CAMSS_660)
                switch (sink_code) {
                case MEDIA_BUS_FMT_YUYV8_2X8:
                {
@@ -1991,12 +1992,19 @@ int msm_vfe_subdev_init(struct camss *camss, struct vfe_device *vfe,
        vfe->isr_ops.comp_done = vfe_isr_comp_done;
        vfe->isr_ops.wm_done = vfe_isr_wm_done;
 
-       if (camss->version == CAMSS_8x16)
+       switch (camss->version) {
+       case CAMSS_8x16:
                vfe->ops = &vfe_ops_4_1;
-       else if (camss->version == CAMSS_8x96)
+               break;
+       case CAMSS_8x96:
                vfe->ops = &vfe_ops_4_7;
-       else
+               break;
+       case CAMSS_660:
+               vfe->ops = &vfe_ops_4_8;
+               break;
+       default:
                return -EINVAL;
+       }
 
        /* Memory */
 
@@ -2095,7 +2103,8 @@ int msm_vfe_subdev_init(struct camss *camss, struct vfe_device *vfe,
                                l->formats = formats_rdi_8x16;
                                l->nformats = ARRAY_SIZE(formats_rdi_8x16);
                        }
-               } else if (camss->version == CAMSS_8x96) {
+               } else if (camss->version == CAMSS_8x96 ||
+                          camss->version == CAMSS_660) {
                        if (i == VFE_LINE_PIX) {
                                l->formats = formats_pix_8x96;
                                l->nformats = ARRAY_SIZE(formats_pix_8x96);
index a90b0d2..5bce673 100644 (file)
@@ -180,5 +180,6 @@ void msm_vfe_get_vfe_line_id(struct media_entity *entity, enum vfe_line_id *id);
 
 extern const struct vfe_hw_ops vfe_ops_4_1;
 extern const struct vfe_hw_ops vfe_ops_4_7;
+extern const struct vfe_hw_ops vfe_ops_4_8;
 
 #endif /* QC_MSM_CAMSS_VFE_H */
index 114c3ae..fbba9e4 100644 (file)
@@ -970,7 +970,8 @@ int msm_video_register(struct camss_video *video, struct v4l2_device *v4l2_dev,
                        video->formats = formats_rdi_8x16;
                        video->nformats = ARRAY_SIZE(formats_rdi_8x16);
                }
-       } else if (video->camss->version == CAMSS_8x96) {
+       } else if (video->camss->version == CAMSS_8x96 ||
+                  video->camss->version == CAMSS_660) {
                if (is_pix) {
                        video->formats = formats_pix_8x96;
                        video->nformats = ARRAY_SIZE(formats_pix_8x96);
index 9186881..8fefce5 100644 (file)
@@ -283,6 +283,188 @@ static const struct resources vfe_res_8x96[] = {
        }
 };
 
+static const struct resources csiphy_res_660[] = {
+       /* CSIPHY0 */
+       {
+               .regulator = { NULL },
+               .clock = { "top_ahb", "ispif_ahb", "ahb", "csiphy0_timer",
+                          "csi0_phy", "csiphy_ahb2crif" },
+               .clock_rate = { { 0 },
+                               { 0 },
+                               { 0 },
+                               { 100000000, 200000000, 269333333 },
+                               { 0 } },
+               .reg = { "csiphy0", "csiphy0_clk_mux" },
+               .interrupt = { "csiphy0" }
+       },
+
+       /* CSIPHY1 */
+       {
+               .regulator = { NULL },
+               .clock = { "top_ahb", "ispif_ahb", "ahb", "csiphy1_timer",
+                          "csi1_phy", "csiphy_ahb2crif" },
+               .clock_rate = { { 0 },
+                               { 0 },
+                               { 0 },
+                               { 100000000, 200000000, 269333333 },
+                               { 0 } },
+               .reg = { "csiphy1", "csiphy1_clk_mux" },
+               .interrupt = { "csiphy1" }
+       },
+
+       /* CSIPHY2 */
+       {
+               .regulator = { NULL },
+               .clock = { "top_ahb", "ispif_ahb", "ahb", "csiphy2_timer",
+                          "csi2_phy", "csiphy_ahb2crif" },
+               .clock_rate = { { 0 },
+                               { 0 },
+                               { 0 },
+                               { 100000000, 200000000, 269333333 },
+                               { 0 } },
+               .reg = { "csiphy2", "csiphy2_clk_mux" },
+               .interrupt = { "csiphy2" }
+       }
+};
+
+static const struct resources csid_res_660[] = {
+       /* CSID0 */
+       {
+               .regulator = { "vdda", "vdd_sec" },
+               .clock = { "top_ahb", "ispif_ahb", "csi0_ahb", "ahb",
+                          "csi0", "csi0_phy", "csi0_pix", "csi0_rdi",
+                          "cphy_csid0" },
+               .clock_rate = { { 0 },
+                               { 0 },
+                               { 0 },
+                               { 0 },
+                               { 100000000, 200000000, 310000000,
+                                 404000000, 465000000 },
+                               { 0 },
+                               { 0 },
+                               { 0 },
+                               { 0 } },
+               .reg = { "csid0" },
+               .interrupt = { "csid0" }
+       },
+
+       /* CSID1 */
+       {
+               .regulator = { "vdda", "vdd_sec" },
+               .clock = { "top_ahb", "ispif_ahb", "csi1_ahb", "ahb",
+                          "csi1", "csi1_phy", "csi1_pix", "csi1_rdi",
+                          "cphy_csid1" },
+               .clock_rate = { { 0 },
+                               { 0 },
+                               { 0 },
+                               { 0 },
+                               { 100000000, 200000000, 310000000,
+                                 404000000, 465000000 },
+                               { 0 },
+                               { 0 },
+                               { 0 },
+                               { 0 } },
+               .reg = { "csid1" },
+               .interrupt = { "csid1" }
+       },
+
+       /* CSID2 */
+       {
+               .regulator = { "vdda", "vdd_sec" },
+               .clock = { "top_ahb", "ispif_ahb", "csi2_ahb", "ahb",
+                          "csi2", "csi2_phy", "csi2_pix", "csi2_rdi",
+                          "cphy_csid2" },
+               .clock_rate = { { 0 },
+                               { 0 },
+                               { 0 },
+                               { 0 },
+                               { 100000000, 200000000, 310000000,
+                                 404000000, 465000000 },
+                               { 0 },
+                               { 0 },
+                               { 0 },
+                               { 0 } },
+               .reg = { "csid2" },
+               .interrupt = { "csid2" }
+       },
+
+       /* CSID3 */
+       {
+               .regulator = { "vdda", "vdd_sec" },
+               .clock = { "top_ahb", "ispif_ahb", "csi3_ahb", "ahb",
+                          "csi3", "csi3_phy", "csi3_pix", "csi3_rdi",
+                          "cphy_csid3" },
+               .clock_rate = { { 0 },
+                               { 0 },
+                               { 0 },
+                               { 0 },
+                               { 100000000, 200000000, 310000000,
+                                 404000000, 465000000 },
+                               { 0 },
+                               { 0 },
+                               { 0 },
+                               { 0 } },
+               .reg = { "csid3" },
+               .interrupt = { "csid3" }
+       }
+};
+
+static const struct resources_ispif ispif_res_660 = {
+       /* ISPIF */
+       .clock = { "top_ahb", "ahb", "ispif_ahb",
+                  "csi0", "csi0_pix", "csi0_rdi",
+                  "csi1", "csi1_pix", "csi1_rdi",
+                  "csi2", "csi2_pix", "csi2_rdi",
+                  "csi3", "csi3_pix", "csi3_rdi" },
+       .clock_for_reset = { "vfe0", "csi_vfe0", "vfe1", "csi_vfe1" },
+       .reg = { "ispif", "csi_clk_mux" },
+       .interrupt = "ispif"
+};
+
+static const struct resources vfe_res_660[] = {
+       /* VFE0 */
+       {
+               .regulator = { NULL },
+               .clock = { "throttle_axi", "top_ahb", "ahb", "vfe0",
+                          "csi_vfe0", "vfe_ahb", "vfe0_ahb", "vfe_axi",
+                          "vfe0_stream"},
+               .clock_rate = { { 0 },
+                               { 0 },
+                               { 0 },
+                               { 120000000, 200000000, 256000000,
+                                 300000000, 404000000, 480000000,
+                                 540000000, 576000000 },
+                               { 0 },
+                               { 0 },
+                               { 0 },
+                               { 0 },
+                               { 0 } },
+               .reg = { "vfe0" },
+               .interrupt = { "vfe0" }
+       },
+
+       /* VFE1 */
+       {
+               .regulator = { NULL },
+               .clock = { "throttle_axi", "top_ahb", "ahb", "vfe1",
+                          "csi_vfe1", "vfe_ahb", "vfe1_ahb", "vfe_axi",
+                          "vfe1_stream"},
+               .clock_rate = { { 0 },
+                               { 0 },
+                               { 0 },
+                               { 120000000, 200000000, 256000000,
+                                 300000000, 404000000, 480000000,
+                                 540000000, 576000000 },
+                               { 0 },
+                               { 0 },
+                               { 0 },
+                               { 0 },
+                               { 0 } },
+               .reg = { "vfe1" },
+               .interrupt = { "vfe1" }
+       }
+};
+
 /*
  * camss_add_clock_margin - Add margin to clock frequency rate
  * @rate: Clock frequency rate
@@ -397,7 +579,8 @@ int camss_get_pixel_clock(struct media_entity *entity, u32 *pixel_clock)
 
 int camss_pm_domain_on(struct camss *camss, int id)
 {
-       if (camss->version == CAMSS_8x96) {
+       if (camss->version == CAMSS_8x96 ||
+           camss->version == CAMSS_660) {
                camss->genpd_link[id] = device_link_add(camss->dev,
                                camss->genpd[id], DL_FLAG_STATELESS |
                                DL_FLAG_PM_RUNTIME | DL_FLAG_RPM_ACTIVE);
@@ -411,7 +594,8 @@ int camss_pm_domain_on(struct camss *camss, int id)
 
 void camss_pm_domain_off(struct camss *camss, int id)
 {
-       if (camss->version == CAMSS_8x96)
+       if (camss->version == CAMSS_8x96 ||
+           camss->version == CAMSS_660)
                device_link_del(camss->genpd_link[id]);
 }
 
@@ -533,6 +717,11 @@ static int camss_init_subdevices(struct camss *camss)
                csid_res = csid_res_8x96;
                ispif_res = &ispif_res_8x96;
                vfe_res = vfe_res_8x96;
+       } else if (camss->version == CAMSS_660) {
+               csiphy_res = csiphy_res_660;
+               csid_res = csid_res_660;
+               ispif_res = &ispif_res_660;
+               vfe_res = vfe_res_660;
        } else {
                return -EINVAL;
        }
@@ -833,6 +1022,12 @@ static int camss_probe(struct platform_device *pdev)
                camss->csiphy_num = 3;
                camss->csid_num = 4;
                camss->vfe_num = 2;
+       } else if (of_device_is_compatible(dev->of_node,
+                                          "qcom,sdm660-camss")) {
+               camss->version = CAMSS_660;
+               camss->csiphy_num = 3;
+               camss->csid_num = 4;
+               camss->vfe_num = 2;
        } else {
                ret = -EINVAL;
                goto err_free;
@@ -919,7 +1114,8 @@ static int camss_probe(struct platform_device *pdev)
                }
        }
 
-       if (camss->version == CAMSS_8x96) {
+       if (camss->version == CAMSS_8x96 ||
+           camss->version == CAMSS_660) {
                camss->genpd[PM_DOMAIN_VFE0] = dev_pm_domain_attach_by_id(
                                                camss->dev, PM_DOMAIN_VFE0);
                if (IS_ERR(camss->genpd[PM_DOMAIN_VFE0]))
@@ -958,7 +1154,8 @@ void camss_delete(struct camss *camss)
 
        pm_runtime_disable(camss->dev);
 
-       if (camss->version == CAMSS_8x96) {
+       if (camss->version == CAMSS_8x96 ||
+           camss->version == CAMSS_660) {
                dev_pm_domain_detach(camss->genpd[PM_DOMAIN_VFE0], true);
                dev_pm_domain_detach(camss->genpd[PM_DOMAIN_VFE1], true);
        }
@@ -989,6 +1186,7 @@ static int camss_remove(struct platform_device *pdev)
 static const struct of_device_id camss_dt_match[] = {
        { .compatible = "qcom,msm8916-camss" },
        { .compatible = "qcom,msm8996-camss" },
+       { .compatible = "qcom,sdm660-camss" },
        { }
 };
 
index 1376b07..3a04846 100644 (file)
@@ -65,6 +65,7 @@ enum pm_domain {
 enum camss_version {
        CAMSS_8x16,
        CAMSS_8x96,
+       CAMSS_660,
 };
 
 struct camss {
index 6103aaf..bdd293f 100644 (file)
@@ -345,6 +345,14 @@ static int venus_remove(struct platform_device *pdev)
        return ret;
 }
 
+static void venus_core_shutdown(struct platform_device *pdev)
+{
+       struct venus_core *core = platform_get_drvdata(pdev);
+
+       venus_shutdown(core);
+       venus_firmware_deinit(core);
+}
+
 static __maybe_unused int venus_runtime_suspend(struct device *dev)
 {
        struct venus_core *core = dev_get_drvdata(dev);
@@ -355,12 +363,26 @@ static __maybe_unused int venus_runtime_suspend(struct device *dev)
        if (ret)
                return ret;
 
+       if (pm_ops->core_power) {
+               ret = pm_ops->core_power(dev, POWER_OFF);
+               if (ret)
+                       return ret;
+       }
+
        ret = icc_set_bw(core->cpucfg_path, 0, 0);
        if (ret)
-               return ret;
+               goto err_cpucfg_path;
 
-       if (pm_ops->core_power)
-               ret = pm_ops->core_power(dev, POWER_OFF);
+       ret = icc_set_bw(core->video_path, 0, 0);
+       if (ret)
+               goto err_video_path;
+
+       return ret;
+
+err_video_path:
+       icc_set_bw(core->cpucfg_path, kbps_to_icc(1000), 0);
+err_cpucfg_path:
+       pm_ops->core_power(dev, POWER_ON);
 
        return ret;
 }
@@ -371,16 +393,20 @@ static __maybe_unused int venus_runtime_resume(struct device *dev)
        const struct venus_pm_ops *pm_ops = core->pm_ops;
        int ret;
 
+       ret = icc_set_bw(core->video_path, kbps_to_icc(20000), 0);
+       if (ret)
+               return ret;
+
+       ret = icc_set_bw(core->cpucfg_path, kbps_to_icc(1000), 0);
+       if (ret)
+               return ret;
+
        if (pm_ops->core_power) {
                ret = pm_ops->core_power(dev, POWER_ON);
                if (ret)
                        return ret;
        }
 
-       ret = icc_set_bw(core->cpucfg_path, 0, kbps_to_icc(1000));
-       if (ret)
-               return ret;
-
        return hfi_core_resume(core, false);
 }
 
@@ -602,6 +628,7 @@ static struct platform_driver qcom_venus_driver = {
                .of_match_table = venus_dt_match,
                .pm = &venus_pm_ops,
        },
+       .shutdown = venus_core_shutdown,
 };
 module_platform_driver(qcom_venus_driver);
 
index 05c9fbd..f03ed42 100644 (file)
@@ -372,6 +372,7 @@ struct venus_inst {
        unsigned int streamon_cap, streamon_out;
        u32 width;
        u32 height;
+       struct v4l2_rect crop;
        u32 out_width;
        u32 out_height;
        u32 colorspace;
index 1db64a8..d03e2dd 100644 (file)
@@ -171,9 +171,14 @@ static int venus_shutdown_no_tz(struct venus_core *core)
 
        iommu = core->fw.iommu_domain;
 
-       unmapped = iommu_unmap(iommu, VENUS_FW_START_ADDR, mapped);
-       if (unmapped != mapped)
-               dev_err(dev, "failed to unmap firmware\n");
+       if (core->fw.mapped_mem_size && iommu) {
+               unmapped = iommu_unmap(iommu, VENUS_FW_START_ADDR, mapped);
+
+               if (unmapped != mapped)
+                       dev_err(dev, "failed to unmap firmware\n");
+               else
+                       core->fw.mapped_mem_size = 0;
+       }
 
        return 0;
 }
@@ -305,7 +310,11 @@ void venus_firmware_deinit(struct venus_core *core)
        iommu = core->fw.iommu_domain;
 
        iommu_detach_device(iommu, core->fw.dev);
-       iommu_domain_free(iommu);
+
+       if (core->fw.iommu_domain) {
+               iommu_domain_free(iommu);
+               core->fw.iommu_domain = NULL;
+       }
 
        platform_device_unregister(to_platform_device(core->fw.dev));
 }
index a59022a..638ed5c 100644 (file)
@@ -198,6 +198,18 @@ int hfi_session_init(struct venus_inst *inst, u32 pixfmt)
        const struct hfi_ops *ops = core->ops;
        int ret;
 
+       /*
+        * If core shutdown is in progress or if we are in system
+        * recovery, return an error as during system error recovery
+        * session_init() can't pass successfully
+        */
+       mutex_lock(&core->lock);
+       if (!core->ops || core->sys_error) {
+               mutex_unlock(&core->lock);
+               return -EIO;
+       }
+       mutex_unlock(&core->lock);
+
        if (inst->state != INST_UNINIT)
                return -EINVAL;
 
index a9538c2..ca99908 100644 (file)
@@ -212,6 +212,16 @@ static int load_scale_bw(struct venus_core *core)
        }
        mutex_unlock(&core->lock);
 
+       /*
+        * keep minimum bandwidth vote for "video-mem" path,
+        * so that clks can be disabled during vdec_session_release().
+        * Actual bandwidth drop will be done during device supend
+        * so that device can power down without any warnings.
+        */
+
+       if (!total_avg && !total_peak)
+               total_avg = kbps_to_icc(1000);
+
        dev_dbg(core->dev, VDBGL "total: avg_bw: %u, peak_bw: %u\n",
                total_avg, total_peak);
 
@@ -928,7 +938,7 @@ static unsigned long calculate_inst_freq(struct venus_inst *inst,
        u32 fps = (u32)inst->fps;
        u32 mbs_per_sec;
 
-       mbs_per_sec = load_per_instance(inst) / fps;
+       mbs_per_sec = load_per_instance(inst);
 
        vpp_freq = mbs_per_sec * inst->clk_data.codec_freq_data->vpp_freq;
        /* 21 / 20 is overhead factor */
index ea13170..8488411 100644 (file)
@@ -325,6 +325,10 @@ static int vdec_s_fmt(struct file *file, void *fh, struct v4l2_format *f)
 
        inst->width = format.fmt.pix_mp.width;
        inst->height = format.fmt.pix_mp.height;
+       inst->crop.top = 0;
+       inst->crop.left = 0;
+       inst->crop.width = inst->width;
+       inst->crop.height = inst->height;
 
        if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE)
                inst->fmt_out = fmt;
@@ -343,6 +347,9 @@ vdec_g_selection(struct file *file, void *fh, struct v4l2_selection *s)
            s->type != V4L2_BUF_TYPE_VIDEO_OUTPUT)
                return -EINVAL;
 
+       s->r.top = 0;
+       s->r.left = 0;
+
        switch (s->target) {
        case V4L2_SEL_TGT_CROP_BOUNDS:
        case V4L2_SEL_TGT_CROP_DEFAULT:
@@ -363,16 +370,12 @@ vdec_g_selection(struct file *file, void *fh, struct v4l2_selection *s)
        case V4L2_SEL_TGT_COMPOSE:
                if (s->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
                        return -EINVAL;
-               s->r.width = inst->out_width;
-               s->r.height = inst->out_height;
+               s->r = inst->crop;
                break;
        default:
                return -EINVAL;
        }
 
-       s->r.top = 0;
-       s->r.left = 0;
-
        return 0;
 }
 
@@ -1309,6 +1312,21 @@ static void vdec_event_change(struct venus_inst *inst,
 
        inst->width = format.fmt.pix_mp.width;
        inst->height = format.fmt.pix_mp.height;
+       /*
+        * Some versions of the firmware do not report crop information for
+        * all codecs. For these cases, set the crop to the coded resolution.
+        */
+       if (ev_data->input_crop.width > 0 && ev_data->input_crop.height > 0) {
+               inst->crop.left = ev_data->input_crop.left;
+               inst->crop.top = ev_data->input_crop.top;
+               inst->crop.width = ev_data->input_crop.width;
+               inst->crop.height = ev_data->input_crop.height;
+       } else {
+               inst->crop.left = 0;
+               inst->crop.top = 0;
+               inst->crop.width = ev_data->width;
+               inst->crop.height = ev_data->height;
+       }
 
        inst->out_width = ev_data->width;
        inst->out_height = ev_data->height;
@@ -1412,6 +1430,10 @@ static void vdec_inst_init(struct venus_inst *inst)
        inst->fmt_cap = &vdec_formats[0];
        inst->width = frame_width_min(inst);
        inst->height = ALIGN(frame_height_min(inst), 32);
+       inst->crop.left = 0;
+       inst->crop.top = 0;
+       inst->crop.width = inst->width;
+       inst->crop.height = inst->height;
        inst->out_width = frame_width_min(inst);
        inst->out_height = frame_height_min(inst);
        inst->fps = 30;
index 4724652..1c61602 100644 (file)
@@ -1028,7 +1028,7 @@ static int m2m_queue_init(void *priv, struct vb2_queue *src_vq,
 
 static void venc_inst_init(struct venus_inst *inst)
 {
-       inst->fmt_cap = &venc_formats[2];
+       inst->fmt_cap = &venc_formats[3];
        inst->fmt_out = &venc_formats[0];
        inst->width = 1280;
        inst->height = ALIGN(720, 32);
index 34d003e..5188134 100644 (file)
@@ -918,6 +918,54 @@ static int rvin_mc_init(struct rvin_dev *vin)
        return ret;
 }
 
+/* -----------------------------------------------------------------------------
+ * Suspend / Resume
+ */
+
+static int __maybe_unused rvin_suspend(struct device *dev)
+{
+       struct rvin_dev *vin = dev_get_drvdata(dev);
+
+       if (vin->state != RUNNING)
+               return 0;
+
+       rvin_stop_streaming(vin);
+
+       vin->state = SUSPENDED;
+
+       return 0;
+}
+
+static int __maybe_unused rvin_resume(struct device *dev)
+{
+       struct rvin_dev *vin = dev_get_drvdata(dev);
+
+       if (vin->state != SUSPENDED)
+               return 0;
+
+       /*
+        * Restore group master CHSEL setting.
+        *
+        * This needs to be done by every VIN resuming not only the master
+        * as we don't know if and in which order the master VINs will
+        * be resumed.
+        */
+       if (vin->info->use_mc) {
+               unsigned int master_id = rvin_group_id_to_master(vin->id);
+               struct rvin_dev *master = vin->group->vin[master_id];
+               int ret;
+
+               if (WARN_ON(!master))
+                       return -ENODEV;
+
+               ret = rvin_set_channel_routing(master, master->chsel);
+               if (ret)
+                       return ret;
+       }
+
+       return rvin_start_streaming(vin);
+}
+
 /* -----------------------------------------------------------------------------
  * Platform Device Driver
  */
@@ -1267,22 +1315,6 @@ static const struct of_device_id rvin_of_id_table[] = {
                .compatible = "renesas,vin-r8a7779",
                .data = &rcar_info_h1,
        },
-       {
-               .compatible = "renesas,vin-r8a7790",
-               .data = &rcar_info_gen2,
-       },
-       {
-               .compatible = "renesas,vin-r8a7791",
-               .data = &rcar_info_gen2,
-       },
-       {
-               .compatible = "renesas,vin-r8a7793",
-               .data = &rcar_info_gen2,
-       },
-       {
-               .compatible = "renesas,vin-r8a7794",
-               .data = &rcar_info_gen2,
-       },
        {
                .compatible = "renesas,rcar-gen2-vin",
                .data = &rcar_info_gen2,
@@ -1421,9 +1453,12 @@ static int rcar_vin_remove(struct platform_device *pdev)
        return 0;
 }
 
+static SIMPLE_DEV_PM_OPS(rvin_pm_ops, rvin_suspend, rvin_resume);
+
 static struct platform_driver rcar_vin_driver = {
        .driver = {
                .name = "rcar-vin",
+               .pm = &rvin_pm_ops,
                .of_match_table = rvin_of_id_table,
        },
        .probe = rcar_vin_probe,
index 79f2297..945d2eb 100644 (file)
@@ -876,31 +876,33 @@ static int rcsi2_parse_dt(struct rcar_csi2 *priv)
 {
        struct v4l2_async_subdev *asd;
        struct fwnode_handle *fwnode;
-       struct device_node *ep;
-       struct v4l2_fwnode_endpoint v4l2_ep = { .bus_type = 0 };
+       struct fwnode_handle *ep;
+       struct v4l2_fwnode_endpoint v4l2_ep = {
+               .bus_type = V4L2_MBUS_CSI2_DPHY
+       };
        int ret;
 
-       ep = of_graph_get_endpoint_by_regs(priv->dev->of_node, 0, 0);
+       ep = fwnode_graph_get_endpoint_by_id(dev_fwnode(priv->dev), 0, 0, 0);
        if (!ep) {
                dev_err(priv->dev, "Not connected to subdevice\n");
                return -EINVAL;
        }
 
-       ret = v4l2_fwnode_endpoint_parse(of_fwnode_handle(ep), &v4l2_ep);
+       ret = v4l2_fwnode_endpoint_parse(ep, &v4l2_ep);
        if (ret) {
                dev_err(priv->dev, "Could not parse v4l2 endpoint\n");
-               of_node_put(ep);
+               fwnode_handle_put(ep);
                return -EINVAL;
        }
 
        ret = rcsi2_parse_v4l2(priv, &v4l2_ep);
        if (ret) {
-               of_node_put(ep);
+               fwnode_handle_put(ep);
                return ret;
        }
 
-       fwnode = fwnode_graph_get_remote_endpoint(of_fwnode_handle(ep));
-       of_node_put(ep);
+       fwnode = fwnode_graph_get_remote_endpoint(ep);
+       fwnode_handle_put(ep);
 
        dev_dbg(priv->dev, "Found '%pOF'\n", to_of_node(fwnode));
 
index 692dea3..5a5f0e5 100644 (file)
@@ -905,7 +905,7 @@ static void rvin_fill_hw_slot(struct rvin_dev *vin, int slot)
                                vin->format.sizeimage / 2;
                        break;
                }
-       } else if (list_empty(&vin->buf_list)) {
+       } else if (vin->state != RUNNING || list_empty(&vin->buf_list)) {
                vin->buf_hw[slot].buffer = NULL;
                vin->buf_hw[slot].type = FULL;
                phys_addr = vin->scratch_phys;
@@ -998,12 +998,6 @@ static irqreturn_t rvin_irq(int irq, void *data)
                goto done;
        }
 
-       /* Nothing to do if capture status is 'STOPPING' */
-       if (vin->state == STOPPING) {
-               vin_dbg(vin, "IRQ while state stopping\n");
-               goto done;
-       }
-
        /* Prepare for capture and update state */
        vnms = rvin_read(vin, VNMS_REG);
        slot = (vnms & VNMS_FBS_MASK) >> VNMS_FBS_SHIFT;
@@ -1056,33 +1050,20 @@ done:
        return IRQ_RETVAL(handled);
 }
 
-/* Need to hold qlock before calling */
-static void return_all_buffers(struct rvin_dev *vin,
-                              enum vb2_buffer_state state)
+static void return_unused_buffers(struct rvin_dev *vin,
+                                 enum vb2_buffer_state state)
 {
        struct rvin_buffer *buf, *node;
-       struct vb2_v4l2_buffer *freed[HW_BUFFER_NUM];
-       unsigned int i, n;
-
-       for (i = 0; i < HW_BUFFER_NUM; i++) {
-               freed[i] = vin->buf_hw[i].buffer;
-               vin->buf_hw[i].buffer = NULL;
-
-               for (n = 0; n < i; n++) {
-                       if (freed[i] == freed[n]) {
-                               freed[i] = NULL;
-                               break;
-                       }
-               }
+       unsigned long flags;
 
-               if (freed[i])
-                       vb2_buffer_done(&freed[i]->vb2_buf, state);
-       }
+       spin_lock_irqsave(&vin->qlock, flags);
 
        list_for_each_entry_safe(buf, node, &vin->buf_list, list) {
                vb2_buffer_done(&buf->vb.vb2_buf, state);
                list_del(&buf->list);
        }
+
+       spin_unlock_irqrestore(&vin->qlock, flags);
 }
 
 static int rvin_queue_setup(struct vb2_queue *vq, unsigned int *nbuffers,
@@ -1266,61 +1247,81 @@ static int rvin_set_stream(struct rvin_dev *vin, int on)
        return ret;
 }
 
-static int rvin_start_streaming(struct vb2_queue *vq, unsigned int count)
+int rvin_start_streaming(struct rvin_dev *vin)
 {
-       struct rvin_dev *vin = vb2_get_drv_priv(vq);
        unsigned long flags;
        int ret;
 
-       /* Allocate scratch buffer. */
-       vin->scratch = dma_alloc_coherent(vin->dev, vin->format.sizeimage,
-                                         &vin->scratch_phys, GFP_KERNEL);
-       if (!vin->scratch) {
-               spin_lock_irqsave(&vin->qlock, flags);
-               return_all_buffers(vin, VB2_BUF_STATE_QUEUED);
-               spin_unlock_irqrestore(&vin->qlock, flags);
-               vin_err(vin, "Failed to allocate scratch buffer\n");
-               return -ENOMEM;
-       }
-
        ret = rvin_set_stream(vin, 1);
-       if (ret) {
-               spin_lock_irqsave(&vin->qlock, flags);
-               return_all_buffers(vin, VB2_BUF_STATE_QUEUED);
-               spin_unlock_irqrestore(&vin->qlock, flags);
-               goto out;
-       }
+       if (ret)
+               return ret;
 
        spin_lock_irqsave(&vin->qlock, flags);
 
        vin->sequence = 0;
 
        ret = rvin_capture_start(vin);
-       if (ret) {
-               return_all_buffers(vin, VB2_BUF_STATE_QUEUED);
+       if (ret)
                rvin_set_stream(vin, 0);
-       }
 
        spin_unlock_irqrestore(&vin->qlock, flags);
-out:
-       if (ret)
-               dma_free_coherent(vin->dev, vin->format.sizeimage, vin->scratch,
-                                 vin->scratch_phys);
 
        return ret;
 }
 
-static void rvin_stop_streaming(struct vb2_queue *vq)
+static int rvin_start_streaming_vq(struct vb2_queue *vq, unsigned int count)
 {
        struct rvin_dev *vin = vb2_get_drv_priv(vq);
+       int ret = -ENOMEM;
+
+       /* Allocate scratch buffer. */
+       vin->scratch = dma_alloc_coherent(vin->dev, vin->format.sizeimage,
+                                         &vin->scratch_phys, GFP_KERNEL);
+       if (!vin->scratch)
+               goto err_scratch;
+
+       ret = rvin_start_streaming(vin);
+       if (ret)
+               goto err_start;
+
+       return 0;
+err_start:
+       dma_free_coherent(vin->dev, vin->format.sizeimage, vin->scratch,
+                         vin->scratch_phys);
+err_scratch:
+       return_unused_buffers(vin, VB2_BUF_STATE_QUEUED);
+
+       return ret;
+}
+
+void rvin_stop_streaming(struct rvin_dev *vin)
+{
+       unsigned int i, retries;
        unsigned long flags;
-       int retries = 0;
+       bool buffersFreed;
 
        spin_lock_irqsave(&vin->qlock, flags);
 
        vin->state = STOPPING;
 
+       /* Wait until only scratch buffer is used, max 3 interrupts. */
+       retries = 0;
+       while (retries++ < RVIN_RETRIES) {
+               buffersFreed = true;
+               for (i = 0; i < HW_BUFFER_NUM; i++)
+                       if (vin->buf_hw[i].buffer)
+                               buffersFreed = false;
+
+               if (buffersFreed)
+                       break;
+
+               spin_unlock_irqrestore(&vin->qlock, flags);
+               msleep(RVIN_TIMEOUT_MS);
+               spin_lock_irqsave(&vin->qlock, flags);
+       }
+
        /* Wait for streaming to stop */
+       retries = 0;
        while (retries++ < RVIN_RETRIES) {
 
                rvin_capture_stop(vin);
@@ -1336,7 +1337,7 @@ static void rvin_stop_streaming(struct vb2_queue *vq)
                spin_lock_irqsave(&vin->qlock, flags);
        }
 
-       if (vin->state != STOPPED) {
+       if (!buffersFreed || vin->state != STOPPED) {
                /*
                 * If this happens something have gone horribly wrong.
                 * Set state to stopped to prevent the interrupt handler
@@ -1346,27 +1347,33 @@ static void rvin_stop_streaming(struct vb2_queue *vq)
                vin->state = STOPPED;
        }
 
-       /* Release all active buffers */
-       return_all_buffers(vin, VB2_BUF_STATE_ERROR);
-
        spin_unlock_irqrestore(&vin->qlock, flags);
 
        rvin_set_stream(vin, 0);
 
        /* disable interrupts */
        rvin_disable_interrupts(vin);
+}
+
+static void rvin_stop_streaming_vq(struct vb2_queue *vq)
+{
+       struct rvin_dev *vin = vb2_get_drv_priv(vq);
+
+       rvin_stop_streaming(vin);
 
        /* Free scratch buffer. */
        dma_free_coherent(vin->dev, vin->format.sizeimage, vin->scratch,
                          vin->scratch_phys);
+
+       return_unused_buffers(vin, VB2_BUF_STATE_ERROR);
 }
 
 static const struct vb2_ops rvin_qops = {
        .queue_setup            = rvin_queue_setup,
        .buf_prepare            = rvin_buffer_prepare,
        .buf_queue              = rvin_buffer_queue,
-       .start_streaming        = rvin_start_streaming,
-       .stop_streaming         = rvin_stop_streaming,
+       .start_streaming        = rvin_start_streaming_vq,
+       .stop_streaming         = rvin_stop_streaming_vq,
        .wait_prepare           = vb2_ops_wait_prepare,
        .wait_finish            = vb2_ops_wait_finish,
 };
@@ -1461,6 +1468,8 @@ int rvin_set_channel_routing(struct rvin_dev *vin, u8 chsel)
 
        vin_dbg(vin, "Set IFMD 0x%x\n", ifmd);
 
+       vin->chsel = chsel;
+
        /* Restore VNMC. */
        rvin_write(vin, vnmc, VNMC_REG);
 
index 8396e0e..4539bd5 100644 (file)
@@ -49,16 +49,18 @@ enum rvin_csi_id {
 };
 
 /**
- * STOPPED  - No operation in progress
- * STARTING - Capture starting up
- * RUNNING  - Operation in progress have buffers
- * STOPPING - Stopping operation
+ * STOPPED   - No operation in progress
+ * STARTING  - Capture starting up
+ * RUNNING   - Operation in progress have buffers
+ * STOPPING  - Stopping operation
+ * SUSPENDED - Capture is suspended
  */
 enum rvin_dma_state {
        STOPPED = 0,
        STARTING,
        RUNNING,
        STOPPING,
+       SUSPENDED,
 };
 
 /**
@@ -189,6 +191,7 @@ struct rvin_info {
  * @state:             keeps track of operation state
  *
  * @is_csi:            flag to mark the VIN as using a CSI-2 subdevice
+ * @chsel              Cached value of the current CSI-2 channel selection
  *
  * @mbus_code:         media bus format code
  * @format:            active V4L2 pixel format
@@ -232,6 +235,7 @@ struct rvin_dev {
        enum rvin_dma_state state;
 
        bool is_csi;
+       unsigned int chsel;
 
        u32 mbus_code;
        struct v4l2_pix_format format;
@@ -297,4 +301,7 @@ void rvin_crop_scale_comp(struct rvin_dev *vin);
 int rvin_set_channel_routing(struct rvin_dev *vin, u8 chsel);
 void rvin_set_alpha(struct rvin_dev *vin, unsigned int alpha);
 
+int rvin_start_streaming(struct rvin_dev *vin);
+void rvin_stop_streaming(struct rvin_dev *vin);
+
 #endif
diff --git a/drivers/media/platform/rockchip/rkisp1/Makefile b/drivers/media/platform/rockchip/rkisp1/Makefile
new file mode 100644 (file)
index 0000000..ab32a77
--- /dev/null
@@ -0,0 +1,10 @@
+# SPDX-License-Identifier: GPL-2.0
+
+obj-$(CONFIG_VIDEO_ROCKCHIP_ISP1) += rockchip-isp1.o
+rockchip-isp1-objs +=  rkisp1-capture.o \
+                       rkisp1-common.o \
+                       rkisp1-dev.o \
+                       rkisp1-isp.o \
+                       rkisp1-resizer.o \
+                       rkisp1-stats.o \
+                       rkisp1-params.o
diff --git a/drivers/media/platform/rockchip/rkisp1/rkisp1-capture.c b/drivers/media/platform/rockchip/rkisp1/rkisp1-capture.c
new file mode 100644 (file)
index 0000000..b81235a
--- /dev/null
@@ -0,0 +1,1431 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Rockchip ISP1 Driver - V4l capture device
+ *
+ * Copyright (C) 2019 Collabora, Ltd.
+ *
+ * Based on Rockchip ISP1 driver by Rockchip Electronics Co., Ltd.
+ * Copyright (C) 2017 Rockchip Electronics Co., Ltd.
+ */
+
+#include <linux/delay.h>
+#include <linux/pm_runtime.h>
+#include <media/v4l2-common.h>
+#include <media/v4l2-event.h>
+#include <media/v4l2-fh.h>
+#include <media/v4l2-ioctl.h>
+#include <media/v4l2-mc.h>
+#include <media/v4l2-subdev.h>
+#include <media/videobuf2-dma-contig.h>
+
+#include "rkisp1-common.h"
+
+/*
+ * NOTE: There are two capture video devices in rkisp1, selfpath and mainpath.
+ *
+ * differences between selfpath and mainpath
+ * available mp sink input: isp
+ * available sp sink input : isp, dma(TODO)
+ * available mp sink pad fmts: yuv422, raw
+ * available sp sink pad fmts: yuv422, yuv420......
+ * available mp source fmts: yuv, raw, jpeg(TODO)
+ * available sp source fmts: yuv, rgb
+ */
+
+#define RKISP1_SP_DEV_NAME     RKISP1_DRIVER_NAME "_selfpath"
+#define RKISP1_MP_DEV_NAME     RKISP1_DRIVER_NAME "_mainpath"
+
+#define RKISP1_MIN_BUFFERS_NEEDED 3
+
+enum rkisp1_plane {
+       RKISP1_PLANE_Y  = 0,
+       RKISP1_PLANE_CB = 1,
+       RKISP1_PLANE_CR = 2
+};
+
+/*
+ * @fourcc: pixel format
+ * @fmt_type: helper filed for pixel format
+ * @uv_swap: if cb cr swaped, for yuv
+ * @write_format: defines how YCbCr self picture data is written to memory
+ * @output_format: defines sp output format
+ * @mbus: the mbus code on the src resizer pad that matches the pixel format
+ */
+struct rkisp1_capture_fmt_cfg {
+       u32 fourcc;
+       u8 uv_swap;
+       u32 write_format;
+       u32 output_format;
+       u32 mbus;
+};
+
+struct rkisp1_capture_ops {
+       void (*config)(struct rkisp1_capture *cap);
+       void (*stop)(struct rkisp1_capture *cap);
+       void (*enable)(struct rkisp1_capture *cap);
+       void (*disable)(struct rkisp1_capture *cap);
+       void (*set_data_path)(struct rkisp1_capture *cap);
+       bool (*is_stopped)(struct rkisp1_capture *cap);
+};
+
+struct rkisp1_capture_config {
+       const struct rkisp1_capture_fmt_cfg *fmts;
+       int fmt_size;
+       struct {
+               u32 y_size_init;
+               u32 cb_size_init;
+               u32 cr_size_init;
+               u32 y_base_ad_init;
+               u32 cb_base_ad_init;
+               u32 cr_base_ad_init;
+               u32 y_offs_cnt_init;
+               u32 cb_offs_cnt_init;
+               u32 cr_offs_cnt_init;
+       } mi;
+};
+
+/*
+ * The supported pixel formats for mainpath. NOTE, pixel formats with identical 'mbus'
+ * are grouped together. This is assumed and used by the function rkisp1_cap_enum_mbus_codes
+ */
+static const struct rkisp1_capture_fmt_cfg rkisp1_mp_fmts[] = {
+       /* yuv422 */
+       {
+               .fourcc = V4L2_PIX_FMT_YUYV,
+               .uv_swap = 0,
+               .write_format = RKISP1_MI_CTRL_MP_WRITE_YUVINT,
+               .mbus = MEDIA_BUS_FMT_YUYV8_2X8,
+       }, {
+               .fourcc = V4L2_PIX_FMT_YUV422P,
+               .uv_swap = 0,
+               .write_format = RKISP1_MI_CTRL_MP_WRITE_YUV_PLA_OR_RAW8,
+               .mbus = MEDIA_BUS_FMT_YUYV8_2X8,
+       }, {
+               .fourcc = V4L2_PIX_FMT_NV16,
+               .uv_swap = 0,
+               .write_format = RKISP1_MI_CTRL_MP_WRITE_YUV_SPLA,
+               .mbus = MEDIA_BUS_FMT_YUYV8_2X8,
+       }, {
+               .fourcc = V4L2_PIX_FMT_NV61,
+               .uv_swap = 1,
+               .write_format = RKISP1_MI_CTRL_MP_WRITE_YUV_SPLA,
+               .mbus = MEDIA_BUS_FMT_YUYV8_2X8,
+       }, {
+               .fourcc = V4L2_PIX_FMT_YVU422M,
+               .uv_swap = 1,
+               .write_format = RKISP1_MI_CTRL_MP_WRITE_YUV_PLA_OR_RAW8,
+               .mbus = MEDIA_BUS_FMT_YUYV8_2X8,
+       },
+       /* yuv400 */
+       {
+               .fourcc = V4L2_PIX_FMT_GREY,
+               .uv_swap = 0,
+               .write_format = RKISP1_MI_CTRL_MP_WRITE_YUV_PLA_OR_RAW8,
+               .mbus = MEDIA_BUS_FMT_YUYV8_2X8,
+       },
+       /* yuv420 */
+       {
+               .fourcc = V4L2_PIX_FMT_NV21,
+               .uv_swap = 1,
+               .write_format = RKISP1_MI_CTRL_MP_WRITE_YUV_SPLA,
+               .mbus = MEDIA_BUS_FMT_YUYV8_1_5X8,
+       }, {
+               .fourcc = V4L2_PIX_FMT_NV12,
+               .uv_swap = 0,
+               .write_format = RKISP1_MI_CTRL_MP_WRITE_YUV_SPLA,
+               .mbus = MEDIA_BUS_FMT_YUYV8_1_5X8,
+       }, {
+               .fourcc = V4L2_PIX_FMT_NV21M,
+               .uv_swap = 1,
+               .write_format = RKISP1_MI_CTRL_MP_WRITE_YUV_SPLA,
+               .mbus = MEDIA_BUS_FMT_YUYV8_1_5X8,
+       }, {
+               .fourcc = V4L2_PIX_FMT_NV12M,
+               .uv_swap = 0,
+               .write_format = RKISP1_MI_CTRL_MP_WRITE_YUV_SPLA,
+               .mbus = MEDIA_BUS_FMT_YUYV8_1_5X8,
+       }, {
+               .fourcc = V4L2_PIX_FMT_YUV420,
+               .uv_swap = 0,
+               .write_format = RKISP1_MI_CTRL_MP_WRITE_YUV_PLA_OR_RAW8,
+               .mbus = MEDIA_BUS_FMT_YUYV8_1_5X8,
+       }, {
+               .fourcc = V4L2_PIX_FMT_YVU420,
+               .uv_swap = 1,
+               .write_format = RKISP1_MI_CTRL_MP_WRITE_YUV_PLA_OR_RAW8,
+               .mbus = MEDIA_BUS_FMT_YUYV8_1_5X8,
+       },
+       /* raw */
+       {
+               .fourcc = V4L2_PIX_FMT_SRGGB8,
+               .write_format = RKISP1_MI_CTRL_MP_WRITE_YUV_PLA_OR_RAW8,
+               .mbus = MEDIA_BUS_FMT_SRGGB8_1X8,
+       }, {
+               .fourcc = V4L2_PIX_FMT_SGRBG8,
+               .write_format = RKISP1_MI_CTRL_MP_WRITE_YUV_PLA_OR_RAW8,
+               .mbus = MEDIA_BUS_FMT_SGRBG8_1X8,
+       }, {
+               .fourcc = V4L2_PIX_FMT_SGBRG8,
+               .write_format = RKISP1_MI_CTRL_MP_WRITE_YUV_PLA_OR_RAW8,
+               .mbus = MEDIA_BUS_FMT_SGBRG8_1X8,
+       }, {
+               .fourcc = V4L2_PIX_FMT_SBGGR8,
+               .write_format = RKISP1_MI_CTRL_MP_WRITE_YUV_PLA_OR_RAW8,
+               .mbus = MEDIA_BUS_FMT_SBGGR8_1X8,
+       }, {
+               .fourcc = V4L2_PIX_FMT_SRGGB10,
+               .write_format = RKISP1_MI_CTRL_MP_WRITE_RAW12,
+               .mbus = MEDIA_BUS_FMT_SRGGB10_1X10,
+       }, {
+               .fourcc = V4L2_PIX_FMT_SGRBG10,
+               .write_format = RKISP1_MI_CTRL_MP_WRITE_RAW12,
+               .mbus = MEDIA_BUS_FMT_SGRBG10_1X10,
+       }, {
+               .fourcc = V4L2_PIX_FMT_SGBRG10,
+               .write_format = RKISP1_MI_CTRL_MP_WRITE_RAW12,
+               .mbus = MEDIA_BUS_FMT_SGBRG10_1X10,
+       }, {
+               .fourcc = V4L2_PIX_FMT_SBGGR10,
+               .write_format = RKISP1_MI_CTRL_MP_WRITE_RAW12,
+               .mbus = MEDIA_BUS_FMT_SBGGR10_1X10,
+       }, {
+               .fourcc = V4L2_PIX_FMT_SRGGB12,
+               .write_format = RKISP1_MI_CTRL_MP_WRITE_RAW12,
+               .mbus = MEDIA_BUS_FMT_SRGGB12_1X12,
+       }, {
+               .fourcc = V4L2_PIX_FMT_SGRBG12,
+               .write_format = RKISP1_MI_CTRL_MP_WRITE_RAW12,
+               .mbus = MEDIA_BUS_FMT_SGRBG12_1X12,
+       }, {
+               .fourcc = V4L2_PIX_FMT_SGBRG12,
+               .write_format = RKISP1_MI_CTRL_MP_WRITE_RAW12,
+               .mbus = MEDIA_BUS_FMT_SGBRG12_1X12,
+       }, {
+               .fourcc = V4L2_PIX_FMT_SBGGR12,
+               .write_format = RKISP1_MI_CTRL_MP_WRITE_RAW12,
+               .mbus = MEDIA_BUS_FMT_SBGGR12_1X12,
+       },
+};
+
+/*
+ * The supported pixel formats for selfpath. NOTE, pixel formats with identical 'mbus'
+ * are grouped together. This is assumed and used by the function rkisp1_cap_enum_mbus_codes
+ */
+static const struct rkisp1_capture_fmt_cfg rkisp1_sp_fmts[] = {
+       /* yuv422 */
+       {
+               .fourcc = V4L2_PIX_FMT_YUYV,
+               .uv_swap = 0,
+               .write_format = RKISP1_MI_CTRL_SP_WRITE_INT,
+               .output_format = RKISP1_MI_CTRL_SP_OUTPUT_YUV422,
+               .mbus = MEDIA_BUS_FMT_YUYV8_2X8,
+       }, {
+               .fourcc = V4L2_PIX_FMT_YUV422P,
+               .uv_swap = 0,
+               .write_format = RKISP1_MI_CTRL_SP_WRITE_PLA,
+               .output_format = RKISP1_MI_CTRL_SP_OUTPUT_YUV422,
+               .mbus = MEDIA_BUS_FMT_YUYV8_2X8,
+       }, {
+               .fourcc = V4L2_PIX_FMT_NV16,
+               .uv_swap = 0,
+               .write_format = RKISP1_MI_CTRL_SP_WRITE_SPLA,
+               .output_format = RKISP1_MI_CTRL_SP_OUTPUT_YUV422,
+               .mbus = MEDIA_BUS_FMT_YUYV8_2X8,
+       }, {
+               .fourcc = V4L2_PIX_FMT_NV61,
+               .uv_swap = 1,
+               .write_format = RKISP1_MI_CTRL_SP_WRITE_SPLA,
+               .output_format = RKISP1_MI_CTRL_SP_OUTPUT_YUV422,
+               .mbus = MEDIA_BUS_FMT_YUYV8_2X8,
+       }, {
+               .fourcc = V4L2_PIX_FMT_YVU422M,
+               .uv_swap = 1,
+               .write_format = RKISP1_MI_CTRL_SP_WRITE_PLA,
+               .output_format = RKISP1_MI_CTRL_SP_OUTPUT_YUV422,
+               .mbus = MEDIA_BUS_FMT_YUYV8_2X8,
+       },
+       /* yuv400 */
+       {
+               .fourcc = V4L2_PIX_FMT_GREY,
+               .uv_swap = 0,
+               .write_format = RKISP1_MI_CTRL_SP_WRITE_PLA,
+               .output_format = RKISP1_MI_CTRL_SP_OUTPUT_YUV400,
+               .mbus = MEDIA_BUS_FMT_YUYV8_2X8,
+       },
+       /* rgb */
+       {
+               .fourcc = V4L2_PIX_FMT_XBGR32,
+               .write_format = RKISP1_MI_CTRL_SP_WRITE_PLA,
+               .output_format = RKISP1_MI_CTRL_SP_OUTPUT_RGB888,
+               .mbus = MEDIA_BUS_FMT_YUYV8_2X8,
+       }, {
+               .fourcc = V4L2_PIX_FMT_RGB565,
+               .write_format = RKISP1_MI_CTRL_SP_WRITE_PLA,
+               .output_format = RKISP1_MI_CTRL_SP_OUTPUT_RGB565,
+               .mbus = MEDIA_BUS_FMT_YUYV8_2X8,
+       },
+       /* yuv420 */
+       {
+               .fourcc = V4L2_PIX_FMT_NV21,
+               .uv_swap = 1,
+               .write_format = RKISP1_MI_CTRL_SP_WRITE_SPLA,
+               .output_format = RKISP1_MI_CTRL_SP_OUTPUT_YUV420,
+               .mbus = MEDIA_BUS_FMT_YUYV8_1_5X8,
+       }, {
+               .fourcc = V4L2_PIX_FMT_NV12,
+               .uv_swap = 0,
+               .write_format = RKISP1_MI_CTRL_SP_WRITE_SPLA,
+               .output_format = RKISP1_MI_CTRL_SP_OUTPUT_YUV420,
+               .mbus = MEDIA_BUS_FMT_YUYV8_1_5X8,
+       }, {
+               .fourcc = V4L2_PIX_FMT_NV21M,
+               .uv_swap = 1,
+               .write_format = RKISP1_MI_CTRL_SP_WRITE_SPLA,
+               .output_format = RKISP1_MI_CTRL_SP_OUTPUT_YUV420,
+               .mbus = MEDIA_BUS_FMT_YUYV8_1_5X8,
+       }, {
+               .fourcc = V4L2_PIX_FMT_NV12M,
+               .uv_swap = 0,
+               .write_format = RKISP1_MI_CTRL_SP_WRITE_SPLA,
+               .output_format = RKISP1_MI_CTRL_SP_OUTPUT_YUV420,
+               .mbus = MEDIA_BUS_FMT_YUYV8_1_5X8,
+       }, {
+               .fourcc = V4L2_PIX_FMT_YUV420,
+               .uv_swap = 0,
+               .write_format = RKISP1_MI_CTRL_SP_WRITE_PLA,
+               .output_format = RKISP1_MI_CTRL_SP_OUTPUT_YUV420,
+               .mbus = MEDIA_BUS_FMT_YUYV8_1_5X8,
+       }, {
+               .fourcc = V4L2_PIX_FMT_YVU420,
+               .uv_swap = 1,
+               .write_format = RKISP1_MI_CTRL_SP_WRITE_PLA,
+               .output_format = RKISP1_MI_CTRL_SP_OUTPUT_YUV420,
+               .mbus = MEDIA_BUS_FMT_YUYV8_1_5X8,
+       },
+};
+
+static const struct rkisp1_capture_config rkisp1_capture_config_mp = {
+       .fmts = rkisp1_mp_fmts,
+       .fmt_size = ARRAY_SIZE(rkisp1_mp_fmts),
+       .mi = {
+               .y_size_init =          RKISP1_CIF_MI_MP_Y_SIZE_INIT,
+               .cb_size_init =         RKISP1_CIF_MI_MP_CB_SIZE_INIT,
+               .cr_size_init =         RKISP1_CIF_MI_MP_CR_SIZE_INIT,
+               .y_base_ad_init =       RKISP1_CIF_MI_MP_Y_BASE_AD_INIT,
+               .cb_base_ad_init =      RKISP1_CIF_MI_MP_CB_BASE_AD_INIT,
+               .cr_base_ad_init =      RKISP1_CIF_MI_MP_CR_BASE_AD_INIT,
+               .y_offs_cnt_init =      RKISP1_CIF_MI_MP_Y_OFFS_CNT_INIT,
+               .cb_offs_cnt_init =     RKISP1_CIF_MI_MP_CB_OFFS_CNT_INIT,
+               .cr_offs_cnt_init =     RKISP1_CIF_MI_MP_CR_OFFS_CNT_INIT,
+       },
+};
+
+static const struct rkisp1_capture_config rkisp1_capture_config_sp = {
+       .fmts = rkisp1_sp_fmts,
+       .fmt_size = ARRAY_SIZE(rkisp1_sp_fmts),
+       .mi = {
+               .y_size_init =          RKISP1_CIF_MI_SP_Y_SIZE_INIT,
+               .cb_size_init =         RKISP1_CIF_MI_SP_CB_SIZE_INIT,
+               .cr_size_init =         RKISP1_CIF_MI_SP_CR_SIZE_INIT,
+               .y_base_ad_init =       RKISP1_CIF_MI_SP_Y_BASE_AD_INIT,
+               .cb_base_ad_init =      RKISP1_CIF_MI_SP_CB_BASE_AD_INIT,
+               .cr_base_ad_init =      RKISP1_CIF_MI_SP_CR_BASE_AD_INIT,
+               .y_offs_cnt_init =      RKISP1_CIF_MI_SP_Y_OFFS_CNT_INIT,
+               .cb_offs_cnt_init =     RKISP1_CIF_MI_SP_CB_OFFS_CNT_INIT,
+               .cr_offs_cnt_init =     RKISP1_CIF_MI_SP_CR_OFFS_CNT_INIT,
+       },
+};
+
+static inline struct rkisp1_vdev_node *
+rkisp1_vdev_to_node(struct video_device *vdev)
+{
+       return container_of(vdev, struct rkisp1_vdev_node, vdev);
+}
+
+int rkisp1_cap_enum_mbus_codes(struct rkisp1_capture *cap,
+                              struct v4l2_subdev_mbus_code_enum *code)
+{
+       const struct rkisp1_capture_fmt_cfg *fmts = cap->config->fmts;
+       /*
+        * initialize curr_mbus to non existing mbus code 0 to ensure it is
+        * different from fmts[0].mbus
+        */
+       u32 curr_mbus = 0;
+       int i, n = 0;
+
+       for (i = 0; i < cap->config->fmt_size; i++) {
+               if (fmts[i].mbus == curr_mbus)
+                       continue;
+
+               curr_mbus = fmts[i].mbus;
+               if (n++ == code->index) {
+                       code->code = curr_mbus;
+                       return 0;
+               }
+       }
+       return -EINVAL;
+}
+
+/* ----------------------------------------------------------------------------
+ * Stream operations for self-picture path (sp) and main-picture path (mp)
+ */
+
+static void rkisp1_mi_config_ctrl(struct rkisp1_capture *cap)
+{
+       u32 mi_ctrl = rkisp1_read(cap->rkisp1, RKISP1_CIF_MI_CTRL);
+
+       mi_ctrl &= ~GENMASK(17, 16);
+       mi_ctrl |= RKISP1_CIF_MI_CTRL_BURST_LEN_LUM_64;
+
+       mi_ctrl &= ~GENMASK(19, 18);
+       mi_ctrl |= RKISP1_CIF_MI_CTRL_BURST_LEN_CHROM_64;
+
+       mi_ctrl |= RKISP1_CIF_MI_CTRL_INIT_BASE_EN |
+                  RKISP1_CIF_MI_CTRL_INIT_OFFSET_EN;
+
+       rkisp1_write(cap->rkisp1, mi_ctrl, RKISP1_CIF_MI_CTRL);
+}
+
+static u32 rkisp1_pixfmt_comp_size(const struct v4l2_pix_format_mplane *pixm,
+                                  unsigned int component)
+{
+       /*
+        * If packed format, then plane_fmt[0].sizeimage is the sum of all
+        * components, so we need to calculate just the size of Y component.
+        * See rkisp1_fill_pixfmt().
+        */
+       if (!component && pixm->num_planes == 1)
+               return pixm->plane_fmt[0].bytesperline * pixm->height;
+       return pixm->plane_fmt[component].sizeimage;
+}
+
+static void rkisp1_irq_frame_end_enable(struct rkisp1_capture *cap)
+{
+       u32 mi_imsc = rkisp1_read(cap->rkisp1, RKISP1_CIF_MI_IMSC);
+
+       mi_imsc |= RKISP1_CIF_MI_FRAME(cap);
+       rkisp1_write(cap->rkisp1, mi_imsc, RKISP1_CIF_MI_IMSC);
+}
+
+static void rkisp1_mp_config(struct rkisp1_capture *cap)
+{
+       const struct v4l2_pix_format_mplane *pixm = &cap->pix.fmt;
+       struct rkisp1_device *rkisp1 = cap->rkisp1;
+       u32 reg;
+
+       rkisp1_write(rkisp1, rkisp1_pixfmt_comp_size(pixm, RKISP1_PLANE_Y),
+                    cap->config->mi.y_size_init);
+       rkisp1_write(rkisp1, rkisp1_pixfmt_comp_size(pixm, RKISP1_PLANE_CB),
+                    cap->config->mi.cb_size_init);
+       rkisp1_write(rkisp1, rkisp1_pixfmt_comp_size(pixm, RKISP1_PLANE_CR),
+                    cap->config->mi.cr_size_init);
+
+       rkisp1_irq_frame_end_enable(cap);
+
+       /* set uv swapping for semiplanar formats */
+       if (cap->pix.info->comp_planes == 2) {
+               reg = rkisp1_read(rkisp1, RKISP1_CIF_MI_XTD_FORMAT_CTRL);
+               if (cap->pix.cfg->uv_swap)
+                       reg |= RKISP1_CIF_MI_XTD_FMT_CTRL_MP_CB_CR_SWAP;
+               else
+                       reg &= ~RKISP1_CIF_MI_XTD_FMT_CTRL_MP_CB_CR_SWAP;
+               rkisp1_write(rkisp1, reg, RKISP1_CIF_MI_XTD_FORMAT_CTRL);
+       }
+
+       rkisp1_mi_config_ctrl(cap);
+
+       reg = rkisp1_read(rkisp1, RKISP1_CIF_MI_CTRL);
+       reg &= ~RKISP1_MI_CTRL_MP_FMT_MASK;
+       reg |= cap->pix.cfg->write_format;
+       rkisp1_write(rkisp1, reg, RKISP1_CIF_MI_CTRL);
+
+       reg = rkisp1_read(rkisp1, RKISP1_CIF_MI_CTRL);
+       reg |= RKISP1_CIF_MI_MP_AUTOUPDATE_ENABLE;
+       rkisp1_write(rkisp1, reg, RKISP1_CIF_MI_CTRL);
+}
+
+static void rkisp1_sp_config(struct rkisp1_capture *cap)
+{
+       const struct v4l2_pix_format_mplane *pixm = &cap->pix.fmt;
+       struct rkisp1_device *rkisp1 = cap->rkisp1;
+       u32 mi_ctrl, reg;
+
+       rkisp1_write(rkisp1, rkisp1_pixfmt_comp_size(pixm, RKISP1_PLANE_Y),
+                    cap->config->mi.y_size_init);
+       rkisp1_write(rkisp1, rkisp1_pixfmt_comp_size(pixm, RKISP1_PLANE_CB),
+                    cap->config->mi.cb_size_init);
+       rkisp1_write(rkisp1, rkisp1_pixfmt_comp_size(pixm, RKISP1_PLANE_CR),
+                    cap->config->mi.cr_size_init);
+
+       rkisp1_write(rkisp1, pixm->width, RKISP1_CIF_MI_SP_Y_PIC_WIDTH);
+       rkisp1_write(rkisp1, pixm->height, RKISP1_CIF_MI_SP_Y_PIC_HEIGHT);
+       rkisp1_write(rkisp1, cap->sp_y_stride, RKISP1_CIF_MI_SP_Y_LLENGTH);
+
+       rkisp1_irq_frame_end_enable(cap);
+
+       /* set uv swapping for semiplanar formats */
+       if (cap->pix.info->comp_planes == 2) {
+               reg = rkisp1_read(rkisp1, RKISP1_CIF_MI_XTD_FORMAT_CTRL);
+               if (cap->pix.cfg->uv_swap)
+                       reg |= RKISP1_CIF_MI_XTD_FMT_CTRL_SP_CB_CR_SWAP;
+               else
+                       reg &= ~RKISP1_CIF_MI_XTD_FMT_CTRL_SP_CB_CR_SWAP;
+               rkisp1_write(rkisp1, reg, RKISP1_CIF_MI_XTD_FORMAT_CTRL);
+       }
+
+       rkisp1_mi_config_ctrl(cap);
+
+       mi_ctrl = rkisp1_read(rkisp1, RKISP1_CIF_MI_CTRL);
+       mi_ctrl &= ~RKISP1_MI_CTRL_SP_FMT_MASK;
+       mi_ctrl |= cap->pix.cfg->write_format |
+                  RKISP1_MI_CTRL_SP_INPUT_YUV422 |
+                  cap->pix.cfg->output_format |
+                  RKISP1_CIF_MI_SP_AUTOUPDATE_ENABLE;
+       rkisp1_write(rkisp1, mi_ctrl, RKISP1_CIF_MI_CTRL);
+}
+
+static void rkisp1_mp_disable(struct rkisp1_capture *cap)
+{
+       u32 mi_ctrl = rkisp1_read(cap->rkisp1, RKISP1_CIF_MI_CTRL);
+
+       mi_ctrl &= ~(RKISP1_CIF_MI_CTRL_MP_ENABLE |
+                    RKISP1_CIF_MI_CTRL_RAW_ENABLE);
+       rkisp1_write(cap->rkisp1, mi_ctrl, RKISP1_CIF_MI_CTRL);
+}
+
+static void rkisp1_sp_disable(struct rkisp1_capture *cap)
+{
+       u32 mi_ctrl = rkisp1_read(cap->rkisp1, RKISP1_CIF_MI_CTRL);
+
+       mi_ctrl &= ~RKISP1_CIF_MI_CTRL_SP_ENABLE;
+       rkisp1_write(cap->rkisp1, mi_ctrl, RKISP1_CIF_MI_CTRL);
+}
+
+static void rkisp1_mp_enable(struct rkisp1_capture *cap)
+{
+       u32 mi_ctrl;
+
+       rkisp1_mp_disable(cap);
+
+       mi_ctrl = rkisp1_read(cap->rkisp1, RKISP1_CIF_MI_CTRL);
+       if (v4l2_is_format_bayer(cap->pix.info))
+               mi_ctrl |= RKISP1_CIF_MI_CTRL_RAW_ENABLE;
+       /* YUV */
+       else
+               mi_ctrl |= RKISP1_CIF_MI_CTRL_MP_ENABLE;
+
+       rkisp1_write(cap->rkisp1, mi_ctrl, RKISP1_CIF_MI_CTRL);
+}
+
+static void rkisp1_sp_enable(struct rkisp1_capture *cap)
+{
+       u32 mi_ctrl = rkisp1_read(cap->rkisp1, RKISP1_CIF_MI_CTRL);
+
+       mi_ctrl |= RKISP1_CIF_MI_CTRL_SP_ENABLE;
+       rkisp1_write(cap->rkisp1, mi_ctrl, RKISP1_CIF_MI_CTRL);
+}
+
+static void rkisp1_mp_sp_stop(struct rkisp1_capture *cap)
+{
+       if (!cap->is_streaming)
+               return;
+       rkisp1_write(cap->rkisp1,
+                    RKISP1_CIF_MI_FRAME(cap), RKISP1_CIF_MI_ICR);
+       cap->ops->disable(cap);
+}
+
+static bool rkisp1_mp_is_stopped(struct rkisp1_capture *cap)
+{
+       u32 en = RKISP1_CIF_MI_CTRL_SHD_MP_IN_ENABLED |
+                RKISP1_CIF_MI_CTRL_SHD_RAW_OUT_ENABLED;
+
+       return !(rkisp1_read(cap->rkisp1, RKISP1_CIF_MI_CTRL_SHD) & en);
+}
+
+static bool rkisp1_sp_is_stopped(struct rkisp1_capture *cap)
+{
+       return !(rkisp1_read(cap->rkisp1, RKISP1_CIF_MI_CTRL_SHD) &
+                RKISP1_CIF_MI_CTRL_SHD_SP_IN_ENABLED);
+}
+
+static void rkisp1_mp_set_data_path(struct rkisp1_capture *cap)
+{
+       u32 dpcl = rkisp1_read(cap->rkisp1, RKISP1_CIF_VI_DPCL);
+
+       dpcl = dpcl | RKISP1_CIF_VI_DPCL_CHAN_MODE_MP |
+              RKISP1_CIF_VI_DPCL_MP_MUX_MRSZ_MI;
+       rkisp1_write(cap->rkisp1, dpcl, RKISP1_CIF_VI_DPCL);
+}
+
+static void rkisp1_sp_set_data_path(struct rkisp1_capture *cap)
+{
+       u32 dpcl = rkisp1_read(cap->rkisp1, RKISP1_CIF_VI_DPCL);
+
+       dpcl |= RKISP1_CIF_VI_DPCL_CHAN_MODE_SP;
+       rkisp1_write(cap->rkisp1, dpcl, RKISP1_CIF_VI_DPCL);
+}
+
+static struct rkisp1_capture_ops rkisp1_capture_ops_mp = {
+       .config = rkisp1_mp_config,
+       .enable = rkisp1_mp_enable,
+       .disable = rkisp1_mp_disable,
+       .stop = rkisp1_mp_sp_stop,
+       .set_data_path = rkisp1_mp_set_data_path,
+       .is_stopped = rkisp1_mp_is_stopped,
+};
+
+static struct rkisp1_capture_ops rkisp1_capture_ops_sp = {
+       .config = rkisp1_sp_config,
+       .enable = rkisp1_sp_enable,
+       .disable = rkisp1_sp_disable,
+       .stop = rkisp1_mp_sp_stop,
+       .set_data_path = rkisp1_sp_set_data_path,
+       .is_stopped = rkisp1_sp_is_stopped,
+};
+
+/* ----------------------------------------------------------------------------
+ * Frame buffer operations
+ */
+
+static int rkisp1_dummy_buf_create(struct rkisp1_capture *cap)
+{
+       const struct v4l2_pix_format_mplane *pixm = &cap->pix.fmt;
+       struct rkisp1_dummy_buffer *dummy_buf = &cap->buf.dummy;
+
+       dummy_buf->size = max3(rkisp1_pixfmt_comp_size(pixm, RKISP1_PLANE_Y),
+                              rkisp1_pixfmt_comp_size(pixm, RKISP1_PLANE_CB),
+                              rkisp1_pixfmt_comp_size(pixm, RKISP1_PLANE_CR));
+
+       /* The driver never access vaddr, no mapping is required */
+       dummy_buf->vaddr = dma_alloc_attrs(cap->rkisp1->dev,
+                                          dummy_buf->size,
+                                          &dummy_buf->dma_addr,
+                                          GFP_KERNEL,
+                                          DMA_ATTR_NO_KERNEL_MAPPING);
+       if (!dummy_buf->vaddr)
+               return -ENOMEM;
+
+       return 0;
+}
+
+static void rkisp1_dummy_buf_destroy(struct rkisp1_capture *cap)
+{
+       dma_free_attrs(cap->rkisp1->dev,
+                      cap->buf.dummy.size, cap->buf.dummy.vaddr,
+                      cap->buf.dummy.dma_addr, DMA_ATTR_NO_KERNEL_MAPPING);
+}
+
+static void rkisp1_set_next_buf(struct rkisp1_capture *cap)
+{
+       cap->buf.curr = cap->buf.next;
+       cap->buf.next = NULL;
+
+       if (!list_empty(&cap->buf.queue)) {
+               u32 *buff_addr;
+
+               cap->buf.next = list_first_entry(&cap->buf.queue, struct rkisp1_buffer, queue);
+               list_del(&cap->buf.next->queue);
+
+               buff_addr = cap->buf.next->buff_addr;
+
+               rkisp1_write(cap->rkisp1,
+                            buff_addr[RKISP1_PLANE_Y],
+                            cap->config->mi.y_base_ad_init);
+               rkisp1_write(cap->rkisp1,
+                            buff_addr[RKISP1_PLANE_CB],
+                            cap->config->mi.cb_base_ad_init);
+               rkisp1_write(cap->rkisp1,
+                            buff_addr[RKISP1_PLANE_CR],
+                            cap->config->mi.cr_base_ad_init);
+       } else {
+               /*
+                * Use the dummy space allocated by dma_alloc_coherent to
+                * throw data if there is no available buffer.
+                */
+               rkisp1_write(cap->rkisp1,
+                            cap->buf.dummy.dma_addr,
+                            cap->config->mi.y_base_ad_init);
+               rkisp1_write(cap->rkisp1,
+                            cap->buf.dummy.dma_addr,
+                            cap->config->mi.cb_base_ad_init);
+               rkisp1_write(cap->rkisp1,
+                            cap->buf.dummy.dma_addr,
+                            cap->config->mi.cr_base_ad_init);
+       }
+
+       /* Set plane offsets */
+       rkisp1_write(cap->rkisp1, 0, cap->config->mi.y_offs_cnt_init);
+       rkisp1_write(cap->rkisp1, 0, cap->config->mi.cb_offs_cnt_init);
+       rkisp1_write(cap->rkisp1, 0, cap->config->mi.cr_offs_cnt_init);
+}
+
+/*
+ * This function is called when a frame end comes. The next frame
+ * is processing and we should set up buffer for next-next frame,
+ * otherwise it will overflow.
+ */
+static void rkisp1_handle_buffer(struct rkisp1_capture *cap)
+{
+       struct rkisp1_isp *isp = &cap->rkisp1->isp;
+       struct rkisp1_buffer *curr_buf;
+
+       spin_lock(&cap->buf.lock);
+       curr_buf = cap->buf.curr;
+
+       if (curr_buf) {
+               curr_buf->vb.sequence = isp->frame_sequence;
+               curr_buf->vb.vb2_buf.timestamp = ktime_get_boottime_ns();
+               curr_buf->vb.field = V4L2_FIELD_NONE;
+               vb2_buffer_done(&curr_buf->vb.vb2_buf, VB2_BUF_STATE_DONE);
+       } else {
+               cap->rkisp1->debug.frame_drop[cap->id]++;
+       }
+
+       rkisp1_set_next_buf(cap);
+       spin_unlock(&cap->buf.lock);
+}
+
+void rkisp1_capture_isr(struct rkisp1_device *rkisp1)
+{
+       unsigned int i;
+       u32 status;
+
+       status = rkisp1_read(rkisp1, RKISP1_CIF_MI_MIS);
+       rkisp1_write(rkisp1, status, RKISP1_CIF_MI_ICR);
+
+       for (i = 0; i < ARRAY_SIZE(rkisp1->capture_devs); ++i) {
+               struct rkisp1_capture *cap = &rkisp1->capture_devs[i];
+
+               if (!(status & RKISP1_CIF_MI_FRAME(cap)))
+                       continue;
+               if (!cap->is_stopping) {
+                       rkisp1_handle_buffer(cap);
+                       continue;
+               }
+               /*
+                * Make sure stream is actually stopped, whose state
+                * can be read from the shadow register, before
+                * wake_up() thread which would immediately free all
+                * frame buffers. stop() takes effect at the next
+                * frame end that sync the configurations to shadow
+                * regs.
+                */
+               if (!cap->ops->is_stopped(cap)) {
+                       cap->ops->stop(cap);
+                       continue;
+               }
+               cap->is_stopping = false;
+               cap->is_streaming = false;
+               wake_up(&cap->done);
+       }
+}
+
+/* ----------------------------------------------------------------------------
+ * Vb2 operations
+ */
+
+static int rkisp1_vb2_queue_setup(struct vb2_queue *queue,
+                                 unsigned int *num_buffers,
+                                 unsigned int *num_planes,
+                                 unsigned int sizes[],
+                                 struct device *alloc_devs[])
+{
+       struct rkisp1_capture *cap = queue->drv_priv;
+       const struct v4l2_pix_format_mplane *pixm = &cap->pix.fmt;
+       unsigned int i;
+
+       if (*num_planes) {
+               if (*num_planes != pixm->num_planes)
+                       return -EINVAL;
+
+               for (i = 0; i < pixm->num_planes; i++)
+                       if (sizes[i] < pixm->plane_fmt[i].sizeimage)
+                               return -EINVAL;
+       } else {
+               *num_planes = pixm->num_planes;
+               for (i = 0; i < pixm->num_planes; i++)
+                       sizes[i] = pixm->plane_fmt[i].sizeimage;
+       }
+
+       return 0;
+}
+
+static void rkisp1_vb2_buf_queue(struct vb2_buffer *vb)
+{
+       struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
+       struct rkisp1_buffer *ispbuf =
+               container_of(vbuf, struct rkisp1_buffer, vb);
+       struct rkisp1_capture *cap = vb->vb2_queue->drv_priv;
+       const struct v4l2_pix_format_mplane *pixm = &cap->pix.fmt;
+       unsigned int i;
+
+       memset(ispbuf->buff_addr, 0, sizeof(ispbuf->buff_addr));
+       for (i = 0; i < pixm->num_planes; i++)
+               ispbuf->buff_addr[i] = vb2_dma_contig_plane_dma_addr(vb, i);
+
+       /* Convert to non-MPLANE */
+       if (pixm->num_planes == 1) {
+               ispbuf->buff_addr[RKISP1_PLANE_CB] =
+                       ispbuf->buff_addr[RKISP1_PLANE_Y] +
+                       rkisp1_pixfmt_comp_size(pixm, RKISP1_PLANE_Y);
+               ispbuf->buff_addr[RKISP1_PLANE_CR] =
+                       ispbuf->buff_addr[RKISP1_PLANE_CB] +
+                       rkisp1_pixfmt_comp_size(pixm, RKISP1_PLANE_CB);
+       }
+
+       /*
+        * uv swap can be supported for planar formats by switching
+        * the address of cb and cr
+        */
+       if (cap->pix.info->comp_planes == 3 && cap->pix.cfg->uv_swap)
+               swap(ispbuf->buff_addr[RKISP1_PLANE_CR],
+                    ispbuf->buff_addr[RKISP1_PLANE_CB]);
+
+       spin_lock_irq(&cap->buf.lock);
+       list_add_tail(&ispbuf->queue, &cap->buf.queue);
+       spin_unlock_irq(&cap->buf.lock);
+}
+
+static int rkisp1_vb2_buf_prepare(struct vb2_buffer *vb)
+{
+       struct rkisp1_capture *cap = vb->vb2_queue->drv_priv;
+       unsigned int i;
+
+       for (i = 0; i < cap->pix.fmt.num_planes; i++) {
+               unsigned long size = cap->pix.fmt.plane_fmt[i].sizeimage;
+
+               if (vb2_plane_size(vb, i) < size) {
+                       dev_err(cap->rkisp1->dev,
+                               "User buffer too small (%ld < %ld)\n",
+                               vb2_plane_size(vb, i), size);
+                       return -EINVAL;
+               }
+               vb2_set_plane_payload(vb, i, size);
+       }
+
+       return 0;
+}
+
+static void rkisp1_return_all_buffers(struct rkisp1_capture *cap,
+                                     enum vb2_buffer_state state)
+{
+       struct rkisp1_buffer *buf;
+
+       spin_lock_irq(&cap->buf.lock);
+       if (cap->buf.curr) {
+               vb2_buffer_done(&cap->buf.curr->vb.vb2_buf, state);
+               cap->buf.curr = NULL;
+       }
+       if (cap->buf.next) {
+               vb2_buffer_done(&cap->buf.next->vb.vb2_buf, state);
+               cap->buf.next = NULL;
+       }
+       while (!list_empty(&cap->buf.queue)) {
+               buf = list_first_entry(&cap->buf.queue,
+                                      struct rkisp1_buffer, queue);
+               list_del(&buf->queue);
+               vb2_buffer_done(&buf->vb.vb2_buf, state);
+       }
+       spin_unlock_irq(&cap->buf.lock);
+}
+
+/*
+ * Most of registers inside rockchip ISP1 have shadow register since
+ * they must be not be changed during processing a frame.
+ * Usually, each sub-module updates its shadow register after
+ * processing the last pixel of a frame.
+ */
+static void rkisp1_cap_stream_enable(struct rkisp1_capture *cap)
+{
+       struct rkisp1_device *rkisp1 = cap->rkisp1;
+       struct rkisp1_capture *other = &rkisp1->capture_devs[cap->id ^ 1];
+
+       cap->ops->set_data_path(cap);
+       cap->ops->config(cap);
+
+       /* Setup a buffer for the next frame */
+       spin_lock_irq(&cap->buf.lock);
+       rkisp1_set_next_buf(cap);
+       cap->ops->enable(cap);
+       /* It's safe to config ACTIVE and SHADOW regs for the
+        * first stream. While when the second is starting, do NOT
+        * force update because it also update the first one.
+        *
+        * The latter case would drop one more buf(that is 2) since
+        * there's not buf in shadow when the second FE received. This's
+        * also required because the second FE maybe corrupt especially
+        * when run at 120fps.
+        */
+       if (!other->is_streaming) {
+               /* force cfg update */
+               rkisp1_write(rkisp1,
+                            RKISP1_CIF_MI_INIT_SOFT_UPD, RKISP1_CIF_MI_INIT);
+               rkisp1_set_next_buf(cap);
+       }
+       spin_unlock_irq(&cap->buf.lock);
+       cap->is_streaming = true;
+}
+
+static void rkisp1_cap_stream_disable(struct rkisp1_capture *cap)
+{
+       int ret;
+
+       /* Stream should stop in interrupt. If it dosn't, stop it by force. */
+       cap->is_stopping = true;
+       ret = wait_event_timeout(cap->done,
+                                !cap->is_streaming,
+                                msecs_to_jiffies(1000));
+       if (!ret) {
+               cap->rkisp1->debug.stop_timeout[cap->id]++;
+               cap->ops->stop(cap);
+               cap->is_stopping = false;
+               cap->is_streaming = false;
+       }
+}
+
+/*
+ * rkisp1_pipeline_stream_disable - disable nodes in the pipeline
+ *
+ * Call s_stream(false) in the reverse order from
+ * rkisp1_pipeline_stream_enable() and disable the DMA engine.
+ * Should be called before media_pipeline_stop()
+ */
+static void rkisp1_pipeline_stream_disable(struct rkisp1_capture *cap)
+       __must_hold(&cap->rkisp1->stream_lock)
+{
+       struct rkisp1_device *rkisp1 = cap->rkisp1;
+
+       rkisp1_cap_stream_disable(cap);
+
+       /*
+        * If the other capture is streaming, isp and sensor nodes shouldn't
+        * be disabled, skip them.
+        */
+       if (rkisp1->pipe.streaming_count < 2) {
+               v4l2_subdev_call(rkisp1->active_sensor->sd, video, s_stream,
+                                false);
+               v4l2_subdev_call(&rkisp1->isp.sd, video, s_stream, false);
+       }
+
+       v4l2_subdev_call(&rkisp1->resizer_devs[cap->id].sd, video, s_stream,
+                        false);
+}
+
+/*
+ * rkisp1_pipeline_stream_enable - enable nodes in the pipeline
+ *
+ * Enable the DMA Engine and call s_stream(true) through the pipeline.
+ * Should be called after media_pipeline_start()
+ */
+static int rkisp1_pipeline_stream_enable(struct rkisp1_capture *cap)
+       __must_hold(&cap->rkisp1->stream_lock)
+{
+       struct rkisp1_device *rkisp1 = cap->rkisp1;
+       int ret;
+
+       rkisp1_cap_stream_enable(cap);
+
+       ret = v4l2_subdev_call(&rkisp1->resizer_devs[cap->id].sd, video,
+                              s_stream, true);
+       if (ret)
+               goto err_disable_cap;
+
+       /*
+        * If the other capture is streaming, isp and sensor nodes are already
+        * enabled, skip them.
+        */
+       if (rkisp1->pipe.streaming_count > 1)
+               return 0;
+
+       ret = v4l2_subdev_call(&rkisp1->isp.sd, video, s_stream, true);
+       if (ret)
+               goto err_disable_rsz;
+
+       ret = v4l2_subdev_call(rkisp1->active_sensor->sd, video, s_stream,
+                              true);
+       if (ret)
+               goto err_disable_isp;
+
+       return 0;
+
+err_disable_isp:
+       v4l2_subdev_call(&rkisp1->isp.sd, video, s_stream, false);
+err_disable_rsz:
+       v4l2_subdev_call(&rkisp1->resizer_devs[cap->id].sd, video, s_stream,
+                        false);
+err_disable_cap:
+       rkisp1_cap_stream_disable(cap);
+
+       return ret;
+}
+
+static void rkisp1_vb2_stop_streaming(struct vb2_queue *queue)
+{
+       struct rkisp1_capture *cap = queue->drv_priv;
+       struct rkisp1_vdev_node *node = &cap->vnode;
+       struct rkisp1_device *rkisp1 = cap->rkisp1;
+       int ret;
+
+       mutex_lock(&cap->rkisp1->stream_lock);
+
+       rkisp1_pipeline_stream_disable(cap);
+
+       rkisp1_return_all_buffers(cap, VB2_BUF_STATE_ERROR);
+
+       v4l2_pipeline_pm_put(&node->vdev.entity);
+       ret = pm_runtime_put(rkisp1->dev);
+       if (ret < 0)
+               dev_err(rkisp1->dev, "power down failed error:%d\n", ret);
+
+       rkisp1_dummy_buf_destroy(cap);
+
+       media_pipeline_stop(&node->vdev.entity);
+
+       mutex_unlock(&cap->rkisp1->stream_lock);
+}
+
+static int
+rkisp1_vb2_start_streaming(struct vb2_queue *queue, unsigned int count)
+{
+       struct rkisp1_capture *cap = queue->drv_priv;
+       struct media_entity *entity = &cap->vnode.vdev.entity;
+       int ret;
+
+       mutex_lock(&cap->rkisp1->stream_lock);
+
+       ret = media_pipeline_start(entity, &cap->rkisp1->pipe);
+       if (ret) {
+               dev_err(cap->rkisp1->dev, "start pipeline failed %d\n", ret);
+               goto err_ret_buffers;
+       }
+
+       ret = rkisp1_dummy_buf_create(cap);
+       if (ret)
+               goto err_pipeline_stop;
+
+       ret = pm_runtime_get_sync(cap->rkisp1->dev);
+       if (ret < 0) {
+               pm_runtime_put_noidle(cap->rkisp1->dev);
+               dev_err(cap->rkisp1->dev, "power up failed %d\n", ret);
+               goto err_destroy_dummy;
+       }
+       ret = v4l2_pipeline_pm_get(entity);
+       if (ret) {
+               dev_err(cap->rkisp1->dev, "open cif pipeline failed %d\n", ret);
+               goto err_pipe_pm_put;
+       }
+
+       ret = rkisp1_pipeline_stream_enable(cap);
+       if (ret)
+               goto err_v4l2_pm_put;
+
+       mutex_unlock(&cap->rkisp1->stream_lock);
+
+       return 0;
+
+err_v4l2_pm_put:
+       v4l2_pipeline_pm_put(entity);
+err_pipe_pm_put:
+       pm_runtime_put(cap->rkisp1->dev);
+err_destroy_dummy:
+       rkisp1_dummy_buf_destroy(cap);
+err_pipeline_stop:
+       media_pipeline_stop(entity);
+err_ret_buffers:
+       rkisp1_return_all_buffers(cap, VB2_BUF_STATE_QUEUED);
+       mutex_unlock(&cap->rkisp1->stream_lock);
+
+       return ret;
+}
+
+static struct vb2_ops rkisp1_vb2_ops = {
+       .queue_setup = rkisp1_vb2_queue_setup,
+       .buf_queue = rkisp1_vb2_buf_queue,
+       .buf_prepare = rkisp1_vb2_buf_prepare,
+       .wait_prepare = vb2_ops_wait_prepare,
+       .wait_finish = vb2_ops_wait_finish,
+       .stop_streaming = rkisp1_vb2_stop_streaming,
+       .start_streaming = rkisp1_vb2_start_streaming,
+};
+
+/* ----------------------------------------------------------------------------
+ * IOCTLs operations
+ */
+
+static const struct v4l2_format_info *
+rkisp1_fill_pixfmt(struct v4l2_pix_format_mplane *pixm,
+                  enum rkisp1_stream_id id)
+{
+       struct v4l2_plane_pix_format *plane_y = &pixm->plane_fmt[0];
+       const struct v4l2_format_info *info;
+       unsigned int i;
+       u32 stride;
+
+       memset(pixm->plane_fmt, 0, sizeof(pixm->plane_fmt));
+       info = v4l2_format_info(pixm->pixelformat);
+       pixm->num_planes = info->mem_planes;
+       stride = info->bpp[0] * pixm->width;
+       /* Self path supports custom stride but Main path doesn't */
+       if (id == RKISP1_MAINPATH || plane_y->bytesperline < stride)
+               plane_y->bytesperline = stride;
+       plane_y->sizeimage = plane_y->bytesperline * pixm->height;
+
+       /* normalize stride to pixels per line */
+       stride = DIV_ROUND_UP(plane_y->bytesperline, info->bpp[0]);
+
+       for (i = 1; i < info->comp_planes; i++) {
+               struct v4l2_plane_pix_format *plane = &pixm->plane_fmt[i];
+
+               /* bytesperline for other components derive from Y component */
+               plane->bytesperline = DIV_ROUND_UP(stride, info->hdiv) *
+                                     info->bpp[i];
+               plane->sizeimage = plane->bytesperline *
+                                  DIV_ROUND_UP(pixm->height, info->vdiv);
+       }
+
+       /*
+        * If pixfmt is packed, then plane_fmt[0] should contain the total size
+        * considering all components. plane_fmt[i] for i > 0 should be ignored
+        * by userspace as mem_planes == 1, but we are keeping information there
+        * for convenience.
+        */
+       if (info->mem_planes == 1)
+               for (i = 1; i < info->comp_planes; i++)
+                       plane_y->sizeimage += pixm->plane_fmt[i].sizeimage;
+
+       return info;
+}
+
+static const struct rkisp1_capture_fmt_cfg *
+rkisp1_find_fmt_cfg(const struct rkisp1_capture *cap, const u32 pixelfmt)
+{
+       unsigned int i;
+
+       for (i = 0; i < cap->config->fmt_size; i++) {
+               if (cap->config->fmts[i].fourcc == pixelfmt)
+                       return &cap->config->fmts[i];
+       }
+       return NULL;
+}
+
+static void rkisp1_try_fmt(const struct rkisp1_capture *cap,
+                          struct v4l2_pix_format_mplane *pixm,
+                          const struct rkisp1_capture_fmt_cfg **fmt_cfg,
+                          const struct v4l2_format_info **fmt_info)
+{
+       const struct rkisp1_capture_config *config = cap->config;
+       const struct rkisp1_capture_fmt_cfg *fmt;
+       const struct v4l2_format_info *info;
+       const unsigned int max_widths[] = { RKISP1_RSZ_MP_SRC_MAX_WIDTH,
+                                           RKISP1_RSZ_SP_SRC_MAX_WIDTH };
+       const unsigned int max_heights[] = { RKISP1_RSZ_MP_SRC_MAX_HEIGHT,
+                                            RKISP1_RSZ_SP_SRC_MAX_HEIGHT};
+
+       fmt = rkisp1_find_fmt_cfg(cap, pixm->pixelformat);
+       if (!fmt) {
+               fmt = config->fmts;
+               pixm->pixelformat = fmt->fourcc;
+       }
+
+       pixm->width = clamp_t(u32, pixm->width,
+                             RKISP1_RSZ_SRC_MIN_WIDTH, max_widths[cap->id]);
+       pixm->height = clamp_t(u32, pixm->height,
+                              RKISP1_RSZ_SRC_MIN_HEIGHT, max_heights[cap->id]);
+
+       pixm->field = V4L2_FIELD_NONE;
+       pixm->colorspace = V4L2_COLORSPACE_DEFAULT;
+       pixm->ycbcr_enc = V4L2_YCBCR_ENC_DEFAULT;
+       pixm->quantization = V4L2_QUANTIZATION_DEFAULT;
+
+       info = rkisp1_fill_pixfmt(pixm, cap->id);
+
+       if (fmt_cfg)
+               *fmt_cfg = fmt;
+       if (fmt_info)
+               *fmt_info = info;
+}
+
+static void rkisp1_set_fmt(struct rkisp1_capture *cap,
+                          struct v4l2_pix_format_mplane *pixm)
+{
+       rkisp1_try_fmt(cap, pixm, &cap->pix.cfg, &cap->pix.info);
+       cap->pix.fmt = *pixm;
+
+       /* SP supports custom stride in number of pixels of the Y plane */
+       if (cap->id == RKISP1_SELFPATH)
+               cap->sp_y_stride = pixm->plane_fmt[0].bytesperline /
+                                  cap->pix.info->bpp[0];
+}
+
+static int rkisp1_try_fmt_vid_cap_mplane(struct file *file, void *fh,
+                                        struct v4l2_format *f)
+{
+       struct rkisp1_capture *cap = video_drvdata(file);
+
+       rkisp1_try_fmt(cap, &f->fmt.pix_mp, NULL, NULL);
+
+       return 0;
+}
+
+static int rkisp1_enum_fmt_vid_cap_mplane(struct file *file, void *priv,
+                                         struct v4l2_fmtdesc *f)
+{
+       struct rkisp1_capture *cap = video_drvdata(file);
+       const struct rkisp1_capture_fmt_cfg *fmt = NULL;
+       unsigned int i, n = 0;
+
+       if (!f->mbus_code) {
+               if (f->index >= cap->config->fmt_size)
+                       return -EINVAL;
+
+               fmt = &cap->config->fmts[f->index];
+               f->pixelformat = fmt->fourcc;
+               return 0;
+       }
+
+       for (i = 0; i < cap->config->fmt_size; i++) {
+               if (cap->config->fmts[i].mbus != f->mbus_code)
+                       continue;
+
+               if (n++ == f->index) {
+                       f->pixelformat = cap->config->fmts[i].fourcc;
+                       return 0;
+               }
+       }
+       return -EINVAL;
+}
+
+static int rkisp1_s_fmt_vid_cap_mplane(struct file *file,
+                                      void *priv, struct v4l2_format *f)
+{
+       struct rkisp1_capture *cap = video_drvdata(file);
+       struct rkisp1_vdev_node *node =
+                               rkisp1_vdev_to_node(&cap->vnode.vdev);
+
+       if (vb2_is_busy(&node->buf_queue))
+               return -EBUSY;
+
+       rkisp1_set_fmt(cap, &f->fmt.pix_mp);
+
+       return 0;
+}
+
+static int rkisp1_g_fmt_vid_cap_mplane(struct file *file, void *fh,
+                                      struct v4l2_format *f)
+{
+       struct rkisp1_capture *cap = video_drvdata(file);
+
+       f->fmt.pix_mp = cap->pix.fmt;
+
+       return 0;
+}
+
+static int
+rkisp1_querycap(struct file *file, void *priv, struct v4l2_capability *cap)
+{
+       struct rkisp1_capture *cap_dev = video_drvdata(file);
+       struct rkisp1_device *rkisp1 = cap_dev->rkisp1;
+
+       strscpy(cap->driver, rkisp1->dev->driver->name, sizeof(cap->driver));
+       strscpy(cap->card, rkisp1->dev->driver->name, sizeof(cap->card));
+       strscpy(cap->bus_info, RKISP1_BUS_INFO, sizeof(cap->bus_info));
+
+       return 0;
+}
+
+static const struct v4l2_ioctl_ops rkisp1_v4l2_ioctl_ops = {
+       .vidioc_reqbufs = vb2_ioctl_reqbufs,
+       .vidioc_querybuf = vb2_ioctl_querybuf,
+       .vidioc_create_bufs = vb2_ioctl_create_bufs,
+       .vidioc_qbuf = vb2_ioctl_qbuf,
+       .vidioc_expbuf = vb2_ioctl_expbuf,
+       .vidioc_dqbuf = vb2_ioctl_dqbuf,
+       .vidioc_prepare_buf = vb2_ioctl_prepare_buf,
+       .vidioc_streamon = vb2_ioctl_streamon,
+       .vidioc_streamoff = vb2_ioctl_streamoff,
+       .vidioc_try_fmt_vid_cap_mplane = rkisp1_try_fmt_vid_cap_mplane,
+       .vidioc_s_fmt_vid_cap_mplane = rkisp1_s_fmt_vid_cap_mplane,
+       .vidioc_g_fmt_vid_cap_mplane = rkisp1_g_fmt_vid_cap_mplane,
+       .vidioc_enum_fmt_vid_cap = rkisp1_enum_fmt_vid_cap_mplane,
+       .vidioc_querycap = rkisp1_querycap,
+       .vidioc_subscribe_event = v4l2_ctrl_subscribe_event,
+       .vidioc_unsubscribe_event = v4l2_event_unsubscribe,
+};
+
+static int rkisp1_capture_link_validate(struct media_link *link)
+{
+       struct video_device *vdev =
+               media_entity_to_video_device(link->sink->entity);
+       struct v4l2_subdev *sd =
+               media_entity_to_v4l2_subdev(link->source->entity);
+       struct rkisp1_capture *cap = video_get_drvdata(vdev);
+       const struct rkisp1_capture_fmt_cfg *fmt =
+               rkisp1_find_fmt_cfg(cap, cap->pix.fmt.pixelformat);
+       struct v4l2_subdev_format sd_fmt;
+       int ret;
+
+       sd_fmt.which = V4L2_SUBDEV_FORMAT_ACTIVE;
+       sd_fmt.pad = link->source->index;
+       ret = v4l2_subdev_call(sd, pad, get_fmt, NULL, &sd_fmt);
+       if (ret)
+               return ret;
+
+       if (sd_fmt.format.height != cap->pix.fmt.height ||
+           sd_fmt.format.width != cap->pix.fmt.width ||
+           sd_fmt.format.code != fmt->mbus)
+               return -EPIPE;
+
+       return 0;
+}
+
+/* ----------------------------------------------------------------------------
+ * core functions
+ */
+
+static const struct media_entity_operations rkisp1_media_ops = {
+       .link_validate = rkisp1_capture_link_validate,
+};
+
+static const struct v4l2_file_operations rkisp1_fops = {
+       .open = v4l2_fh_open,
+       .release = vb2_fop_release,
+       .unlocked_ioctl = video_ioctl2,
+       .poll = vb2_fop_poll,
+       .mmap = vb2_fop_mmap,
+};
+
+static void rkisp1_unregister_capture(struct rkisp1_capture *cap)
+{
+       media_entity_cleanup(&cap->vnode.vdev.entity);
+       vb2_video_unregister_device(&cap->vnode.vdev);
+}
+
+void rkisp1_capture_devs_unregister(struct rkisp1_device *rkisp1)
+{
+       struct rkisp1_capture *mp = &rkisp1->capture_devs[RKISP1_MAINPATH];
+       struct rkisp1_capture *sp = &rkisp1->capture_devs[RKISP1_SELFPATH];
+
+       rkisp1_unregister_capture(mp);
+       rkisp1_unregister_capture(sp);
+}
+
+static int rkisp1_register_capture(struct rkisp1_capture *cap)
+{
+       const char * const dev_names[] = {RKISP1_MP_DEV_NAME,
+                                         RKISP1_SP_DEV_NAME};
+       struct v4l2_device *v4l2_dev = &cap->rkisp1->v4l2_dev;
+       struct video_device *vdev = &cap->vnode.vdev;
+       struct rkisp1_vdev_node *node;
+       struct vb2_queue *q;
+       int ret;
+
+       strscpy(vdev->name, dev_names[cap->id], sizeof(vdev->name));
+       node = rkisp1_vdev_to_node(vdev);
+       mutex_init(&node->vlock);
+
+       vdev->ioctl_ops = &rkisp1_v4l2_ioctl_ops;
+       vdev->release = video_device_release_empty;
+       vdev->fops = &rkisp1_fops;
+       vdev->minor = -1;
+       vdev->v4l2_dev = v4l2_dev;
+       vdev->lock = &node->vlock;
+       vdev->device_caps = V4L2_CAP_VIDEO_CAPTURE_MPLANE |
+                           V4L2_CAP_STREAMING | V4L2_CAP_IO_MC;
+       vdev->entity.ops = &rkisp1_media_ops;
+       video_set_drvdata(vdev, cap);
+       vdev->vfl_dir = VFL_DIR_RX;
+       node->pad.flags = MEDIA_PAD_FL_SINK;
+
+       q = &node->buf_queue;
+       q->type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
+       q->io_modes = VB2_MMAP | VB2_DMABUF;
+       q->drv_priv = cap;
+       q->ops = &rkisp1_vb2_ops;
+       q->mem_ops = &vb2_dma_contig_memops;
+       q->buf_struct_size = sizeof(struct rkisp1_buffer);
+       q->min_buffers_needed = RKISP1_MIN_BUFFERS_NEEDED;
+       q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
+       q->lock = &node->vlock;
+       q->dev = cap->rkisp1->dev;
+       ret = vb2_queue_init(q);
+       if (ret) {
+               dev_err(cap->rkisp1->dev,
+                       "vb2 queue init failed (err=%d)\n", ret);
+               return ret;
+       }
+
+       vdev->queue = q;
+
+       ret = video_register_device(vdev, VFL_TYPE_VIDEO, -1);
+       if (ret) {
+               dev_err(cap->rkisp1->dev,
+                       "failed to register %s, ret=%d\n", vdev->name, ret);
+               return ret;
+       }
+       v4l2_info(v4l2_dev, "registered %s as /dev/video%d\n", vdev->name,
+                 vdev->num);
+
+       ret = media_entity_pads_init(&vdev->entity, 1, &node->pad);
+       if (ret) {
+               video_unregister_device(vdev);
+               return ret;
+       }
+
+       return 0;
+}
+
+static void
+rkisp1_capture_init(struct rkisp1_device *rkisp1, enum rkisp1_stream_id id)
+{
+       struct rkisp1_capture *cap = &rkisp1->capture_devs[id];
+       struct v4l2_pix_format_mplane pixm;
+
+       memset(cap, 0, sizeof(*cap));
+       cap->id = id;
+       cap->rkisp1 = rkisp1;
+
+       INIT_LIST_HEAD(&cap->buf.queue);
+       init_waitqueue_head(&cap->done);
+       spin_lock_init(&cap->buf.lock);
+       if (cap->id == RKISP1_SELFPATH) {
+               cap->ops = &rkisp1_capture_ops_sp;
+               cap->config = &rkisp1_capture_config_sp;
+       } else {
+               cap->ops = &rkisp1_capture_ops_mp;
+               cap->config = &rkisp1_capture_config_mp;
+       }
+
+       cap->is_streaming = false;
+
+       memset(&pixm, 0, sizeof(pixm));
+       pixm.pixelformat = V4L2_PIX_FMT_YUYV;
+       pixm.width = RKISP1_DEFAULT_WIDTH;
+       pixm.height = RKISP1_DEFAULT_HEIGHT;
+       rkisp1_set_fmt(cap, &pixm);
+}
+
+int rkisp1_capture_devs_register(struct rkisp1_device *rkisp1)
+{
+       struct rkisp1_capture *cap;
+       unsigned int i, j;
+       int ret;
+
+       for (i = 0; i < ARRAY_SIZE(rkisp1->capture_devs); i++) {
+               rkisp1_capture_init(rkisp1, i);
+               cap = &rkisp1->capture_devs[i];
+               cap->rkisp1 = rkisp1;
+               ret = rkisp1_register_capture(cap);
+               if (ret)
+                       goto err_unreg_capture_devs;
+       }
+
+       return 0;
+
+err_unreg_capture_devs:
+       for (j = 0; j < i; j++) {
+               cap = &rkisp1->capture_devs[j];
+               rkisp1_unregister_capture(cap);
+       }
+
+       return ret;
+}
diff --git a/drivers/media/platform/rockchip/rkisp1/rkisp1-common.c b/drivers/media/platform/rockchip/rkisp1/rkisp1-common.c
new file mode 100644 (file)
index 0000000..cf88966
--- /dev/null
@@ -0,0 +1,37 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Rockchip ISP1 Driver - Common definitions
+ *
+ * Copyright (C) 2019 Collabora, Ltd.
+ */
+
+#include <media/v4l2-rect.h>
+
+#include "rkisp1-common.h"
+
+static const struct v4l2_rect rkisp1_sd_min_crop = {
+       .width = RKISP1_ISP_MIN_WIDTH,
+       .height = RKISP1_ISP_MIN_HEIGHT,
+       .top = 0,
+       .left = 0,
+};
+
+void rkisp1_sd_adjust_crop_rect(struct v4l2_rect *crop,
+                               const struct v4l2_rect *bounds)
+{
+       v4l2_rect_set_min_size(crop, &rkisp1_sd_min_crop);
+       v4l2_rect_map_inside(crop, bounds);
+}
+
+void rkisp1_sd_adjust_crop(struct v4l2_rect *crop,
+                          const struct v4l2_mbus_framefmt *bounds)
+{
+       struct v4l2_rect crop_bounds = {
+               .left = 0,
+               .top = 0,
+               .width = bounds->width,
+               .height = bounds->height,
+       };
+
+       rkisp1_sd_adjust_crop_rect(crop, &crop_bounds);
+}
diff --git a/drivers/media/platform/rockchip/rkisp1/rkisp1-common.h b/drivers/media/platform/rockchip/rkisp1/rkisp1-common.h
new file mode 100644 (file)
index 0000000..3a134e9
--- /dev/null
@@ -0,0 +1,485 @@
+/* SPDX-License-Identifier: (GPL-2.0+ OR MIT) */
+/*
+ * Rockchip ISP1 Driver - Common definitions
+ *
+ * Copyright (C) 2019 Collabora, Ltd.
+ *
+ * Based on Rockchip ISP1 driver by Rockchip Electronics Co., Ltd.
+ * Copyright (C) 2017 Rockchip Electronics Co., Ltd.
+ */
+
+#ifndef _RKISP1_COMMON_H
+#define _RKISP1_COMMON_H
+
+#include <linux/clk.h>
+#include <linux/mutex.h>
+#include <linux/rkisp1-config.h>
+#include <media/media-device.h>
+#include <media/media-entity.h>
+#include <media/v4l2-ctrls.h>
+#include <media/v4l2-device.h>
+#include <media/videobuf2-v4l2.h>
+
+#include "rkisp1-regs.h"
+
+/*
+ * flags on the 'direction' field in struct 'rkisp1_isp_mbus_info' that indicate
+ * on which pad the media bus format is supported
+ */
+#define RKISP1_ISP_SD_SRC BIT(0)
+#define RKISP1_ISP_SD_SINK BIT(1)
+
+/* min and max values for the widths and heights of the entities */
+#define RKISP1_ISP_MAX_WIDTH           4032
+#define RKISP1_ISP_MAX_HEIGHT          3024
+#define RKISP1_ISP_MIN_WIDTH           32
+#define RKISP1_ISP_MIN_HEIGHT          32
+
+#define RKISP1_RSZ_MP_SRC_MAX_WIDTH            4416
+#define RKISP1_RSZ_MP_SRC_MAX_HEIGHT           3312
+#define RKISP1_RSZ_SP_SRC_MAX_WIDTH            1920
+#define RKISP1_RSZ_SP_SRC_MAX_HEIGHT           1920
+#define RKISP1_RSZ_SRC_MIN_WIDTH               32
+#define RKISP1_RSZ_SRC_MIN_HEIGHT              16
+
+/* the default width and height of all the entities */
+#define RKISP1_DEFAULT_WIDTH           800
+#define RKISP1_DEFAULT_HEIGHT          600
+
+#define RKISP1_DRIVER_NAME     "rkisp1"
+#define RKISP1_BUS_INFO                "platform:" RKISP1_DRIVER_NAME
+
+/* maximum number of clocks */
+#define RKISP1_MAX_BUS_CLK     8
+
+/* a bitmask of the ready stats */
+#define RKISP1_STATS_MEAS_MASK         (RKISP1_CIF_ISP_AWB_DONE |      \
+                                        RKISP1_CIF_ISP_AFM_FIN |       \
+                                        RKISP1_CIF_ISP_EXP_END |       \
+                                        RKISP1_CIF_ISP_HIST_MEASURE_RDY)
+
+/* enum for the resizer pads */
+enum rkisp1_rsz_pad {
+       RKISP1_RSZ_PAD_SINK,
+       RKISP1_RSZ_PAD_SRC,
+       RKISP1_RSZ_PAD_MAX
+};
+
+/* enum for the capture id */
+enum rkisp1_stream_id {
+       RKISP1_MAINPATH,
+       RKISP1_SELFPATH,
+};
+
+/* bayer patterns */
+enum rkisp1_fmt_raw_pat_type {
+       RKISP1_RAW_RGGB = 0,
+       RKISP1_RAW_GRBG,
+       RKISP1_RAW_GBRG,
+       RKISP1_RAW_BGGR,
+};
+
+/* enum for the isp pads */
+enum rkisp1_isp_pad {
+       RKISP1_ISP_PAD_SINK_VIDEO,
+       RKISP1_ISP_PAD_SINK_PARAMS,
+       RKISP1_ISP_PAD_SOURCE_VIDEO,
+       RKISP1_ISP_PAD_SOURCE_STATS,
+       RKISP1_ISP_PAD_MAX
+};
+
+/*
+ * struct rkisp1_sensor_async - A container for the v4l2_async_subdev to add to the notifier
+ *                             of the v4l2-async API
+ *
+ * @asd:               async_subdev variable for the sensor
+ * @lanes:             number of lanes
+ * @mbus_type:         type of bus (currently only CSI2 is supported)
+ * @mbus_flags:                media bus (V4L2_MBUS_*) flags
+ * @sd:                        a pointer to v4l2_subdev struct of the sensor
+ * @pixel_rate_ctrl:   pixel rate of the sensor, used to initialize the phy
+ * @dphy:              a pointer to the phy
+ */
+struct rkisp1_sensor_async {
+       struct v4l2_async_subdev asd;
+       unsigned int lanes;
+       enum v4l2_mbus_type mbus_type;
+       unsigned int mbus_flags;
+       struct v4l2_subdev *sd;
+       struct v4l2_ctrl *pixel_rate_ctrl;
+       struct phy *dphy;
+};
+
+/*
+ * struct rkisp1_isp - ISP subdev entity
+ *
+ * @sd:                                v4l2_subdev variable
+ * @rkisp1:                    pointer to rkisp1_device
+ * @pads:                      media pads
+ * @pad_cfg:                   pads configurations
+ * @sink_fmt:                  input format
+ * @src_fmt:                   output format
+ * @ops_lock:                  ops serialization
+ * @is_dphy_errctrl_disabled:  if dphy errctrl is disabled (avoid endless interrupt)
+ * @frame_sequence:            used to synchronize frame_id between video devices.
+ */
+struct rkisp1_isp {
+       struct v4l2_subdev sd;
+       struct media_pad pads[RKISP1_ISP_PAD_MAX];
+       struct v4l2_subdev_pad_config pad_cfg[RKISP1_ISP_PAD_MAX];
+       const struct rkisp1_isp_mbus_info *sink_fmt;
+       const struct rkisp1_isp_mbus_info *src_fmt;
+       struct mutex ops_lock; /* serialize the subdevice ops */
+       bool is_dphy_errctrl_disabled;
+       __u32 frame_sequence;
+};
+
+/*
+ * struct rkisp1_vdev_node - Container for the video nodes: params, stats, mainpath, selfpath
+ *
+ * @buf_queue: queue of buffers
+ * @vlock:     lock of the video node
+ * @vdev:      video node
+ * @pad:       media pad
+ */
+struct rkisp1_vdev_node {
+       struct vb2_queue buf_queue;
+       struct mutex vlock; /* ioctl serialization mutex */
+       struct video_device vdev;
+       struct media_pad pad;
+};
+
+/*
+ * struct rkisp1_buffer - A container for the vb2 buffers used by the video devices:
+ *                       params, stats, mainpath, selfpath
+ *
+ * @vb:                vb2 buffer
+ * @queue:     entry of the buffer in the queue
+ * @buff_addr: dma addresses of each plane, used only by the capture devices: selfpath, mainpath
+ * @vaddr:     virtual address for buffers used by params and stats devices
+ */
+struct rkisp1_buffer {
+       struct vb2_v4l2_buffer vb;
+       struct list_head queue;
+       union {
+               u32 buff_addr[VIDEO_MAX_PLANES];
+               void *vaddr;
+       };
+};
+
+/*
+ * struct rkisp1_dummy_buffer - A buffer to write the next frame to in case
+ *                             there are no vb2 buffers available.
+ *
+ * @vaddr:     return value of call to dma_alloc_attrs.
+ * @dma_addr:  dma address of the buffer.
+ * @size:      size of the buffer.
+ */
+struct rkisp1_dummy_buffer {
+       void *vaddr;
+       dma_addr_t dma_addr;
+       u32 size;
+};
+
+struct rkisp1_device;
+
+/*
+ * struct rkisp1_capture - ISP capture video device
+ *
+ * @vnode:       video node
+ * @rkisp1:      pointer to rkisp1_device
+ * @id:                  id of the capture, one of RKISP1_SELFPATH, RKISP1_MAINPATH
+ * @ops:         list of callbacks to configure the capture device.
+ * @config:      a pointer to the list of registers to configure the capture format.
+ * @is_streaming: device is streaming
+ * @is_stopping:  stop_streaming callback was called and the device is in the process of
+ *               stopping the streaming.
+ * @done:        when stop_streaming callback is called, the device waits for the next irq
+ *               handler to stop the streaming by waiting on the 'done' wait queue.
+ *               If the irq handler is not called, the stream is stopped by the callback
+ *               after timeout.
+ * @sp_y_stride:  the selfpath allows to configure a y stride that is longer than the image width.
+ * @buf.lock:    lock to protect buf.queue
+ * @buf.queue:   queued buffer list
+ * @buf.dummy:   dummy space to store dropped data
+ *
+ * rkisp1 uses shadow registers, so it needs two buffers at a time
+ * @buf.curr:    the buffer used for current frame
+ * @buf.next:    the buffer used for next frame
+ * @pix.cfg:     pixel configuration
+ * @pix.info:    a pointer to the v4l2_format_info of the pixel format
+ * @pix.fmt:     buffer format
+ */
+struct rkisp1_capture {
+       struct rkisp1_vdev_node vnode;
+       struct rkisp1_device *rkisp1;
+       enum rkisp1_stream_id id;
+       struct rkisp1_capture_ops *ops;
+       const struct rkisp1_capture_config *config;
+       bool is_streaming;
+       bool is_stopping;
+       wait_queue_head_t done;
+       unsigned int sp_y_stride;
+       struct {
+               /* protects queue, curr and next */
+               spinlock_t lock;
+               struct list_head queue;
+               struct rkisp1_dummy_buffer dummy;
+               struct rkisp1_buffer *curr;
+               struct rkisp1_buffer *next;
+       } buf;
+       struct {
+               const struct rkisp1_capture_fmt_cfg *cfg;
+               const struct v4l2_format_info *info;
+               struct v4l2_pix_format_mplane fmt;
+       } pix;
+};
+
+/*
+ * struct rkisp1_stats - ISP Statistics device
+ *
+ * @vnode:       video node
+ * @rkisp1:      pointer to the rkisp1 device
+ * @lock:        locks the buffer list 'stat'
+ * @stat:        queue of rkisp1_buffer
+ * @vdev_fmt:    v4l2_format of the metadata format
+ */
+struct rkisp1_stats {
+       struct rkisp1_vdev_node vnode;
+       struct rkisp1_device *rkisp1;
+
+       spinlock_t lock; /* locks the buffers list 'stats' */
+       struct list_head stat;
+       struct v4l2_format vdev_fmt;
+};
+
+/*
+ * struct rkisp1_params - ISP input parameters device
+ *
+ * @vnode:             video node
+ * @rkisp1:            pointer to the rkisp1 device
+ * @config_lock:       locks the buffer list 'params'
+ * @params:            queue of rkisp1_buffer
+ * @vdev_fmt:          v4l2_format of the metadata format
+ * @quantization:      the quantization configured on the isp's src pad
+ * @raw_type:          the bayer pattern on the isp video sink pad
+ */
+struct rkisp1_params {
+       struct rkisp1_vdev_node vnode;
+       struct rkisp1_device *rkisp1;
+
+       spinlock_t config_lock; /* locks the buffers list 'params' */
+       struct list_head params;
+       struct v4l2_format vdev_fmt;
+
+       enum v4l2_quantization quantization;
+       enum rkisp1_fmt_raw_pat_type raw_type;
+};
+
+/*
+ * struct rkisp1_resizer - Resizer subdev
+ *
+ * @sd:               v4l2_subdev variable
+ * @id:               id of the resizer, one of RKISP1_SELFPATH, RKISP1_MAINPATH
+ * @rkisp1:    pointer to the rkisp1 device
+ * @pads:      media pads
+ * @pad_cfg:   configurations for the pads
+ * @config:    the set of registers to configure the resizer
+ * @pixel_enc: pixel encoding of the resizer
+ * @ops_lock:  a lock for the subdev ops
+ */
+struct rkisp1_resizer {
+       struct v4l2_subdev sd;
+       enum rkisp1_stream_id id;
+       struct rkisp1_device *rkisp1;
+       struct media_pad pads[RKISP1_RSZ_PAD_MAX];
+       struct v4l2_subdev_pad_config pad_cfg[RKISP1_RSZ_PAD_MAX];
+       const struct rkisp1_rsz_config *config;
+       enum v4l2_pixel_encoding pixel_enc;
+       struct mutex ops_lock; /* serialize the subdevice ops */
+};
+
+/*
+ * struct rkisp1_debug - Values to be exposed on debugfs.
+ *                      The parameters are counters of the number of times the
+ *                      event occurred since the driver was loaded.
+ *
+ * @data_loss:                   loss of data occurred within a line, processing failure
+ * @outform_size_error:                  size error is generated in outmux submodule
+ * @img_stabilization_size_error: size error is generated in image stabilization submodule
+ * @inform_size_err:             size error is generated in inform submodule
+ * @mipi_error:                          mipi error occurred
+ * @stats_error:                 writing to the 'Interrupt clear register' did not clear
+ *                               it in the register 'Masked interrupt status'
+ * @stop_timeout:                upon stream stop, the capture waits 1 second for the isr to stop
+ *                               the stream. This param is incremented in case of timeout.
+ * @frame_drop:                          a frame was ready but the buffer queue was empty so the frame
+ *                               was not sent to userspace
+ */
+struct rkisp1_debug {
+       struct dentry *debugfs_dir;
+       unsigned long data_loss;
+       unsigned long outform_size_error;
+       unsigned long img_stabilization_size_error;
+       unsigned long inform_size_error;
+       unsigned long irq_delay;
+       unsigned long mipi_error;
+       unsigned long stats_error;
+       unsigned long stop_timeout[2];
+       unsigned long frame_drop[2];
+};
+
+/*
+ * struct rkisp1_device - ISP platform device
+ *
+ * @base_addr:    base register address
+ * @irq:          the irq number
+ * @dev:          a pointer to the struct device
+ * @clk_size:     number of clocks
+ * @clks:         array of clocks
+ * @v4l2_dev:     v4l2_device variable
+ * @media_dev:    media_device variable
+ * @notifier:     a notifier to register on the v4l2-async API to be notified on the sensor
+ * @active_sensor: sensor in-use, set when streaming on
+ * @isp:          ISP sub-device
+ * @resizer_devs:  resizer sub-devices
+ * @capture_devs:  capture devices
+ * @stats:        ISP statistics metadata capture device
+ * @params:       ISP parameters metadata output device
+ * @pipe:         media pipeline
+ * @stream_lock:   serializes {start/stop}_streaming callbacks between the capture devices.
+ * @debug:        debug params to be exposed on debugfs
+ */
+struct rkisp1_device {
+       void __iomem *base_addr;
+       int irq;
+       struct device *dev;
+       unsigned int clk_size;
+       struct clk_bulk_data clks[RKISP1_MAX_BUS_CLK];
+       struct v4l2_device v4l2_dev;
+       struct media_device media_dev;
+       struct v4l2_async_notifier notifier;
+       struct rkisp1_sensor_async *active_sensor;
+       struct rkisp1_isp isp;
+       struct rkisp1_resizer resizer_devs[2];
+       struct rkisp1_capture capture_devs[2];
+       struct rkisp1_stats stats;
+       struct rkisp1_params params;
+       struct media_pipeline pipe;
+       struct mutex stream_lock; /* serialize {start/stop}_streaming cb between capture devices */
+       struct rkisp1_debug debug;
+};
+
+/*
+ * struct rkisp1_isp_mbus_info - ISP media bus info, Translates media bus code to hardware
+ *                              format values
+ *
+ * @mbus_code: media bus code
+ * @pixel_enc: pixel encoding
+ * @mipi_dt:   mipi data type
+ * @yuv_seq:   the order of the Y, Cb, Cr values
+ * @bus_width: bus width
+ * @bayer_pat: bayer pattern
+ * @direction: a bitmask of the flags indicating on which pad the format is supported on
+ */
+struct rkisp1_isp_mbus_info {
+       u32 mbus_code;
+       enum v4l2_pixel_encoding pixel_enc;
+       u32 mipi_dt;
+       u32 yuv_seq;
+       u8 bus_width;
+       enum rkisp1_fmt_raw_pat_type bayer_pat;
+       unsigned int direction;
+};
+
+static inline void
+rkisp1_write(struct rkisp1_device *rkisp1, u32 val, unsigned int addr)
+{
+       writel(val, rkisp1->base_addr + addr);
+}
+
+static inline u32 rkisp1_read(struct rkisp1_device *rkisp1, unsigned int addr)
+{
+       return readl(rkisp1->base_addr + addr);
+}
+
+/*
+ * rkisp1_cap_enum_mbus_codes - A helper function that return the i'th supported mbus code
+ *                             of the capture entity. This is used to enumerate the supported
+ *                             mbus codes on the source pad of the resizer.
+ *
+ * @cap:  the capture entity
+ * @code: the mbus code, the function reads the code->index and fills the code->code
+ */
+int rkisp1_cap_enum_mbus_codes(struct rkisp1_capture *cap,
+                              struct v4l2_subdev_mbus_code_enum *code);
+
+/*
+ * rkisp1_sd_adjust_crop_rect - adjust a rectangle to fit into another rectangle.
+ *
+ * @crop:   rectangle to adjust.
+ * @bounds: rectangle used as bounds.
+ */
+void rkisp1_sd_adjust_crop_rect(struct v4l2_rect *crop,
+                               const struct v4l2_rect *bounds);
+
+/*
+ * rkisp1_sd_adjust_crop - adjust a rectangle to fit into media bus format
+ *
+ * @crop:   rectangle to adjust.
+ * @bounds: media bus format used as bounds.
+ */
+void rkisp1_sd_adjust_crop(struct v4l2_rect *crop,
+                          const struct v4l2_mbus_framefmt *bounds);
+
+/*
+ * rkisp1_isp_mbus_info - get the isp info of the media bus code
+ *
+ * @mbus_code: the media bus code
+ */
+const struct rkisp1_isp_mbus_info *rkisp1_isp_mbus_info_get(u32 mbus_code);
+
+/* rkisp1_params_configure - configure the params when stream starts.
+ *                          This function is called by the isp entity upon stream starts.
+ *                          The function applies the initial configuration of the parameters.
+ *
+ * @params:      pointer to rkisp1_params.
+ * @bayer_pat:   the bayer pattern on the isp video sink pad
+ * @quantization: the quantization configured on the isp's src pad
+ */
+void rkisp1_params_configure(struct rkisp1_params *params,
+                            enum rkisp1_fmt_raw_pat_type bayer_pat,
+                            enum v4l2_quantization quantization);
+
+/* rkisp1_params_disable - disable all parameters.
+ *                        This function is called by the isp entity upon stream start
+ *                        when capturing bayer format.
+ *
+ * @params: pointer to rkisp1_params.
+ */
+void rkisp1_params_disable(struct rkisp1_params *params);
+
+/* irq handlers */
+void rkisp1_isp_isr(struct rkisp1_device *rkisp1);
+void rkisp1_mipi_isr(struct rkisp1_device *rkisp1);
+void rkisp1_capture_isr(struct rkisp1_device *rkisp1);
+void rkisp1_stats_isr(struct rkisp1_stats *stats, u32 isp_ris);
+void rkisp1_params_isr(struct rkisp1_device *rkisp1);
+
+/* register/unregisters functions of the entities */
+int rkisp1_capture_devs_register(struct rkisp1_device *rkisp1);
+void rkisp1_capture_devs_unregister(struct rkisp1_device *rkisp1);
+
+int rkisp1_isp_register(struct rkisp1_device *rkisp1);
+void rkisp1_isp_unregister(struct rkisp1_device *rkisp1);
+
+int rkisp1_resizer_devs_register(struct rkisp1_device *rkisp1);
+void rkisp1_resizer_devs_unregister(struct rkisp1_device *rkisp1);
+
+int rkisp1_stats_register(struct rkisp1_device *rkisp1);
+void rkisp1_stats_unregister(struct rkisp1_device *rkisp1);
+
+int rkisp1_params_register(struct rkisp1_device *rkisp1);
+void rkisp1_params_unregister(struct rkisp1_device *rkisp1);
+
+#endif /* _RKISP1_COMMON_H */
diff --git a/drivers/media/platform/rockchip/rkisp1/rkisp1-dev.c b/drivers/media/platform/rockchip/rkisp1/rkisp1-dev.c
new file mode 100644 (file)
index 0000000..9af137e
--- /dev/null
@@ -0,0 +1,581 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Rockchip ISP1 Driver - Base driver
+ *
+ * Copyright (C) 2019 Collabora, Ltd.
+ *
+ * Based on Rockchip ISP1 driver by Rockchip Electronics Co., Ltd.
+ * Copyright (C) 2017 Rockchip Electronics Co., Ltd.
+ */
+
+#include <linux/clk.h>
+#include <linux/debugfs.h>
+#include <linux/interrupt.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_graph.h>
+#include <linux/of_platform.h>
+#include <linux/pinctrl/consumer.h>
+#include <linux/phy/phy.h>
+#include <linux/phy/phy-mipi-dphy.h>
+#include <media/v4l2-fwnode.h>
+
+#include "rkisp1-common.h"
+
+/*
+ * ISP Details
+ * -----------
+ *
+ * ISP Comprises with:
+ *     MIPI serial camera interface
+ *     Image Signal Processing
+ *     Many Image Enhancement Blocks
+ *     Crop
+ *     Resizer
+ *     RBG display ready image
+ *     Image Rotation
+ *
+ * ISP Block Diagram
+ * -----------------
+ *                                                             rkisp1-resizer.c          rkisp1-capture.c
+ *                                                          |====================|  |=======================|
+ *                                rkisp1-isp.c                              Main Picture Path
+ *                        |==========================|      |===============================================|
+ *                        +-----------+  +--+--+--+--+      +--------+  +--------+              +-----------+
+ *                        |           |  |  |  |  |  |      |        |  |        |              |           |
+ * +--------+    |\       |           |  |  |  |  |  |   -->|  Crop  |->|  RSZ   |------------->|           |
+ * |  MIPI  |--->|  \     |           |  |  |  |  |  |   |  |        |  |        |              |           |
+ * +--------+    |   |    |           |  |IE|IE|IE|IE|   |  +--------+  +--------+              |  Memory   |
+ *               |MUX|--->|    ISP    |->|0 |1 |2 |3 |---+                                      | Interface |
+ * +--------+    |   |    |           |  |  |  |  |  |   |  +--------+  +--------+  +--------+  |           |
+ * |Parallel|--->|  /     |           |  |  |  |  |  |   |  |        |  |        |  |        |  |           |
+ * +--------+    |/       |           |  |  |  |  |  |   -->|  Crop  |->|  RSZ   |->|  RGB   |->|           |
+ *                        |           |  |  |  |  |  |      |        |  |        |  | Rotate |  |           |
+ *                        +-----------+  +--+--+--+--+      +--------+  +--------+  +--------+  +-----------+
+ *                                               ^
+ * +--------+                                    |          |===============================================|
+ * |  DMA   |------------------------------------+                          Self Picture Path
+ * +--------+
+ *
+ *         rkisp1-stats.c        rkisp1-params.c
+ *       |===============|      |===============|
+ *       +---------------+      +---------------+
+ *       |               |      |               |
+ *       |      ISP      |      |      ISP      |
+ *       |               |      |               |
+ *       +---------------+      +---------------+
+ *
+ *
+ * Media Topology
+ * --------------
+ *      +----------+     +----------+
+ *      | Sensor 2 |     | Sensor X |
+ *      ------------ ... ------------
+ *      |    0     |     |    0     |
+ *      +----------+     +----------+      +-----------+
+ *                  \      |               |  params   |
+ *                   \     |               | (output)  |
+ *    +----------+    \    |               +-----------+
+ *    | Sensor 1 |     v   v                     |
+ *    ------------      +------+------+          |
+ *    |    0     |----->|  0   |  1   |<---------+
+ *    +----------+      |------+------|
+ *                      |     ISP     |
+ *                      |------+------|
+ *        +-------------|  2   |  3   |----------+
+ *        |             +------+------+          |
+ *        |                |                     |
+ *        v                v                     v
+ *  +- ---------+    +-----------+         +-----------+
+ *  |     0     |    |     0     |         |   stats   |
+ *  -------------    -------------         | (capture) |
+ *  |  Resizer  |    |  Resizer  |         +-----------+
+ *  ------------|    ------------|
+ *  |     1     |    |     1     |
+ *  +-----------+    +-----------+
+ *        |                |
+ *        v                v
+ *  +-----------+    +-----------+
+ *  | selfpath  |    | mainpath  |
+ *  | (capture) |    | (capture) |
+ *  +-----------+    +-----------+
+ */
+
+struct rkisp1_match_data {
+       const char * const *clks;
+       unsigned int size;
+};
+
+/* ----------------------------------------------------------------------------
+ * Sensor DT bindings
+ */
+
+static int rkisp1_create_links(struct rkisp1_device *rkisp1)
+{
+       struct media_entity *source, *sink;
+       unsigned int flags, source_pad;
+       struct v4l2_subdev *sd;
+       unsigned int i;
+       int ret;
+
+       /* sensor links */
+       flags = MEDIA_LNK_FL_ENABLED;
+       list_for_each_entry(sd, &rkisp1->v4l2_dev.subdevs, list) {
+               if (sd == &rkisp1->isp.sd ||
+                   sd == &rkisp1->resizer_devs[RKISP1_MAINPATH].sd ||
+                   sd == &rkisp1->resizer_devs[RKISP1_SELFPATH].sd)
+                       continue;
+
+               ret = media_entity_get_fwnode_pad(&sd->entity, sd->fwnode,
+                                                 MEDIA_PAD_FL_SOURCE);
+               if (ret < 0) {
+                       dev_err(rkisp1->dev, "failed to find src pad for %s\n",
+                               sd->name);
+                       return ret;
+               }
+               source_pad = ret;
+
+               ret = media_create_pad_link(&sd->entity, source_pad,
+                                           &rkisp1->isp.sd.entity,
+                                           RKISP1_ISP_PAD_SINK_VIDEO,
+                                           flags);
+               if (ret)
+                       return ret;
+
+               flags = 0;
+       }
+
+       flags = MEDIA_LNK_FL_ENABLED | MEDIA_LNK_FL_IMMUTABLE;
+
+       /* create ISP->RSZ->CAP links */
+       for (i = 0; i < 2; i++) {
+               source = &rkisp1->isp.sd.entity;
+               sink = &rkisp1->resizer_devs[i].sd.entity;
+               ret = media_create_pad_link(source, RKISP1_ISP_PAD_SOURCE_VIDEO,
+                                           sink, RKISP1_RSZ_PAD_SINK,
+                                           MEDIA_LNK_FL_ENABLED);
+               if (ret)
+                       return ret;
+
+               source = sink;
+               sink = &rkisp1->capture_devs[i].vnode.vdev.entity;
+               ret = media_create_pad_link(source, RKISP1_RSZ_PAD_SRC,
+                                           sink, 0, flags);
+               if (ret)
+                       return ret;
+       }
+
+       /* params links */
+       source = &rkisp1->params.vnode.vdev.entity;
+       sink = &rkisp1->isp.sd.entity;
+       ret = media_create_pad_link(source, 0, sink,
+                                   RKISP1_ISP_PAD_SINK_PARAMS, flags);
+       if (ret)
+               return ret;
+
+       /* 3A stats links */
+       source = &rkisp1->isp.sd.entity;
+       sink = &rkisp1->stats.vnode.vdev.entity;
+       return media_create_pad_link(source, RKISP1_ISP_PAD_SOURCE_STATS,
+                                    sink, 0, flags);
+}
+
+static int rkisp1_subdev_notifier_bound(struct v4l2_async_notifier *notifier,
+                                       struct v4l2_subdev *sd,
+                                       struct v4l2_async_subdev *asd)
+{
+       struct rkisp1_device *rkisp1 =
+               container_of(notifier, struct rkisp1_device, notifier);
+       struct rkisp1_sensor_async *s_asd =
+               container_of(asd, struct rkisp1_sensor_async, asd);
+
+       s_asd->pixel_rate_ctrl = v4l2_ctrl_find(sd->ctrl_handler,
+                                               V4L2_CID_PIXEL_RATE);
+       s_asd->sd = sd;
+       s_asd->dphy = devm_phy_get(rkisp1->dev, "dphy");
+       if (IS_ERR(s_asd->dphy)) {
+               if (PTR_ERR(s_asd->dphy) != -EPROBE_DEFER)
+                       dev_err(rkisp1->dev, "Couldn't get the MIPI D-PHY\n");
+               return PTR_ERR(s_asd->dphy);
+       }
+
+       phy_init(s_asd->dphy);
+
+       return 0;
+}
+
+static void rkisp1_subdev_notifier_unbind(struct v4l2_async_notifier *notifier,
+                                         struct v4l2_subdev *sd,
+                                         struct v4l2_async_subdev *asd)
+{
+       struct rkisp1_sensor_async *s_asd =
+               container_of(asd, struct rkisp1_sensor_async, asd);
+
+       phy_exit(s_asd->dphy);
+}
+
+static int rkisp1_subdev_notifier_complete(struct v4l2_async_notifier *notifier)
+{
+       struct rkisp1_device *rkisp1 =
+               container_of(notifier, struct rkisp1_device, notifier);
+       int ret;
+
+       ret = rkisp1_create_links(rkisp1);
+       if (ret)
+               return ret;
+
+       ret = v4l2_device_register_subdev_nodes(&rkisp1->v4l2_dev);
+       if (ret)
+               return ret;
+
+       dev_dbg(rkisp1->dev, "Async subdev notifier completed\n");
+
+       return 0;
+}
+
+static const struct v4l2_async_notifier_operations rkisp1_subdev_notifier_ops = {
+       .bound = rkisp1_subdev_notifier_bound,
+       .unbind = rkisp1_subdev_notifier_unbind,
+       .complete = rkisp1_subdev_notifier_complete,
+};
+
+static int rkisp1_subdev_notifier(struct rkisp1_device *rkisp1)
+{
+       struct v4l2_async_notifier *ntf = &rkisp1->notifier;
+       unsigned int next_id = 0;
+       int ret;
+
+       v4l2_async_notifier_init(ntf);
+
+       while (1) {
+               struct v4l2_fwnode_endpoint vep = {
+                       .bus_type = V4L2_MBUS_CSI2_DPHY
+               };
+               struct rkisp1_sensor_async *rk_asd = NULL;
+               struct fwnode_handle *ep;
+
+               ep = fwnode_graph_get_endpoint_by_id(dev_fwnode(rkisp1->dev),
+                                                    0, next_id,
+                                                    FWNODE_GRAPH_ENDPOINT_NEXT);
+               if (!ep)
+                       break;
+
+               ret = v4l2_fwnode_endpoint_parse(ep, &vep);
+               if (ret)
+                       goto err_parse;
+
+               rk_asd = kzalloc(sizeof(*rk_asd), GFP_KERNEL);
+               if (!rk_asd) {
+                       ret = -ENOMEM;
+                       goto err_parse;
+               }
+
+               rk_asd->mbus_type = vep.bus_type;
+               rk_asd->mbus_flags = vep.bus.mipi_csi2.flags;
+               rk_asd->lanes = vep.bus.mipi_csi2.num_data_lanes;
+
+               ret = v4l2_async_notifier_add_fwnode_remote_subdev(ntf, ep,
+                                                                  &rk_asd->asd);
+               if (ret)
+                       goto err_parse;
+
+               dev_dbg(rkisp1->dev, "registered ep id %d with %d lanes\n",
+                       vep.base.id, rk_asd->lanes);
+
+               next_id = vep.base.id + 1;
+
+               fwnode_handle_put(ep);
+
+               continue;
+err_parse:
+               fwnode_handle_put(ep);
+               kfree(rk_asd);
+               v4l2_async_notifier_cleanup(ntf);
+               return ret;
+       }
+
+       if (next_id == 0)
+               dev_dbg(rkisp1->dev, "no remote subdevice found\n");
+       ntf->ops = &rkisp1_subdev_notifier_ops;
+       ret = v4l2_async_notifier_register(&rkisp1->v4l2_dev, ntf);
+       if (ret) {
+               v4l2_async_notifier_cleanup(ntf);
+               return ret;
+       }
+       return 0;
+}
+
+/* ----------------------------------------------------------------------------
+ * Power
+ */
+
+static int __maybe_unused rkisp1_runtime_suspend(struct device *dev)
+{
+       struct rkisp1_device *rkisp1 = dev_get_drvdata(dev);
+
+       clk_bulk_disable_unprepare(rkisp1->clk_size, rkisp1->clks);
+       return pinctrl_pm_select_sleep_state(dev);
+}
+
+static int __maybe_unused rkisp1_runtime_resume(struct device *dev)
+{
+       struct rkisp1_device *rkisp1 = dev_get_drvdata(dev);
+       int ret;
+
+       ret = pinctrl_pm_select_default_state(dev);
+       if (ret)
+               return ret;
+       ret = clk_bulk_prepare_enable(rkisp1->clk_size, rkisp1->clks);
+       if (ret)
+               return ret;
+
+       return 0;
+}
+
+static const struct dev_pm_ops rkisp1_pm_ops = {
+       SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend,
+                               pm_runtime_force_resume)
+       SET_RUNTIME_PM_OPS(rkisp1_runtime_suspend, rkisp1_runtime_resume, NULL)
+};
+
+/* ----------------------------------------------------------------------------
+ * Core
+ */
+
+static int rkisp1_entities_register(struct rkisp1_device *rkisp1)
+{
+       int ret;
+
+       ret = rkisp1_isp_register(rkisp1);
+       if (ret)
+               return ret;
+
+       ret = rkisp1_resizer_devs_register(rkisp1);
+       if (ret)
+               goto err_unreg_isp_subdev;
+
+       ret = rkisp1_capture_devs_register(rkisp1);
+       if (ret)
+               goto err_unreg_resizer_devs;
+
+       ret = rkisp1_stats_register(rkisp1);
+       if (ret)
+               goto err_unreg_capture_devs;
+
+       ret = rkisp1_params_register(rkisp1);
+       if (ret)
+               goto err_unreg_stats;
+
+       ret = rkisp1_subdev_notifier(rkisp1);
+       if (ret) {
+               dev_err(rkisp1->dev,
+                       "Failed to register subdev notifier(%d)\n", ret);
+               goto err_unreg_params;
+       }
+
+       return 0;
+err_unreg_params:
+       rkisp1_params_unregister(rkisp1);
+err_unreg_stats:
+       rkisp1_stats_unregister(rkisp1);
+err_unreg_capture_devs:
+       rkisp1_capture_devs_unregister(rkisp1);
+err_unreg_resizer_devs:
+       rkisp1_resizer_devs_unregister(rkisp1);
+err_unreg_isp_subdev:
+       rkisp1_isp_unregister(rkisp1);
+       return ret;
+}
+
+static irqreturn_t rkisp1_isr(int irq, void *ctx)
+{
+       struct device *dev = ctx;
+       struct rkisp1_device *rkisp1 = dev_get_drvdata(dev);
+
+       /*
+        * Call rkisp1_capture_isr() first to handle the frame that
+        * potentially completed using the current frame_sequence number before
+        * it is potentially incremented by rkisp1_isp_isr() in the vertical
+        * sync.
+        */
+       rkisp1_capture_isr(rkisp1);
+       rkisp1_isp_isr(rkisp1);
+       rkisp1_mipi_isr(rkisp1);
+
+       return IRQ_HANDLED;
+}
+
+static const char * const rk3399_isp_clks[] = {
+       "isp",
+       "aclk",
+       "hclk",
+};
+
+static const struct rkisp1_match_data rk3399_isp_clk_data = {
+       .clks = rk3399_isp_clks,
+       .size = ARRAY_SIZE(rk3399_isp_clks),
+};
+
+static const struct of_device_id rkisp1_of_match[] = {
+       {
+               .compatible = "rockchip,rk3399-cif-isp",
+               .data = &rk3399_isp_clk_data,
+       },
+       {},
+};
+MODULE_DEVICE_TABLE(of, rkisp1_of_match);
+
+static void rkisp1_debug_init(struct rkisp1_device *rkisp1)
+{
+       struct rkisp1_debug *debug = &rkisp1->debug;
+
+       debug->debugfs_dir = debugfs_create_dir(RKISP1_DRIVER_NAME, NULL);
+       if (!debug->debugfs_dir) {
+               dev_dbg(rkisp1->dev, "failed to create debugfs directory\n");
+               return;
+       }
+       debugfs_create_ulong("data_loss", 0444, debug->debugfs_dir,
+                            &debug->data_loss);
+       debugfs_create_ulong("outform_size_err", 0444,  debug->debugfs_dir,
+                            &debug->outform_size_error);
+       debugfs_create_ulong("img_stabilization_size_error", 0444,
+                            debug->debugfs_dir,
+                            &debug->img_stabilization_size_error);
+       debugfs_create_ulong("inform_size_error", 0444,  debug->debugfs_dir,
+                            &debug->inform_size_error);
+       debugfs_create_ulong("irq_delay", 0444,  debug->debugfs_dir,
+                            &debug->irq_delay);
+       debugfs_create_ulong("mipi_error", 0444, debug->debugfs_dir,
+                            &debug->mipi_error);
+       debugfs_create_ulong("stats_error", 0444, debug->debugfs_dir,
+                            &debug->stats_error);
+       debugfs_create_ulong("mp_stop_timeout", 0444, debug->debugfs_dir,
+                            &debug->stop_timeout[RKISP1_MAINPATH]);
+       debugfs_create_ulong("sp_stop_timeout", 0444, debug->debugfs_dir,
+                            &debug->stop_timeout[RKISP1_SELFPATH]);
+       debugfs_create_ulong("mp_frame_drop", 0444, debug->debugfs_dir,
+                            &debug->frame_drop[RKISP1_MAINPATH]);
+       debugfs_create_ulong("sp_frame_drop", 0444, debug->debugfs_dir,
+                            &debug->frame_drop[RKISP1_SELFPATH]);
+}
+
+static int rkisp1_probe(struct platform_device *pdev)
+{
+       const struct rkisp1_match_data *clk_data;
+       struct device *dev = &pdev->dev;
+       struct rkisp1_device *rkisp1;
+       struct v4l2_device *v4l2_dev;
+       unsigned int i;
+       int ret, irq;
+
+       clk_data = of_device_get_match_data(&pdev->dev);
+       if (!clk_data)
+               return -ENODEV;
+
+       rkisp1 = devm_kzalloc(dev, sizeof(*rkisp1), GFP_KERNEL);
+       if (!rkisp1)
+               return -ENOMEM;
+
+       dev_set_drvdata(dev, rkisp1);
+       rkisp1->dev = dev;
+
+       mutex_init(&rkisp1->stream_lock);
+
+       rkisp1->base_addr = devm_platform_ioremap_resource(pdev, 0);
+       if (IS_ERR(rkisp1->base_addr))
+               return PTR_ERR(rkisp1->base_addr);
+
+       irq = platform_get_irq(pdev, 0);
+       if (irq < 0)
+               return irq;
+
+       ret = devm_request_irq(dev, irq, rkisp1_isr, IRQF_SHARED,
+                              dev_driver_string(dev), dev);
+       if (ret) {
+               dev_err(dev, "request irq failed: %d\n", ret);
+               return ret;
+       }
+
+       rkisp1->irq = irq;
+
+       for (i = 0; i < clk_data->size; i++)
+               rkisp1->clks[i].id = clk_data->clks[i];
+       ret = devm_clk_bulk_get(dev, clk_data->size, rkisp1->clks);
+       if (ret)
+               return ret;
+       rkisp1->clk_size = clk_data->size;
+
+       pm_runtime_enable(&pdev->dev);
+
+       strscpy(rkisp1->media_dev.model, RKISP1_DRIVER_NAME,
+               sizeof(rkisp1->media_dev.model));
+       rkisp1->media_dev.dev = &pdev->dev;
+       strscpy(rkisp1->media_dev.bus_info, RKISP1_BUS_INFO,
+               sizeof(rkisp1->media_dev.bus_info));
+       media_device_init(&rkisp1->media_dev);
+
+       v4l2_dev = &rkisp1->v4l2_dev;
+       v4l2_dev->mdev = &rkisp1->media_dev;
+       strscpy(v4l2_dev->name, RKISP1_DRIVER_NAME, sizeof(v4l2_dev->name));
+
+       ret = v4l2_device_register(rkisp1->dev, &rkisp1->v4l2_dev);
+       if (ret)
+               return ret;
+
+       ret = media_device_register(&rkisp1->media_dev);
+       if (ret) {
+               dev_err(dev, "Failed to register media device: %d\n", ret);
+               goto err_unreg_v4l2_dev;
+       }
+
+       ret = rkisp1_entities_register(rkisp1);
+       if (ret)
+               goto err_unreg_media_dev;
+
+       rkisp1_debug_init(rkisp1);
+
+       return 0;
+
+err_unreg_media_dev:
+       media_device_unregister(&rkisp1->media_dev);
+err_unreg_v4l2_dev:
+       v4l2_device_unregister(&rkisp1->v4l2_dev);
+       pm_runtime_disable(&pdev->dev);
+       return ret;
+}
+
+static int rkisp1_remove(struct platform_device *pdev)
+{
+       struct rkisp1_device *rkisp1 = platform_get_drvdata(pdev);
+
+       v4l2_async_notifier_unregister(&rkisp1->notifier);
+       v4l2_async_notifier_cleanup(&rkisp1->notifier);
+
+       rkisp1_params_unregister(rkisp1);
+       rkisp1_stats_unregister(rkisp1);
+       rkisp1_capture_devs_unregister(rkisp1);
+       rkisp1_resizer_devs_unregister(rkisp1);
+       rkisp1_isp_unregister(rkisp1);
+
+       media_device_unregister(&rkisp1->media_dev);
+       v4l2_device_unregister(&rkisp1->v4l2_dev);
+
+       pm_runtime_disable(&pdev->dev);
+
+       debugfs_remove_recursive(rkisp1->debug.debugfs_dir);
+       return 0;
+}
+
+static struct platform_driver rkisp1_drv = {
+       .driver = {
+               .name = RKISP1_DRIVER_NAME,
+               .of_match_table = of_match_ptr(rkisp1_of_match),
+               .pm = &rkisp1_pm_ops,
+       },
+       .probe = rkisp1_probe,
+       .remove = rkisp1_remove,
+};
+
+module_platform_driver(rkisp1_drv);
+MODULE_DESCRIPTION("Rockchip ISP1 platform driver");
+MODULE_LICENSE("Dual MIT/GPL");
diff --git a/drivers/media/platform/rockchip/rkisp1/rkisp1-isp.c b/drivers/media/platform/rockchip/rkisp1/rkisp1-isp.c
new file mode 100644 (file)
index 0000000..889982d
--- /dev/null
@@ -0,0 +1,1160 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Rockchip ISP1 Driver - ISP Subdevice
+ *
+ * Copyright (C) 2019 Collabora, Ltd.
+ *
+ * Based on Rockchip ISP1 driver by Rockchip Electronics Co., Ltd.
+ * Copyright (C) 2017 Rockchip Electronics Co., Ltd.
+ */
+
+#include <linux/iopoll.h>
+#include <linux/phy/phy.h>
+#include <linux/phy/phy-mipi-dphy.h>
+#include <linux/pm_runtime.h>
+#include <linux/videodev2.h>
+#include <linux/vmalloc.h>
+#include <media/v4l2-event.h>
+
+#include "rkisp1-common.h"
+
+#define RKISP1_DEF_SINK_PAD_FMT MEDIA_BUS_FMT_SRGGB10_1X10
+#define RKISP1_DEF_SRC_PAD_FMT MEDIA_BUS_FMT_YUYV8_2X8
+
+#define RKISP1_ISP_DEV_NAME    RKISP1_DRIVER_NAME "_isp"
+
+/*
+ * NOTE: MIPI controller and input MUX are also configured in this file.
+ * This is because ISP Subdev describes not only ISP submodule (input size,
+ * format, output size, format), but also a virtual route device.
+ */
+
+/*
+ * There are many variables named with format/frame in below code,
+ * please see here for their meaning.
+ * Cropping in the sink pad defines the image region from the sensor.
+ * Cropping in the source pad defines the region for the Image Stabilizer (IS)
+ *
+ * Cropping regions of ISP
+ *
+ * +---------------------------------------------------------+
+ * | Sensor image                                            |
+ * | +---------------------------------------------------+   |
+ * | | CIF_ISP_ACQ (for black level)                     |   |
+ * | | sink pad format                                   |   |
+ * | | +--------------------------------------------+    |   |
+ * | | |    CIF_ISP_OUT                             |    |   |
+ * | | |    sink pad crop                           |    |   |
+ * | | |    +---------------------------------+     |    |   |
+ * | | |    |   CIF_ISP_IS                    |     |    |   |
+ * | | |    |   source pad crop and format    |     |    |   |
+ * | | |    +---------------------------------+     |    |   |
+ * | | +--------------------------------------------+    |   |
+ * | +---------------------------------------------------+   |
+ * +---------------------------------------------------------+
+ */
+
+static const struct rkisp1_isp_mbus_info rkisp1_isp_formats[] = {
+       {
+               .mbus_code      = MEDIA_BUS_FMT_YUYV8_2X8,
+               .pixel_enc      = V4L2_PIXEL_ENC_YUV,
+               .direction      = RKISP1_ISP_SD_SRC,
+       }, {
+               .mbus_code      = MEDIA_BUS_FMT_SRGGB10_1X10,
+               .pixel_enc      = V4L2_PIXEL_ENC_BAYER,
+               .mipi_dt        = RKISP1_CIF_CSI2_DT_RAW10,
+               .bayer_pat      = RKISP1_RAW_RGGB,
+               .bus_width      = 10,
+               .direction      = RKISP1_ISP_SD_SINK | RKISP1_ISP_SD_SRC,
+       }, {
+               .mbus_code      = MEDIA_BUS_FMT_SBGGR10_1X10,
+               .pixel_enc      = V4L2_PIXEL_ENC_BAYER,
+               .mipi_dt        = RKISP1_CIF_CSI2_DT_RAW10,
+               .bayer_pat      = RKISP1_RAW_BGGR,
+               .bus_width      = 10,
+               .direction      = RKISP1_ISP_SD_SINK | RKISP1_ISP_SD_SRC,
+       }, {
+               .mbus_code      = MEDIA_BUS_FMT_SGBRG10_1X10,
+               .pixel_enc      = V4L2_PIXEL_ENC_BAYER,
+               .mipi_dt        = RKISP1_CIF_CSI2_DT_RAW10,
+               .bayer_pat      = RKISP1_RAW_GBRG,
+               .bus_width      = 10,
+               .direction      = RKISP1_ISP_SD_SINK | RKISP1_ISP_SD_SRC,
+       }, {
+               .mbus_code      = MEDIA_BUS_FMT_SGRBG10_1X10,
+               .pixel_enc      = V4L2_PIXEL_ENC_BAYER,
+               .mipi_dt        = RKISP1_CIF_CSI2_DT_RAW10,
+               .bayer_pat      = RKISP1_RAW_GRBG,
+               .bus_width      = 10,
+               .direction      = RKISP1_ISP_SD_SINK | RKISP1_ISP_SD_SRC,
+       }, {
+               .mbus_code      = MEDIA_BUS_FMT_SRGGB12_1X12,
+               .pixel_enc      = V4L2_PIXEL_ENC_BAYER,
+               .mipi_dt        = RKISP1_CIF_CSI2_DT_RAW12,
+               .bayer_pat      = RKISP1_RAW_RGGB,
+               .bus_width      = 12,
+               .direction      = RKISP1_ISP_SD_SINK | RKISP1_ISP_SD_SRC,
+       }, {
+               .mbus_code      = MEDIA_BUS_FMT_SBGGR12_1X12,
+               .pixel_enc      = V4L2_PIXEL_ENC_BAYER,
+               .mipi_dt        = RKISP1_CIF_CSI2_DT_RAW12,
+               .bayer_pat      = RKISP1_RAW_BGGR,
+               .bus_width      = 12,
+               .direction      = RKISP1_ISP_SD_SINK | RKISP1_ISP_SD_SRC,
+       }, {
+               .mbus_code      = MEDIA_BUS_FMT_SGBRG12_1X12,
+               .pixel_enc      = V4L2_PIXEL_ENC_BAYER,
+               .mipi_dt        = RKISP1_CIF_CSI2_DT_RAW12,
+               .bayer_pat      = RKISP1_RAW_GBRG,
+               .bus_width      = 12,
+               .direction      = RKISP1_ISP_SD_SINK | RKISP1_ISP_SD_SRC,
+       }, {
+               .mbus_code      = MEDIA_BUS_FMT_SGRBG12_1X12,
+               .pixel_enc      = V4L2_PIXEL_ENC_BAYER,
+               .mipi_dt        = RKISP1_CIF_CSI2_DT_RAW12,
+               .bayer_pat      = RKISP1_RAW_GRBG,
+               .bus_width      = 12,
+               .direction      = RKISP1_ISP_SD_SINK | RKISP1_ISP_SD_SRC,
+       }, {
+               .mbus_code      = MEDIA_BUS_FMT_SRGGB8_1X8,
+               .pixel_enc      = V4L2_PIXEL_ENC_BAYER,
+               .mipi_dt        = RKISP1_CIF_CSI2_DT_RAW8,
+               .bayer_pat      = RKISP1_RAW_RGGB,
+               .bus_width      = 8,
+               .direction      = RKISP1_ISP_SD_SINK | RKISP1_ISP_SD_SRC,
+       }, {
+               .mbus_code      = MEDIA_BUS_FMT_SBGGR8_1X8,
+               .pixel_enc      = V4L2_PIXEL_ENC_BAYER,
+               .mipi_dt        = RKISP1_CIF_CSI2_DT_RAW8,
+               .bayer_pat      = RKISP1_RAW_BGGR,
+               .bus_width      = 8,
+               .direction      = RKISP1_ISP_SD_SINK | RKISP1_ISP_SD_SRC,
+       }, {
+               .mbus_code      = MEDIA_BUS_FMT_SGBRG8_1X8,
+               .pixel_enc      = V4L2_PIXEL_ENC_BAYER,
+               .mipi_dt        = RKISP1_CIF_CSI2_DT_RAW8,
+               .bayer_pat      = RKISP1_RAW_GBRG,
+               .bus_width      = 8,
+               .direction      = RKISP1_ISP_SD_SINK | RKISP1_ISP_SD_SRC,
+       }, {
+               .mbus_code      = MEDIA_BUS_FMT_SGRBG8_1X8,
+               .pixel_enc      = V4L2_PIXEL_ENC_BAYER,
+               .mipi_dt        = RKISP1_CIF_CSI2_DT_RAW8,
+               .bayer_pat      = RKISP1_RAW_GRBG,
+               .bus_width      = 8,
+               .direction      = RKISP1_ISP_SD_SINK | RKISP1_ISP_SD_SRC,
+       }, {
+               .mbus_code      = MEDIA_BUS_FMT_YUYV8_1X16,
+               .pixel_enc      = V4L2_PIXEL_ENC_YUV,
+               .mipi_dt        = RKISP1_CIF_CSI2_DT_YUV422_8b,
+               .yuv_seq        = RKISP1_CIF_ISP_ACQ_PROP_YCBYCR,
+               .bus_width      = 16,
+               .direction      = RKISP1_ISP_SD_SINK,
+       }, {
+               .mbus_code      = MEDIA_BUS_FMT_YVYU8_1X16,
+               .pixel_enc      = V4L2_PIXEL_ENC_YUV,
+               .mipi_dt        = RKISP1_CIF_CSI2_DT_YUV422_8b,
+               .yuv_seq        = RKISP1_CIF_ISP_ACQ_PROP_YCRYCB,
+               .bus_width      = 16,
+               .direction      = RKISP1_ISP_SD_SINK,
+       }, {
+               .mbus_code      = MEDIA_BUS_FMT_UYVY8_1X16,
+               .pixel_enc      = V4L2_PIXEL_ENC_YUV,
+               .mipi_dt        = RKISP1_CIF_CSI2_DT_YUV422_8b,
+               .yuv_seq        = RKISP1_CIF_ISP_ACQ_PROP_CBYCRY,
+               .bus_width      = 16,
+               .direction      = RKISP1_ISP_SD_SINK,
+       }, {
+               .mbus_code      = MEDIA_BUS_FMT_VYUY8_1X16,
+               .pixel_enc      = V4L2_PIXEL_ENC_YUV,
+               .mipi_dt        = RKISP1_CIF_CSI2_DT_YUV422_8b,
+               .yuv_seq        = RKISP1_CIF_ISP_ACQ_PROP_CRYCBY,
+               .bus_width      = 16,
+               .direction      = RKISP1_ISP_SD_SINK,
+       },
+};
+
+/* ----------------------------------------------------------------------------
+ * Helpers
+ */
+
+const struct rkisp1_isp_mbus_info *rkisp1_isp_mbus_info_get(u32 mbus_code)
+{
+       unsigned int i;
+
+       for (i = 0; i < ARRAY_SIZE(rkisp1_isp_formats); i++) {
+               const struct rkisp1_isp_mbus_info *fmt = &rkisp1_isp_formats[i];
+
+               if (fmt->mbus_code == mbus_code)
+                       return fmt;
+       }
+
+       return NULL;
+}
+
+static struct v4l2_subdev *rkisp1_get_remote_sensor(struct v4l2_subdev *sd)
+{
+       struct media_pad *local, *remote;
+       struct media_entity *sensor_me;
+
+       local = &sd->entity.pads[RKISP1_ISP_PAD_SINK_VIDEO];
+       remote = media_entity_remote_pad(local);
+       if (!remote)
+               return NULL;
+
+       sensor_me = remote->entity;
+       return media_entity_to_v4l2_subdev(sensor_me);
+}
+
+static struct v4l2_mbus_framefmt *
+rkisp1_isp_get_pad_fmt(struct rkisp1_isp *isp,
+                      struct v4l2_subdev_pad_config *cfg,
+                      unsigned int pad, u32 which)
+{
+       if (which == V4L2_SUBDEV_FORMAT_TRY)
+               return v4l2_subdev_get_try_format(&isp->sd, cfg, pad);
+       else
+               return v4l2_subdev_get_try_format(&isp->sd, isp->pad_cfg, pad);
+}
+
+static struct v4l2_rect *
+rkisp1_isp_get_pad_crop(struct rkisp1_isp *isp,
+                       struct v4l2_subdev_pad_config *cfg,
+                       unsigned int pad, u32 which)
+{
+       if (which == V4L2_SUBDEV_FORMAT_TRY)
+               return v4l2_subdev_get_try_crop(&isp->sd, cfg, pad);
+       else
+               return v4l2_subdev_get_try_crop(&isp->sd, isp->pad_cfg, pad);
+}
+
+/* ----------------------------------------------------------------------------
+ * Camera Interface registers configurations
+ */
+
+/*
+ * Image Stabilization.
+ * This should only be called when configuring CIF
+ * or at the frame end interrupt
+ */
+static void rkisp1_config_ism(struct rkisp1_device *rkisp1)
+{
+       struct v4l2_rect *src_crop =
+               rkisp1_isp_get_pad_crop(&rkisp1->isp, NULL,
+                                       RKISP1_ISP_PAD_SOURCE_VIDEO,
+                                       V4L2_SUBDEV_FORMAT_ACTIVE);
+       u32 val;
+
+       rkisp1_write(rkisp1, 0, RKISP1_CIF_ISP_IS_RECENTER);
+       rkisp1_write(rkisp1, 0, RKISP1_CIF_ISP_IS_MAX_DX);
+       rkisp1_write(rkisp1, 0, RKISP1_CIF_ISP_IS_MAX_DY);
+       rkisp1_write(rkisp1, 0, RKISP1_CIF_ISP_IS_DISPLACE);
+       rkisp1_write(rkisp1, src_crop->left, RKISP1_CIF_ISP_IS_H_OFFS);
+       rkisp1_write(rkisp1, src_crop->top, RKISP1_CIF_ISP_IS_V_OFFS);
+       rkisp1_write(rkisp1, src_crop->width, RKISP1_CIF_ISP_IS_H_SIZE);
+       rkisp1_write(rkisp1, src_crop->height, RKISP1_CIF_ISP_IS_V_SIZE);
+
+       /* IS(Image Stabilization) is always on, working as output crop */
+       rkisp1_write(rkisp1, 1, RKISP1_CIF_ISP_IS_CTRL);
+       val = rkisp1_read(rkisp1, RKISP1_CIF_ISP_CTRL);
+       val |= RKISP1_CIF_ISP_CTRL_ISP_CFG_UPD;
+       rkisp1_write(rkisp1, val, RKISP1_CIF_ISP_CTRL);
+}
+
+/*
+ * configure ISP blocks with input format, size......
+ */
+static int rkisp1_config_isp(struct rkisp1_device *rkisp1)
+{
+       u32 isp_ctrl = 0, irq_mask = 0, acq_mult = 0, signal = 0;
+       const struct rkisp1_isp_mbus_info *src_fmt, *sink_fmt;
+       struct rkisp1_sensor_async *sensor;
+       struct v4l2_mbus_framefmt *sink_frm;
+       struct v4l2_rect *sink_crop;
+
+       sensor = rkisp1->active_sensor;
+       sink_fmt = rkisp1->isp.sink_fmt;
+       src_fmt = rkisp1->isp.src_fmt;
+       sink_frm = rkisp1_isp_get_pad_fmt(&rkisp1->isp, NULL,
+                                         RKISP1_ISP_PAD_SINK_VIDEO,
+                                         V4L2_SUBDEV_FORMAT_ACTIVE);
+       sink_crop = rkisp1_isp_get_pad_crop(&rkisp1->isp, NULL,
+                                           RKISP1_ISP_PAD_SINK_VIDEO,
+                                           V4L2_SUBDEV_FORMAT_ACTIVE);
+
+       if (sink_fmt->pixel_enc == V4L2_PIXEL_ENC_BAYER) {
+               acq_mult = 1;
+               if (src_fmt->pixel_enc == V4L2_PIXEL_ENC_BAYER) {
+                       if (sensor->mbus_type == V4L2_MBUS_BT656)
+                               isp_ctrl = RKISP1_CIF_ISP_CTRL_ISP_MODE_RAW_PICT_ITU656;
+                       else
+                               isp_ctrl = RKISP1_CIF_ISP_CTRL_ISP_MODE_RAW_PICT;
+               } else {
+                       rkisp1_write(rkisp1, RKISP1_CIF_ISP_DEMOSAIC_TH(0xc),
+                                    RKISP1_CIF_ISP_DEMOSAIC);
+
+                       if (sensor->mbus_type == V4L2_MBUS_BT656)
+                               isp_ctrl = RKISP1_CIF_ISP_CTRL_ISP_MODE_BAYER_ITU656;
+                       else
+                               isp_ctrl = RKISP1_CIF_ISP_CTRL_ISP_MODE_BAYER_ITU601;
+               }
+       } else if (sink_fmt->pixel_enc == V4L2_PIXEL_ENC_YUV) {
+               acq_mult = 2;
+               if (sensor->mbus_type == V4L2_MBUS_CSI2_DPHY) {
+                       isp_ctrl = RKISP1_CIF_ISP_CTRL_ISP_MODE_ITU601;
+               } else {
+                       if (sensor->mbus_type == V4L2_MBUS_BT656)
+                               isp_ctrl = RKISP1_CIF_ISP_CTRL_ISP_MODE_ITU656;
+                       else
+                               isp_ctrl = RKISP1_CIF_ISP_CTRL_ISP_MODE_ITU601;
+               }
+
+               irq_mask |= RKISP1_CIF_ISP_DATA_LOSS;
+       }
+
+       /* Set up input acquisition properties */
+       if (sensor->mbus_type == V4L2_MBUS_BT656 ||
+           sensor->mbus_type == V4L2_MBUS_PARALLEL) {
+               if (sensor->mbus_flags & V4L2_MBUS_PCLK_SAMPLE_RISING)
+                       signal = RKISP1_CIF_ISP_ACQ_PROP_POS_EDGE;
+       }
+
+       if (sensor->mbus_type == V4L2_MBUS_PARALLEL) {
+               if (sensor->mbus_flags & V4L2_MBUS_VSYNC_ACTIVE_LOW)
+                       signal |= RKISP1_CIF_ISP_ACQ_PROP_VSYNC_LOW;
+
+               if (sensor->mbus_flags & V4L2_MBUS_HSYNC_ACTIVE_LOW)
+                       signal |= RKISP1_CIF_ISP_ACQ_PROP_HSYNC_LOW;
+       }
+
+       rkisp1_write(rkisp1, isp_ctrl, RKISP1_CIF_ISP_CTRL);
+       rkisp1_write(rkisp1, signal | sink_fmt->yuv_seq |
+                    RKISP1_CIF_ISP_ACQ_PROP_BAYER_PAT(sink_fmt->bayer_pat) |
+                    RKISP1_CIF_ISP_ACQ_PROP_FIELD_SEL_ALL,
+                    RKISP1_CIF_ISP_ACQ_PROP);
+       rkisp1_write(rkisp1, 0, RKISP1_CIF_ISP_ACQ_NR_FRAMES);
+
+       /* Acquisition Size */
+       rkisp1_write(rkisp1, 0, RKISP1_CIF_ISP_ACQ_H_OFFS);
+       rkisp1_write(rkisp1, 0, RKISP1_CIF_ISP_ACQ_V_OFFS);
+       rkisp1_write(rkisp1,
+                    acq_mult * sink_frm->width, RKISP1_CIF_ISP_ACQ_H_SIZE);
+       rkisp1_write(rkisp1, sink_frm->height, RKISP1_CIF_ISP_ACQ_V_SIZE);
+
+       /* ISP Out Area */
+       rkisp1_write(rkisp1, sink_crop->left, RKISP1_CIF_ISP_OUT_H_OFFS);
+       rkisp1_write(rkisp1, sink_crop->top, RKISP1_CIF_ISP_OUT_V_OFFS);
+       rkisp1_write(rkisp1, sink_crop->width, RKISP1_CIF_ISP_OUT_H_SIZE);
+       rkisp1_write(rkisp1, sink_crop->height, RKISP1_CIF_ISP_OUT_V_SIZE);
+
+       irq_mask |= RKISP1_CIF_ISP_FRAME | RKISP1_CIF_ISP_V_START |
+                   RKISP1_CIF_ISP_PIC_SIZE_ERROR;
+       rkisp1_write(rkisp1, irq_mask, RKISP1_CIF_ISP_IMSC);
+
+       if (src_fmt->pixel_enc == V4L2_PIXEL_ENC_BAYER) {
+               rkisp1_params_disable(&rkisp1->params);
+       } else {
+               struct v4l2_mbus_framefmt *src_frm;
+
+               src_frm = rkisp1_isp_get_pad_fmt(&rkisp1->isp, NULL,
+                                                RKISP1_ISP_PAD_SINK_VIDEO,
+                                                V4L2_SUBDEV_FORMAT_ACTIVE);
+               rkisp1_params_configure(&rkisp1->params, sink_fmt->bayer_pat,
+                                       src_frm->quantization);
+       }
+
+       return 0;
+}
+
+static int rkisp1_config_dvp(struct rkisp1_device *rkisp1)
+{
+       const struct rkisp1_isp_mbus_info *sink_fmt = rkisp1->isp.sink_fmt;
+       u32 val, input_sel;
+
+       switch (sink_fmt->bus_width) {
+       case 8:
+               input_sel = RKISP1_CIF_ISP_ACQ_PROP_IN_SEL_8B_ZERO;
+               break;
+       case 10:
+               input_sel = RKISP1_CIF_ISP_ACQ_PROP_IN_SEL_10B_ZERO;
+               break;
+       case 12:
+               input_sel = RKISP1_CIF_ISP_ACQ_PROP_IN_SEL_12B;
+               break;
+       default:
+               dev_err(rkisp1->dev, "Invalid bus width\n");
+               return -EINVAL;
+       }
+
+       val = rkisp1_read(rkisp1, RKISP1_CIF_ISP_ACQ_PROP);
+       rkisp1_write(rkisp1, val | input_sel, RKISP1_CIF_ISP_ACQ_PROP);
+
+       return 0;
+}
+
+static int rkisp1_config_mipi(struct rkisp1_device *rkisp1)
+{
+       const struct rkisp1_isp_mbus_info *sink_fmt = rkisp1->isp.sink_fmt;
+       unsigned int lanes = rkisp1->active_sensor->lanes;
+       u32 mipi_ctrl;
+
+       if (lanes < 1 || lanes > 4)
+               return -EINVAL;
+
+       mipi_ctrl = RKISP1_CIF_MIPI_CTRL_NUM_LANES(lanes - 1) |
+                   RKISP1_CIF_MIPI_CTRL_SHUTDOWNLANES(0xf) |
+                   RKISP1_CIF_MIPI_CTRL_ERR_SOT_SYNC_HS_SKIP |
+                   RKISP1_CIF_MIPI_CTRL_CLOCKLANE_ENA;
+
+       rkisp1_write(rkisp1, mipi_ctrl, RKISP1_CIF_MIPI_CTRL);
+
+       /* Configure Data Type and Virtual Channel */
+       rkisp1_write(rkisp1,
+                    RKISP1_CIF_MIPI_DATA_SEL_DT(sink_fmt->mipi_dt) |
+                    RKISP1_CIF_MIPI_DATA_SEL_VC(0),
+                    RKISP1_CIF_MIPI_IMG_DATA_SEL);
+
+       /* Clear MIPI interrupts */
+       rkisp1_write(rkisp1, ~0, RKISP1_CIF_MIPI_ICR);
+       /*
+        * Disable RKISP1_CIF_MIPI_ERR_DPHY interrupt here temporary for
+        * isp bus may be dead when switch isp.
+        */
+       rkisp1_write(rkisp1,
+                    RKISP1_CIF_MIPI_FRAME_END | RKISP1_CIF_MIPI_ERR_CSI |
+                    RKISP1_CIF_MIPI_ERR_DPHY |
+                    RKISP1_CIF_MIPI_SYNC_FIFO_OVFLW(0x03) |
+                    RKISP1_CIF_MIPI_ADD_DATA_OVFLW,
+                    RKISP1_CIF_MIPI_IMSC);
+
+       dev_dbg(rkisp1->dev, "\n  MIPI_CTRL 0x%08x\n"
+               "  MIPI_IMG_DATA_SEL 0x%08x\n"
+               "  MIPI_STATUS 0x%08x\n"
+               "  MIPI_IMSC 0x%08x\n",
+               rkisp1_read(rkisp1, RKISP1_CIF_MIPI_CTRL),
+               rkisp1_read(rkisp1, RKISP1_CIF_MIPI_IMG_DATA_SEL),
+               rkisp1_read(rkisp1, RKISP1_CIF_MIPI_STATUS),
+               rkisp1_read(rkisp1, RKISP1_CIF_MIPI_IMSC));
+
+       return 0;
+}
+
+/* Configure MUX */
+static int rkisp1_config_path(struct rkisp1_device *rkisp1)
+{
+       struct rkisp1_sensor_async *sensor = rkisp1->active_sensor;
+       u32 dpcl = rkisp1_read(rkisp1, RKISP1_CIF_VI_DPCL);
+       int ret = 0;
+
+       if (sensor->mbus_type == V4L2_MBUS_BT656 ||
+           sensor->mbus_type == V4L2_MBUS_PARALLEL) {
+               ret = rkisp1_config_dvp(rkisp1);
+               dpcl |= RKISP1_CIF_VI_DPCL_IF_SEL_PARALLEL;
+       } else if (sensor->mbus_type == V4L2_MBUS_CSI2_DPHY) {
+               ret = rkisp1_config_mipi(rkisp1);
+               dpcl |= RKISP1_CIF_VI_DPCL_IF_SEL_MIPI;
+       }
+
+       rkisp1_write(rkisp1, dpcl, RKISP1_CIF_VI_DPCL);
+
+       return ret;
+}
+
+/* Hardware configure Entry */
+static int rkisp1_config_cif(struct rkisp1_device *rkisp1)
+{
+       u32 cif_id;
+       int ret;
+
+       cif_id = rkisp1_read(rkisp1, RKISP1_CIF_VI_ID);
+       dev_dbg(rkisp1->dev, "CIF_ID 0x%08x\n", cif_id);
+
+       ret = rkisp1_config_isp(rkisp1);
+       if (ret)
+               return ret;
+       ret = rkisp1_config_path(rkisp1);
+       if (ret)
+               return ret;
+       rkisp1_config_ism(rkisp1);
+
+       return 0;
+}
+
+static void rkisp1_isp_stop(struct rkisp1_device *rkisp1)
+{
+       u32 val;
+
+       /*
+        * ISP(mi) stop in mi frame end -> Stop ISP(mipi) ->
+        * Stop ISP(isp) ->wait for ISP isp off
+        */
+       /* stop and clear MI, MIPI, and ISP interrupts */
+       rkisp1_write(rkisp1, 0, RKISP1_CIF_MIPI_IMSC);
+       rkisp1_write(rkisp1, ~0, RKISP1_CIF_MIPI_ICR);
+
+       rkisp1_write(rkisp1, 0, RKISP1_CIF_ISP_IMSC);
+       rkisp1_write(rkisp1, ~0, RKISP1_CIF_ISP_ICR);
+
+       rkisp1_write(rkisp1, 0, RKISP1_CIF_MI_IMSC);
+       rkisp1_write(rkisp1, ~0, RKISP1_CIF_MI_ICR);
+       val = rkisp1_read(rkisp1, RKISP1_CIF_MIPI_CTRL);
+       rkisp1_write(rkisp1, val & (~RKISP1_CIF_MIPI_CTRL_OUTPUT_ENA),
+                    RKISP1_CIF_MIPI_CTRL);
+       /* stop ISP */
+       val = rkisp1_read(rkisp1, RKISP1_CIF_ISP_CTRL);
+       val &= ~(RKISP1_CIF_ISP_CTRL_ISP_INFORM_ENABLE |
+                RKISP1_CIF_ISP_CTRL_ISP_ENABLE);
+       rkisp1_write(rkisp1, val, RKISP1_CIF_ISP_CTRL);
+
+       val = rkisp1_read(rkisp1,       RKISP1_CIF_ISP_CTRL);
+       rkisp1_write(rkisp1, val | RKISP1_CIF_ISP_CTRL_ISP_CFG_UPD,
+                    RKISP1_CIF_ISP_CTRL);
+
+       readx_poll_timeout(readl, rkisp1->base_addr + RKISP1_CIF_ISP_RIS,
+                          val, val & RKISP1_CIF_ISP_OFF, 20, 100);
+       rkisp1_write(rkisp1,
+                    RKISP1_CIF_IRCL_MIPI_SW_RST | RKISP1_CIF_IRCL_ISP_SW_RST,
+                    RKISP1_CIF_IRCL);
+       rkisp1_write(rkisp1, 0x0, RKISP1_CIF_IRCL);
+}
+
+static void rkisp1_config_clk(struct rkisp1_device *rkisp1)
+{
+       u32 val = RKISP1_CIF_ICCL_ISP_CLK | RKISP1_CIF_ICCL_CP_CLK |
+                 RKISP1_CIF_ICCL_MRSZ_CLK | RKISP1_CIF_ICCL_SRSZ_CLK |
+                 RKISP1_CIF_ICCL_JPEG_CLK | RKISP1_CIF_ICCL_MI_CLK |
+                 RKISP1_CIF_ICCL_IE_CLK | RKISP1_CIF_ICCL_MIPI_CLK |
+                 RKISP1_CIF_ICCL_DCROP_CLK;
+
+       rkisp1_write(rkisp1, val, RKISP1_CIF_ICCL);
+}
+
+static void rkisp1_isp_start(struct rkisp1_device *rkisp1)
+{
+       struct rkisp1_sensor_async *sensor = rkisp1->active_sensor;
+       u32 val;
+
+       rkisp1_config_clk(rkisp1);
+
+       /* Activate MIPI */
+       if (sensor->mbus_type == V4L2_MBUS_CSI2_DPHY) {
+               val = rkisp1_read(rkisp1, RKISP1_CIF_MIPI_CTRL);
+               rkisp1_write(rkisp1, val | RKISP1_CIF_MIPI_CTRL_OUTPUT_ENA,
+                            RKISP1_CIF_MIPI_CTRL);
+       }
+       /* Activate ISP */
+       val = rkisp1_read(rkisp1, RKISP1_CIF_ISP_CTRL);
+       val |= RKISP1_CIF_ISP_CTRL_ISP_CFG_UPD |
+              RKISP1_CIF_ISP_CTRL_ISP_ENABLE |
+              RKISP1_CIF_ISP_CTRL_ISP_INFORM_ENABLE;
+       rkisp1_write(rkisp1, val, RKISP1_CIF_ISP_CTRL);
+
+       /*
+        * CIF spec says to wait for sufficient time after enabling
+        * the MIPI interface and before starting the sensor output.
+        */
+       usleep_range(1000, 1200);
+}
+
+/* ----------------------------------------------------------------------------
+ * Subdev pad operations
+ */
+
+static int rkisp1_isp_enum_mbus_code(struct v4l2_subdev *sd,
+                                    struct v4l2_subdev_pad_config *cfg,
+                                    struct v4l2_subdev_mbus_code_enum *code)
+{
+       unsigned int i, dir;
+       int pos = 0;
+
+       if (code->pad == RKISP1_ISP_PAD_SINK_VIDEO) {
+               dir = RKISP1_ISP_SD_SINK;
+       } else if (code->pad == RKISP1_ISP_PAD_SOURCE_VIDEO) {
+               dir = RKISP1_ISP_SD_SRC;
+       } else {
+               if (code->index > 0)
+                       return -EINVAL;
+               code->code = MEDIA_BUS_FMT_METADATA_FIXED;
+               return 0;
+       }
+
+       if (code->index >= ARRAY_SIZE(rkisp1_isp_formats))
+               return -EINVAL;
+
+       for (i = 0; i < ARRAY_SIZE(rkisp1_isp_formats); i++) {
+               const struct rkisp1_isp_mbus_info *fmt = &rkisp1_isp_formats[i];
+
+               if (fmt->direction & dir)
+                       pos++;
+
+               if (code->index == pos - 1) {
+                       code->code = fmt->mbus_code;
+                       if (fmt->pixel_enc == V4L2_PIXEL_ENC_YUV &&
+                           dir == RKISP1_ISP_SD_SRC)
+                               code->flags =
+                                       V4L2_SUBDEV_MBUS_CODE_CSC_QUANTIZATION;
+                       return 0;
+               }
+       }
+
+       return -EINVAL;
+}
+
+static int rkisp1_isp_init_config(struct v4l2_subdev *sd,
+                                 struct v4l2_subdev_pad_config *cfg)
+{
+       struct v4l2_mbus_framefmt *sink_fmt, *src_fmt;
+       struct v4l2_rect *sink_crop, *src_crop;
+
+       sink_fmt = v4l2_subdev_get_try_format(sd, cfg,
+                                             RKISP1_ISP_PAD_SINK_VIDEO);
+       sink_fmt->width = RKISP1_DEFAULT_WIDTH;
+       sink_fmt->height = RKISP1_DEFAULT_HEIGHT;
+       sink_fmt->field = V4L2_FIELD_NONE;
+       sink_fmt->code = RKISP1_DEF_SINK_PAD_FMT;
+
+       sink_crop = v4l2_subdev_get_try_crop(sd, cfg,
+                                            RKISP1_ISP_PAD_SINK_VIDEO);
+       sink_crop->width = RKISP1_DEFAULT_WIDTH;
+       sink_crop->height = RKISP1_DEFAULT_HEIGHT;
+       sink_crop->left = 0;
+       sink_crop->top = 0;
+
+       src_fmt = v4l2_subdev_get_try_format(sd, cfg,
+                                            RKISP1_ISP_PAD_SOURCE_VIDEO);
+       *src_fmt = *sink_fmt;
+       src_fmt->code = RKISP1_DEF_SRC_PAD_FMT;
+
+       src_crop = v4l2_subdev_get_try_crop(sd, cfg,
+                                           RKISP1_ISP_PAD_SOURCE_VIDEO);
+       *src_crop = *sink_crop;
+
+       sink_fmt = v4l2_subdev_get_try_format(sd, cfg,
+                                             RKISP1_ISP_PAD_SINK_PARAMS);
+       src_fmt = v4l2_subdev_get_try_format(sd, cfg,
+                                            RKISP1_ISP_PAD_SOURCE_STATS);
+       sink_fmt->width = 0;
+       sink_fmt->height = 0;
+       sink_fmt->field = V4L2_FIELD_NONE;
+       sink_fmt->code = MEDIA_BUS_FMT_METADATA_FIXED;
+       *src_fmt = *sink_fmt;
+
+       return 0;
+}
+
+static void rkisp1_isp_set_src_fmt(struct rkisp1_isp *isp,
+                                  struct v4l2_subdev_pad_config *cfg,
+                                  struct v4l2_mbus_framefmt *format,
+                                  unsigned int which)
+{
+       const struct rkisp1_isp_mbus_info *mbus_info;
+       struct v4l2_mbus_framefmt *src_fmt;
+       const struct v4l2_rect *src_crop;
+
+       src_fmt = rkisp1_isp_get_pad_fmt(isp, cfg,
+                                        RKISP1_ISP_PAD_SOURCE_VIDEO, which);
+       src_crop = rkisp1_isp_get_pad_crop(isp, cfg,
+                                          RKISP1_ISP_PAD_SOURCE_VIDEO, which);
+
+       src_fmt->code = format->code;
+       mbus_info = rkisp1_isp_mbus_info_get(src_fmt->code);
+       if (!mbus_info || !(mbus_info->direction & RKISP1_ISP_SD_SRC)) {
+               src_fmt->code = RKISP1_DEF_SRC_PAD_FMT;
+               mbus_info = rkisp1_isp_mbus_info_get(src_fmt->code);
+       }
+       if (which == V4L2_SUBDEV_FORMAT_ACTIVE)
+               isp->src_fmt = mbus_info;
+       src_fmt->width  = src_crop->width;
+       src_fmt->height = src_crop->height;
+
+       /*
+        * The CSC API is used to allow userspace to force full
+        * quantization on YUV formats.
+        */
+       if (format->flags & V4L2_MBUS_FRAMEFMT_SET_CSC &&
+           format->quantization == V4L2_QUANTIZATION_FULL_RANGE &&
+           mbus_info->pixel_enc == V4L2_PIXEL_ENC_YUV)
+               src_fmt->quantization = V4L2_QUANTIZATION_FULL_RANGE;
+       else if (mbus_info->pixel_enc == V4L2_PIXEL_ENC_YUV)
+               src_fmt->quantization = V4L2_QUANTIZATION_LIM_RANGE;
+       else
+               src_fmt->quantization = V4L2_QUANTIZATION_FULL_RANGE;
+
+       *format = *src_fmt;
+}
+
+static void rkisp1_isp_set_src_crop(struct rkisp1_isp *isp,
+                                   struct v4l2_subdev_pad_config *cfg,
+                                   struct v4l2_rect *r, unsigned int which)
+{
+       struct v4l2_mbus_framefmt *src_fmt;
+       const struct v4l2_rect *sink_crop;
+       struct v4l2_rect *src_crop;
+
+       src_crop = rkisp1_isp_get_pad_crop(isp, cfg,
+                                          RKISP1_ISP_PAD_SOURCE_VIDEO,
+                                          which);
+       sink_crop = rkisp1_isp_get_pad_crop(isp, cfg,
+                                           RKISP1_ISP_PAD_SINK_VIDEO,
+                                           which);
+
+       src_crop->left = ALIGN(r->left, 2);
+       src_crop->width = ALIGN(r->width, 2);
+       src_crop->top = r->top;
+       src_crop->height = r->height;
+       rkisp1_sd_adjust_crop_rect(src_crop, sink_crop);
+
+       *r = *src_crop;
+
+       /* Propagate to out format */
+       src_fmt = rkisp1_isp_get_pad_fmt(isp, cfg,
+                                        RKISP1_ISP_PAD_SOURCE_VIDEO, which);
+       rkisp1_isp_set_src_fmt(isp, cfg, src_fmt, which);
+}
+
+static void rkisp1_isp_set_sink_crop(struct rkisp1_isp *isp,
+                                    struct v4l2_subdev_pad_config *cfg,
+                                    struct v4l2_rect *r, unsigned int which)
+{
+       struct v4l2_rect *sink_crop, *src_crop;
+       struct v4l2_mbus_framefmt *sink_fmt;
+
+       sink_crop = rkisp1_isp_get_pad_crop(isp, cfg, RKISP1_ISP_PAD_SINK_VIDEO,
+                                           which);
+       sink_fmt = rkisp1_isp_get_pad_fmt(isp, cfg, RKISP1_ISP_PAD_SINK_VIDEO,
+                                         which);
+
+       sink_crop->left = ALIGN(r->left, 2);
+       sink_crop->width = ALIGN(r->width, 2);
+       sink_crop->top = r->top;
+       sink_crop->height = r->height;
+       rkisp1_sd_adjust_crop(sink_crop, sink_fmt);
+
+       *r = *sink_crop;
+
+       /* Propagate to out crop */
+       src_crop = rkisp1_isp_get_pad_crop(isp, cfg,
+                                          RKISP1_ISP_PAD_SOURCE_VIDEO, which);
+       rkisp1_isp_set_src_crop(isp, cfg, src_crop, which);
+}
+
+static void rkisp1_isp_set_sink_fmt(struct rkisp1_isp *isp,
+                                   struct v4l2_subdev_pad_config *cfg,
+                                   struct v4l2_mbus_framefmt *format,
+                                   unsigned int which)
+{
+       const struct rkisp1_isp_mbus_info *mbus_info;
+       struct v4l2_mbus_framefmt *sink_fmt;
+       struct v4l2_rect *sink_crop;
+
+       sink_fmt = rkisp1_isp_get_pad_fmt(isp, cfg, RKISP1_ISP_PAD_SINK_VIDEO,
+                                         which);
+       sink_fmt->code = format->code;
+       mbus_info = rkisp1_isp_mbus_info_get(sink_fmt->code);
+       if (!mbus_info || !(mbus_info->direction & RKISP1_ISP_SD_SINK)) {
+               sink_fmt->code = RKISP1_DEF_SINK_PAD_FMT;
+               mbus_info = rkisp1_isp_mbus_info_get(sink_fmt->code);
+       }
+       if (which == V4L2_SUBDEV_FORMAT_ACTIVE)
+               isp->sink_fmt = mbus_info;
+
+       sink_fmt->width = clamp_t(u32, format->width,
+                                 RKISP1_ISP_MIN_WIDTH,
+                                 RKISP1_ISP_MAX_WIDTH);
+       sink_fmt->height = clamp_t(u32, format->height,
+                                  RKISP1_ISP_MIN_HEIGHT,
+                                  RKISP1_ISP_MAX_HEIGHT);
+
+       *format = *sink_fmt;
+
+       /* Propagate to in crop */
+       sink_crop = rkisp1_isp_get_pad_crop(isp, cfg, RKISP1_ISP_PAD_SINK_VIDEO,
+                                           which);
+       rkisp1_isp_set_sink_crop(isp, cfg, sink_crop, which);
+}
+
+static int rkisp1_isp_get_fmt(struct v4l2_subdev *sd,
+                             struct v4l2_subdev_pad_config *cfg,
+                             struct v4l2_subdev_format *fmt)
+{
+       struct rkisp1_isp *isp = container_of(sd, struct rkisp1_isp, sd);
+
+       mutex_lock(&isp->ops_lock);
+       fmt->format = *rkisp1_isp_get_pad_fmt(isp, cfg, fmt->pad, fmt->which);
+       mutex_unlock(&isp->ops_lock);
+       return 0;
+}
+
+static int rkisp1_isp_set_fmt(struct v4l2_subdev *sd,
+                             struct v4l2_subdev_pad_config *cfg,
+                             struct v4l2_subdev_format *fmt)
+{
+       struct rkisp1_isp *isp = container_of(sd, struct rkisp1_isp, sd);
+
+       mutex_lock(&isp->ops_lock);
+       if (fmt->pad == RKISP1_ISP_PAD_SINK_VIDEO)
+               rkisp1_isp_set_sink_fmt(isp, cfg, &fmt->format, fmt->which);
+       else if (fmt->pad == RKISP1_ISP_PAD_SOURCE_VIDEO)
+               rkisp1_isp_set_src_fmt(isp, cfg, &fmt->format, fmt->which);
+       else
+               fmt->format = *rkisp1_isp_get_pad_fmt(isp, cfg, fmt->pad,
+                                                     fmt->which);
+
+       mutex_unlock(&isp->ops_lock);
+       return 0;
+}
+
+static int rkisp1_isp_get_selection(struct v4l2_subdev *sd,
+                                   struct v4l2_subdev_pad_config *cfg,
+                                   struct v4l2_subdev_selection *sel)
+{
+       struct rkisp1_isp *isp = container_of(sd, struct rkisp1_isp, sd);
+       int ret = 0;
+
+       if (sel->pad != RKISP1_ISP_PAD_SOURCE_VIDEO &&
+           sel->pad != RKISP1_ISP_PAD_SINK_VIDEO)
+               return -EINVAL;
+
+       mutex_lock(&isp->ops_lock);
+       switch (sel->target) {
+       case V4L2_SEL_TGT_CROP_BOUNDS:
+               if (sel->pad == RKISP1_ISP_PAD_SINK_VIDEO) {
+                       struct v4l2_mbus_framefmt *fmt;
+
+                       fmt = rkisp1_isp_get_pad_fmt(isp, cfg, sel->pad,
+                                                    sel->which);
+                       sel->r.height = fmt->height;
+                       sel->r.width = fmt->width;
+                       sel->r.left = 0;
+                       sel->r.top = 0;
+               } else {
+                       sel->r = *rkisp1_isp_get_pad_crop(isp, cfg,
+                                               RKISP1_ISP_PAD_SINK_VIDEO,
+                                               sel->which);
+               }
+               break;
+       case V4L2_SEL_TGT_CROP:
+               sel->r = *rkisp1_isp_get_pad_crop(isp, cfg, sel->pad,
+                                                 sel->which);
+               break;
+       default:
+               ret = -EINVAL;
+       }
+       mutex_unlock(&isp->ops_lock);
+       return ret;
+}
+
+static int rkisp1_isp_set_selection(struct v4l2_subdev *sd,
+                                   struct v4l2_subdev_pad_config *cfg,
+                                   struct v4l2_subdev_selection *sel)
+{
+       struct rkisp1_device *rkisp1 =
+               container_of(sd->v4l2_dev, struct rkisp1_device, v4l2_dev);
+       struct rkisp1_isp *isp = container_of(sd, struct rkisp1_isp, sd);
+       int ret = 0;
+
+       if (sel->target != V4L2_SEL_TGT_CROP)
+               return -EINVAL;
+
+       dev_dbg(rkisp1->dev, "%s: pad: %d sel(%d,%d)/%dx%d\n", __func__,
+               sel->pad, sel->r.left, sel->r.top, sel->r.width, sel->r.height);
+       mutex_lock(&isp->ops_lock);
+       if (sel->pad == RKISP1_ISP_PAD_SINK_VIDEO)
+               rkisp1_isp_set_sink_crop(isp, cfg, &sel->r, sel->which);
+       else if (sel->pad == RKISP1_ISP_PAD_SOURCE_VIDEO)
+               rkisp1_isp_set_src_crop(isp, cfg, &sel->r, sel->which);
+       else
+               ret = -EINVAL;
+
+       mutex_unlock(&isp->ops_lock);
+       return ret;
+}
+
+static int rkisp1_subdev_link_validate(struct media_link *link)
+{
+       if (link->sink->index == RKISP1_ISP_PAD_SINK_PARAMS)
+               return 0;
+
+       return v4l2_subdev_link_validate(link);
+}
+
+static const struct v4l2_subdev_pad_ops rkisp1_isp_pad_ops = {
+       .enum_mbus_code = rkisp1_isp_enum_mbus_code,
+       .get_selection = rkisp1_isp_get_selection,
+       .set_selection = rkisp1_isp_set_selection,
+       .init_cfg = rkisp1_isp_init_config,
+       .get_fmt = rkisp1_isp_get_fmt,
+       .set_fmt = rkisp1_isp_set_fmt,
+       .link_validate = v4l2_subdev_link_validate_default,
+};
+
+/* ----------------------------------------------------------------------------
+ * Stream operations
+ */
+
+static int rkisp1_mipi_csi2_start(struct rkisp1_isp *isp,
+                                 struct rkisp1_sensor_async *sensor)
+{
+       struct rkisp1_device *rkisp1 =
+               container_of(isp->sd.v4l2_dev, struct rkisp1_device, v4l2_dev);
+       union phy_configure_opts opts;
+       struct phy_configure_opts_mipi_dphy *cfg = &opts.mipi_dphy;
+       s64 pixel_clock;
+
+       if (!sensor->pixel_rate_ctrl) {
+               dev_warn(rkisp1->dev, "No pixel rate control in sensor subdev\n");
+               return -EPIPE;
+       }
+
+       pixel_clock = v4l2_ctrl_g_ctrl_int64(sensor->pixel_rate_ctrl);
+       if (!pixel_clock) {
+               dev_err(rkisp1->dev, "Invalid pixel rate value\n");
+               return -EINVAL;
+       }
+
+       phy_mipi_dphy_get_default_config(pixel_clock, isp->sink_fmt->bus_width,
+                                        sensor->lanes, cfg);
+       phy_set_mode(sensor->dphy, PHY_MODE_MIPI_DPHY);
+       phy_configure(sensor->dphy, &opts);
+       phy_power_on(sensor->dphy);
+
+       return 0;
+}
+
+static void rkisp1_mipi_csi2_stop(struct rkisp1_sensor_async *sensor)
+{
+       phy_power_off(sensor->dphy);
+}
+
+static int rkisp1_isp_s_stream(struct v4l2_subdev *sd, int enable)
+{
+       struct rkisp1_device *rkisp1 =
+               container_of(sd->v4l2_dev, struct rkisp1_device, v4l2_dev);
+       struct rkisp1_isp *isp = &rkisp1->isp;
+       struct v4l2_subdev *sensor_sd;
+       int ret = 0;
+
+       if (!enable) {
+               rkisp1_isp_stop(rkisp1);
+               rkisp1_mipi_csi2_stop(rkisp1->active_sensor);
+               return 0;
+       }
+
+       sensor_sd = rkisp1_get_remote_sensor(sd);
+       if (!sensor_sd) {
+               dev_warn(rkisp1->dev, "No link between isp and sensor\n");
+               return -ENODEV;
+       }
+
+       rkisp1->active_sensor = container_of(sensor_sd->asd,
+                                            struct rkisp1_sensor_async, asd);
+
+       if (rkisp1->active_sensor->mbus_type != V4L2_MBUS_CSI2_DPHY)
+               return -EINVAL;
+
+       rkisp1->isp.frame_sequence = -1;
+       mutex_lock(&isp->ops_lock);
+       ret = rkisp1_config_cif(rkisp1);
+       if (ret)
+               goto mutex_unlock;
+
+       ret = rkisp1_mipi_csi2_start(&rkisp1->isp, rkisp1->active_sensor);
+       if (ret)
+               goto mutex_unlock;
+
+       rkisp1_isp_start(rkisp1);
+
+mutex_unlock:
+       mutex_unlock(&isp->ops_lock);
+       return ret;
+}
+
+static int rkisp1_isp_subs_evt(struct v4l2_subdev *sd, struct v4l2_fh *fh,
+                              struct v4l2_event_subscription *sub)
+{
+       if (sub->type != V4L2_EVENT_FRAME_SYNC)
+               return -EINVAL;
+
+       /* V4L2_EVENT_FRAME_SYNC doesn't require an id, so zero should be set */
+       if (sub->id != 0)
+               return -EINVAL;
+
+       return v4l2_event_subscribe(fh, sub, 0, NULL);
+}
+
+static const struct media_entity_operations rkisp1_isp_media_ops = {
+       .link_validate = rkisp1_subdev_link_validate,
+};
+
+static const struct v4l2_subdev_video_ops rkisp1_isp_video_ops = {
+       .s_stream = rkisp1_isp_s_stream,
+};
+
+static const struct v4l2_subdev_core_ops rkisp1_isp_core_ops = {
+       .subscribe_event = rkisp1_isp_subs_evt,
+       .unsubscribe_event = v4l2_event_subdev_unsubscribe,
+};
+
+static const struct v4l2_subdev_ops rkisp1_isp_ops = {
+       .core = &rkisp1_isp_core_ops,
+       .video = &rkisp1_isp_video_ops,
+       .pad = &rkisp1_isp_pad_ops,
+};
+
+int rkisp1_isp_register(struct rkisp1_device *rkisp1)
+{
+       struct rkisp1_isp *isp = &rkisp1->isp;
+       struct media_pad *pads = isp->pads;
+       struct v4l2_subdev *sd = &isp->sd;
+       int ret;
+
+       v4l2_subdev_init(sd, &rkisp1_isp_ops);
+       sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE | V4L2_SUBDEV_FL_HAS_EVENTS;
+       sd->entity.ops = &rkisp1_isp_media_ops;
+       sd->entity.function = MEDIA_ENT_F_PROC_VIDEO_PIXEL_FORMATTER;
+       sd->owner = THIS_MODULE;
+       strscpy(sd->name, RKISP1_ISP_DEV_NAME, sizeof(sd->name));
+
+       pads[RKISP1_ISP_PAD_SINK_VIDEO].flags = MEDIA_PAD_FL_SINK |
+                                               MEDIA_PAD_FL_MUST_CONNECT;
+       pads[RKISP1_ISP_PAD_SINK_PARAMS].flags = MEDIA_PAD_FL_SINK;
+       pads[RKISP1_ISP_PAD_SOURCE_VIDEO].flags = MEDIA_PAD_FL_SOURCE;
+       pads[RKISP1_ISP_PAD_SOURCE_STATS].flags = MEDIA_PAD_FL_SOURCE;
+
+       isp->sink_fmt = rkisp1_isp_mbus_info_get(RKISP1_DEF_SINK_PAD_FMT);
+       isp->src_fmt = rkisp1_isp_mbus_info_get(RKISP1_DEF_SRC_PAD_FMT);
+
+       mutex_init(&isp->ops_lock);
+       ret = media_entity_pads_init(&sd->entity, RKISP1_ISP_PAD_MAX, pads);
+       if (ret)
+               return ret;
+
+       ret = v4l2_device_register_subdev(&rkisp1->v4l2_dev, sd);
+       if (ret) {
+               dev_err(rkisp1->dev, "Failed to register isp subdev\n");
+               goto err_cleanup_media_entity;
+       }
+
+       rkisp1_isp_init_config(sd, rkisp1->isp.pad_cfg);
+       return 0;
+
+err_cleanup_media_entity:
+       media_entity_cleanup(&sd->entity);
+
+       return ret;
+}
+
+void rkisp1_isp_unregister(struct rkisp1_device *rkisp1)
+{
+       struct v4l2_subdev *sd = &rkisp1->isp.sd;
+
+       v4l2_device_unregister_subdev(sd);
+       media_entity_cleanup(&sd->entity);
+}
+
+/* ----------------------------------------------------------------------------
+ * Interrupt handlers
+ */
+
+void rkisp1_mipi_isr(struct rkisp1_device *rkisp1)
+{
+       u32 val, status;
+
+       status = rkisp1_read(rkisp1, RKISP1_CIF_MIPI_MIS);
+       if (!status)
+               return;
+
+       rkisp1_write(rkisp1, status, RKISP1_CIF_MIPI_ICR);
+
+       /*
+        * Disable DPHY errctrl interrupt, because this dphy
+        * erctrl signal is asserted until the next changes
+        * of line state. This time is may be too long and cpu
+        * is hold in this interrupt.
+        */
+       if (status & RKISP1_CIF_MIPI_ERR_CTRL(0x0f)) {
+               val = rkisp1_read(rkisp1, RKISP1_CIF_MIPI_IMSC);
+               rkisp1_write(rkisp1, val & ~RKISP1_CIF_MIPI_ERR_CTRL(0x0f),
+                            RKISP1_CIF_MIPI_IMSC);
+               rkisp1->isp.is_dphy_errctrl_disabled = true;
+       }
+
+       /*
+        * Enable DPHY errctrl interrupt again, if mipi have receive
+        * the whole frame without any error.
+        */
+       if (status == RKISP1_CIF_MIPI_FRAME_END) {
+               /*
+                * Enable DPHY errctrl interrupt again, if mipi have receive
+                * the whole frame without any error.
+                */
+               if (rkisp1->isp.is_dphy_errctrl_disabled) {
+                       val = rkisp1_read(rkisp1, RKISP1_CIF_MIPI_IMSC);
+                       val |= RKISP1_CIF_MIPI_ERR_CTRL(0x0f);
+                       rkisp1_write(rkisp1, val, RKISP1_CIF_MIPI_IMSC);
+                       rkisp1->isp.is_dphy_errctrl_disabled = false;
+               }
+       } else {
+               rkisp1->debug.mipi_error++;
+       }
+}
+
+static void rkisp1_isp_queue_event_sof(struct rkisp1_isp *isp)
+{
+       struct v4l2_event event = {
+               .type = V4L2_EVENT_FRAME_SYNC,
+       };
+       event.u.frame_sync.frame_sequence = isp->frame_sequence;
+
+       v4l2_event_queue(isp->sd.devnode, &event);
+}
+
+void rkisp1_isp_isr(struct rkisp1_device *rkisp1)
+{
+       u32 status, isp_err;
+
+       status = rkisp1_read(rkisp1, RKISP1_CIF_ISP_MIS);
+       if (!status)
+               return;
+
+       rkisp1_write(rkisp1, status, RKISP1_CIF_ISP_ICR);
+
+       /* Vertical sync signal, starting generating new frame */
+       if (status & RKISP1_CIF_ISP_V_START) {
+               rkisp1->isp.frame_sequence++;
+               rkisp1_isp_queue_event_sof(&rkisp1->isp);
+               if (status & RKISP1_CIF_ISP_FRAME) {
+                       WARN_ONCE(1, "irq delay is too long, buffers might not be in sync\n");
+                       rkisp1->debug.irq_delay++;
+               }
+       }
+       if (status & RKISP1_CIF_ISP_PIC_SIZE_ERROR) {
+               /* Clear pic_size_error */
+               isp_err = rkisp1_read(rkisp1, RKISP1_CIF_ISP_ERR);
+               if (isp_err & RKISP1_CIF_ISP_ERR_INFORM_SIZE)
+                       rkisp1->debug.inform_size_error++;
+               if (isp_err & RKISP1_CIF_ISP_ERR_IS_SIZE)
+                       rkisp1->debug.img_stabilization_size_error++;
+               if (isp_err & RKISP1_CIF_ISP_ERR_OUTFORM_SIZE)
+                       rkisp1->debug.outform_size_error++;
+               rkisp1_write(rkisp1, isp_err, RKISP1_CIF_ISP_ERR_CLR);
+       } else if (status & RKISP1_CIF_ISP_DATA_LOSS) {
+               /* keep track of data_loss in debugfs */
+               rkisp1->debug.data_loss++;
+       }
+
+       if (status & RKISP1_CIF_ISP_FRAME) {
+               u32 isp_ris;
+
+               /* New frame from the sensor received */
+               isp_ris = rkisp1_read(rkisp1, RKISP1_CIF_ISP_RIS);
+               if (isp_ris & RKISP1_STATS_MEAS_MASK)
+                       rkisp1_stats_isr(&rkisp1->stats, isp_ris);
+               /*
+                * Then update changed configs. Some of them involve
+                * lot of register writes. Do those only one per frame.
+                * Do the updates in the order of the processing flow.
+                */
+               rkisp1_params_isr(rkisp1);
+       }
+}
diff --git a/drivers/media/platform/rockchip/rkisp1/rkisp1-params.c b/drivers/media/platform/rockchip/rkisp1/rkisp1-params.c
new file mode 100644 (file)
index 0000000..03f9a81
--- /dev/null
@@ -0,0 +1,1572 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Rockchip ISP1 Driver - Params subdevice
+ *
+ * Copyright (C) 2017 Rockchip Electronics Co., Ltd.
+ */
+
+#include <media/v4l2-common.h>
+#include <media/v4l2-event.h>
+#include <media/v4l2-ioctl.h>
+#include <media/videobuf2-core.h>
+#include <media/videobuf2-vmalloc.h>   /* for ISP params */
+
+#include "rkisp1-common.h"
+
+#define RKISP1_PARAMS_DEV_NAME RKISP1_DRIVER_NAME "_params"
+
+#define RKISP1_ISP_PARAMS_REQ_BUFS_MIN 2
+#define RKISP1_ISP_PARAMS_REQ_BUFS_MAX 8
+
+#define RKISP1_ISP_DPCC_LINE_THRESH(n) \
+                       (RKISP1_CIF_ISP_DPCC_LINE_THRESH_1 + 0x14 * (n))
+#define RKISP1_ISP_DPCC_LINE_MAD_FAC(n) \
+                       (RKISP1_CIF_ISP_DPCC_LINE_MAD_FAC_1 + 0x14 * (n))
+#define RKISP1_ISP_DPCC_PG_FAC(n) \
+                       (RKISP1_CIF_ISP_DPCC_PG_FAC_1 + 0x14 * (n))
+#define RKISP1_ISP_DPCC_RND_THRESH(n) \
+                       (RKISP1_CIF_ISP_DPCC_RND_THRESH_1 + 0x14 * (n))
+#define RKISP1_ISP_DPCC_RG_FAC(n) \
+                       (RKISP1_CIF_ISP_DPCC_RG_FAC_1 + 0x14 * (n))
+#define RKISP1_ISP_CC_COEFF(n) \
+                       (RKISP1_CIF_ISP_CC_COEFF_0 + (n) * 4)
+
+static inline void
+rkisp1_param_set_bits(struct rkisp1_params *params, u32 reg, u32 bit_mask)
+{
+       u32 val;
+
+       val = rkisp1_read(params->rkisp1, reg);
+       rkisp1_write(params->rkisp1, val | bit_mask, reg);
+}
+
+static inline void
+rkisp1_param_clear_bits(struct rkisp1_params *params, u32 reg, u32 bit_mask)
+{
+       u32 val;
+
+       val = rkisp1_read(params->rkisp1, reg);
+       rkisp1_write(params->rkisp1, val & ~bit_mask, reg);
+}
+
+/* ISP BP interface function */
+static void rkisp1_dpcc_config(struct rkisp1_params *params,
+                              const struct rkisp1_cif_isp_dpcc_config *arg)
+{
+       unsigned int i;
+       u32 mode;
+
+       /* avoid to override the old enable value */
+       mode = rkisp1_read(params->rkisp1, RKISP1_CIF_ISP_DPCC_MODE);
+       mode &= RKISP1_CIF_ISP_DPCC_ENA;
+       mode |= arg->mode & ~RKISP1_CIF_ISP_DPCC_ENA;
+       rkisp1_write(params->rkisp1, mode, RKISP1_CIF_ISP_DPCC_MODE);
+       rkisp1_write(params->rkisp1, arg->output_mode,
+                    RKISP1_CIF_ISP_DPCC_OUTPUT_MODE);
+       rkisp1_write(params->rkisp1, arg->set_use,
+                    RKISP1_CIF_ISP_DPCC_SET_USE);
+
+       rkisp1_write(params->rkisp1, arg->methods[0].method,
+                    RKISP1_CIF_ISP_DPCC_METHODS_SET_1);
+       rkisp1_write(params->rkisp1, arg->methods[1].method,
+                    RKISP1_CIF_ISP_DPCC_METHODS_SET_2);
+       rkisp1_write(params->rkisp1, arg->methods[2].method,
+                    RKISP1_CIF_ISP_DPCC_METHODS_SET_3);
+       for (i = 0; i < RKISP1_CIF_ISP_DPCC_METHODS_MAX; i++) {
+               rkisp1_write(params->rkisp1, arg->methods[i].line_thresh,
+                            RKISP1_ISP_DPCC_LINE_THRESH(i));
+               rkisp1_write(params->rkisp1, arg->methods[i].line_mad_fac,
+                            RKISP1_ISP_DPCC_LINE_MAD_FAC(i));
+               rkisp1_write(params->rkisp1, arg->methods[i].pg_fac,
+                            RKISP1_ISP_DPCC_PG_FAC(i));
+               rkisp1_write(params->rkisp1, arg->methods[i].rnd_thresh,
+                            RKISP1_ISP_DPCC_RND_THRESH(i));
+               rkisp1_write(params->rkisp1, arg->methods[i].rg_fac,
+                            RKISP1_ISP_DPCC_RG_FAC(i));
+       }
+
+       rkisp1_write(params->rkisp1, arg->rnd_offs,
+                    RKISP1_CIF_ISP_DPCC_RND_OFFS);
+       rkisp1_write(params->rkisp1, arg->ro_limits,
+                    RKISP1_CIF_ISP_DPCC_RO_LIMITS);
+}
+
+/* ISP black level subtraction interface function */
+static void rkisp1_bls_config(struct rkisp1_params *params,
+                             const struct rkisp1_cif_isp_bls_config *arg)
+{
+       /* avoid to override the old enable value */
+       u32 new_control;
+
+       new_control = rkisp1_read(params->rkisp1, RKISP1_CIF_ISP_BLS_CTRL);
+       new_control &= RKISP1_CIF_ISP_BLS_ENA;
+       /* fixed subtraction values */
+       if (!arg->enable_auto) {
+               const struct rkisp1_cif_isp_bls_fixed_val *pval =
+                                                               &arg->fixed_val;
+
+               switch (params->raw_type) {
+               case RKISP1_RAW_BGGR:
+                       rkisp1_write(params->rkisp1,
+                                    pval->r, RKISP1_CIF_ISP_BLS_D_FIXED);
+                       rkisp1_write(params->rkisp1,
+                                    pval->gr, RKISP1_CIF_ISP_BLS_C_FIXED);
+                       rkisp1_write(params->rkisp1,
+                                    pval->gb, RKISP1_CIF_ISP_BLS_B_FIXED);
+                       rkisp1_write(params->rkisp1,
+                                    pval->b, RKISP1_CIF_ISP_BLS_A_FIXED);
+                       break;
+               case RKISP1_RAW_GBRG:
+                       rkisp1_write(params->rkisp1,
+                                    pval->r, RKISP1_CIF_ISP_BLS_C_FIXED);
+                       rkisp1_write(params->rkisp1,
+                                    pval->gr, RKISP1_CIF_ISP_BLS_D_FIXED);
+                       rkisp1_write(params->rkisp1,
+                                    pval->gb, RKISP1_CIF_ISP_BLS_A_FIXED);
+                       rkisp1_write(params->rkisp1,
+                                    pval->b, RKISP1_CIF_ISP_BLS_B_FIXED);
+                       break;
+               case RKISP1_RAW_GRBG:
+                       rkisp1_write(params->rkisp1,
+                                    pval->r, RKISP1_CIF_ISP_BLS_B_FIXED);
+                       rkisp1_write(params->rkisp1,
+                                    pval->gr, RKISP1_CIF_ISP_BLS_A_FIXED);
+                       rkisp1_write(params->rkisp1,
+                                    pval->gb, RKISP1_CIF_ISP_BLS_D_FIXED);
+                       rkisp1_write(params->rkisp1,
+                                    pval->b, RKISP1_CIF_ISP_BLS_C_FIXED);
+                       break;
+               case RKISP1_RAW_RGGB:
+                       rkisp1_write(params->rkisp1,
+                                    pval->r, RKISP1_CIF_ISP_BLS_A_FIXED);
+                       rkisp1_write(params->rkisp1,
+                                    pval->gr, RKISP1_CIF_ISP_BLS_B_FIXED);
+                       rkisp1_write(params->rkisp1,
+                                    pval->gb, RKISP1_CIF_ISP_BLS_C_FIXED);
+                       rkisp1_write(params->rkisp1,
+                                    pval->b, RKISP1_CIF_ISP_BLS_D_FIXED);
+                       break;
+               default:
+                       break;
+               }
+
+       } else {
+               if (arg->en_windows & BIT(1)) {
+                       rkisp1_write(params->rkisp1, arg->bls_window2.h_offs,
+                                    RKISP1_CIF_ISP_BLS_H2_START);
+                       rkisp1_write(params->rkisp1, arg->bls_window2.h_size,
+                                    RKISP1_CIF_ISP_BLS_H2_STOP);
+                       rkisp1_write(params->rkisp1, arg->bls_window2.v_offs,
+                                    RKISP1_CIF_ISP_BLS_V2_START);
+                       rkisp1_write(params->rkisp1, arg->bls_window2.v_size,
+                                    RKISP1_CIF_ISP_BLS_V2_STOP);
+                       new_control |= RKISP1_CIF_ISP_BLS_WINDOW_2;
+               }
+
+               if (arg->en_windows & BIT(0)) {
+                       rkisp1_write(params->rkisp1, arg->bls_window1.h_offs,
+                                    RKISP1_CIF_ISP_BLS_H1_START);
+                       rkisp1_write(params->rkisp1, arg->bls_window1.h_size,
+                                    RKISP1_CIF_ISP_BLS_H1_STOP);
+                       rkisp1_write(params->rkisp1, arg->bls_window1.v_offs,
+                                    RKISP1_CIF_ISP_BLS_V1_START);
+                       rkisp1_write(params->rkisp1, arg->bls_window1.v_size,
+                                    RKISP1_CIF_ISP_BLS_V1_STOP);
+                       new_control |= RKISP1_CIF_ISP_BLS_WINDOW_1;
+               }
+
+               rkisp1_write(params->rkisp1, arg->bls_samples,
+                            RKISP1_CIF_ISP_BLS_SAMPLES);
+
+               new_control |= RKISP1_CIF_ISP_BLS_MODE_MEASURED;
+       }
+       rkisp1_write(params->rkisp1, new_control, RKISP1_CIF_ISP_BLS_CTRL);
+}
+
+/* ISP LS correction interface function */
+static void
+rkisp1_lsc_correct_matrix_config(struct rkisp1_params *params,
+                                const struct rkisp1_cif_isp_lsc_config *pconfig)
+{
+       unsigned int isp_lsc_status, sram_addr, isp_lsc_table_sel, i, j, data;
+
+       isp_lsc_status = rkisp1_read(params->rkisp1, RKISP1_CIF_ISP_LSC_STATUS);
+
+       /* RKISP1_CIF_ISP_LSC_TABLE_ADDRESS_153 = ( 17 * 18 ) >> 1 */
+       sram_addr = (isp_lsc_status & RKISP1_CIF_ISP_LSC_ACTIVE_TABLE) ?
+                   RKISP1_CIF_ISP_LSC_TABLE_ADDRESS_0 :
+                   RKISP1_CIF_ISP_LSC_TABLE_ADDRESS_153;
+       rkisp1_write(params->rkisp1, sram_addr,
+                    RKISP1_CIF_ISP_LSC_R_TABLE_ADDR);
+       rkisp1_write(params->rkisp1, sram_addr,
+                    RKISP1_CIF_ISP_LSC_GR_TABLE_ADDR);
+       rkisp1_write(params->rkisp1, sram_addr,
+                    RKISP1_CIF_ISP_LSC_GB_TABLE_ADDR);
+       rkisp1_write(params->rkisp1, sram_addr,
+                    RKISP1_CIF_ISP_LSC_B_TABLE_ADDR);
+
+       /* program data tables (table size is 9 * 17 = 153) */
+       for (i = 0; i < RKISP1_CIF_ISP_LSC_SAMPLES_MAX; i++) {
+               /*
+                * 17 sectors with 2 values in one DWORD = 9
+                * DWORDs (2nd value of last DWORD unused)
+                */
+               for (j = 0; j < RKISP1_CIF_ISP_LSC_SAMPLES_MAX - 1; j += 2) {
+                       data = RKISP1_CIF_ISP_LSC_TABLE_DATA(pconfig->r_data_tbl[i][j],
+                                                            pconfig->r_data_tbl[i][j + 1]);
+                       rkisp1_write(params->rkisp1, data,
+                                    RKISP1_CIF_ISP_LSC_R_TABLE_DATA);
+
+                       data = RKISP1_CIF_ISP_LSC_TABLE_DATA(pconfig->gr_data_tbl[i][j],
+                                                            pconfig->gr_data_tbl[i][j + 1]);
+                       rkisp1_write(params->rkisp1, data,
+                                    RKISP1_CIF_ISP_LSC_GR_TABLE_DATA);
+
+                       data = RKISP1_CIF_ISP_LSC_TABLE_DATA(pconfig->gb_data_tbl[i][j],
+                                                            pconfig->gb_data_tbl[i][j + 1]);
+                       rkisp1_write(params->rkisp1, data,
+                                    RKISP1_CIF_ISP_LSC_GB_TABLE_DATA);
+
+                       data = RKISP1_CIF_ISP_LSC_TABLE_DATA(pconfig->b_data_tbl[i][j],
+                                                            pconfig->b_data_tbl[i][j + 1]);
+                       rkisp1_write(params->rkisp1, data,
+                                    RKISP1_CIF_ISP_LSC_B_TABLE_DATA);
+               }
+               data = RKISP1_CIF_ISP_LSC_TABLE_DATA(pconfig->r_data_tbl[i][j], 0);
+               rkisp1_write(params->rkisp1, data,
+                            RKISP1_CIF_ISP_LSC_R_TABLE_DATA);
+
+               data = RKISP1_CIF_ISP_LSC_TABLE_DATA(pconfig->gr_data_tbl[i][j], 0);
+               rkisp1_write(params->rkisp1, data,
+                            RKISP1_CIF_ISP_LSC_GR_TABLE_DATA);
+
+               data = RKISP1_CIF_ISP_LSC_TABLE_DATA(pconfig->gb_data_tbl[i][j], 0);
+               rkisp1_write(params->rkisp1, data,
+                            RKISP1_CIF_ISP_LSC_GB_TABLE_DATA);
+
+               data = RKISP1_CIF_ISP_LSC_TABLE_DATA(pconfig->b_data_tbl[i][j], 0);
+               rkisp1_write(params->rkisp1, data,
+                            RKISP1_CIF_ISP_LSC_B_TABLE_DATA);
+       }
+       isp_lsc_table_sel = (isp_lsc_status & RKISP1_CIF_ISP_LSC_ACTIVE_TABLE) ?
+                           RKISP1_CIF_ISP_LSC_TABLE_0 :
+                           RKISP1_CIF_ISP_LSC_TABLE_1;
+       rkisp1_write(params->rkisp1, isp_lsc_table_sel,
+                    RKISP1_CIF_ISP_LSC_TABLE_SEL);
+}
+
+static void rkisp1_lsc_config(struct rkisp1_params *params,
+                             const struct rkisp1_cif_isp_lsc_config *arg)
+{
+       unsigned int i, data;
+       u32 lsc_ctrl;
+
+       /* To config must be off , store the current status firstly */
+       lsc_ctrl = rkisp1_read(params->rkisp1, RKISP1_CIF_ISP_LSC_CTRL);
+       rkisp1_param_clear_bits(params, RKISP1_CIF_ISP_LSC_CTRL,
+                               RKISP1_CIF_ISP_LSC_CTRL_ENA);
+       rkisp1_lsc_correct_matrix_config(params, arg);
+
+       for (i = 0; i < RKISP1_CIF_ISP_LSC_SECTORS_TBL_SIZE / 2; i++) {
+               /* program x size tables */
+               data = RKISP1_CIF_ISP_LSC_SECT_SIZE(arg->x_size_tbl[i * 2],
+                                                   arg->x_size_tbl[i * 2 + 1]);
+               rkisp1_write(params->rkisp1, data,
+                            RKISP1_CIF_ISP_LSC_XSIZE_01 + i * 4);
+
+               /* program x grad tables */
+               data = RKISP1_CIF_ISP_LSC_SECT_SIZE(arg->x_grad_tbl[i * 2],
+                                                   arg->x_grad_tbl[i * 2 + 1]);
+               rkisp1_write(params->rkisp1, data,
+                            RKISP1_CIF_ISP_LSC_XGRAD_01 + i * 4);
+
+               /* program y size tables */
+               data = RKISP1_CIF_ISP_LSC_SECT_SIZE(arg->y_size_tbl[i * 2],
+                                                   arg->y_size_tbl[i * 2 + 1]);
+               rkisp1_write(params->rkisp1, data,
+                            RKISP1_CIF_ISP_LSC_YSIZE_01 + i * 4);
+
+               /* program y grad tables */
+               data = RKISP1_CIF_ISP_LSC_SECT_SIZE(arg->y_grad_tbl[i * 2],
+                                                   arg->y_grad_tbl[i * 2 + 1]);
+               rkisp1_write(params->rkisp1, data,
+                            RKISP1_CIF_ISP_LSC_YGRAD_01 + i * 4);
+       }
+
+       /* restore the lsc ctrl status */
+       if (lsc_ctrl & RKISP1_CIF_ISP_LSC_CTRL_ENA) {
+               rkisp1_param_set_bits(params,
+                                     RKISP1_CIF_ISP_LSC_CTRL,
+                                     RKISP1_CIF_ISP_LSC_CTRL_ENA);
+       } else {
+               rkisp1_param_clear_bits(params,
+                                       RKISP1_CIF_ISP_LSC_CTRL,
+                                       RKISP1_CIF_ISP_LSC_CTRL_ENA);
+       }
+}
+
+/* ISP Filtering function */
+static void rkisp1_flt_config(struct rkisp1_params *params,
+                             const struct rkisp1_cif_isp_flt_config *arg)
+{
+       u32 filt_mode;
+
+       rkisp1_write(params->rkisp1,
+                    arg->thresh_bl0, RKISP1_CIF_ISP_FILT_THRESH_BL0);
+       rkisp1_write(params->rkisp1,
+                    arg->thresh_bl1, RKISP1_CIF_ISP_FILT_THRESH_BL1);
+       rkisp1_write(params->rkisp1,
+                    arg->thresh_sh0, RKISP1_CIF_ISP_FILT_THRESH_SH0);
+       rkisp1_write(params->rkisp1,
+                    arg->thresh_sh1, RKISP1_CIF_ISP_FILT_THRESH_SH1);
+       rkisp1_write(params->rkisp1, arg->fac_bl0, RKISP1_CIF_ISP_FILT_FAC_BL0);
+       rkisp1_write(params->rkisp1, arg->fac_bl1, RKISP1_CIF_ISP_FILT_FAC_BL1);
+       rkisp1_write(params->rkisp1, arg->fac_mid, RKISP1_CIF_ISP_FILT_FAC_MID);
+       rkisp1_write(params->rkisp1, arg->fac_sh0, RKISP1_CIF_ISP_FILT_FAC_SH0);
+       rkisp1_write(params->rkisp1, arg->fac_sh1, RKISP1_CIF_ISP_FILT_FAC_SH1);
+       rkisp1_write(params->rkisp1,
+                    arg->lum_weight, RKISP1_CIF_ISP_FILT_LUM_WEIGHT);
+
+       rkisp1_write(params->rkisp1,
+                    (arg->mode ? RKISP1_CIF_ISP_FLT_MODE_DNR : 0) |
+                    RKISP1_CIF_ISP_FLT_CHROMA_V_MODE(arg->chr_v_mode) |
+                    RKISP1_CIF_ISP_FLT_CHROMA_H_MODE(arg->chr_h_mode) |
+                    RKISP1_CIF_ISP_FLT_GREEN_STAGE1(arg->grn_stage1),
+                    RKISP1_CIF_ISP_FILT_MODE);
+
+       /* avoid to override the old enable value */
+       filt_mode = rkisp1_read(params->rkisp1, RKISP1_CIF_ISP_FILT_MODE);
+       filt_mode &= RKISP1_CIF_ISP_FLT_ENA;
+       if (arg->mode)
+               filt_mode |= RKISP1_CIF_ISP_FLT_MODE_DNR;
+       filt_mode |= RKISP1_CIF_ISP_FLT_CHROMA_V_MODE(arg->chr_v_mode) |
+                    RKISP1_CIF_ISP_FLT_CHROMA_H_MODE(arg->chr_h_mode) |
+                    RKISP1_CIF_ISP_FLT_GREEN_STAGE1(arg->grn_stage1);
+       rkisp1_write(params->rkisp1, filt_mode, RKISP1_CIF_ISP_FILT_MODE);
+}
+
+/* ISP demosaic interface function */
+static int rkisp1_bdm_config(struct rkisp1_params *params,
+                            const struct rkisp1_cif_isp_bdm_config *arg)
+{
+       u32 bdm_th;
+
+       /* avoid to override the old enable value */
+       bdm_th = rkisp1_read(params->rkisp1, RKISP1_CIF_ISP_DEMOSAIC);
+       bdm_th &= RKISP1_CIF_ISP_DEMOSAIC_BYPASS;
+       bdm_th |= arg->demosaic_th & ~RKISP1_CIF_ISP_DEMOSAIC_BYPASS;
+       /* set demosaic threshold */
+       rkisp1_write(params->rkisp1, bdm_th, RKISP1_CIF_ISP_DEMOSAIC);
+       return 0;
+}
+
+/* ISP GAMMA correction interface function */
+static void rkisp1_sdg_config(struct rkisp1_params *params,
+                             const struct rkisp1_cif_isp_sdg_config *arg)
+{
+       unsigned int i;
+
+       rkisp1_write(params->rkisp1,
+                    arg->xa_pnts.gamma_dx0, RKISP1_CIF_ISP_GAMMA_DX_LO);
+       rkisp1_write(params->rkisp1,
+                    arg->xa_pnts.gamma_dx1, RKISP1_CIF_ISP_GAMMA_DX_HI);
+
+       for (i = 0; i < RKISP1_CIF_ISP_DEGAMMA_CURVE_SIZE; i++) {
+               rkisp1_write(params->rkisp1, arg->curve_r.gamma_y[i],
+                            RKISP1_CIF_ISP_GAMMA_R_Y0 + i * 4);
+               rkisp1_write(params->rkisp1, arg->curve_g.gamma_y[i],
+                            RKISP1_CIF_ISP_GAMMA_G_Y0 + i * 4);
+               rkisp1_write(params->rkisp1, arg->curve_b.gamma_y[i],
+                            RKISP1_CIF_ISP_GAMMA_B_Y0 + i * 4);
+       }
+}
+
+/* ISP GAMMA correction interface function */
+static void rkisp1_goc_config(struct rkisp1_params *params,
+                             const struct rkisp1_cif_isp_goc_config *arg)
+{
+       unsigned int i;
+
+       rkisp1_param_clear_bits(params, RKISP1_CIF_ISP_CTRL,
+                               RKISP1_CIF_ISP_CTRL_ISP_GAMMA_OUT_ENA);
+       rkisp1_write(params->rkisp1, arg->mode, RKISP1_CIF_ISP_GAMMA_OUT_MODE);
+
+       for (i = 0; i < RKISP1_CIF_ISP_GAMMA_OUT_MAX_SAMPLES; i++)
+               rkisp1_write(params->rkisp1, arg->gamma_y[i],
+                            RKISP1_CIF_ISP_GAMMA_OUT_Y_0 + i * 4);
+}
+
+/* ISP Cross Talk */
+static void rkisp1_ctk_config(struct rkisp1_params *params,
+                             const struct rkisp1_cif_isp_ctk_config *arg)
+{
+       unsigned int i, j, k = 0;
+
+       for (i = 0; i < 3; i++)
+               for (j = 0; j < 3; j++)
+                       rkisp1_write(params->rkisp1, arg->coeff[i][j],
+                                    RKISP1_CIF_ISP_CT_COEFF_0 + 4 * k++);
+       for (i = 0; i < 3; i++)
+               rkisp1_write(params->rkisp1, arg->ct_offset[i],
+                            RKISP1_CIF_ISP_CT_OFFSET_R + i * 4);
+}
+
+static void rkisp1_ctk_enable(struct rkisp1_params *params, bool en)
+{
+       if (en)
+               return;
+
+       /* Write back the default values. */
+       rkisp1_write(params->rkisp1, 0x80, RKISP1_CIF_ISP_CT_COEFF_0);
+       rkisp1_write(params->rkisp1, 0, RKISP1_CIF_ISP_CT_COEFF_1);
+       rkisp1_write(params->rkisp1, 0, RKISP1_CIF_ISP_CT_COEFF_2);
+       rkisp1_write(params->rkisp1, 0, RKISP1_CIF_ISP_CT_COEFF_3);
+       rkisp1_write(params->rkisp1, 0x80, RKISP1_CIF_ISP_CT_COEFF_4);
+       rkisp1_write(params->rkisp1, 0, RKISP1_CIF_ISP_CT_COEFF_5);
+       rkisp1_write(params->rkisp1, 0, RKISP1_CIF_ISP_CT_COEFF_6);
+       rkisp1_write(params->rkisp1, 0, RKISP1_CIF_ISP_CT_COEFF_7);
+       rkisp1_write(params->rkisp1, 0x80, RKISP1_CIF_ISP_CT_COEFF_8);
+
+       rkisp1_write(params->rkisp1, 0, RKISP1_CIF_ISP_CT_OFFSET_R);
+       rkisp1_write(params->rkisp1, 0, RKISP1_CIF_ISP_CT_OFFSET_G);
+       rkisp1_write(params->rkisp1, 0, RKISP1_CIF_ISP_CT_OFFSET_B);
+}
+
+/* ISP White Balance Mode */
+static void rkisp1_awb_meas_config(struct rkisp1_params *params,
+                                  const struct rkisp1_cif_isp_awb_meas_config *arg)
+{
+       u32 reg_val = 0;
+       /* based on the mode,configure the awb module */
+       if (arg->awb_mode == RKISP1_CIF_ISP_AWB_MODE_YCBCR) {
+               /* Reference Cb and Cr */
+               rkisp1_write(params->rkisp1,
+                            RKISP1_CIF_ISP_AWB_REF_CR_SET(arg->awb_ref_cr) |
+                            arg->awb_ref_cb, RKISP1_CIF_ISP_AWB_REF);
+               /* Yc Threshold */
+               rkisp1_write(params->rkisp1,
+                            RKISP1_CIF_ISP_AWB_MAX_Y_SET(arg->max_y) |
+                            RKISP1_CIF_ISP_AWB_MIN_Y_SET(arg->min_y) |
+                            RKISP1_CIF_ISP_AWB_MAX_CS_SET(arg->max_csum) |
+                            arg->min_c, RKISP1_CIF_ISP_AWB_THRESH);
+       }
+
+       reg_val = rkisp1_read(params->rkisp1, RKISP1_CIF_ISP_AWB_PROP);
+       if (arg->enable_ymax_cmp)
+               reg_val |= RKISP1_CIF_ISP_AWB_YMAX_CMP_EN;
+       else
+               reg_val &= ~RKISP1_CIF_ISP_AWB_YMAX_CMP_EN;
+       rkisp1_write(params->rkisp1, reg_val, RKISP1_CIF_ISP_AWB_PROP);
+
+       /* window offset */
+       rkisp1_write(params->rkisp1,
+                    arg->awb_wnd.v_offs, RKISP1_CIF_ISP_AWB_WND_V_OFFS);
+       rkisp1_write(params->rkisp1,
+                    arg->awb_wnd.h_offs, RKISP1_CIF_ISP_AWB_WND_H_OFFS);
+       /* AWB window size */
+       rkisp1_write(params->rkisp1,
+                    arg->awb_wnd.v_size, RKISP1_CIF_ISP_AWB_WND_V_SIZE);
+       rkisp1_write(params->rkisp1,
+                    arg->awb_wnd.h_size, RKISP1_CIF_ISP_AWB_WND_H_SIZE);
+       /* Number of frames */
+       rkisp1_write(params->rkisp1,
+                    arg->frames, RKISP1_CIF_ISP_AWB_FRAMES);
+}
+
+static void
+rkisp1_awb_meas_enable(struct rkisp1_params *params,
+                      const struct rkisp1_cif_isp_awb_meas_config *arg,
+                      bool en)
+{
+       u32 reg_val = rkisp1_read(params->rkisp1, RKISP1_CIF_ISP_AWB_PROP);
+
+       /* switch off */
+       reg_val &= RKISP1_CIF_ISP_AWB_MODE_MASK_NONE;
+
+       if (en) {
+               if (arg->awb_mode == RKISP1_CIF_ISP_AWB_MODE_RGB)
+                       reg_val |= RKISP1_CIF_ISP_AWB_MODE_RGB_EN;
+               else
+                       reg_val |= RKISP1_CIF_ISP_AWB_MODE_YCBCR_EN;
+
+               rkisp1_write(params->rkisp1, reg_val, RKISP1_CIF_ISP_AWB_PROP);
+
+               /* Measurements require AWB block be active. */
+               rkisp1_param_set_bits(params, RKISP1_CIF_ISP_CTRL,
+                                     RKISP1_CIF_ISP_CTRL_ISP_AWB_ENA);
+       } else {
+               rkisp1_write(params->rkisp1,
+                            reg_val, RKISP1_CIF_ISP_AWB_PROP);
+               rkisp1_param_clear_bits(params, RKISP1_CIF_ISP_CTRL,
+                                       RKISP1_CIF_ISP_CTRL_ISP_AWB_ENA);
+       }
+}
+
+static void
+rkisp1_awb_gain_config(struct rkisp1_params *params,
+                      const struct rkisp1_cif_isp_awb_gain_config *arg)
+{
+       rkisp1_write(params->rkisp1,
+                    RKISP1_CIF_ISP_AWB_GAIN_R_SET(arg->gain_green_r) |
+                    arg->gain_green_b, RKISP1_CIF_ISP_AWB_GAIN_G);
+
+       rkisp1_write(params->rkisp1,
+                    RKISP1_CIF_ISP_AWB_GAIN_R_SET(arg->gain_red) |
+                    arg->gain_blue, RKISP1_CIF_ISP_AWB_GAIN_RB);
+}
+
+static void rkisp1_aec_config(struct rkisp1_params *params,
+                             const struct rkisp1_cif_isp_aec_config *arg)
+{
+       unsigned int block_hsize, block_vsize;
+       u32 exp_ctrl;
+
+       /* avoid to override the old enable value */
+       exp_ctrl = rkisp1_read(params->rkisp1, RKISP1_CIF_ISP_EXP_CTRL);
+       exp_ctrl &= RKISP1_CIF_ISP_EXP_ENA;
+       if (arg->autostop)
+               exp_ctrl |= RKISP1_CIF_ISP_EXP_CTRL_AUTOSTOP;
+       if (arg->mode == RKISP1_CIF_ISP_EXP_MEASURING_MODE_1)
+               exp_ctrl |= RKISP1_CIF_ISP_EXP_CTRL_MEASMODE_1;
+       rkisp1_write(params->rkisp1, exp_ctrl, RKISP1_CIF_ISP_EXP_CTRL);
+
+       rkisp1_write(params->rkisp1,
+                    arg->meas_window.h_offs, RKISP1_CIF_ISP_EXP_H_OFFSET);
+       rkisp1_write(params->rkisp1,
+                    arg->meas_window.v_offs, RKISP1_CIF_ISP_EXP_V_OFFSET);
+
+       block_hsize = arg->meas_window.h_size /
+                     RKISP1_CIF_ISP_EXP_COLUMN_NUM - 1;
+       block_vsize = arg->meas_window.v_size /
+                     RKISP1_CIF_ISP_EXP_ROW_NUM - 1;
+
+       rkisp1_write(params->rkisp1,
+                    RKISP1_CIF_ISP_EXP_H_SIZE_SET(block_hsize),
+                    RKISP1_CIF_ISP_EXP_H_SIZE);
+       rkisp1_write(params->rkisp1,
+                    RKISP1_CIF_ISP_EXP_V_SIZE_SET(block_vsize),
+                    RKISP1_CIF_ISP_EXP_V_SIZE);
+}
+
+static void rkisp1_cproc_config(struct rkisp1_params *params,
+                               const struct rkisp1_cif_isp_cproc_config *arg)
+{
+       struct rkisp1_cif_isp_isp_other_cfg *cur_other_cfg =
+               container_of(arg, struct rkisp1_cif_isp_isp_other_cfg, cproc_config);
+       struct rkisp1_cif_isp_ie_config *cur_ie_config =
+                                               &cur_other_cfg->ie_config;
+       u32 effect = cur_ie_config->effect;
+       u32 quantization = params->quantization;
+
+       rkisp1_write(params->rkisp1, arg->contrast, RKISP1_CIF_C_PROC_CONTRAST);
+       rkisp1_write(params->rkisp1, arg->hue, RKISP1_CIF_C_PROC_HUE);
+       rkisp1_write(params->rkisp1, arg->sat, RKISP1_CIF_C_PROC_SATURATION);
+       rkisp1_write(params->rkisp1, arg->brightness,
+                    RKISP1_CIF_C_PROC_BRIGHTNESS);
+
+       if (quantization != V4L2_QUANTIZATION_FULL_RANGE ||
+           effect != V4L2_COLORFX_NONE) {
+               rkisp1_param_clear_bits(params, RKISP1_CIF_C_PROC_CTRL,
+                                       RKISP1_CIF_C_PROC_YOUT_FULL |
+                                       RKISP1_CIF_C_PROC_YIN_FULL |
+                                       RKISP1_CIF_C_PROC_COUT_FULL);
+       } else {
+               rkisp1_param_set_bits(params, RKISP1_CIF_C_PROC_CTRL,
+                                     RKISP1_CIF_C_PROC_YOUT_FULL |
+                                     RKISP1_CIF_C_PROC_YIN_FULL |
+                                     RKISP1_CIF_C_PROC_COUT_FULL);
+       }
+}
+
+static void rkisp1_hst_config(struct rkisp1_params *params,
+                             const struct rkisp1_cif_isp_hst_config *arg)
+{
+       unsigned int block_hsize, block_vsize;
+       static const u32 hist_weight_regs[] = {
+               RKISP1_CIF_ISP_HIST_WEIGHT_00TO30,
+               RKISP1_CIF_ISP_HIST_WEIGHT_40TO21,
+               RKISP1_CIF_ISP_HIST_WEIGHT_31TO12,
+               RKISP1_CIF_ISP_HIST_WEIGHT_22TO03,
+               RKISP1_CIF_ISP_HIST_WEIGHT_13TO43,
+               RKISP1_CIF_ISP_HIST_WEIGHT_04TO34,
+               RKISP1_CIF_ISP_HIST_WEIGHT_44,
+       };
+       const u8 *weight;
+       unsigned int i;
+       u32 hist_prop;
+
+       /* avoid to override the old enable value */
+       hist_prop = rkisp1_read(params->rkisp1, RKISP1_CIF_ISP_HIST_PROP);
+       hist_prop &= RKISP1_CIF_ISP_HIST_PROP_MODE_MASK;
+       hist_prop |= RKISP1_CIF_ISP_HIST_PREDIV_SET(arg->histogram_predivider);
+       rkisp1_write(params->rkisp1, hist_prop, RKISP1_CIF_ISP_HIST_PROP);
+       rkisp1_write(params->rkisp1,
+                    arg->meas_window.h_offs,
+                    RKISP1_CIF_ISP_HIST_H_OFFS);
+       rkisp1_write(params->rkisp1,
+                    arg->meas_window.v_offs,
+                    RKISP1_CIF_ISP_HIST_V_OFFS);
+
+       block_hsize = arg->meas_window.h_size /
+                     RKISP1_CIF_ISP_HIST_COLUMN_NUM - 1;
+       block_vsize = arg->meas_window.v_size / RKISP1_CIF_ISP_HIST_ROW_NUM - 1;
+
+       rkisp1_write(params->rkisp1, block_hsize, RKISP1_CIF_ISP_HIST_H_SIZE);
+       rkisp1_write(params->rkisp1, block_vsize, RKISP1_CIF_ISP_HIST_V_SIZE);
+
+       weight = arg->hist_weight;
+       for (i = 0; i < ARRAY_SIZE(hist_weight_regs); ++i, weight += 4)
+               rkisp1_write(params->rkisp1,
+                            RKISP1_CIF_ISP_HIST_WEIGHT_SET(weight[0],
+                                                           weight[1],
+                                                           weight[2],
+                                                           weight[3]),
+                                hist_weight_regs[i]);
+}
+
+static void
+rkisp1_hst_enable(struct rkisp1_params *params,
+                 const struct rkisp1_cif_isp_hst_config *arg, bool en)
+{
+       if (en) {
+               u32 hist_prop = rkisp1_read(params->rkisp1,
+                                           RKISP1_CIF_ISP_HIST_PROP);
+
+               hist_prop &= ~RKISP1_CIF_ISP_HIST_PROP_MODE_MASK;
+               hist_prop |= arg->mode;
+               rkisp1_param_set_bits(params, RKISP1_CIF_ISP_HIST_PROP,
+                                     hist_prop);
+       } else {
+               rkisp1_param_clear_bits(params, RKISP1_CIF_ISP_HIST_PROP,
+                                       RKISP1_CIF_ISP_HIST_PROP_MODE_MASK);
+       }
+}
+
+static void rkisp1_afm_config(struct rkisp1_params *params,
+                             const struct rkisp1_cif_isp_afc_config *arg)
+{
+       size_t num_of_win = min_t(size_t, ARRAY_SIZE(arg->afm_win),
+                                 arg->num_afm_win);
+       u32 afm_ctrl = rkisp1_read(params->rkisp1, RKISP1_CIF_ISP_AFM_CTRL);
+       unsigned int i;
+
+       /* Switch off to configure. */
+       rkisp1_param_clear_bits(params, RKISP1_CIF_ISP_AFM_CTRL,
+                               RKISP1_CIF_ISP_AFM_ENA);
+
+       for (i = 0; i < num_of_win; i++) {
+               rkisp1_write(params->rkisp1,
+                            RKISP1_CIF_ISP_AFM_WINDOW_X(arg->afm_win[i].h_offs) |
+                            RKISP1_CIF_ISP_AFM_WINDOW_Y(arg->afm_win[i].v_offs),
+                            RKISP1_CIF_ISP_AFM_LT_A + i * 8);
+               rkisp1_write(params->rkisp1,
+                            RKISP1_CIF_ISP_AFM_WINDOW_X(arg->afm_win[i].h_size +
+                                                        arg->afm_win[i].h_offs) |
+                            RKISP1_CIF_ISP_AFM_WINDOW_Y(arg->afm_win[i].v_size +
+                                                        arg->afm_win[i].v_offs),
+                            RKISP1_CIF_ISP_AFM_RB_A + i * 8);
+       }
+       rkisp1_write(params->rkisp1, arg->thres, RKISP1_CIF_ISP_AFM_THRES);
+       rkisp1_write(params->rkisp1, arg->var_shift,
+                    RKISP1_CIF_ISP_AFM_VAR_SHIFT);
+       /* restore afm status */
+       rkisp1_write(params->rkisp1, afm_ctrl, RKISP1_CIF_ISP_AFM_CTRL);
+}
+
+static void rkisp1_ie_config(struct rkisp1_params *params,
+                            const struct rkisp1_cif_isp_ie_config *arg)
+{
+       u32 eff_ctrl;
+
+       eff_ctrl = rkisp1_read(params->rkisp1, RKISP1_CIF_IMG_EFF_CTRL);
+       eff_ctrl &= ~RKISP1_CIF_IMG_EFF_CTRL_MODE_MASK;
+
+       if (params->quantization == V4L2_QUANTIZATION_FULL_RANGE)
+               eff_ctrl |= RKISP1_CIF_IMG_EFF_CTRL_YCBCR_FULL;
+
+       switch (arg->effect) {
+       case V4L2_COLORFX_SEPIA:
+               eff_ctrl |= RKISP1_CIF_IMG_EFF_CTRL_MODE_SEPIA;
+               break;
+       case V4L2_COLORFX_SET_CBCR:
+               rkisp1_write(params->rkisp1, arg->eff_tint,
+                            RKISP1_CIF_IMG_EFF_TINT);
+               eff_ctrl |= RKISP1_CIF_IMG_EFF_CTRL_MODE_SEPIA;
+               break;
+               /*
+                * Color selection is similar to water color(AQUA):
+                * grayscale + selected color w threshold
+                */
+       case V4L2_COLORFX_AQUA:
+               eff_ctrl |= RKISP1_CIF_IMG_EFF_CTRL_MODE_COLOR_SEL;
+               rkisp1_write(params->rkisp1, arg->color_sel,
+                            RKISP1_CIF_IMG_EFF_COLOR_SEL);
+               break;
+       case V4L2_COLORFX_EMBOSS:
+               eff_ctrl |= RKISP1_CIF_IMG_EFF_CTRL_MODE_EMBOSS;
+               rkisp1_write(params->rkisp1, arg->eff_mat_1,
+                            RKISP1_CIF_IMG_EFF_MAT_1);
+               rkisp1_write(params->rkisp1, arg->eff_mat_2,
+                            RKISP1_CIF_IMG_EFF_MAT_2);
+               rkisp1_write(params->rkisp1, arg->eff_mat_3,
+                            RKISP1_CIF_IMG_EFF_MAT_3);
+               break;
+       case V4L2_COLORFX_SKETCH:
+               eff_ctrl |= RKISP1_CIF_IMG_EFF_CTRL_MODE_SKETCH;
+               rkisp1_write(params->rkisp1, arg->eff_mat_3,
+                            RKISP1_CIF_IMG_EFF_MAT_3);
+               rkisp1_write(params->rkisp1, arg->eff_mat_4,
+                            RKISP1_CIF_IMG_EFF_MAT_4);
+               rkisp1_write(params->rkisp1, arg->eff_mat_5,
+                            RKISP1_CIF_IMG_EFF_MAT_5);
+               break;
+       case V4L2_COLORFX_BW:
+               eff_ctrl |= RKISP1_CIF_IMG_EFF_CTRL_MODE_BLACKWHITE;
+               break;
+       case V4L2_COLORFX_NEGATIVE:
+               eff_ctrl |= RKISP1_CIF_IMG_EFF_CTRL_MODE_NEGATIVE;
+               break;
+       default:
+               break;
+       }
+
+       rkisp1_write(params->rkisp1, eff_ctrl, RKISP1_CIF_IMG_EFF_CTRL);
+}
+
+static void rkisp1_ie_enable(struct rkisp1_params *params, bool en)
+{
+       if (en) {
+               rkisp1_param_set_bits(params, RKISP1_CIF_ICCL,
+                                     RKISP1_CIF_ICCL_IE_CLK);
+               rkisp1_write(params->rkisp1, RKISP1_CIF_IMG_EFF_CTRL_ENABLE,
+                            RKISP1_CIF_IMG_EFF_CTRL);
+               rkisp1_param_set_bits(params, RKISP1_CIF_IMG_EFF_CTRL,
+                                     RKISP1_CIF_IMG_EFF_CTRL_CFG_UPD);
+       } else {
+               rkisp1_param_clear_bits(params, RKISP1_CIF_IMG_EFF_CTRL,
+                                       RKISP1_CIF_IMG_EFF_CTRL_ENABLE);
+               rkisp1_param_clear_bits(params, RKISP1_CIF_ICCL,
+                                       RKISP1_CIF_ICCL_IE_CLK);
+       }
+}
+
+static void rkisp1_csm_config(struct rkisp1_params *params, bool full_range)
+{
+       static const u16 full_range_coeff[] = {
+               0x0026, 0x004b, 0x000f,
+               0x01ea, 0x01d6, 0x0040,
+               0x0040, 0x01ca, 0x01f6
+       };
+       static const u16 limited_range_coeff[] = {
+               0x0021, 0x0040, 0x000d,
+               0x01ed, 0x01db, 0x0038,
+               0x0038, 0x01d1, 0x01f7,
+       };
+       unsigned int i;
+
+       if (full_range) {
+               for (i = 0; i < ARRAY_SIZE(full_range_coeff); i++)
+                       rkisp1_write(params->rkisp1, full_range_coeff[i],
+                                    RKISP1_CIF_ISP_CC_COEFF_0 + i * 4);
+
+               rkisp1_param_set_bits(params, RKISP1_CIF_ISP_CTRL,
+                                     RKISP1_CIF_ISP_CTRL_ISP_CSM_Y_FULL_ENA |
+                                     RKISP1_CIF_ISP_CTRL_ISP_CSM_C_FULL_ENA);
+       } else {
+               for (i = 0; i < ARRAY_SIZE(limited_range_coeff); i++)
+                       rkisp1_write(params->rkisp1, limited_range_coeff[i],
+                                    RKISP1_CIF_ISP_CC_COEFF_0 + i * 4);
+
+               rkisp1_param_clear_bits(params, RKISP1_CIF_ISP_CTRL,
+                                       RKISP1_CIF_ISP_CTRL_ISP_CSM_Y_FULL_ENA |
+                                       RKISP1_CIF_ISP_CTRL_ISP_CSM_C_FULL_ENA);
+       }
+}
+
+/* ISP De-noise Pre-Filter(DPF) function */
+static void rkisp1_dpf_config(struct rkisp1_params *params,
+                             const struct rkisp1_cif_isp_dpf_config *arg)
+{
+       unsigned int isp_dpf_mode, spatial_coeff, i;
+
+       switch (arg->gain.mode) {
+       case RKISP1_CIF_ISP_DPF_GAIN_USAGE_NF_GAINS:
+               isp_dpf_mode = RKISP1_CIF_ISP_DPF_MODE_USE_NF_GAIN |
+                              RKISP1_CIF_ISP_DPF_MODE_AWB_GAIN_COMP;
+               break;
+       case RKISP1_CIF_ISP_DPF_GAIN_USAGE_LSC_GAINS:
+               isp_dpf_mode = RKISP1_CIF_ISP_DPF_MODE_LSC_GAIN_COMP;
+               break;
+       case RKISP1_CIF_ISP_DPF_GAIN_USAGE_NF_LSC_GAINS:
+               isp_dpf_mode = RKISP1_CIF_ISP_DPF_MODE_USE_NF_GAIN |
+                              RKISP1_CIF_ISP_DPF_MODE_AWB_GAIN_COMP |
+                              RKISP1_CIF_ISP_DPF_MODE_LSC_GAIN_COMP;
+               break;
+       case RKISP1_CIF_ISP_DPF_GAIN_USAGE_AWB_GAINS:
+               isp_dpf_mode = RKISP1_CIF_ISP_DPF_MODE_AWB_GAIN_COMP;
+               break;
+       case RKISP1_CIF_ISP_DPF_GAIN_USAGE_AWB_LSC_GAINS:
+               isp_dpf_mode = RKISP1_CIF_ISP_DPF_MODE_LSC_GAIN_COMP |
+                              RKISP1_CIF_ISP_DPF_MODE_AWB_GAIN_COMP;
+               break;
+       case RKISP1_CIF_ISP_DPF_GAIN_USAGE_DISABLED:
+       default:
+               isp_dpf_mode = 0;
+               break;
+       }
+
+       if (arg->nll.scale_mode == RKISP1_CIF_ISP_NLL_SCALE_LOGARITHMIC)
+               isp_dpf_mode |= RKISP1_CIF_ISP_DPF_MODE_NLL_SEGMENTATION;
+       if (arg->rb_flt.fltsize == RKISP1_CIF_ISP_DPF_RB_FILTERSIZE_9x9)
+               isp_dpf_mode |= RKISP1_CIF_ISP_DPF_MODE_RB_FLTSIZE_9x9;
+       if (!arg->rb_flt.r_enable)
+               isp_dpf_mode |= RKISP1_CIF_ISP_DPF_MODE_R_FLT_DIS;
+       if (!arg->rb_flt.b_enable)
+               isp_dpf_mode |= RKISP1_CIF_ISP_DPF_MODE_B_FLT_DIS;
+       if (!arg->g_flt.gb_enable)
+               isp_dpf_mode |= RKISP1_CIF_ISP_DPF_MODE_GB_FLT_DIS;
+       if (!arg->g_flt.gr_enable)
+               isp_dpf_mode |= RKISP1_CIF_ISP_DPF_MODE_GR_FLT_DIS;
+
+       rkisp1_param_set_bits(params, RKISP1_CIF_ISP_DPF_MODE,
+                             isp_dpf_mode);
+       rkisp1_write(params->rkisp1, arg->gain.nf_b_gain,
+                    RKISP1_CIF_ISP_DPF_NF_GAIN_B);
+       rkisp1_write(params->rkisp1, arg->gain.nf_r_gain,
+                    RKISP1_CIF_ISP_DPF_NF_GAIN_R);
+       rkisp1_write(params->rkisp1, arg->gain.nf_gb_gain,
+                    RKISP1_CIF_ISP_DPF_NF_GAIN_GB);
+       rkisp1_write(params->rkisp1, arg->gain.nf_gr_gain,
+                    RKISP1_CIF_ISP_DPF_NF_GAIN_GR);
+
+       for (i = 0; i < RKISP1_CIF_ISP_DPF_MAX_NLF_COEFFS; i++) {
+               rkisp1_write(params->rkisp1, arg->nll.coeff[i],
+                            RKISP1_CIF_ISP_DPF_NULL_COEFF_0 + i * 4);
+       }
+
+       spatial_coeff = arg->g_flt.spatial_coeff[0] |
+                       (arg->g_flt.spatial_coeff[1] << 8) |
+                       (arg->g_flt.spatial_coeff[2] << 16) |
+                       (arg->g_flt.spatial_coeff[3] << 24);
+       rkisp1_write(params->rkisp1, spatial_coeff,
+                    RKISP1_CIF_ISP_DPF_S_WEIGHT_G_1_4);
+
+       spatial_coeff = arg->g_flt.spatial_coeff[4] |
+                       (arg->g_flt.spatial_coeff[5] << 8);
+       rkisp1_write(params->rkisp1, spatial_coeff,
+                    RKISP1_CIF_ISP_DPF_S_WEIGHT_G_5_6);
+
+       spatial_coeff = arg->rb_flt.spatial_coeff[0] |
+                       (arg->rb_flt.spatial_coeff[1] << 8) |
+                       (arg->rb_flt.spatial_coeff[2] << 16) |
+                       (arg->rb_flt.spatial_coeff[3] << 24);
+       rkisp1_write(params->rkisp1, spatial_coeff,
+                    RKISP1_CIF_ISP_DPF_S_WEIGHT_RB_1_4);
+
+       spatial_coeff = arg->rb_flt.spatial_coeff[4] |
+                       (arg->rb_flt.spatial_coeff[5] << 8);
+       rkisp1_write(params->rkisp1, spatial_coeff,
+                    RKISP1_CIF_ISP_DPF_S_WEIGHT_RB_5_6);
+}
+
+static void
+rkisp1_dpf_strength_config(struct rkisp1_params *params,
+                          const struct rkisp1_cif_isp_dpf_strength_config *arg)
+{
+       rkisp1_write(params->rkisp1, arg->b, RKISP1_CIF_ISP_DPF_STRENGTH_B);
+       rkisp1_write(params->rkisp1, arg->g, RKISP1_CIF_ISP_DPF_STRENGTH_G);
+       rkisp1_write(params->rkisp1, arg->r, RKISP1_CIF_ISP_DPF_STRENGTH_R);
+}
+
+static void
+rkisp1_isp_isr_other_config(struct rkisp1_params *params,
+                           const struct rkisp1_params_cfg *new_params)
+{
+       unsigned int module_en_update, module_cfg_update, module_ens;
+
+       module_en_update = new_params->module_en_update;
+       module_cfg_update = new_params->module_cfg_update;
+       module_ens = new_params->module_ens;
+
+       if ((module_en_update & RKISP1_CIF_ISP_MODULE_DPCC) ||
+           (module_cfg_update & RKISP1_CIF_ISP_MODULE_DPCC)) {
+               /*update dpc config */
+               if (module_cfg_update & RKISP1_CIF_ISP_MODULE_DPCC)
+                       rkisp1_dpcc_config(params,
+                                          &new_params->others.dpcc_config);
+
+               if (module_en_update & RKISP1_CIF_ISP_MODULE_DPCC) {
+                       if (module_ens & RKISP1_CIF_ISP_MODULE_DPCC)
+                               rkisp1_param_set_bits(params,
+                                                     RKISP1_CIF_ISP_DPCC_MODE,
+                                                     RKISP1_CIF_ISP_DPCC_ENA);
+                       else
+                               rkisp1_param_clear_bits(params,
+                                                       RKISP1_CIF_ISP_DPCC_MODE,
+                                                       RKISP1_CIF_ISP_DPCC_ENA);
+               }
+       }
+
+       if ((module_en_update & RKISP1_CIF_ISP_MODULE_BLS) ||
+           (module_cfg_update & RKISP1_CIF_ISP_MODULE_BLS)) {
+               /* update bls config */
+               if (module_cfg_update & RKISP1_CIF_ISP_MODULE_BLS)
+                       rkisp1_bls_config(params,
+                                         &new_params->others.bls_config);
+
+               if (module_en_update & RKISP1_CIF_ISP_MODULE_BLS) {
+                       if (module_ens & RKISP1_CIF_ISP_MODULE_BLS)
+                               rkisp1_param_set_bits(params,
+                                                     RKISP1_CIF_ISP_BLS_CTRL,
+                                                     RKISP1_CIF_ISP_BLS_ENA);
+                       else
+                               rkisp1_param_clear_bits(params,
+                                                       RKISP1_CIF_ISP_BLS_CTRL,
+                                                       RKISP1_CIF_ISP_BLS_ENA);
+               }
+       }
+
+       if ((module_en_update & RKISP1_CIF_ISP_MODULE_SDG) ||
+           (module_cfg_update & RKISP1_CIF_ISP_MODULE_SDG)) {
+               /* update sdg config */
+               if (module_cfg_update & RKISP1_CIF_ISP_MODULE_SDG)
+                       rkisp1_sdg_config(params,
+                                         &new_params->others.sdg_config);
+
+               if (module_en_update & RKISP1_CIF_ISP_MODULE_SDG) {
+                       if (module_ens & RKISP1_CIF_ISP_MODULE_SDG)
+                               rkisp1_param_set_bits(params,
+                                                     RKISP1_CIF_ISP_CTRL,
+                                                     RKISP1_CIF_ISP_CTRL_ISP_GAMMA_IN_ENA);
+                       else
+                               rkisp1_param_clear_bits(params,
+                                                       RKISP1_CIF_ISP_CTRL,
+                                                       RKISP1_CIF_ISP_CTRL_ISP_GAMMA_IN_ENA);
+               }
+       }
+
+       if ((module_en_update & RKISP1_CIF_ISP_MODULE_LSC) ||
+           (module_cfg_update & RKISP1_CIF_ISP_MODULE_LSC)) {
+               /* update lsc config */
+               if (module_cfg_update & RKISP1_CIF_ISP_MODULE_LSC)
+                       rkisp1_lsc_config(params,
+                                         &new_params->others.lsc_config);
+
+               if (module_en_update & RKISP1_CIF_ISP_MODULE_LSC) {
+                       if (module_ens & RKISP1_CIF_ISP_MODULE_LSC)
+                               rkisp1_param_set_bits(params,
+                                                     RKISP1_CIF_ISP_LSC_CTRL,
+                                                     RKISP1_CIF_ISP_LSC_CTRL_ENA);
+                       else
+                               rkisp1_param_clear_bits(params,
+                                                       RKISP1_CIF_ISP_LSC_CTRL,
+                                                       RKISP1_CIF_ISP_LSC_CTRL_ENA);
+               }
+       }
+
+       if ((module_en_update & RKISP1_CIF_ISP_MODULE_AWB_GAIN) ||
+           (module_cfg_update & RKISP1_CIF_ISP_MODULE_AWB_GAIN)) {
+               /* update awb gains */
+               if (module_cfg_update & RKISP1_CIF_ISP_MODULE_AWB_GAIN)
+                       rkisp1_awb_gain_config(params,
+                                              &new_params->others.awb_gain_config);
+
+               if (module_en_update & RKISP1_CIF_ISP_MODULE_AWB_GAIN) {
+                       if (module_ens & RKISP1_CIF_ISP_MODULE_AWB_GAIN)
+                               rkisp1_param_set_bits(params,
+                                                     RKISP1_CIF_ISP_CTRL,
+                                                     RKISP1_CIF_ISP_CTRL_ISP_AWB_ENA);
+                       else
+                               rkisp1_param_clear_bits(params,
+                                                       RKISP1_CIF_ISP_CTRL,
+                                                       RKISP1_CIF_ISP_CTRL_ISP_AWB_ENA);
+               }
+       }
+
+       if ((module_en_update & RKISP1_CIF_ISP_MODULE_BDM) ||
+           (module_cfg_update & RKISP1_CIF_ISP_MODULE_BDM)) {
+               /* update bdm config */
+               if (module_cfg_update & RKISP1_CIF_ISP_MODULE_BDM)
+                       rkisp1_bdm_config(params,
+                                         &new_params->others.bdm_config);
+
+               if (module_en_update & RKISP1_CIF_ISP_MODULE_BDM) {
+                       if (module_ens & RKISP1_CIF_ISP_MODULE_BDM)
+                               rkisp1_param_set_bits(params,
+                                                     RKISP1_CIF_ISP_DEMOSAIC,
+                                                     RKISP1_CIF_ISP_DEMOSAIC_BYPASS);
+                       else
+                               rkisp1_param_clear_bits(params,
+                                                       RKISP1_CIF_ISP_DEMOSAIC,
+                                                       RKISP1_CIF_ISP_DEMOSAIC_BYPASS);
+               }
+       }
+
+       if ((module_en_update & RKISP1_CIF_ISP_MODULE_FLT) ||
+           (module_cfg_update & RKISP1_CIF_ISP_MODULE_FLT)) {
+               /* update filter config */
+               if (module_cfg_update & RKISP1_CIF_ISP_MODULE_FLT)
+                       rkisp1_flt_config(params,
+                                         &new_params->others.flt_config);
+
+               if (module_en_update & RKISP1_CIF_ISP_MODULE_FLT) {
+                       if (module_ens & RKISP1_CIF_ISP_MODULE_FLT)
+                               rkisp1_param_set_bits(params,
+                                                     RKISP1_CIF_ISP_FILT_MODE,
+                                                     RKISP1_CIF_ISP_FLT_ENA);
+                       else
+                               rkisp1_param_clear_bits(params,
+                                                       RKISP1_CIF_ISP_FILT_MODE,
+                                                       RKISP1_CIF_ISP_FLT_ENA);
+               }
+       }
+
+       if ((module_en_update & RKISP1_CIF_ISP_MODULE_CTK) ||
+           (module_cfg_update & RKISP1_CIF_ISP_MODULE_CTK)) {
+               /* update ctk config */
+               if (module_cfg_update & RKISP1_CIF_ISP_MODULE_CTK)
+                       rkisp1_ctk_config(params,
+                                         &new_params->others.ctk_config);
+
+               if (module_en_update & RKISP1_CIF_ISP_MODULE_CTK)
+                       rkisp1_ctk_enable(params,
+                                         !!(module_ens & RKISP1_CIF_ISP_MODULE_CTK));
+       }
+
+       if ((module_en_update & RKISP1_CIF_ISP_MODULE_GOC) ||
+           (module_cfg_update & RKISP1_CIF_ISP_MODULE_GOC)) {
+               /* update goc config */
+               if (module_cfg_update & RKISP1_CIF_ISP_MODULE_GOC)
+                       rkisp1_goc_config(params,
+                                         &new_params->others.goc_config);
+
+               if (module_en_update & RKISP1_CIF_ISP_MODULE_GOC) {
+                       if (module_ens & RKISP1_CIF_ISP_MODULE_GOC)
+                               rkisp1_param_set_bits(params,
+                                                     RKISP1_CIF_ISP_CTRL,
+                                                     RKISP1_CIF_ISP_CTRL_ISP_GAMMA_OUT_ENA);
+                       else
+                               rkisp1_param_clear_bits(params,
+                                                       RKISP1_CIF_ISP_CTRL,
+                                                       RKISP1_CIF_ISP_CTRL_ISP_GAMMA_OUT_ENA);
+               }
+       }
+
+       if ((module_en_update & RKISP1_CIF_ISP_MODULE_CPROC) ||
+           (module_cfg_update & RKISP1_CIF_ISP_MODULE_CPROC)) {
+               /* update cproc config */
+               if (module_cfg_update & RKISP1_CIF_ISP_MODULE_CPROC) {
+                       rkisp1_cproc_config(params,
+                                           &new_params->others.cproc_config);
+               }
+
+               if (module_en_update & RKISP1_CIF_ISP_MODULE_CPROC) {
+                       if (module_ens & RKISP1_CIF_ISP_MODULE_CPROC)
+                               rkisp1_param_set_bits(params,
+                                                     RKISP1_CIF_C_PROC_CTRL,
+                                                     RKISP1_CIF_C_PROC_CTR_ENABLE);
+                       else
+                               rkisp1_param_clear_bits(params,
+                                                       RKISP1_CIF_C_PROC_CTRL,
+                                                       RKISP1_CIF_C_PROC_CTR_ENABLE);
+               }
+       }
+
+       if ((module_en_update & RKISP1_CIF_ISP_MODULE_IE) ||
+           (module_cfg_update & RKISP1_CIF_ISP_MODULE_IE)) {
+               /* update ie config */
+               if (module_cfg_update & RKISP1_CIF_ISP_MODULE_IE)
+                       rkisp1_ie_config(params,
+                                        &new_params->others.ie_config);
+
+               if (module_en_update & RKISP1_CIF_ISP_MODULE_IE)
+                       rkisp1_ie_enable(params,
+                                        !!(module_ens & RKISP1_CIF_ISP_MODULE_IE));
+       }
+
+       if ((module_en_update & RKISP1_CIF_ISP_MODULE_DPF) ||
+           (module_cfg_update & RKISP1_CIF_ISP_MODULE_DPF)) {
+               /* update dpf  config */
+               if (module_cfg_update & RKISP1_CIF_ISP_MODULE_DPF)
+                       rkisp1_dpf_config(params,
+                                         &new_params->others.dpf_config);
+
+               if (module_en_update & RKISP1_CIF_ISP_MODULE_DPF) {
+                       if (module_ens & RKISP1_CIF_ISP_MODULE_DPF)
+                               rkisp1_param_set_bits(params,
+                                                     RKISP1_CIF_ISP_DPF_MODE,
+                                                     RKISP1_CIF_ISP_DPF_MODE_EN);
+                       else
+                               rkisp1_param_clear_bits(params,
+                                                       RKISP1_CIF_ISP_DPF_MODE,
+                                                       RKISP1_CIF_ISP_DPF_MODE_EN);
+               }
+       }
+
+       if ((module_en_update & RKISP1_CIF_ISP_MODULE_DPF_STRENGTH) ||
+           (module_cfg_update & RKISP1_CIF_ISP_MODULE_DPF_STRENGTH)) {
+               /* update dpf strength config */
+               rkisp1_dpf_strength_config(params,
+                                          &new_params->others.dpf_strength_config);
+       }
+}
+
+static void rkisp1_isp_isr_meas_config(struct rkisp1_params *params,
+                                      struct  rkisp1_params_cfg *new_params)
+{
+       unsigned int module_en_update, module_cfg_update, module_ens;
+
+       module_en_update = new_params->module_en_update;
+       module_cfg_update = new_params->module_cfg_update;
+       module_ens = new_params->module_ens;
+
+       if ((module_en_update & RKISP1_CIF_ISP_MODULE_AWB) ||
+           (module_cfg_update & RKISP1_CIF_ISP_MODULE_AWB)) {
+               /* update awb config */
+               if (module_cfg_update & RKISP1_CIF_ISP_MODULE_AWB)
+                       rkisp1_awb_meas_config(params,
+                                              &new_params->meas.awb_meas_config);
+
+               if (module_en_update & RKISP1_CIF_ISP_MODULE_AWB)
+                       rkisp1_awb_meas_enable(params,
+                                              &new_params->meas.awb_meas_config,
+                                              !!(module_ens & RKISP1_CIF_ISP_MODULE_AWB));
+       }
+
+       if ((module_en_update & RKISP1_CIF_ISP_MODULE_AFC) ||
+           (module_cfg_update & RKISP1_CIF_ISP_MODULE_AFC)) {
+               /* update afc config */
+               if (module_cfg_update & RKISP1_CIF_ISP_MODULE_AFC)
+                       rkisp1_afm_config(params,
+                                         &new_params->meas.afc_config);
+
+               if (module_en_update & RKISP1_CIF_ISP_MODULE_AFC) {
+                       if (module_ens & RKISP1_CIF_ISP_MODULE_AFC)
+                               rkisp1_param_set_bits(params,
+                                                     RKISP1_CIF_ISP_AFM_CTRL,
+                                                     RKISP1_CIF_ISP_AFM_ENA);
+                       else
+                               rkisp1_param_clear_bits(params,
+                                                       RKISP1_CIF_ISP_AFM_CTRL,
+                                                       RKISP1_CIF_ISP_AFM_ENA);
+               }
+       }
+
+       if ((module_en_update & RKISP1_CIF_ISP_MODULE_HST) ||
+           (module_cfg_update & RKISP1_CIF_ISP_MODULE_HST)) {
+               /* update hst config */
+               if (module_cfg_update & RKISP1_CIF_ISP_MODULE_HST)
+                       rkisp1_hst_config(params,
+                                         &new_params->meas.hst_config);
+
+               if (module_en_update & RKISP1_CIF_ISP_MODULE_HST)
+                       rkisp1_hst_enable(params,
+                                         &new_params->meas.hst_config,
+                                         !!(module_ens & RKISP1_CIF_ISP_MODULE_HST));
+       }
+
+       if ((module_en_update & RKISP1_CIF_ISP_MODULE_AEC) ||
+           (module_cfg_update & RKISP1_CIF_ISP_MODULE_AEC)) {
+               /* update aec config */
+               if (module_cfg_update & RKISP1_CIF_ISP_MODULE_AEC)
+                       rkisp1_aec_config(params,
+                                         &new_params->meas.aec_config);
+
+               if (module_en_update & RKISP1_CIF_ISP_MODULE_AEC) {
+                       if (module_ens & RKISP1_CIF_ISP_MODULE_AEC)
+                               rkisp1_param_set_bits(params,
+                                                     RKISP1_CIF_ISP_EXP_CTRL,
+                                                     RKISP1_CIF_ISP_EXP_ENA);
+                       else
+                               rkisp1_param_clear_bits(params,
+                                                       RKISP1_CIF_ISP_EXP_CTRL,
+                                                       RKISP1_CIF_ISP_EXP_ENA);
+               }
+       }
+}
+
+static void rkisp1_params_apply_params_cfg(struct rkisp1_params *params,
+                                          unsigned int frame_sequence)
+{
+       struct rkisp1_params_cfg *new_params;
+       struct rkisp1_buffer *cur_buf = NULL;
+
+       if (list_empty(&params->params))
+               return;
+
+       cur_buf = list_first_entry(&params->params,
+                                  struct rkisp1_buffer, queue);
+
+       new_params = (struct rkisp1_params_cfg *)(cur_buf->vaddr);
+
+       rkisp1_isp_isr_other_config(params, new_params);
+       rkisp1_isp_isr_meas_config(params, new_params);
+
+       /* update shadow register immediately */
+       rkisp1_param_set_bits(params, RKISP1_CIF_ISP_CTRL, RKISP1_CIF_ISP_CTRL_ISP_CFG_UPD);
+
+       list_del(&cur_buf->queue);
+
+       cur_buf->vb.sequence = frame_sequence;
+       vb2_buffer_done(&cur_buf->vb.vb2_buf, VB2_BUF_STATE_DONE);
+}
+
+void rkisp1_params_isr(struct rkisp1_device *rkisp1)
+{
+       /*
+        * This isr is called when the ISR finishes processing a frame (RKISP1_CIF_ISP_FRAME).
+        * Configurations performed here will be applied on the next frame.
+        * Since frame_sequence is updated on the vertical sync signal, we should use
+        * frame_sequence + 1 here to indicate to userspace on which frame these parameters
+        * are being applied.
+        */
+       unsigned int frame_sequence = rkisp1->isp.frame_sequence + 1;
+       struct rkisp1_params *params = &rkisp1->params;
+
+       spin_lock(&params->config_lock);
+       rkisp1_params_apply_params_cfg(params, frame_sequence);
+
+       spin_unlock(&params->config_lock);
+}
+
+static const struct rkisp1_cif_isp_awb_meas_config rkisp1_awb_params_default_config = {
+       {
+               0, 0, RKISP1_DEFAULT_WIDTH, RKISP1_DEFAULT_HEIGHT
+       },
+       RKISP1_CIF_ISP_AWB_MODE_YCBCR, 200, 30, 20, 20, 0, 128, 128
+};
+
+static const struct rkisp1_cif_isp_aec_config rkisp1_aec_params_default_config = {
+       RKISP1_CIF_ISP_EXP_MEASURING_MODE_0,
+       RKISP1_CIF_ISP_EXP_CTRL_AUTOSTOP_0,
+       {
+               RKISP1_DEFAULT_WIDTH >> 2, RKISP1_DEFAULT_HEIGHT >> 2,
+               RKISP1_DEFAULT_WIDTH >> 1, RKISP1_DEFAULT_HEIGHT >> 1
+       }
+};
+
+static const struct rkisp1_cif_isp_hst_config rkisp1_hst_params_default_config = {
+       RKISP1_CIF_ISP_HISTOGRAM_MODE_RGB_COMBINED,
+       3,
+       {
+               RKISP1_DEFAULT_WIDTH >> 2, RKISP1_DEFAULT_HEIGHT >> 2,
+               RKISP1_DEFAULT_WIDTH >> 1, RKISP1_DEFAULT_HEIGHT >> 1
+       },
+       {
+               0, /* To be filled in with 0x01 at runtime. */
+       }
+};
+
+static const struct rkisp1_cif_isp_afc_config rkisp1_afc_params_default_config = {
+       1,
+       {
+               {
+                       300, 225, 200, 150
+               }
+       },
+       4,
+       14
+};
+
+static void rkisp1_params_config_parameter(struct rkisp1_params *params)
+{
+       struct rkisp1_cif_isp_hst_config hst = rkisp1_hst_params_default_config;
+
+       rkisp1_awb_meas_config(params, &rkisp1_awb_params_default_config);
+       rkisp1_awb_meas_enable(params, &rkisp1_awb_params_default_config,
+                              true);
+
+       rkisp1_aec_config(params, &rkisp1_aec_params_default_config);
+       rkisp1_param_set_bits(params, RKISP1_CIF_ISP_EXP_CTRL,
+                             RKISP1_CIF_ISP_EXP_ENA);
+
+       rkisp1_afm_config(params, &rkisp1_afc_params_default_config);
+       rkisp1_param_set_bits(params, RKISP1_CIF_ISP_AFM_CTRL,
+                             RKISP1_CIF_ISP_AFM_ENA);
+
+       memset(hst.hist_weight, 0x01, sizeof(hst.hist_weight));
+       rkisp1_hst_config(params, &hst);
+       rkisp1_param_set_bits(params, RKISP1_CIF_ISP_HIST_PROP,
+                             ~RKISP1_CIF_ISP_HIST_PROP_MODE_MASK |
+                             rkisp1_hst_params_default_config.mode);
+
+       /* set the  range */
+       if (params->quantization == V4L2_QUANTIZATION_FULL_RANGE)
+               rkisp1_csm_config(params, true);
+       else
+               rkisp1_csm_config(params, false);
+
+       spin_lock_irq(&params->config_lock);
+
+       /* apply the first buffer if there is one already */
+       rkisp1_params_apply_params_cfg(params, 0);
+
+       spin_unlock_irq(&params->config_lock);
+}
+
+void rkisp1_params_configure(struct rkisp1_params *params,
+                            enum rkisp1_fmt_raw_pat_type bayer_pat,
+                            enum v4l2_quantization quantization)
+{
+       params->quantization = quantization;
+       params->raw_type = bayer_pat;
+       rkisp1_params_config_parameter(params);
+}
+
+/* Not called when the camera active, thus not isr protection. */
+void rkisp1_params_disable(struct rkisp1_params *params)
+{
+       rkisp1_param_clear_bits(params, RKISP1_CIF_ISP_DPCC_MODE,
+                               RKISP1_CIF_ISP_DPCC_ENA);
+       rkisp1_param_clear_bits(params, RKISP1_CIF_ISP_LSC_CTRL,
+                               RKISP1_CIF_ISP_LSC_CTRL_ENA);
+       rkisp1_param_clear_bits(params, RKISP1_CIF_ISP_BLS_CTRL,
+                               RKISP1_CIF_ISP_BLS_ENA);
+       rkisp1_param_clear_bits(params, RKISP1_CIF_ISP_CTRL,
+                               RKISP1_CIF_ISP_CTRL_ISP_GAMMA_IN_ENA);
+       rkisp1_param_clear_bits(params, RKISP1_CIF_ISP_CTRL,
+                               RKISP1_CIF_ISP_CTRL_ISP_GAMMA_OUT_ENA);
+       rkisp1_param_clear_bits(params, RKISP1_CIF_ISP_DEMOSAIC,
+                               RKISP1_CIF_ISP_DEMOSAIC_BYPASS);
+       rkisp1_param_clear_bits(params, RKISP1_CIF_ISP_FILT_MODE,
+                               RKISP1_CIF_ISP_FLT_ENA);
+       rkisp1_awb_meas_enable(params, NULL, false);
+       rkisp1_param_clear_bits(params, RKISP1_CIF_ISP_CTRL,
+                               RKISP1_CIF_ISP_CTRL_ISP_AWB_ENA);
+       rkisp1_param_clear_bits(params, RKISP1_CIF_ISP_EXP_CTRL,
+                               RKISP1_CIF_ISP_EXP_ENA);
+       rkisp1_ctk_enable(params, false);
+       rkisp1_param_clear_bits(params, RKISP1_CIF_C_PROC_CTRL,
+                               RKISP1_CIF_C_PROC_CTR_ENABLE);
+       rkisp1_hst_enable(params, NULL, false);
+       rkisp1_param_clear_bits(params, RKISP1_CIF_ISP_AFM_CTRL,
+                               RKISP1_CIF_ISP_AFM_ENA);
+       rkisp1_ie_enable(params, false);
+       rkisp1_param_clear_bits(params, RKISP1_CIF_ISP_DPF_MODE,
+                               RKISP1_CIF_ISP_DPF_MODE_EN);
+}
+
+static int rkisp1_params_enum_fmt_meta_out(struct file *file, void *priv,
+                                          struct v4l2_fmtdesc *f)
+{
+       struct video_device *video = video_devdata(file);
+       struct rkisp1_params *params = video_get_drvdata(video);
+
+       if (f->index > 0 || f->type != video->queue->type)
+               return -EINVAL;
+
+       f->pixelformat = params->vdev_fmt.fmt.meta.dataformat;
+
+       return 0;
+}
+
+static int rkisp1_params_g_fmt_meta_out(struct file *file, void *fh,
+                                       struct v4l2_format *f)
+{
+       struct video_device *video = video_devdata(file);
+       struct rkisp1_params *params = video_get_drvdata(video);
+       struct v4l2_meta_format *meta = &f->fmt.meta;
+
+       if (f->type != video->queue->type)
+               return -EINVAL;
+
+       memset(meta, 0, sizeof(*meta));
+       meta->dataformat = params->vdev_fmt.fmt.meta.dataformat;
+       meta->buffersize = params->vdev_fmt.fmt.meta.buffersize;
+
+       return 0;
+}
+
+static int rkisp1_params_querycap(struct file *file,
+                                 void *priv, struct v4l2_capability *cap)
+{
+       struct video_device *vdev = video_devdata(file);
+
+       strscpy(cap->driver, RKISP1_DRIVER_NAME, sizeof(cap->driver));
+       strscpy(cap->card, vdev->name, sizeof(cap->card));
+       strscpy(cap->bus_info, RKISP1_BUS_INFO, sizeof(cap->bus_info));
+
+       return 0;
+}
+
+/* ISP params video device IOCTLs */
+static const struct v4l2_ioctl_ops rkisp1_params_ioctl = {
+       .vidioc_reqbufs = vb2_ioctl_reqbufs,
+       .vidioc_querybuf = vb2_ioctl_querybuf,
+       .vidioc_create_bufs = vb2_ioctl_create_bufs,
+       .vidioc_qbuf = vb2_ioctl_qbuf,
+       .vidioc_dqbuf = vb2_ioctl_dqbuf,
+       .vidioc_prepare_buf = vb2_ioctl_prepare_buf,
+       .vidioc_expbuf = vb2_ioctl_expbuf,
+       .vidioc_streamon = vb2_ioctl_streamon,
+       .vidioc_streamoff = vb2_ioctl_streamoff,
+       .vidioc_enum_fmt_meta_out = rkisp1_params_enum_fmt_meta_out,
+       .vidioc_g_fmt_meta_out = rkisp1_params_g_fmt_meta_out,
+       .vidioc_s_fmt_meta_out = rkisp1_params_g_fmt_meta_out,
+       .vidioc_try_fmt_meta_out = rkisp1_params_g_fmt_meta_out,
+       .vidioc_querycap = rkisp1_params_querycap,
+       .vidioc_subscribe_event = v4l2_ctrl_subscribe_event,
+       .vidioc_unsubscribe_event = v4l2_event_unsubscribe,
+};
+
+static int rkisp1_params_vb2_queue_setup(struct vb2_queue *vq,
+                                        unsigned int *num_buffers,
+                                        unsigned int *num_planes,
+                                        unsigned int sizes[],
+                                        struct device *alloc_devs[])
+{
+       *num_buffers = clamp_t(u32, *num_buffers,
+                              RKISP1_ISP_PARAMS_REQ_BUFS_MIN,
+                              RKISP1_ISP_PARAMS_REQ_BUFS_MAX);
+
+       *num_planes = 1;
+
+       sizes[0] = sizeof(struct rkisp1_params_cfg);
+
+       return 0;
+}
+
+static void rkisp1_params_vb2_buf_queue(struct vb2_buffer *vb)
+{
+       struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
+       struct rkisp1_buffer *params_buf =
+               container_of(vbuf, struct rkisp1_buffer, vb);
+       struct vb2_queue *vq = vb->vb2_queue;
+       struct rkisp1_params *params = vq->drv_priv;
+
+       params_buf->vaddr = vb2_plane_vaddr(vb, 0);
+       spin_lock_irq(&params->config_lock);
+       list_add_tail(&params_buf->queue, &params->params);
+       spin_unlock_irq(&params->config_lock);
+}
+
+static int rkisp1_params_vb2_buf_prepare(struct vb2_buffer *vb)
+{
+       if (vb2_plane_size(vb, 0) < sizeof(struct rkisp1_params_cfg))
+               return -EINVAL;
+
+       vb2_set_plane_payload(vb, 0, sizeof(struct rkisp1_params_cfg));
+
+       return 0;
+}
+
+static void rkisp1_params_vb2_stop_streaming(struct vb2_queue *vq)
+{
+       struct rkisp1_params *params = vq->drv_priv;
+       struct rkisp1_buffer *buf;
+       LIST_HEAD(tmp_list);
+
+       /*
+        * we first move the buffers into a local list 'tmp_list'
+        * and then we can iterate it and call vb2_buffer_done
+        * without holding the lock
+        */
+       spin_lock_irq(&params->config_lock);
+       list_splice_init(&params->params, &tmp_list);
+       spin_unlock_irq(&params->config_lock);
+
+       list_for_each_entry(buf, &tmp_list, queue)
+               vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_ERROR);
+}
+
+static struct vb2_ops rkisp1_params_vb2_ops = {
+       .queue_setup = rkisp1_params_vb2_queue_setup,
+       .wait_prepare = vb2_ops_wait_prepare,
+       .wait_finish = vb2_ops_wait_finish,
+       .buf_queue = rkisp1_params_vb2_buf_queue,
+       .buf_prepare = rkisp1_params_vb2_buf_prepare,
+       .stop_streaming = rkisp1_params_vb2_stop_streaming,
+
+};
+
+static struct v4l2_file_operations rkisp1_params_fops = {
+       .mmap = vb2_fop_mmap,
+       .unlocked_ioctl = video_ioctl2,
+       .poll = vb2_fop_poll,
+       .open = v4l2_fh_open,
+       .release = vb2_fop_release
+};
+
+static int rkisp1_params_init_vb2_queue(struct vb2_queue *q,
+                                       struct rkisp1_params *params)
+{
+       struct rkisp1_vdev_node *node;
+
+       node = container_of(q, struct rkisp1_vdev_node, buf_queue);
+
+       q->type = V4L2_BUF_TYPE_META_OUTPUT;
+       q->io_modes = VB2_MMAP | VB2_USERPTR | VB2_DMABUF;
+       q->drv_priv = params;
+       q->ops = &rkisp1_params_vb2_ops;
+       q->mem_ops = &vb2_vmalloc_memops;
+       q->buf_struct_size = sizeof(struct rkisp1_buffer);
+       q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
+       q->lock = &node->vlock;
+
+       return vb2_queue_init(q);
+}
+
+static void rkisp1_init_params(struct rkisp1_params *params)
+{
+       params->vdev_fmt.fmt.meta.dataformat =
+               V4L2_META_FMT_RK_ISP1_PARAMS;
+       params->vdev_fmt.fmt.meta.buffersize =
+               sizeof(struct rkisp1_params_cfg);
+}
+
+int rkisp1_params_register(struct rkisp1_device *rkisp1)
+{
+       struct rkisp1_params *params = &rkisp1->params;
+       struct rkisp1_vdev_node *node = &params->vnode;
+       struct video_device *vdev = &node->vdev;
+       int ret;
+
+       params->rkisp1 = rkisp1;
+       mutex_init(&node->vlock);
+       INIT_LIST_HEAD(&params->params);
+       spin_lock_init(&params->config_lock);
+
+       strscpy(vdev->name, RKISP1_PARAMS_DEV_NAME, sizeof(vdev->name));
+
+       video_set_drvdata(vdev, params);
+       vdev->ioctl_ops = &rkisp1_params_ioctl;
+       vdev->fops = &rkisp1_params_fops;
+       vdev->release = video_device_release_empty;
+       /*
+        * Provide a mutex to v4l2 core. It will be used
+        * to protect all fops and v4l2 ioctls.
+        */
+       vdev->lock = &node->vlock;
+       vdev->v4l2_dev = &rkisp1->v4l2_dev;
+       vdev->queue = &node->buf_queue;
+       vdev->device_caps = V4L2_CAP_STREAMING | V4L2_CAP_META_OUTPUT;
+       vdev->vfl_dir = VFL_DIR_TX;
+       rkisp1_params_init_vb2_queue(vdev->queue, params);
+       rkisp1_init_params(params);
+       video_set_drvdata(vdev, params);
+
+       node->pad.flags = MEDIA_PAD_FL_SOURCE;
+       ret = media_entity_pads_init(&vdev->entity, 1, &node->pad);
+       if (ret)
+               return ret;
+       ret = video_register_device(vdev, VFL_TYPE_VIDEO, -1);
+       if (ret) {
+               dev_err(rkisp1->dev,
+                       "failed to register %s, ret=%d\n", vdev->name, ret);
+               goto err_cleanup_media_entity;
+       }
+       return 0;
+err_cleanup_media_entity:
+       media_entity_cleanup(&vdev->entity);
+       return ret;
+}
+
+void rkisp1_params_unregister(struct rkisp1_device *rkisp1)
+{
+       struct rkisp1_params *params = &rkisp1->params;
+       struct rkisp1_vdev_node *node = &params->vnode;
+       struct video_device *vdev = &node->vdev;
+
+       vb2_video_unregister_device(vdev);
+       media_entity_cleanup(&vdev->entity);
+}
diff --git a/drivers/media/platform/rockchip/rkisp1/rkisp1-regs.h b/drivers/media/platform/rockchip/rkisp1/rkisp1-regs.h
new file mode 100644 (file)
index 0000000..049f6c3
--- /dev/null
@@ -0,0 +1,1262 @@
+/* SPDX-License-Identifier: (GPL-2.0+ OR MIT) */
+/*
+ * Rockchip ISP1 Driver - Registers header
+ *
+ * Copyright (C) 2017 Rockchip Electronics Co., Ltd.
+ */
+
+#ifndef _RKISP1_REGS_H
+#define _RKISP1_REGS_H
+
+/* ISP_CTRL */
+#define RKISP1_CIF_ISP_CTRL_ISP_ENABLE                 BIT(0)
+#define RKISP1_CIF_ISP_CTRL_ISP_MODE_RAW_PICT          (0 << 1)
+#define RKISP1_CIF_ISP_CTRL_ISP_MODE_ITU656            BIT(1)
+#define RKISP1_CIF_ISP_CTRL_ISP_MODE_ITU601            (2 << 1)
+#define RKISP1_CIF_ISP_CTRL_ISP_MODE_BAYER_ITU601      (3 << 1)
+#define RKISP1_CIF_ISP_CTRL_ISP_MODE_DATA_MODE         (4 << 1)
+#define RKISP1_CIF_ISP_CTRL_ISP_MODE_BAYER_ITU656      (5 << 1)
+#define RKISP1_CIF_ISP_CTRL_ISP_MODE_RAW_PICT_ITU656   (6 << 1)
+#define RKISP1_CIF_ISP_CTRL_ISP_INFORM_ENABLE          BIT(4)
+#define RKISP1_CIF_ISP_CTRL_ISP_GAMMA_IN_ENA           BIT(6)
+#define RKISP1_CIF_ISP_CTRL_ISP_AWB_ENA                        BIT(7)
+#define RKISP1_CIF_ISP_CTRL_ISP_CFG_UPD_PERMANENT      BIT(8)
+#define RKISP1_CIF_ISP_CTRL_ISP_CFG_UPD                        BIT(9)
+#define RKISP1_CIF_ISP_CTRL_ISP_GEN_CFG_UPD            BIT(10)
+#define RKISP1_CIF_ISP_CTRL_ISP_GAMMA_OUT_ENA          BIT(11)
+#define RKISP1_CIF_ISP_CTRL_ISP_FLASH_MODE_ENA         BIT(12)
+#define RKISP1_CIF_ISP_CTRL_ISP_CSM_Y_FULL_ENA         BIT(13)
+#define RKISP1_CIF_ISP_CTRL_ISP_CSM_C_FULL_ENA         BIT(14)
+
+/* ISP_ACQ_PROP */
+#define RKISP1_CIF_ISP_ACQ_PROP_POS_EDGE               BIT(0)
+#define RKISP1_CIF_ISP_ACQ_PROP_HSYNC_LOW              BIT(1)
+#define RKISP1_CIF_ISP_ACQ_PROP_VSYNC_LOW              BIT(2)
+#define RKISP1_CIF_ISP_ACQ_PROP_BAYER_PAT_RGGB         (0 << 3)
+#define RKISP1_CIF_ISP_ACQ_PROP_BAYER_PAT_GRBG         BIT(3)
+#define RKISP1_CIF_ISP_ACQ_PROP_BAYER_PAT_GBRG         (2 << 3)
+#define RKISP1_CIF_ISP_ACQ_PROP_BAYER_PAT_BGGR         (3 << 3)
+#define RKISP1_CIF_ISP_ACQ_PROP_BAYER_PAT(pat)         ((pat) << 3)
+#define RKISP1_CIF_ISP_ACQ_PROP_YCBYCR                 (0 << 7)
+#define RKISP1_CIF_ISP_ACQ_PROP_YCRYCB                 BIT(7)
+#define RKISP1_CIF_ISP_ACQ_PROP_CBYCRY                 (2 << 7)
+#define RKISP1_CIF_ISP_ACQ_PROP_CRYCBY                 (3 << 7)
+#define RKISP1_CIF_ISP_ACQ_PROP_FIELD_SEL_ALL          (0 << 9)
+#define RKISP1_CIF_ISP_ACQ_PROP_FIELD_SEL_EVEN         BIT(9)
+#define RKISP1_CIF_ISP_ACQ_PROP_FIELD_SEL_ODD          (2 << 9)
+#define RKISP1_CIF_ISP_ACQ_PROP_IN_SEL_12B             (0 << 12)
+#define RKISP1_CIF_ISP_ACQ_PROP_IN_SEL_10B_ZERO                BIT(12)
+#define RKISP1_CIF_ISP_ACQ_PROP_IN_SEL_10B_MSB         (2 << 12)
+#define RKISP1_CIF_ISP_ACQ_PROP_IN_SEL_8B_ZERO         (3 << 12)
+#define RKISP1_CIF_ISP_ACQ_PROP_IN_SEL_8B_MSB          (4 << 12)
+
+/* VI_DPCL */
+#define RKISP1_CIF_VI_DPCL_DMA_JPEG                    (0 << 0)
+#define RKISP1_CIF_VI_DPCL_MP_MUX_MRSZ_MI              BIT(0)
+#define RKISP1_CIF_VI_DPCL_MP_MUX_MRSZ_JPEG            (2 << 0)
+#define RKISP1_CIF_VI_DPCL_CHAN_MODE_MP                        BIT(2)
+#define RKISP1_CIF_VI_DPCL_CHAN_MODE_SP                        (2 << 2)
+#define RKISP1_CIF_VI_DPCL_CHAN_MODE_MPSP              (3 << 2)
+#define RKISP1_CIF_VI_DPCL_DMA_SW_SPMUX                        (0 << 4)
+#define RKISP1_CIF_VI_DPCL_DMA_SW_SI                   BIT(4)
+#define RKISP1_CIF_VI_DPCL_DMA_SW_IE                   (2 << 4)
+#define RKISP1_CIF_VI_DPCL_DMA_SW_JPEG                 (3 << 4)
+#define RKISP1_CIF_VI_DPCL_DMA_SW_ISP                  (4 << 4)
+#define RKISP1_CIF_VI_DPCL_IF_SEL_PARALLEL             (0 << 8)
+#define RKISP1_CIF_VI_DPCL_IF_SEL_SMIA                 BIT(8)
+#define RKISP1_CIF_VI_DPCL_IF_SEL_MIPI                 (2 << 8)
+#define RKISP1_CIF_VI_DPCL_DMA_IE_MUX_DMA              BIT(10)
+#define RKISP1_CIF_VI_DPCL_DMA_SP_MUX_DMA              BIT(11)
+
+/* ISP_IMSC - ISP_MIS - ISP_RIS - ISP_ICR - ISP_ISR */
+#define RKISP1_CIF_ISP_OFF                             BIT(0)
+#define RKISP1_CIF_ISP_FRAME                           BIT(1)
+#define RKISP1_CIF_ISP_DATA_LOSS                       BIT(2)
+#define RKISP1_CIF_ISP_PIC_SIZE_ERROR                  BIT(3)
+#define RKISP1_CIF_ISP_AWB_DONE                                BIT(4)
+#define RKISP1_CIF_ISP_FRAME_IN                                BIT(5)
+#define RKISP1_CIF_ISP_V_START                         BIT(6)
+#define RKISP1_CIF_ISP_H_START                         BIT(7)
+#define RKISP1_CIF_ISP_FLASH_ON                                BIT(8)
+#define RKISP1_CIF_ISP_FLASH_OFF                       BIT(9)
+#define RKISP1_CIF_ISP_SHUTTER_ON                      BIT(10)
+#define RKISP1_CIF_ISP_SHUTTER_OFF                     BIT(11)
+#define RKISP1_CIF_ISP_AFM_SUM_OF                      BIT(12)
+#define RKISP1_CIF_ISP_AFM_LUM_OF                      BIT(13)
+#define RKISP1_CIF_ISP_AFM_FIN                         BIT(14)
+#define RKISP1_CIF_ISP_HIST_MEASURE_RDY                        BIT(15)
+#define RKISP1_CIF_ISP_FLASH_CAP                       BIT(17)
+#define RKISP1_CIF_ISP_EXP_END                         BIT(18)
+#define RKISP1_CIF_ISP_VSM_END                         BIT(19)
+
+/* ISP_ERR */
+#define RKISP1_CIF_ISP_ERR_INFORM_SIZE                 BIT(0)
+#define RKISP1_CIF_ISP_ERR_IS_SIZE                     BIT(1)
+#define RKISP1_CIF_ISP_ERR_OUTFORM_SIZE                        BIT(2)
+
+/* MI_CTRL */
+#define RKISP1_CIF_MI_CTRL_MP_ENABLE                   BIT(0)
+#define RKISP1_CIF_MI_CTRL_SP_ENABLE                   (2 << 0)
+#define RKISP1_CIF_MI_CTRL_JPEG_ENABLE                 (4 << 0)
+#define RKISP1_CIF_MI_CTRL_RAW_ENABLE                  (8 << 0)
+#define RKISP1_CIF_MI_CTRL_HFLIP                       BIT(4)
+#define RKISP1_CIF_MI_CTRL_VFLIP                       BIT(5)
+#define RKISP1_CIF_MI_CTRL_ROT                         BIT(6)
+#define RKISP1_CIF_MI_BYTE_SWAP                                BIT(7)
+#define RKISP1_CIF_MI_SP_Y_FULL_YUV2RGB                        BIT(8)
+#define RKISP1_CIF_MI_SP_CBCR_FULL_YUV2RGB             BIT(9)
+#define RKISP1_CIF_MI_SP_422NONCOSITEED                        BIT(10)
+#define RKISP1_CIF_MI_MP_PINGPONG_ENABEL               BIT(11)
+#define RKISP1_CIF_MI_SP_PINGPONG_ENABEL               BIT(12)
+#define RKISP1_CIF_MI_MP_AUTOUPDATE_ENABLE             BIT(13)
+#define RKISP1_CIF_MI_SP_AUTOUPDATE_ENABLE             BIT(14)
+#define RKISP1_CIF_MI_LAST_PIXEL_SIG_ENABLE            BIT(15)
+#define RKISP1_CIF_MI_CTRL_BURST_LEN_LUM_16            (0 << 16)
+#define RKISP1_CIF_MI_CTRL_BURST_LEN_LUM_32            BIT(16)
+#define RKISP1_CIF_MI_CTRL_BURST_LEN_LUM_64            (2 << 16)
+#define RKISP1_CIF_MI_CTRL_BURST_LEN_CHROM_16          (0 << 18)
+#define RKISP1_CIF_MI_CTRL_BURST_LEN_CHROM_32          BIT(18)
+#define RKISP1_CIF_MI_CTRL_BURST_LEN_CHROM_64          (2 << 18)
+#define RKISP1_CIF_MI_CTRL_INIT_BASE_EN                        BIT(20)
+#define RKISP1_CIF_MI_CTRL_INIT_OFFSET_EN              BIT(21)
+#define RKISP1_MI_CTRL_MP_WRITE_YUV_PLA_OR_RAW8                (0 << 22)
+#define RKISP1_MI_CTRL_MP_WRITE_YUV_SPLA               BIT(22)
+#define RKISP1_MI_CTRL_MP_WRITE_YUVINT                 (2 << 22)
+#define RKISP1_MI_CTRL_MP_WRITE_RAW12                  (2 << 22)
+#define RKISP1_MI_CTRL_SP_WRITE_PLA                    (0 << 24)
+#define RKISP1_MI_CTRL_SP_WRITE_SPLA                   BIT(24)
+#define RKISP1_MI_CTRL_SP_WRITE_INT                    (2 << 24)
+#define RKISP1_MI_CTRL_SP_INPUT_YUV400                 (0 << 26)
+#define RKISP1_MI_CTRL_SP_INPUT_YUV420                 BIT(26)
+#define RKISP1_MI_CTRL_SP_INPUT_YUV422                 (2 << 26)
+#define RKISP1_MI_CTRL_SP_INPUT_YUV444                 (3 << 26)
+#define RKISP1_MI_CTRL_SP_OUTPUT_YUV400                        (0 << 28)
+#define RKISP1_MI_CTRL_SP_OUTPUT_YUV420                        BIT(28)
+#define RKISP1_MI_CTRL_SP_OUTPUT_YUV422                        (2 << 28)
+#define RKISP1_MI_CTRL_SP_OUTPUT_YUV444                        (3 << 28)
+#define RKISP1_MI_CTRL_SP_OUTPUT_RGB565                        (4 << 28)
+#define RKISP1_MI_CTRL_SP_OUTPUT_RGB666                        (5 << 28)
+#define RKISP1_MI_CTRL_SP_OUTPUT_RGB888                        (6 << 28)
+
+#define RKISP1_MI_CTRL_MP_FMT_MASK                     GENMASK(23, 22)
+#define RKISP1_MI_CTRL_SP_FMT_MASK                     GENMASK(30, 24)
+
+/* MI_INIT */
+#define RKISP1_CIF_MI_INIT_SKIP                                BIT(2)
+#define RKISP1_CIF_MI_INIT_SOFT_UPD                    BIT(4)
+
+/* MI_CTRL_SHD */
+#define RKISP1_CIF_MI_CTRL_SHD_MP_IN_ENABLED           BIT(0)
+#define RKISP1_CIF_MI_CTRL_SHD_SP_IN_ENABLED           BIT(1)
+#define RKISP1_CIF_MI_CTRL_SHD_JPEG_IN_ENABLED         BIT(2)
+#define RKISP1_CIF_MI_CTRL_SHD_RAW_IN_ENABLED          BIT(3)
+#define RKISP1_CIF_MI_CTRL_SHD_MP_OUT_ENABLED          BIT(16)
+#define RKISP1_CIF_MI_CTRL_SHD_SP_OUT_ENABLED          BIT(17)
+#define RKISP1_CIF_MI_CTRL_SHD_JPEG_OUT_ENABLED                BIT(18)
+#define RKISP1_CIF_MI_CTRL_SHD_RAW_OUT_ENABLED         BIT(19)
+
+/* RSZ_CTRL */
+#define RKISP1_CIF_RSZ_CTRL_SCALE_HY_ENABLE            BIT(0)
+#define RKISP1_CIF_RSZ_CTRL_SCALE_HC_ENABLE            BIT(1)
+#define RKISP1_CIF_RSZ_CTRL_SCALE_VY_ENABLE            BIT(2)
+#define RKISP1_CIF_RSZ_CTRL_SCALE_VC_ENABLE            BIT(3)
+#define RKISP1_CIF_RSZ_CTRL_SCALE_HY_UP                        BIT(4)
+#define RKISP1_CIF_RSZ_CTRL_SCALE_HC_UP                        BIT(5)
+#define RKISP1_CIF_RSZ_CTRL_SCALE_VY_UP                        BIT(6)
+#define RKISP1_CIF_RSZ_CTRL_SCALE_VC_UP                        BIT(7)
+#define RKISP1_CIF_RSZ_CTRL_CFG_UPD                    BIT(8)
+#define RKISP1_CIF_RSZ_CTRL_CFG_UPD_AUTO               BIT(9)
+#define RKISP1_CIF_RSZ_SCALER_FACTOR                   BIT(16)
+
+/* MI_IMSC - MI_MIS - MI_RIS - MI_ICR - MI_ISR */
+#define RKISP1_CIF_MI_FRAME(stream)                    BIT((stream)->id)
+#define RKISP1_CIF_MI_MBLK_LINE                                BIT(2)
+#define RKISP1_CIF_MI_FILL_MP_Y                                BIT(3)
+#define RKISP1_CIF_MI_WRAP_MP_Y                                BIT(4)
+#define RKISP1_CIF_MI_WRAP_MP_CB                       BIT(5)
+#define RKISP1_CIF_MI_WRAP_MP_CR                       BIT(6)
+#define RKISP1_CIF_MI_WRAP_SP_Y                                BIT(7)
+#define RKISP1_CIF_MI_WRAP_SP_CB                       BIT(8)
+#define RKISP1_CIF_MI_WRAP_SP_CR                       BIT(9)
+#define RKISP1_CIF_MI_DMA_READY                                BIT(11)
+
+/* MI_STATUS */
+#define RKISP1_CIF_MI_STATUS_MP_Y_FIFO_FULL            BIT(0)
+#define RKISP1_CIF_MI_STATUS_SP_Y_FIFO_FULL            BIT(4)
+
+/* MI_DMA_CTRL */
+#define RKISP1_CIF_MI_DMA_CTRL_BURST_LEN_LUM_16                (0 << 0)
+#define RKISP1_CIF_MI_DMA_CTRL_BURST_LEN_LUM_32                BIT(0)
+#define RKISP1_CIF_MI_DMA_CTRL_BURST_LEN_LUM_64                (2 << 0)
+#define RKISP1_CIF_MI_DMA_CTRL_BURST_LEN_CHROM_16      (0 << 2)
+#define RKISP1_CIF_MI_DMA_CTRL_BURST_LEN_CHROM_32      BIT(2)
+#define RKISP1_CIF_MI_DMA_CTRL_BURST_LEN_CHROM_64      (2 << 2)
+#define RKISP1_CIF_MI_DMA_CTRL_READ_FMT_PLANAR         (0 << 4)
+#define RKISP1_CIF_MI_DMA_CTRL_READ_FMT_SPLANAR                BIT(4)
+#define RKISP1_CIF_MI_DMA_CTRL_FMT_YUV400              (0 << 6)
+#define RKISP1_CIF_MI_DMA_CTRL_FMT_YUV420              BIT(6)
+#define RKISP1_CIF_MI_DMA_CTRL_READ_FMT_PACKED         (2 << 4)
+#define RKISP1_CIF_MI_DMA_CTRL_FMT_YUV422              (2 << 6)
+#define RKISP1_CIF_MI_DMA_CTRL_FMT_YUV444              (3 << 6)
+#define RKISP1_CIF_MI_DMA_CTRL_BYTE_SWAP               BIT(8)
+#define RKISP1_CIF_MI_DMA_CTRL_CONTINUOUS_ENA          BIT(9)
+#define RKISP1_CIF_MI_DMA_CTRL_RGB_BAYER_NO            (0 << 12)
+#define RKISP1_CIF_MI_DMA_CTRL_RGB_BAYER_8BIT          BIT(12)
+#define RKISP1_CIF_MI_DMA_CTRL_RGB_BAYER_16BIT         (2 << 12)
+/* MI_DMA_START */
+#define RKISP1_CIF_MI_DMA_START_ENABLE                 BIT(0)
+/* MI_XTD_FORMAT_CTRL  */
+#define RKISP1_CIF_MI_XTD_FMT_CTRL_MP_CB_CR_SWAP       BIT(0)
+#define RKISP1_CIF_MI_XTD_FMT_CTRL_SP_CB_CR_SWAP       BIT(1)
+#define RKISP1_CIF_MI_XTD_FMT_CTRL_DMA_CB_CR_SWAP      BIT(2)
+
+/* CCL */
+#define RKISP1_CIF_CCL_CIF_CLK_DIS                     BIT(2)
+/* ICCL */
+#define RKISP1_CIF_ICCL_ISP_CLK                                BIT(0)
+#define RKISP1_CIF_ICCL_CP_CLK                         BIT(1)
+#define RKISP1_CIF_ICCL_RES_2                          BIT(2)
+#define RKISP1_CIF_ICCL_MRSZ_CLK                       BIT(3)
+#define RKISP1_CIF_ICCL_SRSZ_CLK                       BIT(4)
+#define RKISP1_CIF_ICCL_JPEG_CLK                       BIT(5)
+#define RKISP1_CIF_ICCL_MI_CLK                         BIT(6)
+#define RKISP1_CIF_ICCL_RES_7                          BIT(7)
+#define RKISP1_CIF_ICCL_IE_CLK                         BIT(8)
+#define RKISP1_CIF_ICCL_SIMP_CLK                       BIT(9)
+#define RKISP1_CIF_ICCL_SMIA_CLK                       BIT(10)
+#define RKISP1_CIF_ICCL_MIPI_CLK                       BIT(11)
+#define RKISP1_CIF_ICCL_DCROP_CLK                      BIT(12)
+/* IRCL */
+#define RKISP1_CIF_IRCL_ISP_SW_RST                     BIT(0)
+#define RKISP1_CIF_IRCL_CP_SW_RST                      BIT(1)
+#define RKISP1_CIF_IRCL_YCS_SW_RST                     BIT(2)
+#define RKISP1_CIF_IRCL_MRSZ_SW_RST                    BIT(3)
+#define RKISP1_CIF_IRCL_SRSZ_SW_RST                    BIT(4)
+#define RKISP1_CIF_IRCL_JPEG_SW_RST                    BIT(5)
+#define RKISP1_CIF_IRCL_MI_SW_RST                      BIT(6)
+#define RKISP1_CIF_IRCL_CIF_SW_RST                     BIT(7)
+#define RKISP1_CIF_IRCL_IE_SW_RST                      BIT(8)
+#define RKISP1_CIF_IRCL_SI_SW_RST                      BIT(9)
+#define RKISP1_CIF_IRCL_MIPI_SW_RST                    BIT(11)
+
+/* C_PROC_CTR */
+#define RKISP1_CIF_C_PROC_CTR_ENABLE                   BIT(0)
+#define RKISP1_CIF_C_PROC_YOUT_FULL                    BIT(1)
+#define RKISP1_CIF_C_PROC_YIN_FULL                     BIT(2)
+#define RKISP1_CIF_C_PROC_COUT_FULL                    BIT(3)
+#define RKISP1_CIF_C_PROC_CTRL_RESERVED                        0xFFFFFFFE
+#define RKISP1_CIF_C_PROC_CONTRAST_RESERVED            0xFFFFFF00
+#define RKISP1_CIF_C_PROC_BRIGHTNESS_RESERVED          0xFFFFFF00
+#define RKISP1_CIF_C_PROC_HUE_RESERVED                 0xFFFFFF00
+#define RKISP1_CIF_C_PROC_SATURATION_RESERVED          0xFFFFFF00
+#define RKISP1_CIF_C_PROC_MACC_RESERVED                        0xE000E000
+#define RKISP1_CIF_C_PROC_TONE_RESERVED                        0xF000
+/* DUAL_CROP_CTRL */
+#define RKISP1_CIF_DUAL_CROP_MP_MODE_BYPASS            (0 << 0)
+#define RKISP1_CIF_DUAL_CROP_MP_MODE_YUV               BIT(0)
+#define RKISP1_CIF_DUAL_CROP_MP_MODE_RAW               (2 << 0)
+#define RKISP1_CIF_DUAL_CROP_SP_MODE_BYPASS            (0 << 2)
+#define RKISP1_CIF_DUAL_CROP_SP_MODE_YUV               BIT(2)
+#define RKISP1_CIF_DUAL_CROP_SP_MODE_RAW               (2 << 2)
+#define RKISP1_CIF_DUAL_CROP_CFG_UPD_PERMANENT         BIT(4)
+#define RKISP1_CIF_DUAL_CROP_CFG_UPD                   BIT(5)
+#define RKISP1_CIF_DUAL_CROP_GEN_CFG_UPD               BIT(6)
+
+/* IMG_EFF_CTRL */
+#define RKISP1_CIF_IMG_EFF_CTRL_ENABLE                 BIT(0)
+#define RKISP1_CIF_IMG_EFF_CTRL_MODE_BLACKWHITE                (0 << 1)
+#define RKISP1_CIF_IMG_EFF_CTRL_MODE_NEGATIVE          BIT(1)
+#define RKISP1_CIF_IMG_EFF_CTRL_MODE_SEPIA             (2 << 1)
+#define RKISP1_CIF_IMG_EFF_CTRL_MODE_COLOR_SEL         (3 << 1)
+#define RKISP1_CIF_IMG_EFF_CTRL_MODE_EMBOSS            (4 << 1)
+#define RKISP1_CIF_IMG_EFF_CTRL_MODE_SKETCH            (5 << 1)
+#define RKISP1_CIF_IMG_EFF_CTRL_MODE_SHARPEN           (6 << 1)
+#define RKISP1_CIF_IMG_EFF_CTRL_CFG_UPD                        BIT(4)
+#define RKISP1_CIF_IMG_EFF_CTRL_YCBCR_FULL             BIT(5)
+
+#define RKISP1_CIF_IMG_EFF_CTRL_MODE_BLACKWHITE_SHIFT  0
+#define RKISP1_CIF_IMG_EFF_CTRL_MODE_NEGATIVE_SHIFT    1
+#define RKISP1_CIF_IMG_EFF_CTRL_MODE_SEPIA_SHIFT       2
+#define RKISP1_CIF_IMG_EFF_CTRL_MODE_COLOR_SEL_SHIFT   3
+#define RKISP1_CIF_IMG_EFF_CTRL_MODE_EMBOSS_SHIFT      4
+#define RKISP1_CIF_IMG_EFF_CTRL_MODE_SKETCH_SHIFT      5
+#define RKISP1_CIF_IMG_EFF_CTRL_MODE_SHARPEN_SHIFT     6
+#define RKISP1_CIF_IMG_EFF_CTRL_MODE_MASK              0xE
+
+/* IMG_EFF_COLOR_SEL */
+#define RKISP1_CIF_IMG_EFF_COLOR_RGB                   0
+#define RKISP1_CIF_IMG_EFF_COLOR_B                     BIT(0)
+#define RKISP1_CIF_IMG_EFF_COLOR_G                     (2 << 0)
+#define RKISP1_CIF_IMG_EFF_COLOR_GB                    (3 << 0)
+#define RKISP1_CIF_IMG_EFF_COLOR_R                     (4 << 0)
+#define RKISP1_CIF_IMG_EFF_COLOR_RB                    (5 << 0)
+#define RKISP1_CIF_IMG_EFF_COLOR_RG                    (6 << 0)
+#define RKISP1_CIF_IMG_EFF_COLOR_RGB2                  (7 << 0)
+
+/* MIPI_CTRL */
+#define RKISP1_CIF_MIPI_CTRL_OUTPUT_ENA                        BIT(0)
+#define RKISP1_CIF_MIPI_CTRL_SHUTDOWNLANES(a)          (((a) & 0xF) << 8)
+#define RKISP1_CIF_MIPI_CTRL_NUM_LANES(a)              (((a) & 0x3) << 12)
+#define RKISP1_CIF_MIPI_CTRL_ERR_SOT_HS_SKIP           BIT(16)
+#define RKISP1_CIF_MIPI_CTRL_ERR_SOT_SYNC_HS_SKIP      BIT(17)
+#define RKISP1_CIF_MIPI_CTRL_CLOCKLANE_ENA             BIT(18)
+
+/* MIPI_DATA_SEL */
+#define RKISP1_CIF_MIPI_DATA_SEL_VC(a)                 (((a) & 0x3) << 6)
+#define RKISP1_CIF_MIPI_DATA_SEL_DT(a)                 (((a) & 0x3F) << 0)
+/* MIPI DATA_TYPE */
+#define RKISP1_CIF_CSI2_DT_YUV420_8b                   0x18
+#define RKISP1_CIF_CSI2_DT_YUV420_10b                  0x19
+#define RKISP1_CIF_CSI2_DT_YUV422_8b                   0x1E
+#define RKISP1_CIF_CSI2_DT_YUV422_10b                  0x1F
+#define RKISP1_CIF_CSI2_DT_RGB565                      0x22
+#define RKISP1_CIF_CSI2_DT_RGB666                      0x23
+#define RKISP1_CIF_CSI2_DT_RGB888                      0x24
+#define RKISP1_CIF_CSI2_DT_RAW8                                0x2A
+#define RKISP1_CIF_CSI2_DT_RAW10                       0x2B
+#define RKISP1_CIF_CSI2_DT_RAW12                       0x2C
+
+/* MIPI_IMSC, MIPI_RIS, MIPI_MIS, MIPI_ICR, MIPI_ISR */
+#define RKISP1_CIF_MIPI_SYNC_FIFO_OVFLW(a)             (((a) & 0xF) << 0)
+#define RKISP1_CIF_MIPI_ERR_SOT(a)                     (((a) & 0xF) << 4)
+#define RKISP1_CIF_MIPI_ERR_SOT_SYNC(a)                        (((a) & 0xF) << 8)
+#define RKISP1_CIF_MIPI_ERR_EOT_SYNC(a)                        (((a) & 0xF) << 12)
+#define RKISP1_CIF_MIPI_ERR_CTRL(a)                    (((a) & 0xF) << 16)
+#define RKISP1_CIF_MIPI_ERR_PROTOCOL                   BIT(20)
+#define RKISP1_CIF_MIPI_ERR_ECC1                       BIT(21)
+#define RKISP1_CIF_MIPI_ERR_ECC2                       BIT(22)
+#define RKISP1_CIF_MIPI_ERR_CS                         BIT(23)
+#define RKISP1_CIF_MIPI_FRAME_END                      BIT(24)
+#define RKISP1_CIF_MIPI_ADD_DATA_OVFLW                 BIT(25)
+#define RKISP1_CIF_MIPI_ADD_DATA_WATER_MARK            BIT(26)
+
+#define RKISP1_CIF_MIPI_ERR_CSI  (RKISP1_CIF_MIPI_ERR_PROTOCOL | \
+       RKISP1_CIF_MIPI_ERR_ECC1 | \
+       RKISP1_CIF_MIPI_ERR_ECC2 | \
+       RKISP1_CIF_MIPI_ERR_CS)
+
+#define RKISP1_CIF_MIPI_ERR_DPHY  (RKISP1_CIF_MIPI_ERR_SOT(3) | \
+       RKISP1_CIF_MIPI_ERR_SOT_SYNC(3) | \
+       RKISP1_CIF_MIPI_ERR_EOT_SYNC(3) | \
+       RKISP1_CIF_MIPI_ERR_CTRL(3))
+
+/* SUPER_IMPOSE */
+#define RKISP1_CIF_SUPER_IMP_CTRL_NORMAL_MODE          BIT(0)
+#define RKISP1_CIF_SUPER_IMP_CTRL_REF_IMG_MEM          BIT(1)
+#define RKISP1_CIF_SUPER_IMP_CTRL_TRANSP_DIS           BIT(2)
+
+/* ISP HISTOGRAM CALCULATION : ISP_HIST_PROP */
+#define RKISP1_CIF_ISP_HIST_PROP_MODE_DIS              (0 << 0)
+#define RKISP1_CIF_ISP_HIST_PROP_MODE_RGB              BIT(0)
+#define RKISP1_CIF_ISP_HIST_PROP_MODE_RED              (2 << 0)
+#define RKISP1_CIF_ISP_HIST_PROP_MODE_GREEN            (3 << 0)
+#define RKISP1_CIF_ISP_HIST_PROP_MODE_BLUE             (4 << 0)
+#define RKISP1_CIF_ISP_HIST_PROP_MODE_LUM              (5 << 0)
+#define RKISP1_CIF_ISP_HIST_PROP_MODE_MASK             0x7
+#define RKISP1_CIF_ISP_HIST_PREDIV_SET(x)              (((x) & 0x7F) << 3)
+#define RKISP1_CIF_ISP_HIST_WEIGHT_SET(v0, v1, v2, v3) \
+                                    (((v0) & 0x1F) | (((v1) & 0x1F) << 8)  |\
+                                    (((v2) & 0x1F) << 16) | \
+                                    (((v3) & 0x1F) << 24))
+
+#define RKISP1_CIF_ISP_HIST_WINDOW_OFFSET_RESERVED     0xFFFFF000
+#define RKISP1_CIF_ISP_HIST_WINDOW_SIZE_RESERVED       0xFFFFF800
+#define RKISP1_CIF_ISP_HIST_WEIGHT_RESERVED            0xE0E0E0E0
+#define RKISP1_CIF_ISP_MAX_HIST_PREDIVIDER             0x0000007F
+#define RKISP1_CIF_ISP_HIST_ROW_NUM                    5
+#define RKISP1_CIF_ISP_HIST_COLUMN_NUM                 5
+
+/* AUTO FOCUS MEASUREMENT:  ISP_AFM_CTRL */
+#define RKISP1_ISP_AFM_CTRL_ENABLE                     BIT(0)
+
+/* SHUTTER CONTROL */
+#define RKISP1_CIF_ISP_SH_CTRL_SH_ENA                  BIT(0)
+#define RKISP1_CIF_ISP_SH_CTRL_REP_EN                  BIT(1)
+#define RKISP1_CIF_ISP_SH_CTRL_SRC_SH_TRIG             BIT(2)
+#define RKISP1_CIF_ISP_SH_CTRL_EDGE_POS                        BIT(3)
+#define RKISP1_CIF_ISP_SH_CTRL_POL_LOW                 BIT(4)
+
+/* FLASH MODULE */
+/* ISP_FLASH_CMD */
+#define RKISP1_CIFFLASH_CMD_PRELIGHT_ON                        BIT(0)
+#define RKISP1_CIFFLASH_CMD_FLASH_ON                   BIT(1)
+#define RKISP1_CIFFLASH_CMD_PRE_FLASH_ON               BIT(2)
+/* ISP_FLASH_CONFIG */
+#define RKISP1_CIFFLASH_CONFIG_PRELIGHT_END            BIT(0)
+#define RKISP1_CIFFLASH_CONFIG_VSYNC_POS               BIT(1)
+#define RKISP1_CIFFLASH_CONFIG_PRELIGHT_LOW            BIT(2)
+#define RKISP1_CIFFLASH_CONFIG_SRC_FL_TRIG             BIT(3)
+#define RKISP1_CIFFLASH_CONFIG_DELAY(a)                        (((a) & 0xF) << 4)
+
+/* Demosaic:  ISP_DEMOSAIC */
+#define RKISP1_CIF_ISP_DEMOSAIC_BYPASS                 BIT(10)
+#define RKISP1_CIF_ISP_DEMOSAIC_TH(x)                  ((x) & 0xFF)
+
+/* AWB */
+/* ISP_AWB_PROP */
+#define RKISP1_CIF_ISP_AWB_YMAX_CMP_EN                 BIT(2)
+#define RKISP1_CIF_ISP_AWB_YMAX_READ(x)                        (((x) >> 2) & 1)
+#define RKISP1_CIF_ISP_AWB_MODE_RGB_EN                 ((1 << 31) | (0x2 << 0))
+#define RKISP1_CIF_ISP_AWB_MODE_YCBCR_EN               ((0 << 31) | (0x2 << 0))
+#define RKISP1_CIF_ISP_AWB_MODE_MASK_NONE              0xFFFFFFFC
+#define RKISP1_CIF_ISP_AWB_MODE_READ(x)                        ((x) & 3)
+/* ISP_AWB_GAIN_RB, ISP_AWB_GAIN_G  */
+#define RKISP1_CIF_ISP_AWB_GAIN_R_SET(x)               (((x) & 0x3FF) << 16)
+#define RKISP1_CIF_ISP_AWB_GAIN_R_READ(x)              (((x) >> 16) & 0x3FF)
+#define RKISP1_CIF_ISP_AWB_GAIN_B_SET(x)               ((x) & 0x3FFF)
+#define RKISP1_CIF_ISP_AWB_GAIN_B_READ(x)              ((x) & 0x3FFF)
+/* ISP_AWB_REF */
+#define RKISP1_CIF_ISP_AWB_REF_CR_SET(x)               (((x) & 0xFF) << 8)
+#define RKISP1_CIF_ISP_AWB_REF_CR_READ(x)              (((x) >> 8) & 0xFF)
+#define RKISP1_CIF_ISP_AWB_REF_CB_READ(x)              ((x) & 0xFF)
+/* ISP_AWB_THRESH */
+#define RKISP1_CIF_ISP_AWB_MAX_CS_SET(x)               (((x) & 0xFF) << 8)
+#define RKISP1_CIF_ISP_AWB_MAX_CS_READ(x)              (((x) >> 8) & 0xFF)
+#define RKISP1_CIF_ISP_AWB_MIN_C_READ(x)               ((x) & 0xFF)
+#define RKISP1_CIF_ISP_AWB_MIN_Y_SET(x)                        (((x) & 0xFF) << 16)
+#define RKISP1_CIF_ISP_AWB_MIN_Y_READ(x)               (((x) >> 16) & 0xFF)
+#define RKISP1_CIF_ISP_AWB_MAX_Y_SET(x)                        (((x) & 0xFF) << 24)
+#define RKISP1_CIF_ISP_AWB_MAX_Y_READ(x)                       (((x) >> 24) & 0xFF)
+/* ISP_AWB_MEAN */
+#define RKISP1_CIF_ISP_AWB_GET_MEAN_CR_R(x)            ((x) & 0xFF)
+#define RKISP1_CIF_ISP_AWB_GET_MEAN_CB_B(x)            (((x) >> 8) & 0xFF)
+#define RKISP1_CIF_ISP_AWB_GET_MEAN_Y_G(x)             (((x) >> 16) & 0xFF)
+/* ISP_AWB_WHITE_CNT */
+#define RKISP1_CIF_ISP_AWB_GET_PIXEL_CNT(x)            ((x) & 0x3FFFFFF)
+
+#define RKISP1_CIF_ISP_AWB_GAINS_MAX_VAL               0x000003FF
+#define RKISP1_CIF_ISP_AWB_WINDOW_OFFSET_MAX           0x00000FFF
+#define RKISP1_CIF_ISP_AWB_WINDOW_MAX_SIZE             0x00001FFF
+#define RKISP1_CIF_ISP_AWB_CBCR_MAX_REF                        0x000000FF
+#define RKISP1_CIF_ISP_AWB_THRES_MAX_YC                        0x000000FF
+
+/* AE */
+/* ISP_EXP_CTRL */
+#define RKISP1_CIF_ISP_EXP_ENA                         BIT(0)
+#define RKISP1_CIF_ISP_EXP_CTRL_AUTOSTOP               BIT(1)
+/*
+ *'1' luminance calculation according to  Y=(R+G+B) x 0.332 (85/256)
+ *'0' luminance calculation according to Y=16+0.25R+0.5G+0.1094B
+ */
+#define RKISP1_CIF_ISP_EXP_CTRL_MEASMODE_1             BIT(31)
+
+/* ISP_EXP_H_SIZE */
+#define RKISP1_CIF_ISP_EXP_H_SIZE_SET(x)               ((x) & 0x7FF)
+#define RKISP1_CIF_ISP_EXP_HEIGHT_MASK                 0x000007FF
+/* ISP_EXP_V_SIZE : vertical size must be a multiple of 2). */
+#define RKISP1_CIF_ISP_EXP_V_SIZE_SET(x)               ((x) & 0x7FE)
+
+/* ISP_EXP_H_OFFSET */
+#define RKISP1_CIF_ISP_EXP_H_OFFSET_SET(x)             ((x) & 0x1FFF)
+#define RKISP1_CIF_ISP_EXP_MAX_HOFFS                   2424
+/* ISP_EXP_V_OFFSET */
+#define RKISP1_CIF_ISP_EXP_V_OFFSET_SET(x)             ((x) & 0x1FFF)
+#define RKISP1_CIF_ISP_EXP_MAX_VOFFS                   1806
+
+#define RKISP1_CIF_ISP_EXP_ROW_NUM                     5
+#define RKISP1_CIF_ISP_EXP_COLUMN_NUM                  5
+#define RKISP1_CIF_ISP_EXP_NUM_LUMA_REGS \
+       (RKISP1_CIF_ISP_EXP_ROW_NUM * RKISP1_CIF_ISP_EXP_COLUMN_NUM)
+#define RKISP1_CIF_ISP_EXP_BLOCK_MAX_HSIZE             516
+#define RKISP1_CIF_ISP_EXP_BLOCK_MIN_HSIZE             35
+#define RKISP1_CIF_ISP_EXP_BLOCK_MAX_VSIZE             390
+#define RKISP1_CIF_ISP_EXP_BLOCK_MIN_VSIZE             28
+#define RKISP1_CIF_ISP_EXP_MAX_HSIZE   \
+       (RKISP1_CIF_ISP_EXP_BLOCK_MAX_HSIZE * RKISP1_CIF_ISP_EXP_COLUMN_NUM + 1)
+#define RKISP1_CIF_ISP_EXP_MIN_HSIZE   \
+       (RKISP1_CIF_ISP_EXP_BLOCK_MIN_HSIZE * RKISP1_CIF_ISP_EXP_COLUMN_NUM + 1)
+#define RKISP1_CIF_ISP_EXP_MAX_VSIZE   \
+       (RKISP1_CIF_ISP_EXP_BLOCK_MAX_VSIZE * RKISP1_CIF_ISP_EXP_ROW_NUM + 1)
+#define RKISP1_CIF_ISP_EXP_MIN_VSIZE   \
+       (RKISP1_CIF_ISP_EXP_BLOCK_MIN_VSIZE * RKISP1_CIF_ISP_EXP_ROW_NUM + 1)
+
+/* LSC: ISP_LSC_CTRL */
+#define RKISP1_CIF_ISP_LSC_CTRL_ENA                    BIT(0)
+#define RKISP1_CIF_ISP_LSC_SECT_SIZE_RESERVED          0xFC00FC00
+#define RKISP1_CIF_ISP_LSC_GRAD_RESERVED               0xF000F000
+#define RKISP1_CIF_ISP_LSC_SAMPLE_RESERVED             0xF000F000
+#define RKISP1_CIF_ISP_LSC_TABLE_DATA(v0, v1)     \
+       (((v0) & 0xFFF) | (((v1) & 0xFFF) << 12))
+#define RKISP1_CIF_ISP_LSC_SECT_SIZE(v0, v1)      \
+       (((v0) & 0xFFF) | (((v1) & 0xFFF) << 16))
+#define RKISP1_CIF_ISP_LSC_GRAD_SIZE(v0, v1)      \
+       (((v0) & 0xFFF) | (((v1) & 0xFFF) << 16))
+
+/* LSC: ISP_LSC_TABLE_SEL */
+#define RKISP1_CIF_ISP_LSC_TABLE_0                     0
+#define RKISP1_CIF_ISP_LSC_TABLE_1                     1
+
+/* LSC: ISP_LSC_STATUS */
+#define RKISP1_CIF_ISP_LSC_ACTIVE_TABLE                        BIT(1)
+#define RKISP1_CIF_ISP_LSC_TABLE_ADDRESS_0             0
+#define RKISP1_CIF_ISP_LSC_TABLE_ADDRESS_153           153
+
+/* FLT */
+/* ISP_FILT_MODE */
+#define RKISP1_CIF_ISP_FLT_ENA                         BIT(0)
+
+/*
+ * 0: green filter static mode (active filter factor = FILT_FAC_MID)
+ * 1: dynamic noise reduction/sharpen Default
+ */
+#define RKISP1_CIF_ISP_FLT_MODE_DNR                    BIT(1)
+#define RKISP1_CIF_ISP_FLT_MODE_MAX                    1
+#define RKISP1_CIF_ISP_FLT_CHROMA_V_MODE(x)            (((x) & 0x3) << 4)
+#define RKISP1_CIF_ISP_FLT_CHROMA_H_MODE(x)            (((x) & 0x3) << 6)
+#define RKISP1_CIF_ISP_FLT_CHROMA_MODE_MAX             3
+#define RKISP1_CIF_ISP_FLT_GREEN_STAGE1(x)             (((x) & 0xF) << 8)
+#define RKISP1_CIF_ISP_FLT_GREEN_STAGE1_MAX            8
+#define RKISP1_CIF_ISP_FLT_THREAD_RESERVED             0xFFFFFC00
+#define RKISP1_CIF_ISP_FLT_FAC_RESERVED                        0xFFFFFFC0
+#define RKISP1_CIF_ISP_FLT_LUM_WEIGHT_RESERVED         0xFFF80000
+
+#define RKISP1_CIF_ISP_CTK_COEFF_RESERVED              0xFFFFF800
+#define RKISP1_CIF_ISP_XTALK_OFFSET_RESERVED           0xFFFFF000
+
+/* GOC */
+#define RKISP1_CIF_ISP_GAMMA_OUT_MODE_EQU              BIT(0)
+#define RKISP1_CIF_ISP_GOC_MODE_MAX                    1
+#define RKISP1_CIF_ISP_GOC_RESERVED                    0xFFFFF800
+/* ISP_CTRL BIT 11*/
+#define RKISP1_CIF_ISP_CTRL_ISP_GAMMA_OUT_ENA_READ(x)  (((x) >> 11) & 1)
+
+/* DPCC */
+/* ISP_DPCC_MODE */
+#define RKISP1_CIF_ISP_DPCC_ENA                                BIT(0)
+#define RKISP1_CIF_ISP_DPCC_MODE_MAX                   0x07
+#define RKISP1_CIF_ISP_DPCC_OUTPUTMODE_MAX             0x0F
+#define RKISP1_CIF_ISP_DPCC_SETUSE_MAX                 0x0F
+#define RKISP1_CIF_ISP_DPCC_METHODS_SET_RESERVED       0xFFFFE000
+#define RKISP1_CIF_ISP_DPCC_LINE_THRESH_RESERVED       0xFFFF0000
+#define RKISP1_CIF_ISP_DPCC_LINE_MAD_FAC_RESERVED      0xFFFFC0C0
+#define RKISP1_CIF_ISP_DPCC_PG_FAC_RESERVED            0xFFFFC0C0
+#define RKISP1_CIF_ISP_DPCC_RND_THRESH_RESERVED                0xFFFF0000
+#define RKISP1_CIF_ISP_DPCC_RG_FAC_RESERVED            0xFFFFC0C0
+#define RKISP1_CIF_ISP_DPCC_RO_LIMIT_RESERVED          0xFFFFF000
+#define RKISP1_CIF_ISP_DPCC_RND_OFFS_RESERVED          0xFFFFF000
+
+/* BLS */
+/* ISP_BLS_CTRL */
+#define RKISP1_CIF_ISP_BLS_ENA                         BIT(0)
+#define RKISP1_CIF_ISP_BLS_MODE_MEASURED               BIT(1)
+#define RKISP1_CIF_ISP_BLS_MODE_FIXED                  0
+#define RKISP1_CIF_ISP_BLS_WINDOW_1                    BIT(2)
+#define RKISP1_CIF_ISP_BLS_WINDOW_2                    (2 << 2)
+
+/* GAMMA-IN */
+#define RKISP1_CIFISP_DEGAMMA_X_RESERVED       \
+       ((1 << 31) | (1 << 27) | (1 << 23) | (1 << 19) |\
+       (1 << 15) | (1 << 11) | (1 << 7) | (1 << 3))
+#define RKISP1_CIFISP_DEGAMMA_Y_RESERVED               0xFFFFF000
+
+/* AFM */
+#define RKISP1_CIF_ISP_AFM_ENA                         BIT(0)
+#define RKISP1_CIF_ISP_AFM_THRES_RESERVED              0xFFFF0000
+#define RKISP1_CIF_ISP_AFM_VAR_SHIFT_RESERVED          0xFFF8FFF8
+#define RKISP1_CIF_ISP_AFM_WINDOW_X_RESERVED           0xE000
+#define RKISP1_CIF_ISP_AFM_WINDOW_Y_RESERVED           0xF000
+#define RKISP1_CIF_ISP_AFM_WINDOW_X_MIN                        0x5
+#define RKISP1_CIF_ISP_AFM_WINDOW_Y_MIN                        0x2
+#define RKISP1_CIF_ISP_AFM_WINDOW_X(x)                 (((x) & 0x1FFF) << 16)
+#define RKISP1_CIF_ISP_AFM_WINDOW_Y(x)                 ((x) & 0x1FFF)
+
+/* DPF */
+#define RKISP1_CIF_ISP_DPF_MODE_EN                     BIT(0)
+#define RKISP1_CIF_ISP_DPF_MODE_B_FLT_DIS              BIT(1)
+#define RKISP1_CIF_ISP_DPF_MODE_GB_FLT_DIS             BIT(2)
+#define RKISP1_CIF_ISP_DPF_MODE_GR_FLT_DIS             BIT(3)
+#define RKISP1_CIF_ISP_DPF_MODE_R_FLT_DIS              BIT(4)
+#define RKISP1_CIF_ISP_DPF_MODE_RB_FLTSIZE_9x9         BIT(5)
+#define RKISP1_CIF_ISP_DPF_MODE_NLL_SEGMENTATION       BIT(6)
+#define RKISP1_CIF_ISP_DPF_MODE_AWB_GAIN_COMP          BIT(7)
+#define RKISP1_CIF_ISP_DPF_MODE_LSC_GAIN_COMP          BIT(8)
+#define RKISP1_CIF_ISP_DPF_MODE_USE_NF_GAIN            BIT(9)
+#define RKISP1_CIF_ISP_DPF_NF_GAIN_RESERVED            0xFFFFF000
+#define RKISP1_CIF_ISP_DPF_SPATIAL_COEFF_MAX           0x1F
+#define RKISP1_CIF_ISP_DPF_NLL_COEFF_N_MAX             0x3FF
+
+/* =================================================================== */
+/*                            CIF Registers                            */
+/* =================================================================== */
+#define RKISP1_CIF_CTRL_BASE                   0x00000000
+#define RKISP1_CIF_CCL                         (RKISP1_CIF_CTRL_BASE + 0x00000000)
+#define RKISP1_CIF_VI_ID                       (RKISP1_CIF_CTRL_BASE + 0x00000008)
+#define RKISP1_CIF_ICCL                                (RKISP1_CIF_CTRL_BASE + 0x00000010)
+#define RKISP1_CIF_IRCL                                (RKISP1_CIF_CTRL_BASE + 0x00000014)
+#define RKISP1_CIF_VI_DPCL                     (RKISP1_CIF_CTRL_BASE + 0x00000018)
+
+#define RKISP1_CIF_IMG_EFF_BASE                        0x00000200
+#define RKISP1_CIF_IMG_EFF_CTRL                        (RKISP1_CIF_IMG_EFF_BASE + 0x00000000)
+#define RKISP1_CIF_IMG_EFF_COLOR_SEL           (RKISP1_CIF_IMG_EFF_BASE + 0x00000004)
+#define RKISP1_CIF_IMG_EFF_MAT_1               (RKISP1_CIF_IMG_EFF_BASE + 0x00000008)
+#define RKISP1_CIF_IMG_EFF_MAT_2               (RKISP1_CIF_IMG_EFF_BASE + 0x0000000C)
+#define RKISP1_CIF_IMG_EFF_MAT_3               (RKISP1_CIF_IMG_EFF_BASE + 0x00000010)
+#define RKISP1_CIF_IMG_EFF_MAT_4               (RKISP1_CIF_IMG_EFF_BASE + 0x00000014)
+#define RKISP1_CIF_IMG_EFF_MAT_5               (RKISP1_CIF_IMG_EFF_BASE + 0x00000018)
+#define RKISP1_CIF_IMG_EFF_TINT                        (RKISP1_CIF_IMG_EFF_BASE + 0x0000001C)
+#define RKISP1_CIF_IMG_EFF_CTRL_SHD            (RKISP1_CIF_IMG_EFF_BASE + 0x00000020)
+#define RKISP1_CIF_IMG_EFF_SHARPEN             (RKISP1_CIF_IMG_EFF_BASE + 0x00000024)
+
+#define RKISP1_CIF_SUPER_IMP_BASE              0x00000300
+#define RKISP1_CIF_SUPER_IMP_CTRL              (RKISP1_CIF_SUPER_IMP_BASE + 0x00000000)
+#define RKISP1_CIF_SUPER_IMP_OFFSET_X          (RKISP1_CIF_SUPER_IMP_BASE + 0x00000004)
+#define RKISP1_CIF_SUPER_IMP_OFFSET_Y          (RKISP1_CIF_SUPER_IMP_BASE + 0x00000008)
+#define RKISP1_CIF_SUPER_IMP_COLOR_Y           (RKISP1_CIF_SUPER_IMP_BASE + 0x0000000C)
+#define RKISP1_CIF_SUPER_IMP_COLOR_CB          (RKISP1_CIF_SUPER_IMP_BASE + 0x00000010)
+#define RKISP1_CIF_SUPER_IMP_COLOR_CR          (RKISP1_CIF_SUPER_IMP_BASE + 0x00000014)
+
+#define RKISP1_CIF_ISP_BASE                    0x00000400
+#define RKISP1_CIF_ISP_CTRL                    (RKISP1_CIF_ISP_BASE + 0x00000000)
+#define RKISP1_CIF_ISP_ACQ_PROP                        (RKISP1_CIF_ISP_BASE + 0x00000004)
+#define RKISP1_CIF_ISP_ACQ_H_OFFS              (RKISP1_CIF_ISP_BASE + 0x00000008)
+#define RKISP1_CIF_ISP_ACQ_V_OFFS              (RKISP1_CIF_ISP_BASE + 0x0000000C)
+#define RKISP1_CIF_ISP_ACQ_H_SIZE              (RKISP1_CIF_ISP_BASE + 0x00000010)
+#define RKISP1_CIF_ISP_ACQ_V_SIZE              (RKISP1_CIF_ISP_BASE + 0x00000014)
+#define RKISP1_CIF_ISP_ACQ_NR_FRAMES           (RKISP1_CIF_ISP_BASE + 0x00000018)
+#define RKISP1_CIF_ISP_GAMMA_DX_LO             (RKISP1_CIF_ISP_BASE + 0x0000001C)
+#define RKISP1_CIF_ISP_GAMMA_DX_HI             (RKISP1_CIF_ISP_BASE + 0x00000020)
+#define RKISP1_CIF_ISP_GAMMA_R_Y0              (RKISP1_CIF_ISP_BASE + 0x00000024)
+#define RKISP1_CIF_ISP_GAMMA_R_Y1              (RKISP1_CIF_ISP_BASE + 0x00000028)
+#define RKISP1_CIF_ISP_GAMMA_R_Y2              (RKISP1_CIF_ISP_BASE + 0x0000002C)
+#define RKISP1_CIF_ISP_GAMMA_R_Y3              (RKISP1_CIF_ISP_BASE + 0x00000030)
+#define RKISP1_CIF_ISP_GAMMA_R_Y4              (RKISP1_CIF_ISP_BASE + 0x00000034)
+#define RKISP1_CIF_ISP_GAMMA_R_Y5              (RKISP1_CIF_ISP_BASE + 0x00000038)
+#define RKISP1_CIF_ISP_GAMMA_R_Y6              (RKISP1_CIF_ISP_BASE + 0x0000003C)
+#define RKISP1_CIF_ISP_GAMMA_R_Y7              (RKISP1_CIF_ISP_BASE + 0x00000040)
+#define RKISP1_CIF_ISP_GAMMA_R_Y8              (RKISP1_CIF_ISP_BASE + 0x00000044)
+#define RKISP1_CIF_ISP_GAMMA_R_Y9              (RKISP1_CIF_ISP_BASE + 0x00000048)
+#define RKISP1_CIF_ISP_GAMMA_R_Y10             (RKISP1_CIF_ISP_BASE + 0x0000004C)
+#define RKISP1_CIF_ISP_GAMMA_R_Y11             (RKISP1_CIF_ISP_BASE + 0x00000050)
+#define RKISP1_CIF_ISP_GAMMA_R_Y12             (RKISP1_CIF_ISP_BASE + 0x00000054)
+#define RKISP1_CIF_ISP_GAMMA_R_Y13             (RKISP1_CIF_ISP_BASE + 0x00000058)
+#define RKISP1_CIF_ISP_GAMMA_R_Y14             (RKISP1_CIF_ISP_BASE + 0x0000005C)
+#define RKISP1_CIF_ISP_GAMMA_R_Y15             (RKISP1_CIF_ISP_BASE + 0x00000060)
+#define RKISP1_CIF_ISP_GAMMA_R_Y16             (RKISP1_CIF_ISP_BASE + 0x00000064)
+#define RKISP1_CIF_ISP_GAMMA_G_Y0              (RKISP1_CIF_ISP_BASE + 0x00000068)
+#define RKISP1_CIF_ISP_GAMMA_G_Y1              (RKISP1_CIF_ISP_BASE + 0x0000006C)
+#define RKISP1_CIF_ISP_GAMMA_G_Y2              (RKISP1_CIF_ISP_BASE + 0x00000070)
+#define RKISP1_CIF_ISP_GAMMA_G_Y3              (RKISP1_CIF_ISP_BASE + 0x00000074)
+#define RKISP1_CIF_ISP_GAMMA_G_Y4              (RKISP1_CIF_ISP_BASE + 0x00000078)
+#define RKISP1_CIF_ISP_GAMMA_G_Y5              (RKISP1_CIF_ISP_BASE + 0x0000007C)
+#define RKISP1_CIF_ISP_GAMMA_G_Y6              (RKISP1_CIF_ISP_BASE + 0x00000080)
+#define RKISP1_CIF_ISP_GAMMA_G_Y7              (RKISP1_CIF_ISP_BASE + 0x00000084)
+#define RKISP1_CIF_ISP_GAMMA_G_Y8              (RKISP1_CIF_ISP_BASE + 0x00000088)
+#define RKISP1_CIF_ISP_GAMMA_G_Y9              (RKISP1_CIF_ISP_BASE + 0x0000008C)
+#define RKISP1_CIF_ISP_GAMMA_G_Y10             (RKISP1_CIF_ISP_BASE + 0x00000090)
+#define RKISP1_CIF_ISP_GAMMA_G_Y11             (RKISP1_CIF_ISP_BASE + 0x00000094)
+#define RKISP1_CIF_ISP_GAMMA_G_Y12             (RKISP1_CIF_ISP_BASE + 0x00000098)
+#define RKISP1_CIF_ISP_GAMMA_G_Y13             (RKISP1_CIF_ISP_BASE + 0x0000009C)
+#define RKISP1_CIF_ISP_GAMMA_G_Y14             (RKISP1_CIF_ISP_BASE + 0x000000A0)
+#define RKISP1_CIF_ISP_GAMMA_G_Y15             (RKISP1_CIF_ISP_BASE + 0x000000A4)
+#define RKISP1_CIF_ISP_GAMMA_G_Y16             (RKISP1_CIF_ISP_BASE + 0x000000A8)
+#define RKISP1_CIF_ISP_GAMMA_B_Y0              (RKISP1_CIF_ISP_BASE + 0x000000AC)
+#define RKISP1_CIF_ISP_GAMMA_B_Y1              (RKISP1_CIF_ISP_BASE + 0x000000B0)
+#define RKISP1_CIF_ISP_GAMMA_B_Y2              (RKISP1_CIF_ISP_BASE + 0x000000B4)
+#define RKISP1_CIF_ISP_GAMMA_B_Y3              (RKISP1_CIF_ISP_BASE + 0x000000B8)
+#define RKISP1_CIF_ISP_GAMMA_B_Y4              (RKISP1_CIF_ISP_BASE + 0x000000BC)
+#define RKISP1_CIF_ISP_GAMMA_B_Y5              (RKISP1_CIF_ISP_BASE + 0x000000C0)
+#define RKISP1_CIF_ISP_GAMMA_B_Y6              (RKISP1_CIF_ISP_BASE + 0x000000C4)
+#define RKISP1_CIF_ISP_GAMMA_B_Y7              (RKISP1_CIF_ISP_BASE + 0x000000C8)
+#define RKISP1_CIF_ISP_GAMMA_B_Y8              (RKISP1_CIF_ISP_BASE + 0x000000CC)
+#define RKISP1_CIF_ISP_GAMMA_B_Y9              (RKISP1_CIF_ISP_BASE + 0x000000D0)
+#define RKISP1_CIF_ISP_GAMMA_B_Y10             (RKISP1_CIF_ISP_BASE + 0x000000D4)
+#define RKISP1_CIF_ISP_GAMMA_B_Y11             (RKISP1_CIF_ISP_BASE + 0x000000D8)
+#define RKISP1_CIF_ISP_GAMMA_B_Y12             (RKISP1_CIF_ISP_BASE + 0x000000DC)
+#define RKISP1_CIF_ISP_GAMMA_B_Y13             (RKISP1_CIF_ISP_BASE + 0x000000E0)
+#define RKISP1_CIF_ISP_GAMMA_B_Y14             (RKISP1_CIF_ISP_BASE + 0x000000E4)
+#define RKISP1_CIF_ISP_GAMMA_B_Y15             (RKISP1_CIF_ISP_BASE + 0x000000E8)
+#define RKISP1_CIF_ISP_GAMMA_B_Y16             (RKISP1_CIF_ISP_BASE + 0x000000EC)
+#define RKISP1_CIF_ISP_AWB_PROP                        (RKISP1_CIF_ISP_BASE + 0x00000110)
+#define RKISP1_CIF_ISP_AWB_WND_H_OFFS          (RKISP1_CIF_ISP_BASE + 0x00000114)
+#define RKISP1_CIF_ISP_AWB_WND_V_OFFS          (RKISP1_CIF_ISP_BASE + 0x00000118)
+#define RKISP1_CIF_ISP_AWB_WND_H_SIZE          (RKISP1_CIF_ISP_BASE + 0x0000011C)
+#define RKISP1_CIF_ISP_AWB_WND_V_SIZE          (RKISP1_CIF_ISP_BASE + 0x00000120)
+#define RKISP1_CIF_ISP_AWB_FRAMES              (RKISP1_CIF_ISP_BASE + 0x00000124)
+#define RKISP1_CIF_ISP_AWB_REF                 (RKISP1_CIF_ISP_BASE + 0x00000128)
+#define RKISP1_CIF_ISP_AWB_THRESH              (RKISP1_CIF_ISP_BASE + 0x0000012C)
+#define RKISP1_CIF_ISP_AWB_GAIN_G              (RKISP1_CIF_ISP_BASE + 0x00000138)
+#define RKISP1_CIF_ISP_AWB_GAIN_RB             (RKISP1_CIF_ISP_BASE + 0x0000013C)
+#define RKISP1_CIF_ISP_AWB_WHITE_CNT           (RKISP1_CIF_ISP_BASE + 0x00000140)
+#define RKISP1_CIF_ISP_AWB_MEAN                        (RKISP1_CIF_ISP_BASE + 0x00000144)
+#define RKISP1_CIF_ISP_CC_COEFF_0              (RKISP1_CIF_ISP_BASE + 0x00000170)
+#define RKISP1_CIF_ISP_CC_COEFF_1              (RKISP1_CIF_ISP_BASE + 0x00000174)
+#define RKISP1_CIF_ISP_CC_COEFF_2              (RKISP1_CIF_ISP_BASE + 0x00000178)
+#define RKISP1_CIF_ISP_CC_COEFF_3              (RKISP1_CIF_ISP_BASE + 0x0000017C)
+#define RKISP1_CIF_ISP_CC_COEFF_4              (RKISP1_CIF_ISP_BASE + 0x00000180)
+#define RKISP1_CIF_ISP_CC_COEFF_5              (RKISP1_CIF_ISP_BASE + 0x00000184)
+#define RKISP1_CIF_ISP_CC_COEFF_6              (RKISP1_CIF_ISP_BASE + 0x00000188)
+#define RKISP1_CIF_ISP_CC_COEFF_7              (RKISP1_CIF_ISP_BASE + 0x0000018C)
+#define RKISP1_CIF_ISP_CC_COEFF_8              (RKISP1_CIF_ISP_BASE + 0x00000190)
+#define RKISP1_CIF_ISP_OUT_H_OFFS              (RKISP1_CIF_ISP_BASE + 0x00000194)
+#define RKISP1_CIF_ISP_OUT_V_OFFS              (RKISP1_CIF_ISP_BASE + 0x00000198)
+#define RKISP1_CIF_ISP_OUT_H_SIZE              (RKISP1_CIF_ISP_BASE + 0x0000019C)
+#define RKISP1_CIF_ISP_OUT_V_SIZE              (RKISP1_CIF_ISP_BASE + 0x000001A0)
+#define RKISP1_CIF_ISP_DEMOSAIC                        (RKISP1_CIF_ISP_BASE + 0x000001A4)
+#define RKISP1_CIF_ISP_FLAGS_SHD               (RKISP1_CIF_ISP_BASE + 0x000001A8)
+#define RKISP1_CIF_ISP_OUT_H_OFFS_SHD          (RKISP1_CIF_ISP_BASE + 0x000001AC)
+#define RKISP1_CIF_ISP_OUT_V_OFFS_SHD          (RKISP1_CIF_ISP_BASE + 0x000001B0)
+#define RKISP1_CIF_ISP_OUT_H_SIZE_SHD          (RKISP1_CIF_ISP_BASE + 0x000001B4)
+#define RKISP1_CIF_ISP_OUT_V_SIZE_SHD          (RKISP1_CIF_ISP_BASE + 0x000001B8)
+#define RKISP1_CIF_ISP_IMSC                    (RKISP1_CIF_ISP_BASE + 0x000001BC)
+#define RKISP1_CIF_ISP_RIS                     (RKISP1_CIF_ISP_BASE + 0x000001C0)
+#define RKISP1_CIF_ISP_MIS                     (RKISP1_CIF_ISP_BASE + 0x000001C4)
+#define RKISP1_CIF_ISP_ICR                     (RKISP1_CIF_ISP_BASE + 0x000001C8)
+#define RKISP1_CIF_ISP_ISR                     (RKISP1_CIF_ISP_BASE + 0x000001CC)
+#define RKISP1_CIF_ISP_CT_COEFF_0              (RKISP1_CIF_ISP_BASE + 0x000001D0)
+#define RKISP1_CIF_ISP_CT_COEFF_1              (RKISP1_CIF_ISP_BASE + 0x000001D4)
+#define RKISP1_CIF_ISP_CT_COEFF_2              (RKISP1_CIF_ISP_BASE + 0x000001D8)
+#define RKISP1_CIF_ISP_CT_COEFF_3              (RKISP1_CIF_ISP_BASE + 0x000001DC)
+#define RKISP1_CIF_ISP_CT_COEFF_4              (RKISP1_CIF_ISP_BASE + 0x000001E0)
+#define RKISP1_CIF_ISP_CT_COEFF_5              (RKISP1_CIF_ISP_BASE + 0x000001E4)
+#define RKISP1_CIF_ISP_CT_COEFF_6              (RKISP1_CIF_ISP_BASE + 0x000001E8)
+#define RKISP1_CIF_ISP_CT_COEFF_7              (RKISP1_CIF_ISP_BASE + 0x000001EC)
+#define RKISP1_CIF_ISP_CT_COEFF_8              (RKISP1_CIF_ISP_BASE + 0x000001F0)
+#define RKISP1_CIF_ISP_GAMMA_OUT_MODE          (RKISP1_CIF_ISP_BASE + 0x000001F4)
+#define RKISP1_CIF_ISP_GAMMA_OUT_Y_0           (RKISP1_CIF_ISP_BASE + 0x000001F8)
+#define RKISP1_CIF_ISP_GAMMA_OUT_Y_1           (RKISP1_CIF_ISP_BASE + 0x000001FC)
+#define RKISP1_CIF_ISP_GAMMA_OUT_Y_2           (RKISP1_CIF_ISP_BASE + 0x00000200)
+#define RKISP1_CIF_ISP_GAMMA_OUT_Y_3           (RKISP1_CIF_ISP_BASE + 0x00000204)
+#define RKISP1_CIF_ISP_GAMMA_OUT_Y_4           (RKISP1_CIF_ISP_BASE + 0x00000208)
+#define RKISP1_CIF_ISP_GAMMA_OUT_Y_5           (RKISP1_CIF_ISP_BASE + 0x0000020C)
+#define RKISP1_CIF_ISP_GAMMA_OUT_Y_6           (RKISP1_CIF_ISP_BASE + 0x00000210)
+#define RKISP1_CIF_ISP_GAMMA_OUT_Y_7           (RKISP1_CIF_ISP_BASE + 0x00000214)
+#define RKISP1_CIF_ISP_GAMMA_OUT_Y_8           (RKISP1_CIF_ISP_BASE + 0x00000218)
+#define RKISP1_CIF_ISP_GAMMA_OUT_Y_9           (RKISP1_CIF_ISP_BASE + 0x0000021C)
+#define RKISP1_CIF_ISP_GAMMA_OUT_Y_10          (RKISP1_CIF_ISP_BASE + 0x00000220)
+#define RKISP1_CIF_ISP_GAMMA_OUT_Y_11          (RKISP1_CIF_ISP_BASE + 0x00000224)
+#define RKISP1_CIF_ISP_GAMMA_OUT_Y_12          (RKISP1_CIF_ISP_BASE + 0x00000228)
+#define RKISP1_CIF_ISP_GAMMA_OUT_Y_13          (RKISP1_CIF_ISP_BASE + 0x0000022C)
+#define RKISP1_CIF_ISP_GAMMA_OUT_Y_14          (RKISP1_CIF_ISP_BASE + 0x00000230)
+#define RKISP1_CIF_ISP_GAMMA_OUT_Y_15          (RKISP1_CIF_ISP_BASE + 0x00000234)
+#define RKISP1_CIF_ISP_GAMMA_OUT_Y_16          (RKISP1_CIF_ISP_BASE + 0x00000238)
+#define RKISP1_CIF_ISP_ERR                     (RKISP1_CIF_ISP_BASE + 0x0000023C)
+#define RKISP1_CIF_ISP_ERR_CLR                 (RKISP1_CIF_ISP_BASE + 0x00000240)
+#define RKISP1_CIF_ISP_FRAME_COUNT             (RKISP1_CIF_ISP_BASE + 0x00000244)
+#define RKISP1_CIF_ISP_CT_OFFSET_R             (RKISP1_CIF_ISP_BASE + 0x00000248)
+#define RKISP1_CIF_ISP_CT_OFFSET_G             (RKISP1_CIF_ISP_BASE + 0x0000024C)
+#define RKISP1_CIF_ISP_CT_OFFSET_B             (RKISP1_CIF_ISP_BASE + 0x00000250)
+
+#define RKISP1_CIF_ISP_FLASH_BASE              0x00000660
+#define RKISP1_CIF_ISP_FLASH_CMD               (RKISP1_CIF_ISP_FLASH_BASE + 0x00000000)
+#define RKISP1_CIF_ISP_FLASH_CONFIG            (RKISP1_CIF_ISP_FLASH_BASE + 0x00000004)
+#define RKISP1_CIF_ISP_FLASH_PREDIV            (RKISP1_CIF_ISP_FLASH_BASE + 0x00000008)
+#define RKISP1_CIF_ISP_FLASH_DELAY             (RKISP1_CIF_ISP_FLASH_BASE + 0x0000000C)
+#define RKISP1_CIF_ISP_FLASH_TIME              (RKISP1_CIF_ISP_FLASH_BASE + 0x00000010)
+#define RKISP1_CIF_ISP_FLASH_MAXP              (RKISP1_CIF_ISP_FLASH_BASE + 0x00000014)
+
+#define RKISP1_CIF_ISP_SH_BASE                 0x00000680
+#define RKISP1_CIF_ISP_SH_CTRL                 (RKISP1_CIF_ISP_SH_BASE + 0x00000000)
+#define RKISP1_CIF_ISP_SH_PREDIV               (RKISP1_CIF_ISP_SH_BASE + 0x00000004)
+#define RKISP1_CIF_ISP_SH_DELAY                        (RKISP1_CIF_ISP_SH_BASE + 0x00000008)
+#define RKISP1_CIF_ISP_SH_TIME                 (RKISP1_CIF_ISP_SH_BASE + 0x0000000C)
+
+#define RKISP1_CIF_C_PROC_BASE                 0x00000800
+#define RKISP1_CIF_C_PROC_CTRL                 (RKISP1_CIF_C_PROC_BASE + 0x00000000)
+#define RKISP1_CIF_C_PROC_CONTRAST             (RKISP1_CIF_C_PROC_BASE + 0x00000004)
+#define RKISP1_CIF_C_PROC_BRIGHTNESS           (RKISP1_CIF_C_PROC_BASE + 0x00000008)
+#define RKISP1_CIF_C_PROC_SATURATION           (RKISP1_CIF_C_PROC_BASE + 0x0000000C)
+#define RKISP1_CIF_C_PROC_HUE                  (RKISP1_CIF_C_PROC_BASE + 0x00000010)
+
+#define RKISP1_CIF_DUAL_CROP_BASE              0x00000880
+#define RKISP1_CIF_DUAL_CROP_CTRL              (RKISP1_CIF_DUAL_CROP_BASE + 0x00000000)
+#define RKISP1_CIF_DUAL_CROP_M_H_OFFS          (RKISP1_CIF_DUAL_CROP_BASE + 0x00000004)
+#define RKISP1_CIF_DUAL_CROP_M_V_OFFS          (RKISP1_CIF_DUAL_CROP_BASE + 0x00000008)
+#define RKISP1_CIF_DUAL_CROP_M_H_SIZE          (RKISP1_CIF_DUAL_CROP_BASE + 0x0000000C)
+#define RKISP1_CIF_DUAL_CROP_M_V_SIZE          (RKISP1_CIF_DUAL_CROP_BASE + 0x00000010)
+#define RKISP1_CIF_DUAL_CROP_S_H_OFFS          (RKISP1_CIF_DUAL_CROP_BASE + 0x00000014)
+#define RKISP1_CIF_DUAL_CROP_S_V_OFFS          (RKISP1_CIF_DUAL_CROP_BASE + 0x00000018)
+#define RKISP1_CIF_DUAL_CROP_S_H_SIZE          (RKISP1_CIF_DUAL_CROP_BASE + 0x0000001C)
+#define RKISP1_CIF_DUAL_CROP_S_V_SIZE          (RKISP1_CIF_DUAL_CROP_BASE + 0x00000020)
+#define RKISP1_CIF_DUAL_CROP_M_H_OFFS_SHD      (RKISP1_CIF_DUAL_CROP_BASE + 0x00000024)
+#define RKISP1_CIF_DUAL_CROP_M_V_OFFS_SHD      (RKISP1_CIF_DUAL_CROP_BASE + 0x00000028)
+#define RKISP1_CIF_DUAL_CROP_M_H_SIZE_SHD      (RKISP1_CIF_DUAL_CROP_BASE + 0x0000002C)
+#define RKISP1_CIF_DUAL_CROP_M_V_SIZE_SHD      (RKISP1_CIF_DUAL_CROP_BASE + 0x00000030)
+#define RKISP1_CIF_DUAL_CROP_S_H_OFFS_SHD      (RKISP1_CIF_DUAL_CROP_BASE + 0x00000034)
+#define RKISP1_CIF_DUAL_CROP_S_V_OFFS_SHD      (RKISP1_CIF_DUAL_CROP_BASE + 0x00000038)
+#define RKISP1_CIF_DUAL_CROP_S_H_SIZE_SHD      (RKISP1_CIF_DUAL_CROP_BASE + 0x0000003C)
+#define RKISP1_CIF_DUAL_CROP_S_V_SIZE_SHD      (RKISP1_CIF_DUAL_CROP_BASE + 0x00000040)
+
+#define RKISP1_CIF_MRSZ_BASE                   0x00000C00
+#define RKISP1_CIF_MRSZ_CTRL                   (RKISP1_CIF_MRSZ_BASE + 0x00000000)
+#define RKISP1_CIF_MRSZ_SCALE_HY               (RKISP1_CIF_MRSZ_BASE + 0x00000004)
+#define RKISP1_CIF_MRSZ_SCALE_HCB              (RKISP1_CIF_MRSZ_BASE + 0x00000008)
+#define RKISP1_CIF_MRSZ_SCALE_HCR              (RKISP1_CIF_MRSZ_BASE + 0x0000000C)
+#define RKISP1_CIF_MRSZ_SCALE_VY               (RKISP1_CIF_MRSZ_BASE + 0x00000010)
+#define RKISP1_CIF_MRSZ_SCALE_VC               (RKISP1_CIF_MRSZ_BASE + 0x00000014)
+#define RKISP1_CIF_MRSZ_PHASE_HY               (RKISP1_CIF_MRSZ_BASE + 0x00000018)
+#define RKISP1_CIF_MRSZ_PHASE_HC               (RKISP1_CIF_MRSZ_BASE + 0x0000001C)
+#define RKISP1_CIF_MRSZ_PHASE_VY               (RKISP1_CIF_MRSZ_BASE + 0x00000020)
+#define RKISP1_CIF_MRSZ_PHASE_VC               (RKISP1_CIF_MRSZ_BASE + 0x00000024)
+#define RKISP1_CIF_MRSZ_SCALE_LUT_ADDR         (RKISP1_CIF_MRSZ_BASE + 0x00000028)
+#define RKISP1_CIF_MRSZ_SCALE_LUT              (RKISP1_CIF_MRSZ_BASE + 0x0000002C)
+#define RKISP1_CIF_MRSZ_CTRL_SHD               (RKISP1_CIF_MRSZ_BASE + 0x00000030)
+#define RKISP1_CIF_MRSZ_SCALE_HY_SHD           (RKISP1_CIF_MRSZ_BASE + 0x00000034)
+#define RKISP1_CIF_MRSZ_SCALE_HCB_SHD          (RKISP1_CIF_MRSZ_BASE + 0x00000038)
+#define RKISP1_CIF_MRSZ_SCALE_HCR_SHD          (RKISP1_CIF_MRSZ_BASE + 0x0000003C)
+#define RKISP1_CIF_MRSZ_SCALE_VY_SHD           (RKISP1_CIF_MRSZ_BASE + 0x00000040)
+#define RKISP1_CIF_MRSZ_SCALE_VC_SHD           (RKISP1_CIF_MRSZ_BASE + 0x00000044)
+#define RKISP1_CIF_MRSZ_PHASE_HY_SHD           (RKISP1_CIF_MRSZ_BASE + 0x00000048)
+#define RKISP1_CIF_MRSZ_PHASE_HC_SHD           (RKISP1_CIF_MRSZ_BASE + 0x0000004C)
+#define RKISP1_CIF_MRSZ_PHASE_VY_SHD           (RKISP1_CIF_MRSZ_BASE + 0x00000050)
+#define RKISP1_CIF_MRSZ_PHASE_VC_SHD           (RKISP1_CIF_MRSZ_BASE + 0x00000054)
+
+#define RKISP1_CIF_SRSZ_BASE                   0x00001000
+#define RKISP1_CIF_SRSZ_CTRL                   (RKISP1_CIF_SRSZ_BASE + 0x00000000)
+#define RKISP1_CIF_SRSZ_SCALE_HY               (RKISP1_CIF_SRSZ_BASE + 0x00000004)
+#define RKISP1_CIF_SRSZ_SCALE_HCB              (RKISP1_CIF_SRSZ_BASE + 0x00000008)
+#define RKISP1_CIF_SRSZ_SCALE_HCR              (RKISP1_CIF_SRSZ_BASE + 0x0000000C)
+#define RKISP1_CIF_SRSZ_SCALE_VY               (RKISP1_CIF_SRSZ_BASE + 0x00000010)
+#define RKISP1_CIF_SRSZ_SCALE_VC               (RKISP1_CIF_SRSZ_BASE + 0x00000014)
+#define RKISP1_CIF_SRSZ_PHASE_HY               (RKISP1_CIF_SRSZ_BASE + 0x00000018)
+#define RKISP1_CIF_SRSZ_PHASE_HC               (RKISP1_CIF_SRSZ_BASE + 0x0000001C)
+#define RKISP1_CIF_SRSZ_PHASE_VY               (RKISP1_CIF_SRSZ_BASE + 0x00000020)
+#define RKISP1_CIF_SRSZ_PHASE_VC               (RKISP1_CIF_SRSZ_BASE + 0x00000024)
+#define RKISP1_CIF_SRSZ_SCALE_LUT_ADDR         (RKISP1_CIF_SRSZ_BASE + 0x00000028)
+#define RKISP1_CIF_SRSZ_SCALE_LUT              (RKISP1_CIF_SRSZ_BASE + 0x0000002C)
+#define RKISP1_CIF_SRSZ_CTRL_SHD               (RKISP1_CIF_SRSZ_BASE + 0x00000030)
+#define RKISP1_CIF_SRSZ_SCALE_HY_SHD           (RKISP1_CIF_SRSZ_BASE + 0x00000034)
+#define RKISP1_CIF_SRSZ_SCALE_HCB_SHD          (RKISP1_CIF_SRSZ_BASE + 0x00000038)
+#define RKISP1_CIF_SRSZ_SCALE_HCR_SHD          (RKISP1_CIF_SRSZ_BASE + 0x0000003C)
+#define RKISP1_CIF_SRSZ_SCALE_VY_SHD           (RKISP1_CIF_SRSZ_BASE + 0x00000040)
+#define RKISP1_CIF_SRSZ_SCALE_VC_SHD           (RKISP1_CIF_SRSZ_BASE + 0x00000044)
+#define RKISP1_CIF_SRSZ_PHASE_HY_SHD           (RKISP1_CIF_SRSZ_BASE + 0x00000048)
+#define RKISP1_CIF_SRSZ_PHASE_HC_SHD           (RKISP1_CIF_SRSZ_BASE + 0x0000004C)
+#define RKISP1_CIF_SRSZ_PHASE_VY_SHD           (RKISP1_CIF_SRSZ_BASE + 0x00000050)
+#define RKISP1_CIF_SRSZ_PHASE_VC_SHD           (RKISP1_CIF_SRSZ_BASE + 0x00000054)
+
+#define RKISP1_CIF_MI_BASE                     0x00001400
+#define RKISP1_CIF_MI_CTRL                     (RKISP1_CIF_MI_BASE + 0x00000000)
+#define RKISP1_CIF_MI_INIT                     (RKISP1_CIF_MI_BASE + 0x00000004)
+#define RKISP1_CIF_MI_MP_Y_BASE_AD_INIT                (RKISP1_CIF_MI_BASE + 0x00000008)
+#define RKISP1_CIF_MI_MP_Y_SIZE_INIT           (RKISP1_CIF_MI_BASE + 0x0000000C)
+#define RKISP1_CIF_MI_MP_Y_OFFS_CNT_INIT       (RKISP1_CIF_MI_BASE + 0x00000010)
+#define RKISP1_CIF_MI_MP_Y_OFFS_CNT_START      (RKISP1_CIF_MI_BASE + 0x00000014)
+#define RKISP1_CIF_MI_MP_Y_IRQ_OFFS_INIT       (RKISP1_CIF_MI_BASE + 0x00000018)
+#define RKISP1_CIF_MI_MP_CB_BASE_AD_INIT       (RKISP1_CIF_MI_BASE + 0x0000001C)
+#define RKISP1_CIF_MI_MP_CB_SIZE_INIT          (RKISP1_CIF_MI_BASE + 0x00000020)
+#define RKISP1_CIF_MI_MP_CB_OFFS_CNT_INIT      (RKISP1_CIF_MI_BASE + 0x00000024)
+#define RKISP1_CIF_MI_MP_CB_OFFS_CNT_START     (RKISP1_CIF_MI_BASE + 0x00000028)
+#define RKISP1_CIF_MI_MP_CR_BASE_AD_INIT       (RKISP1_CIF_MI_BASE + 0x0000002C)
+#define RKISP1_CIF_MI_MP_CR_SIZE_INIT          (RKISP1_CIF_MI_BASE + 0x00000030)
+#define RKISP1_CIF_MI_MP_CR_OFFS_CNT_INIT      (RKISP1_CIF_MI_BASE + 0x00000034)
+#define RKISP1_CIF_MI_MP_CR_OFFS_CNT_START     (RKISP1_CIF_MI_BASE + 0x00000038)
+#define RKISP1_CIF_MI_SP_Y_BASE_AD_INIT                (RKISP1_CIF_MI_BASE + 0x0000003C)
+#define RKISP1_CIF_MI_SP_Y_SIZE_INIT           (RKISP1_CIF_MI_BASE + 0x00000040)
+#define RKISP1_CIF_MI_SP_Y_OFFS_CNT_INIT       (RKISP1_CIF_MI_BASE + 0x00000044)
+#define RKISP1_CIF_MI_SP_Y_OFFS_CNT_START      (RKISP1_CIF_MI_BASE + 0x00000048)
+#define RKISP1_CIF_MI_SP_Y_LLENGTH             (RKISP1_CIF_MI_BASE + 0x0000004C)
+#define RKISP1_CIF_MI_SP_CB_BASE_AD_INIT       (RKISP1_CIF_MI_BASE + 0x00000050)
+#define RKISP1_CIF_MI_SP_CB_SIZE_INIT          (RKISP1_CIF_MI_BASE + 0x00000054)
+#define RKISP1_CIF_MI_SP_CB_OFFS_CNT_INIT      (RKISP1_CIF_MI_BASE + 0x00000058)
+#define RKISP1_CIF_MI_SP_CB_OFFS_CNT_START     (RKISP1_CIF_MI_BASE + 0x0000005C)
+#define RKISP1_CIF_MI_SP_CR_BASE_AD_INIT       (RKISP1_CIF_MI_BASE + 0x00000060)
+#define RKISP1_CIF_MI_SP_CR_SIZE_INIT          (RKISP1_CIF_MI_BASE + 0x00000064)
+#define RKISP1_CIF_MI_SP_CR_OFFS_CNT_INIT      (RKISP1_CIF_MI_BASE + 0x00000068)
+#define RKISP1_CIF_MI_SP_CR_OFFS_CNT_START     (RKISP1_CIF_MI_BASE + 0x0000006C)
+#define RKISP1_CIF_MI_BYTE_CNT                 (RKISP1_CIF_MI_BASE + 0x00000070)
+#define RKISP1_CIF_MI_CTRL_SHD                 (RKISP1_CIF_MI_BASE + 0x00000074)
+#define RKISP1_CIF_MI_MP_Y_BASE_AD_SHD         (RKISP1_CIF_MI_BASE + 0x00000078)
+#define RKISP1_CIF_MI_MP_Y_SIZE_SHD            (RKISP1_CIF_MI_BASE + 0x0000007C)
+#define RKISP1_CIF_MI_MP_Y_OFFS_CNT_SHD                (RKISP1_CIF_MI_BASE + 0x00000080)
+#define RKISP1_CIF_MI_MP_Y_IRQ_OFFS_SHD                (RKISP1_CIF_MI_BASE + 0x00000084)
+#define RKISP1_CIF_MI_MP_CB_BASE_AD_SHD                (RKISP1_CIF_MI_BASE + 0x00000088)
+#define RKISP1_CIF_MI_MP_CB_SIZE_SHD           (RKISP1_CIF_MI_BASE + 0x0000008C)
+#define RKISP1_CIF_MI_MP_CB_OFFS_CNT_SHD       (RKISP1_CIF_MI_BASE + 0x00000090)
+#define RKISP1_CIF_MI_MP_CR_BASE_AD_SHD                (RKISP1_CIF_MI_BASE + 0x00000094)
+#define RKISP1_CIF_MI_MP_CR_SIZE_SHD           (RKISP1_CIF_MI_BASE + 0x00000098)
+#define RKISP1_CIF_MI_MP_CR_OFFS_CNT_SHD       (RKISP1_CIF_MI_BASE + 0x0000009C)
+#define RKISP1_CIF_MI_SP_Y_BASE_AD_SHD         (RKISP1_CIF_MI_BASE + 0x000000A0)
+#define RKISP1_CIF_MI_SP_Y_SIZE_SHD            (RKISP1_CIF_MI_BASE + 0x000000A4)
+#define RKISP1_CIF_MI_SP_Y_OFFS_CNT_SHD                (RKISP1_CIF_MI_BASE + 0x000000A8)
+#define RKISP1_CIF_MI_SP_CB_BASE_AD_SHD                (RKISP1_CIF_MI_BASE + 0x000000B0)
+#define RKISP1_CIF_MI_SP_CB_SIZE_SHD           (RKISP1_CIF_MI_BASE + 0x000000B4)
+#define RKISP1_CIF_MI_SP_CB_OFFS_CNT_SHD       (RKISP1_CIF_MI_BASE + 0x000000B8)
+#define RKISP1_CIF_MI_SP_CR_BASE_AD_SHD                (RKISP1_CIF_MI_BASE + 0x000000BC)
+#define RKISP1_CIF_MI_SP_CR_SIZE_SHD           (RKISP1_CIF_MI_BASE + 0x000000C0)
+#define RKISP1_CIF_MI_SP_CR_OFFS_CNT_SHD       (RKISP1_CIF_MI_BASE + 0x000000C4)
+#define RKISP1_CIF_MI_DMA_Y_PIC_START_AD       (RKISP1_CIF_MI_BASE + 0x000000C8)
+#define RKISP1_CIF_MI_DMA_Y_PIC_WIDTH          (RKISP1_CIF_MI_BASE + 0x000000CC)
+#define RKISP1_CIF_MI_DMA_Y_LLENGTH            (RKISP1_CIF_MI_BASE + 0x000000D0)
+#define RKISP1_CIF_MI_DMA_Y_PIC_SIZE           (RKISP1_CIF_MI_BASE + 0x000000D4)
+#define RKISP1_CIF_MI_DMA_CB_PIC_START_AD      (RKISP1_CIF_MI_BASE + 0x000000D8)
+#define RKISP1_CIF_MI_DMA_CR_PIC_START_AD      (RKISP1_CIF_MI_BASE + 0x000000E8)
+#define RKISP1_CIF_MI_IMSC                     (RKISP1_CIF_MI_BASE + 0x000000F8)
+#define RKISP1_CIF_MI_RIS                      (RKISP1_CIF_MI_BASE + 0x000000FC)
+#define RKISP1_CIF_MI_MIS                      (RKISP1_CIF_MI_BASE + 0x00000100)
+#define RKISP1_CIF_MI_ICR                      (RKISP1_CIF_MI_BASE + 0x00000104)
+#define RKISP1_CIF_MI_ISR                      (RKISP1_CIF_MI_BASE + 0x00000108)
+#define RKISP1_CIF_MI_STATUS                   (RKISP1_CIF_MI_BASE + 0x0000010C)
+#define RKISP1_CIF_MI_STATUS_CLR               (RKISP1_CIF_MI_BASE + 0x00000110)
+#define RKISP1_CIF_MI_SP_Y_PIC_WIDTH           (RKISP1_CIF_MI_BASE + 0x00000114)
+#define RKISP1_CIF_MI_SP_Y_PIC_HEIGHT          (RKISP1_CIF_MI_BASE + 0x00000118)
+#define RKISP1_CIF_MI_SP_Y_PIC_SIZE            (RKISP1_CIF_MI_BASE + 0x0000011C)
+#define RKISP1_CIF_MI_DMA_CTRL                 (RKISP1_CIF_MI_BASE + 0x00000120)
+#define RKISP1_CIF_MI_DMA_START                        (RKISP1_CIF_MI_BASE + 0x00000124)
+#define RKISP1_CIF_MI_DMA_STATUS               (RKISP1_CIF_MI_BASE + 0x00000128)
+#define RKISP1_CIF_MI_PIXEL_COUNT              (RKISP1_CIF_MI_BASE + 0x0000012C)
+#define RKISP1_CIF_MI_MP_Y_BASE_AD_INIT2       (RKISP1_CIF_MI_BASE + 0x00000130)
+#define RKISP1_CIF_MI_MP_CB_BASE_AD_INIT2      (RKISP1_CIF_MI_BASE + 0x00000134)
+#define RKISP1_CIF_MI_MP_CR_BASE_AD_INIT2      (RKISP1_CIF_MI_BASE + 0x00000138)
+#define RKISP1_CIF_MI_SP_Y_BASE_AD_INIT2       (RKISP1_CIF_MI_BASE + 0x0000013C)
+#define RKISP1_CIF_MI_SP_CB_BASE_AD_INIT2      (RKISP1_CIF_MI_BASE + 0x00000140)
+#define RKISP1_CIF_MI_SP_CR_BASE_AD_INIT2      (RKISP1_CIF_MI_BASE + 0x00000144)
+#define RKISP1_CIF_MI_XTD_FORMAT_CTRL          (RKISP1_CIF_MI_BASE + 0x00000148)
+
+#define RKISP1_CIF_SMIA_BASE                   0x00001A00
+#define RKISP1_CIF_SMIA_CTRL                   (RKISP1_CIF_SMIA_BASE + 0x00000000)
+#define RKISP1_CIF_SMIA_STATUS                 (RKISP1_CIF_SMIA_BASE + 0x00000004)
+#define RKISP1_CIF_SMIA_IMSC                   (RKISP1_CIF_SMIA_BASE + 0x00000008)
+#define RKISP1_CIF_SMIA_RIS                    (RKISP1_CIF_SMIA_BASE + 0x0000000C)
+#define RKISP1_CIF_SMIA_MIS                    (RKISP1_CIF_SMIA_BASE + 0x00000010)
+#define RKISP1_CIF_SMIA_ICR                    (RKISP1_CIF_SMIA_BASE + 0x00000014)
+#define RKISP1_CIF_SMIA_ISR                    (RKISP1_CIF_SMIA_BASE + 0x00000018)
+#define RKISP1_CIF_SMIA_DATA_FORMAT_SEL                (RKISP1_CIF_SMIA_BASE + 0x0000001C)
+#define RKISP1_CIF_SMIA_SOF_EMB_DATA_LINES     (RKISP1_CIF_SMIA_BASE + 0x00000020)
+#define RKISP1_CIF_SMIA_EMB_HSTART             (RKISP1_CIF_SMIA_BASE + 0x00000024)
+#define RKISP1_CIF_SMIA_EMB_HSIZE              (RKISP1_CIF_SMIA_BASE + 0x00000028)
+#define RKISP1_CIF_SMIA_EMB_VSTART             (RKISP1_CIF_SMIA_BASE + 0x0000002c)
+#define RKISP1_CIF_SMIA_NUM_LINES              (RKISP1_CIF_SMIA_BASE + 0x00000030)
+#define RKISP1_CIF_SMIA_EMB_DATA_FIFO          (RKISP1_CIF_SMIA_BASE + 0x00000034)
+#define RKISP1_CIF_SMIA_EMB_DATA_WATERMARK     (RKISP1_CIF_SMIA_BASE + 0x00000038)
+
+#define RKISP1_CIF_MIPI_BASE                   0x00001C00
+#define RKISP1_CIF_MIPI_CTRL                   (RKISP1_CIF_MIPI_BASE + 0x00000000)
+#define RKISP1_CIF_MIPI_STATUS                 (RKISP1_CIF_MIPI_BASE + 0x00000004)
+#define RKISP1_CIF_MIPI_IMSC                   (RKISP1_CIF_MIPI_BASE + 0x00000008)
+#define RKISP1_CIF_MIPI_RIS                    (RKISP1_CIF_MIPI_BASE + 0x0000000C)
+#define RKISP1_CIF_MIPI_MIS                    (RKISP1_CIF_MIPI_BASE + 0x00000010)
+#define RKISP1_CIF_MIPI_ICR                    (RKISP1_CIF_MIPI_BASE + 0x00000014)
+#define RKISP1_CIF_MIPI_ISR                    (RKISP1_CIF_MIPI_BASE + 0x00000018)
+#define RKISP1_CIF_MIPI_CUR_DATA_ID            (RKISP1_CIF_MIPI_BASE + 0x0000001C)
+#define RKISP1_CIF_MIPI_IMG_DATA_SEL           (RKISP1_CIF_MIPI_BASE + 0x00000020)
+#define RKISP1_CIF_MIPI_ADD_DATA_SEL_1         (RKISP1_CIF_MIPI_BASE + 0x00000024)
+#define RKISP1_CIF_MIPI_ADD_DATA_SEL_2         (RKISP1_CIF_MIPI_BASE + 0x00000028)
+#define RKISP1_CIF_MIPI_ADD_DATA_SEL_3         (RKISP1_CIF_MIPI_BASE + 0x0000002C)
+#define RKISP1_CIF_MIPI_ADD_DATA_SEL_4         (RKISP1_CIF_MIPI_BASE + 0x00000030)
+#define RKISP1_CIF_MIPI_ADD_DATA_FIFO          (RKISP1_CIF_MIPI_BASE + 0x00000034)
+#define RKISP1_CIF_MIPI_FIFO_FILL_LEVEL                (RKISP1_CIF_MIPI_BASE + 0x00000038)
+#define RKISP1_CIF_MIPI_COMPRESSED_MODE                (RKISP1_CIF_MIPI_BASE + 0x0000003C)
+#define RKISP1_CIF_MIPI_FRAME                  (RKISP1_CIF_MIPI_BASE + 0x00000040)
+#define RKISP1_CIF_MIPI_GEN_SHORT_DT           (RKISP1_CIF_MIPI_BASE + 0x00000044)
+#define RKISP1_CIF_MIPI_GEN_SHORT_8_9          (RKISP1_CIF_MIPI_BASE + 0x00000048)
+#define RKISP1_CIF_MIPI_GEN_SHORT_A_B          (RKISP1_CIF_MIPI_BASE + 0x0000004C)
+#define RKISP1_CIF_MIPI_GEN_SHORT_C_D          (RKISP1_CIF_MIPI_BASE + 0x00000050)
+#define RKISP1_CIF_MIPI_GEN_SHORT_E_F          (RKISP1_CIF_MIPI_BASE + 0x00000054)
+
+#define RKISP1_CIF_ISP_AFM_BASE                        0x00002000
+#define RKISP1_CIF_ISP_AFM_CTRL                        (RKISP1_CIF_ISP_AFM_BASE + 0x00000000)
+#define RKISP1_CIF_ISP_AFM_LT_A                        (RKISP1_CIF_ISP_AFM_BASE + 0x00000004)
+#define RKISP1_CIF_ISP_AFM_RB_A                        (RKISP1_CIF_ISP_AFM_BASE + 0x00000008)
+#define RKISP1_CIF_ISP_AFM_LT_B                        (RKISP1_CIF_ISP_AFM_BASE + 0x0000000C)
+#define RKISP1_CIF_ISP_AFM_RB_B                        (RKISP1_CIF_ISP_AFM_BASE + 0x00000010)
+#define RKISP1_CIF_ISP_AFM_LT_C                        (RKISP1_CIF_ISP_AFM_BASE + 0x00000014)
+#define RKISP1_CIF_ISP_AFM_RB_C                        (RKISP1_CIF_ISP_AFM_BASE + 0x00000018)
+#define RKISP1_CIF_ISP_AFM_THRES               (RKISP1_CIF_ISP_AFM_BASE + 0x0000001C)
+#define RKISP1_CIF_ISP_AFM_VAR_SHIFT           (RKISP1_CIF_ISP_AFM_BASE + 0x00000020)
+#define RKISP1_CIF_ISP_AFM_SUM_A               (RKISP1_CIF_ISP_AFM_BASE + 0x00000024)
+#define RKISP1_CIF_ISP_AFM_SUM_B               (RKISP1_CIF_ISP_AFM_BASE + 0x00000028)
+#define RKISP1_CIF_ISP_AFM_SUM_C               (RKISP1_CIF_ISP_AFM_BASE + 0x0000002C)
+#define RKISP1_CIF_ISP_AFM_LUM_A               (RKISP1_CIF_ISP_AFM_BASE + 0x00000030)
+#define RKISP1_CIF_ISP_AFM_LUM_B               (RKISP1_CIF_ISP_AFM_BASE + 0x00000034)
+#define RKISP1_CIF_ISP_AFM_LUM_C               (RKISP1_CIF_ISP_AFM_BASE + 0x00000038)
+
+#define RKISP1_CIF_ISP_LSC_BASE                        0x00002200
+#define RKISP1_CIF_ISP_LSC_CTRL                        (RKISP1_CIF_ISP_LSC_BASE + 0x00000000)
+#define RKISP1_CIF_ISP_LSC_R_TABLE_ADDR                (RKISP1_CIF_ISP_LSC_BASE + 0x00000004)
+#define RKISP1_CIF_ISP_LSC_GR_TABLE_ADDR       (RKISP1_CIF_ISP_LSC_BASE + 0x00000008)
+#define RKISP1_CIF_ISP_LSC_B_TABLE_ADDR                (RKISP1_CIF_ISP_LSC_BASE + 0x0000000C)
+#define RKISP1_CIF_ISP_LSC_GB_TABLE_ADDR       (RKISP1_CIF_ISP_LSC_BASE + 0x00000010)
+#define RKISP1_CIF_ISP_LSC_R_TABLE_DATA                (RKISP1_CIF_ISP_LSC_BASE + 0x00000014)
+#define RKISP1_CIF_ISP_LSC_GR_TABLE_DATA       (RKISP1_CIF_ISP_LSC_BASE + 0x00000018)
+#define RKISP1_CIF_ISP_LSC_B_TABLE_DATA                (RKISP1_CIF_ISP_LSC_BASE + 0x0000001C)
+#define RKISP1_CIF_ISP_LSC_GB_TABLE_DATA       (RKISP1_CIF_ISP_LSC_BASE + 0x00000020)
+#define RKISP1_CIF_ISP_LSC_XGRAD_01            (RKISP1_CIF_ISP_LSC_BASE + 0x00000024)
+#define RKISP1_CIF_ISP_LSC_XGRAD_23            (RKISP1_CIF_ISP_LSC_BASE + 0x00000028)
+#define RKISP1_CIF_ISP_LSC_XGRAD_45            (RKISP1_CIF_ISP_LSC_BASE + 0x0000002C)
+#define RKISP1_CIF_ISP_LSC_XGRAD_67            (RKISP1_CIF_ISP_LSC_BASE + 0x00000030)
+#define RKISP1_CIF_ISP_LSC_YGRAD_01            (RKISP1_CIF_ISP_LSC_BASE + 0x00000034)
+#define RKISP1_CIF_ISP_LSC_YGRAD_23            (RKISP1_CIF_ISP_LSC_BASE + 0x00000038)
+#define RKISP1_CIF_ISP_LSC_YGRAD_45            (RKISP1_CIF_ISP_LSC_BASE + 0x0000003C)
+#define RKISP1_CIF_ISP_LSC_YGRAD_67            (RKISP1_CIF_ISP_LSC_BASE + 0x00000040)
+#define RKISP1_CIF_ISP_LSC_XSIZE_01            (RKISP1_CIF_ISP_LSC_BASE + 0x00000044)
+#define RKISP1_CIF_ISP_LSC_XSIZE_23            (RKISP1_CIF_ISP_LSC_BASE + 0x00000048)
+#define RKISP1_CIF_ISP_LSC_XSIZE_45            (RKISP1_CIF_ISP_LSC_BASE + 0x0000004C)
+#define RKISP1_CIF_ISP_LSC_XSIZE_67            (RKISP1_CIF_ISP_LSC_BASE + 0x00000050)
+#define RKISP1_CIF_ISP_LSC_YSIZE_01            (RKISP1_CIF_ISP_LSC_BASE + 0x00000054)
+#define RKISP1_CIF_ISP_LSC_YSIZE_23            (RKISP1_CIF_ISP_LSC_BASE + 0x00000058)
+#define RKISP1_CIF_ISP_LSC_YSIZE_45            (RKISP1_CIF_ISP_LSC_BASE + 0x0000005C)
+#define RKISP1_CIF_ISP_LSC_YSIZE_67            (RKISP1_CIF_ISP_LSC_BASE + 0x00000060)
+#define RKISP1_CIF_ISP_LSC_TABLE_SEL           (RKISP1_CIF_ISP_LSC_BASE + 0x00000064)
+#define RKISP1_CIF_ISP_LSC_STATUS              (RKISP1_CIF_ISP_LSC_BASE + 0x00000068)
+
+#define RKISP1_CIF_ISP_IS_BASE                 0x00002300
+#define RKISP1_CIF_ISP_IS_CTRL                 (RKISP1_CIF_ISP_IS_BASE + 0x00000000)
+#define RKISP1_CIF_ISP_IS_RECENTER             (RKISP1_CIF_ISP_IS_BASE + 0x00000004)
+#define RKISP1_CIF_ISP_IS_H_OFFS               (RKISP1_CIF_ISP_IS_BASE + 0x00000008)
+#define RKISP1_CIF_ISP_IS_V_OFFS               (RKISP1_CIF_ISP_IS_BASE + 0x0000000C)
+#define RKISP1_CIF_ISP_IS_H_SIZE               (RKISP1_CIF_ISP_IS_BASE + 0x00000010)
+#define RKISP1_CIF_ISP_IS_V_SIZE               (RKISP1_CIF_ISP_IS_BASE + 0x00000014)
+#define RKISP1_CIF_ISP_IS_MAX_DX               (RKISP1_CIF_ISP_IS_BASE + 0x00000018)
+#define RKISP1_CIF_ISP_IS_MAX_DY               (RKISP1_CIF_ISP_IS_BASE + 0x0000001C)
+#define RKISP1_CIF_ISP_IS_DISPLACE             (RKISP1_CIF_ISP_IS_BASE + 0x00000020)
+#define RKISP1_CIF_ISP_IS_H_OFFS_SHD           (RKISP1_CIF_ISP_IS_BASE + 0x00000024)
+#define RKISP1_CIF_ISP_IS_V_OFFS_SHD           (RKISP1_CIF_ISP_IS_BASE + 0x00000028)
+#define RKISP1_CIF_ISP_IS_H_SIZE_SHD           (RKISP1_CIF_ISP_IS_BASE + 0x0000002C)
+#define RKISP1_CIF_ISP_IS_V_SIZE_SHD           (RKISP1_CIF_ISP_IS_BASE + 0x00000030)
+
+#define RKISP1_CIF_ISP_HIST_BASE               0x00002400
+
+#define RKISP1_CIF_ISP_HIST_PROP               (RKISP1_CIF_ISP_HIST_BASE + 0x00000000)
+#define RKISP1_CIF_ISP_HIST_H_OFFS             (RKISP1_CIF_ISP_HIST_BASE + 0x00000004)
+#define RKISP1_CIF_ISP_HIST_V_OFFS             (RKISP1_CIF_ISP_HIST_BASE + 0x00000008)
+#define RKISP1_CIF_ISP_HIST_H_SIZE             (RKISP1_CIF_ISP_HIST_BASE + 0x0000000C)
+#define RKISP1_CIF_ISP_HIST_V_SIZE             (RKISP1_CIF_ISP_HIST_BASE + 0x00000010)
+#define RKISP1_CIF_ISP_HIST_BIN_0              (RKISP1_CIF_ISP_HIST_BASE + 0x00000014)
+#define RKISP1_CIF_ISP_HIST_BIN_1              (RKISP1_CIF_ISP_HIST_BASE + 0x00000018)
+#define RKISP1_CIF_ISP_HIST_BIN_2              (RKISP1_CIF_ISP_HIST_BASE + 0x0000001C)
+#define RKISP1_CIF_ISP_HIST_BIN_3              (RKISP1_CIF_ISP_HIST_BASE + 0x00000020)
+#define RKISP1_CIF_ISP_HIST_BIN_4              (RKISP1_CIF_ISP_HIST_BASE + 0x00000024)
+#define RKISP1_CIF_ISP_HIST_BIN_5              (RKISP1_CIF_ISP_HIST_BASE + 0x00000028)
+#define RKISP1_CIF_ISP_HIST_BIN_6              (RKISP1_CIF_ISP_HIST_BASE + 0x0000002C)
+#define RKISP1_CIF_ISP_HIST_BIN_7              (RKISP1_CIF_ISP_HIST_BASE + 0x00000030)
+#define RKISP1_CIF_ISP_HIST_BIN_8              (RKISP1_CIF_ISP_HIST_BASE + 0x00000034)
+#define RKISP1_CIF_ISP_HIST_BIN_9              (RKISP1_CIF_ISP_HIST_BASE + 0x00000038)
+#define RKISP1_CIF_ISP_HIST_BIN_10             (RKISP1_CIF_ISP_HIST_BASE + 0x0000003C)
+#define RKISP1_CIF_ISP_HIST_BIN_11             (RKISP1_CIF_ISP_HIST_BASE + 0x00000040)
+#define RKISP1_CIF_ISP_HIST_BIN_12             (RKISP1_CIF_ISP_HIST_BASE + 0x00000044)
+#define RKISP1_CIF_ISP_HIST_BIN_13             (RKISP1_CIF_ISP_HIST_BASE + 0x00000048)
+#define RKISP1_CIF_ISP_HIST_BIN_14             (RKISP1_CIF_ISP_HIST_BASE + 0x0000004C)
+#define RKISP1_CIF_ISP_HIST_BIN_15             (RKISP1_CIF_ISP_HIST_BASE + 0x00000050)
+#define RKISP1_CIF_ISP_HIST_WEIGHT_00TO30      (RKISP1_CIF_ISP_HIST_BASE + 0x00000054)
+#define RKISP1_CIF_ISP_HIST_WEIGHT_40TO21      (RKISP1_CIF_ISP_HIST_BASE + 0x00000058)
+#define RKISP1_CIF_ISP_HIST_WEIGHT_31TO12      (RKISP1_CIF_ISP_HIST_BASE + 0x0000005C)
+#define RKISP1_CIF_ISP_HIST_WEIGHT_22TO03      (RKISP1_CIF_ISP_HIST_BASE + 0x00000060)
+#define RKISP1_CIF_ISP_HIST_WEIGHT_13TO43      (RKISP1_CIF_ISP_HIST_BASE + 0x00000064)
+#define RKISP1_CIF_ISP_HIST_WEIGHT_04TO34      (RKISP1_CIF_ISP_HIST_BASE + 0x00000068)
+#define RKISP1_CIF_ISP_HIST_WEIGHT_44          (RKISP1_CIF_ISP_HIST_BASE + 0x0000006C)
+
+#define RKISP1_CIF_ISP_FILT_BASE               0x00002500
+#define RKISP1_CIF_ISP_FILT_MODE               (RKISP1_CIF_ISP_FILT_BASE + 0x00000000)
+#define RKISP1_CIF_ISP_FILT_THRESH_BL0         (RKISP1_CIF_ISP_FILT_BASE + 0x00000028)
+#define RKISP1_CIF_ISP_FILT_THRESH_BL1         (RKISP1_CIF_ISP_FILT_BASE + 0x0000002c)
+#define RKISP1_CIF_ISP_FILT_THRESH_SH0         (RKISP1_CIF_ISP_FILT_BASE + 0x00000030)
+#define RKISP1_CIF_ISP_FILT_THRESH_SH1         (RKISP1_CIF_ISP_FILT_BASE + 0x00000034)
+#define RKISP1_CIF_ISP_FILT_LUM_WEIGHT         (RKISP1_CIF_ISP_FILT_BASE + 0x00000038)
+#define RKISP1_CIF_ISP_FILT_FAC_SH1            (RKISP1_CIF_ISP_FILT_BASE + 0x0000003c)
+#define RKISP1_CIF_ISP_FILT_FAC_SH0            (RKISP1_CIF_ISP_FILT_BASE + 0x00000040)
+#define RKISP1_CIF_ISP_FILT_FAC_MID            (RKISP1_CIF_ISP_FILT_BASE + 0x00000044)
+#define RKISP1_CIF_ISP_FILT_FAC_BL0            (RKISP1_CIF_ISP_FILT_BASE + 0x00000048)
+#define RKISP1_CIF_ISP_FILT_FAC_BL1            (RKISP1_CIF_ISP_FILT_BASE + 0x0000004C)
+
+#define RKISP1_CIF_ISP_CAC_BASE                        0x00002580
+#define RKISP1_CIF_ISP_CAC_CTRL                        (RKISP1_CIF_ISP_CAC_BASE + 0x00000000)
+#define RKISP1_CIF_ISP_CAC_COUNT_START         (RKISP1_CIF_ISP_CAC_BASE + 0x00000004)
+#define RKISP1_CIF_ISP_CAC_A                   (RKISP1_CIF_ISP_CAC_BASE + 0x00000008)
+#define RKISP1_CIF_ISP_CAC_B                   (RKISP1_CIF_ISP_CAC_BASE + 0x0000000C)
+#define RKISP1_CIF_ISP_CAC_C                   (RKISP1_CIF_ISP_CAC_BASE + 0x00000010)
+#define RKISP1_CIF_ISP_X_NORM                  (RKISP1_CIF_ISP_CAC_BASE + 0x00000014)
+#define RKISP1_CIF_ISP_Y_NORM                  (RKISP1_CIF_ISP_CAC_BASE + 0x00000018)
+
+#define RKISP1_CIF_ISP_EXP_BASE                        0x00002600
+#define RKISP1_CIF_ISP_EXP_CTRL                        (RKISP1_CIF_ISP_EXP_BASE + 0x00000000)
+#define RKISP1_CIF_ISP_EXP_H_OFFSET            (RKISP1_CIF_ISP_EXP_BASE + 0x00000004)
+#define RKISP1_CIF_ISP_EXP_V_OFFSET            (RKISP1_CIF_ISP_EXP_BASE + 0x00000008)
+#define RKISP1_CIF_ISP_EXP_H_SIZE              (RKISP1_CIF_ISP_EXP_BASE + 0x0000000C)
+#define RKISP1_CIF_ISP_EXP_V_SIZE              (RKISP1_CIF_ISP_EXP_BASE + 0x00000010)
+#define RKISP1_CIF_ISP_EXP_MEAN_00             (RKISP1_CIF_ISP_EXP_BASE + 0x00000014)
+#define RKISP1_CIF_ISP_EXP_MEAN_10             (RKISP1_CIF_ISP_EXP_BASE + 0x00000018)
+#define RKISP1_CIF_ISP_EXP_MEAN_20             (RKISP1_CIF_ISP_EXP_BASE + 0x0000001c)
+#define RKISP1_CIF_ISP_EXP_MEAN_30             (RKISP1_CIF_ISP_EXP_BASE + 0x00000020)
+#define RKISP1_CIF_ISP_EXP_MEAN_40             (RKISP1_CIF_ISP_EXP_BASE + 0x00000024)
+#define RKISP1_CIF_ISP_EXP_MEAN_01             (RKISP1_CIF_ISP_EXP_BASE + 0x00000028)
+#define RKISP1_CIF_ISP_EXP_MEAN_11             (RKISP1_CIF_ISP_EXP_BASE + 0x0000002c)
+#define RKISP1_CIF_ISP_EXP_MEAN_21             (RKISP1_CIF_ISP_EXP_BASE + 0x00000030)
+#define RKISP1_CIF_ISP_EXP_MEAN_31             (RKISP1_CIF_ISP_EXP_BASE + 0x00000034)
+#define RKISP1_CIF_ISP_EXP_MEAN_41             (RKISP1_CIF_ISP_EXP_BASE + 0x00000038)
+#define RKISP1_CIF_ISP_EXP_MEAN_02             (RKISP1_CIF_ISP_EXP_BASE + 0x0000003c)
+#define RKISP1_CIF_ISP_EXP_MEAN_12             (RKISP1_CIF_ISP_EXP_BASE + 0x00000040)
+#define RKISP1_CIF_ISP_EXP_MEAN_22             (RKISP1_CIF_ISP_EXP_BASE + 0x00000044)
+#define RKISP1_CIF_ISP_EXP_MEAN_32             (RKISP1_CIF_ISP_EXP_BASE + 0x00000048)
+#define RKISP1_CIF_ISP_EXP_MEAN_42             (RKISP1_CIF_ISP_EXP_BASE + 0x0000004c)
+#define RKISP1_CIF_ISP_EXP_MEAN_03             (RKISP1_CIF_ISP_EXP_BASE + 0x00000050)
+#define RKISP1_CIF_ISP_EXP_MEAN_13             (RKISP1_CIF_ISP_EXP_BASE + 0x00000054)
+#define RKISP1_CIF_ISP_EXP_MEAN_23             (RKISP1_CIF_ISP_EXP_BASE + 0x00000058)
+#define RKISP1_CIF_ISP_EXP_MEAN_33             (RKISP1_CIF_ISP_EXP_BASE + 0x0000005c)
+#define RKISP1_CIF_ISP_EXP_MEAN_43             (RKISP1_CIF_ISP_EXP_BASE + 0x00000060)
+#define RKISP1_CIF_ISP_EXP_MEAN_04             (RKISP1_CIF_ISP_EXP_BASE + 0x00000064)
+#define RKISP1_CIF_ISP_EXP_MEAN_14             (RKISP1_CIF_ISP_EXP_BASE + 0x00000068)
+#define RKISP1_CIF_ISP_EXP_MEAN_24             (RKISP1_CIF_ISP_EXP_BASE + 0x0000006c)
+#define RKISP1_CIF_ISP_EXP_MEAN_34             (RKISP1_CIF_ISP_EXP_BASE + 0x00000070)
+#define RKISP1_CIF_ISP_EXP_MEAN_44             (RKISP1_CIF_ISP_EXP_BASE + 0x00000074)
+
+#define RKISP1_CIF_ISP_BLS_BASE                        0x00002700
+#define RKISP1_CIF_ISP_BLS_CTRL                        (RKISP1_CIF_ISP_BLS_BASE + 0x00000000)
+#define RKISP1_CIF_ISP_BLS_SAMPLES             (RKISP1_CIF_ISP_BLS_BASE + 0x00000004)
+#define RKISP1_CIF_ISP_BLS_H1_START            (RKISP1_CIF_ISP_BLS_BASE + 0x00000008)
+#define RKISP1_CIF_ISP_BLS_H1_STOP             (RKISP1_CIF_ISP_BLS_BASE + 0x0000000c)
+#define RKISP1_CIF_ISP_BLS_V1_START            (RKISP1_CIF_ISP_BLS_BASE + 0x00000010)
+#define RKISP1_CIF_ISP_BLS_V1_STOP             (RKISP1_CIF_ISP_BLS_BASE + 0x00000014)
+#define RKISP1_CIF_ISP_BLS_H2_START            (RKISP1_CIF_ISP_BLS_BASE + 0x00000018)
+#define RKISP1_CIF_ISP_BLS_H2_STOP             (RKISP1_CIF_ISP_BLS_BASE + 0x0000001c)
+#define RKISP1_CIF_ISP_BLS_V2_START            (RKISP1_CIF_ISP_BLS_BASE + 0x00000020)
+#define RKISP1_CIF_ISP_BLS_V2_STOP             (RKISP1_CIF_ISP_BLS_BASE + 0x00000024)
+#define RKISP1_CIF_ISP_BLS_A_FIXED             (RKISP1_CIF_ISP_BLS_BASE + 0x00000028)
+#define RKISP1_CIF_ISP_BLS_B_FIXED             (RKISP1_CIF_ISP_BLS_BASE + 0x0000002c)
+#define RKISP1_CIF_ISP_BLS_C_FIXED             (RKISP1_CIF_ISP_BLS_BASE + 0x00000030)
+#define RKISP1_CIF_ISP_BLS_D_FIXED             (RKISP1_CIF_ISP_BLS_BASE + 0x00000034)
+#define RKISP1_CIF_ISP_BLS_A_MEASURED          (RKISP1_CIF_ISP_BLS_BASE + 0x00000038)
+#define RKISP1_CIF_ISP_BLS_B_MEASURED          (RKISP1_CIF_ISP_BLS_BASE + 0x0000003c)
+#define RKISP1_CIF_ISP_BLS_C_MEASURED          (RKISP1_CIF_ISP_BLS_BASE + 0x00000040)
+#define RKISP1_CIF_ISP_BLS_D_MEASURED          (RKISP1_CIF_ISP_BLS_BASE + 0x00000044)
+
+#define RKISP1_CIF_ISP_DPF_BASE                        0x00002800
+#define RKISP1_CIF_ISP_DPF_MODE                        (RKISP1_CIF_ISP_DPF_BASE + 0x00000000)
+#define RKISP1_CIF_ISP_DPF_STRENGTH_R          (RKISP1_CIF_ISP_DPF_BASE + 0x00000004)
+#define RKISP1_CIF_ISP_DPF_STRENGTH_G          (RKISP1_CIF_ISP_DPF_BASE + 0x00000008)
+#define RKISP1_CIF_ISP_DPF_STRENGTH_B          (RKISP1_CIF_ISP_DPF_BASE + 0x0000000C)
+#define RKISP1_CIF_ISP_DPF_S_WEIGHT_G_1_4      (RKISP1_CIF_ISP_DPF_BASE + 0x00000010)
+#define RKISP1_CIF_ISP_DPF_S_WEIGHT_G_5_6      (RKISP1_CIF_ISP_DPF_BASE + 0x00000014)
+#define RKISP1_CIF_ISP_DPF_S_WEIGHT_RB_1_4     (RKISP1_CIF_ISP_DPF_BASE + 0x00000018)
+#define RKISP1_CIF_ISP_DPF_S_WEIGHT_RB_5_6     (RKISP1_CIF_ISP_DPF_BASE + 0x0000001C)
+#define RKISP1_CIF_ISP_DPF_NULL_COEFF_0                (RKISP1_CIF_ISP_DPF_BASE + 0x00000020)
+#define RKISP1_CIF_ISP_DPF_NULL_COEFF_1                (RKISP1_CIF_ISP_DPF_BASE + 0x00000024)
+#define RKISP1_CIF_ISP_DPF_NULL_COEFF_2                (RKISP1_CIF_ISP_DPF_BASE + 0x00000028)
+#define RKISP1_CIF_ISP_DPF_NULL_COEFF_3                (RKISP1_CIF_ISP_DPF_BASE + 0x0000002C)
+#define RKISP1_CIF_ISP_DPF_NULL_COEFF_4                (RKISP1_CIF_ISP_DPF_BASE + 0x00000030)
+#define RKISP1_CIF_ISP_DPF_NULL_COEFF_5                (RKISP1_CIF_ISP_DPF_BASE + 0x00000034)
+#define RKISP1_CIF_ISP_DPF_NULL_COEFF_6                (RKISP1_CIF_ISP_DPF_BASE + 0x00000038)
+#define RKISP1_CIF_ISP_DPF_NULL_COEFF_7                (RKISP1_CIF_ISP_DPF_BASE + 0x0000003C)
+#define RKISP1_CIF_ISP_DPF_NULL_COEFF_8                (RKISP1_CIF_ISP_DPF_BASE + 0x00000040)
+#define RKISP1_CIF_ISP_DPF_NULL_COEFF_9                (RKISP1_CIF_ISP_DPF_BASE + 0x00000044)
+#define RKISP1_CIF_ISP_DPF_NULL_COEFF_10       (RKISP1_CIF_ISP_DPF_BASE + 0x00000048)
+#define RKISP1_CIF_ISP_DPF_NULL_COEFF_11       (RKISP1_CIF_ISP_DPF_BASE + 0x0000004C)
+#define RKISP1_CIF_ISP_DPF_NULL_COEFF_12       (RKISP1_CIF_ISP_DPF_BASE + 0x00000050)
+#define RKISP1_CIF_ISP_DPF_NULL_COEFF_13       (RKISP1_CIF_ISP_DPF_BASE + 0x00000054)
+#define RKISP1_CIF_ISP_DPF_NULL_COEFF_14       (RKISP1_CIF_ISP_DPF_BASE + 0x00000058)
+#define RKISP1_CIF_ISP_DPF_NULL_COEFF_15       (RKISP1_CIF_ISP_DPF_BASE + 0x0000005C)
+#define RKISP1_CIF_ISP_DPF_NULL_COEFF_16       (RKISP1_CIF_ISP_DPF_BASE + 0x00000060)
+#define RKISP1_CIF_ISP_DPF_NF_GAIN_R           (RKISP1_CIF_ISP_DPF_BASE + 0x00000064)
+#define RKISP1_CIF_ISP_DPF_NF_GAIN_GR          (RKISP1_CIF_ISP_DPF_BASE + 0x00000068)
+#define RKISP1_CIF_ISP_DPF_NF_GAIN_GB          (RKISP1_CIF_ISP_DPF_BASE + 0x0000006C)
+#define RKISP1_CIF_ISP_DPF_NF_GAIN_B           (RKISP1_CIF_ISP_DPF_BASE + 0x00000070)
+
+#define RKISP1_CIF_ISP_DPCC_BASE               0x00002900
+#define RKISP1_CIF_ISP_DPCC_MODE               (RKISP1_CIF_ISP_DPCC_BASE + 0x00000000)
+#define RKISP1_CIF_ISP_DPCC_OUTPUT_MODE                (RKISP1_CIF_ISP_DPCC_BASE + 0x00000004)
+#define RKISP1_CIF_ISP_DPCC_SET_USE            (RKISP1_CIF_ISP_DPCC_BASE + 0x00000008)
+#define RKISP1_CIF_ISP_DPCC_METHODS_SET_1      (RKISP1_CIF_ISP_DPCC_BASE + 0x0000000C)
+#define RKISP1_CIF_ISP_DPCC_METHODS_SET_2      (RKISP1_CIF_ISP_DPCC_BASE + 0x00000010)
+#define RKISP1_CIF_ISP_DPCC_METHODS_SET_3      (RKISP1_CIF_ISP_DPCC_BASE + 0x00000014)
+#define RKISP1_CIF_ISP_DPCC_LINE_THRESH_1      (RKISP1_CIF_ISP_DPCC_BASE + 0x00000018)
+#define RKISP1_CIF_ISP_DPCC_LINE_MAD_FAC_1     (RKISP1_CIF_ISP_DPCC_BASE + 0x0000001C)
+#define RKISP1_CIF_ISP_DPCC_PG_FAC_1           (RKISP1_CIF_ISP_DPCC_BASE + 0x00000020)
+#define RKISP1_CIF_ISP_DPCC_RND_THRESH_1       (RKISP1_CIF_ISP_DPCC_BASE + 0x00000024)
+#define RKISP1_CIF_ISP_DPCC_RG_FAC_1           (RKISP1_CIF_ISP_DPCC_BASE + 0x00000028)
+#define RKISP1_CIF_ISP_DPCC_LINE_THRESH_2      (RKISP1_CIF_ISP_DPCC_BASE + 0x0000002C)
+#define RKISP1_CIF_ISP_DPCC_LINE_MAD_FAC_2     (RKISP1_CIF_ISP_DPCC_BASE + 0x00000030)
+#define RKISP1_CIF_ISP_DPCC_PG_FAC_2           (RKISP1_CIF_ISP_DPCC_BASE + 0x00000034)
+#define RKISP1_CIF_ISP_DPCC_RND_THRESH_2       (RKISP1_CIF_ISP_DPCC_BASE + 0x00000038)
+#define RKISP1_CIF_ISP_DPCC_RG_FAC_2           (RKISP1_CIF_ISP_DPCC_BASE + 0x0000003C)
+#define RKISP1_CIF_ISP_DPCC_LINE_THRESH_3      (RKISP1_CIF_ISP_DPCC_BASE + 0x00000040)
+#define RKISP1_CIF_ISP_DPCC_LINE_MAD_FAC_3     (RKISP1_CIF_ISP_DPCC_BASE + 0x00000044)
+#define RKISP1_CIF_ISP_DPCC_PG_FAC_3           (RKISP1_CIF_ISP_DPCC_BASE + 0x00000048)
+#define RKISP1_CIF_ISP_DPCC_RND_THRESH_3       (RKISP1_CIF_ISP_DPCC_BASE + 0x0000004C)
+#define RKISP1_CIF_ISP_DPCC_RG_FAC_3           (RKISP1_CIF_ISP_DPCC_BASE + 0x00000050)
+#define RKISP1_CIF_ISP_DPCC_RO_LIMITS          (RKISP1_CIF_ISP_DPCC_BASE + 0x00000054)
+#define RKISP1_CIF_ISP_DPCC_RND_OFFS           (RKISP1_CIF_ISP_DPCC_BASE + 0x00000058)
+#define RKISP1_CIF_ISP_DPCC_BPT_CTRL           (RKISP1_CIF_ISP_DPCC_BASE + 0x0000005C)
+#define RKISP1_CIF_ISP_DPCC_BPT_NUMBER         (RKISP1_CIF_ISP_DPCC_BASE + 0x00000060)
+#define RKISP1_CIF_ISP_DPCC_BPT_ADDR           (RKISP1_CIF_ISP_DPCC_BASE + 0x00000064)
+#define RKISP1_CIF_ISP_DPCC_BPT_DATA           (RKISP1_CIF_ISP_DPCC_BASE + 0x00000068)
+
+#define RKISP1_CIF_ISP_WDR_BASE                        0x00002A00
+#define RKISP1_CIF_ISP_WDR_CTRL                        (RKISP1_CIF_ISP_WDR_BASE + 0x00000000)
+#define RKISP1_CIF_ISP_WDR_TONECURVE_1         (RKISP1_CIF_ISP_WDR_BASE + 0x00000004)
+#define RKISP1_CIF_ISP_WDR_TONECURVE_2         (RKISP1_CIF_ISP_WDR_BASE + 0x00000008)
+#define RKISP1_CIF_ISP_WDR_TONECURVE_3         (RKISP1_CIF_ISP_WDR_BASE + 0x0000000C)
+#define RKISP1_CIF_ISP_WDR_TONECURVE_4         (RKISP1_CIF_ISP_WDR_BASE + 0x00000010)
+#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_0      (RKISP1_CIF_ISP_WDR_BASE + 0x00000014)
+#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_1      (RKISP1_CIF_ISP_WDR_BASE + 0x00000018)
+#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_2      (RKISP1_CIF_ISP_WDR_BASE + 0x0000001C)
+#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_3      (RKISP1_CIF_ISP_WDR_BASE + 0x00000020)
+#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_4      (RKISP1_CIF_ISP_WDR_BASE + 0x00000024)
+#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_5      (RKISP1_CIF_ISP_WDR_BASE + 0x00000028)
+#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_6      (RKISP1_CIF_ISP_WDR_BASE + 0x0000002C)
+#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_7      (RKISP1_CIF_ISP_WDR_BASE + 0x00000030)
+#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_8      (RKISP1_CIF_ISP_WDR_BASE + 0x00000034)
+#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_9      (RKISP1_CIF_ISP_WDR_BASE + 0x00000038)
+#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_10     (RKISP1_CIF_ISP_WDR_BASE + 0x0000003C)
+#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_11     (RKISP1_CIF_ISP_WDR_BASE + 0x00000040)
+#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_12     (RKISP1_CIF_ISP_WDR_BASE + 0x00000044)
+#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_13     (RKISP1_CIF_ISP_WDR_BASE + 0x00000048)
+#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_14     (RKISP1_CIF_ISP_WDR_BASE + 0x0000004C)
+#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_15     (RKISP1_CIF_ISP_WDR_BASE + 0x00000050)
+#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_16     (RKISP1_CIF_ISP_WDR_BASE + 0x00000054)
+#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_17     (RKISP1_CIF_ISP_WDR_BASE + 0x00000058)
+#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_18     (RKISP1_CIF_ISP_WDR_BASE + 0x0000005C)
+#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_19     (RKISP1_CIF_ISP_WDR_BASE + 0x00000060)
+#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_20     (RKISP1_CIF_ISP_WDR_BASE + 0x00000064)
+#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_21     (RKISP1_CIF_ISP_WDR_BASE + 0x00000068)
+#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_22     (RKISP1_CIF_ISP_WDR_BASE + 0x0000006C)
+#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_23     (RKISP1_CIF_ISP_WDR_BASE + 0x00000070)
+#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_24     (RKISP1_CIF_ISP_WDR_BASE + 0x00000074)
+#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_25     (RKISP1_CIF_ISP_WDR_BASE + 0x00000078)
+#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_26     (RKISP1_CIF_ISP_WDR_BASE + 0x0000007C)
+#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_27     (RKISP1_CIF_ISP_WDR_BASE + 0x00000080)
+#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_28     (RKISP1_CIF_ISP_WDR_BASE + 0x00000084)
+#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_29     (RKISP1_CIF_ISP_WDR_BASE + 0x00000088)
+#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_30     (RKISP1_CIF_ISP_WDR_BASE + 0x0000008C)
+#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_31     (RKISP1_CIF_ISP_WDR_BASE + 0x00000090)
+#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_32     (RKISP1_CIF_ISP_WDR_BASE + 0x00000094)
+#define RKISP1_CIF_ISP_WDR_OFFSET              (RKISP1_CIF_ISP_WDR_BASE + 0x00000098)
+#define RKISP1_CIF_ISP_WDR_DELTAMIN            (RKISP1_CIF_ISP_WDR_BASE + 0x0000009C)
+#define RKISP1_CIF_ISP_WDR_TONECURVE_1_SHD     (RKISP1_CIF_ISP_WDR_BASE + 0x000000A0)
+#define RKISP1_CIF_ISP_WDR_TONECURVE_2_SHD     (RKISP1_CIF_ISP_WDR_BASE + 0x000000A4)
+#define RKISP1_CIF_ISP_WDR_TONECURVE_3_SHD     (RKISP1_CIF_ISP_WDR_BASE + 0x000000A8)
+#define RKISP1_CIF_ISP_WDR_TONECURVE_4_SHD     (RKISP1_CIF_ISP_WDR_BASE + 0x000000AC)
+#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_0_SHD  (RKISP1_CIF_ISP_WDR_BASE + 0x000000B0)
+#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_1_SHD  (RKISP1_CIF_ISP_WDR_BASE + 0x000000B4)
+#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_2_SHD  (RKISP1_CIF_ISP_WDR_BASE + 0x000000B8)
+#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_3_SHD  (RKISP1_CIF_ISP_WDR_BASE + 0x000000BC)
+#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_4_SHD  (RKISP1_CIF_ISP_WDR_BASE + 0x000000C0)
+#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_5_SHD  (RKISP1_CIF_ISP_WDR_BASE + 0x000000C4)
+#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_6_SHD  (RKISP1_CIF_ISP_WDR_BASE + 0x000000C8)
+#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_7_SHD  (RKISP1_CIF_ISP_WDR_BASE + 0x000000CC)
+#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_8_SHD  (RKISP1_CIF_ISP_WDR_BASE + 0x000000D0)
+#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_9_SHD  (RKISP1_CIF_ISP_WDR_BASE + 0x000000D4)
+#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_10_SHD (RKISP1_CIF_ISP_WDR_BASE + 0x000000D8)
+#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_11_SHD (RKISP1_CIF_ISP_WDR_BASE + 0x000000DC)
+#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_12_SHD (RKISP1_CIF_ISP_WDR_BASE + 0x000000E0)
+#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_13_SHD (RKISP1_CIF_ISP_WDR_BASE + 0x000000E4)
+#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_14_SHD (RKISP1_CIF_ISP_WDR_BASE + 0x000000E8)
+#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_15_SHD (RKISP1_CIF_ISP_WDR_BASE + 0x000000EC)
+#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_16_SHD (RKISP1_CIF_ISP_WDR_BASE + 0x000000F0)
+#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_17_SHD (RKISP1_CIF_ISP_WDR_BASE + 0x000000F4)
+#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_18_SHD (RKISP1_CIF_ISP_WDR_BASE + 0x000000F8)
+#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_19_SHD (RKISP1_CIF_ISP_WDR_BASE + 0x000000FC)
+#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_20_SHD (RKISP1_CIF_ISP_WDR_BASE + 0x00000100)
+#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_21_SHD (RKISP1_CIF_ISP_WDR_BASE + 0x00000104)
+#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_22_SHD (RKISP1_CIF_ISP_WDR_BASE + 0x00000108)
+#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_23_SHD (RKISP1_CIF_ISP_WDR_BASE + 0x0000010C)
+#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_24_SHD (RKISP1_CIF_ISP_WDR_BASE + 0x00000110)
+#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_25_SHD (RKISP1_CIF_ISP_WDR_BASE + 0x00000114)
+#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_26_SHD (RKISP1_CIF_ISP_WDR_BASE + 0x00000118)
+#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_27_SHD (RKISP1_CIF_ISP_WDR_BASE + 0x0000011C)
+#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_28_SHD (RKISP1_CIF_ISP_WDR_BASE + 0x00000120)
+#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_29_SHD (RKISP1_CIF_ISP_WDR_BASE + 0x00000124)
+#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_30_SHD (RKISP1_CIF_ISP_WDR_BASE + 0x00000128)
+#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_31_SHD (RKISP1_CIF_ISP_WDR_BASE + 0x0000012C)
+#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_32_SHD (RKISP1_CIF_ISP_WDR_BASE + 0x00000130)
+
+#define RKISP1_CIF_ISP_VSM_BASE                        0x00002F00
+#define RKISP1_CIF_ISP_VSM_MODE                        (RKISP1_CIF_ISP_VSM_BASE + 0x00000000)
+#define RKISP1_CIF_ISP_VSM_H_OFFS              (RKISP1_CIF_ISP_VSM_BASE + 0x00000004)
+#define RKISP1_CIF_ISP_VSM_V_OFFS              (RKISP1_CIF_ISP_VSM_BASE + 0x00000008)
+#define RKISP1_CIF_ISP_VSM_H_SIZE              (RKISP1_CIF_ISP_VSM_BASE + 0x0000000C)
+#define RKISP1_CIF_ISP_VSM_V_SIZE              (RKISP1_CIF_ISP_VSM_BASE + 0x00000010)
+#define RKISP1_CIF_ISP_VSM_H_SEGMENTS          (RKISP1_CIF_ISP_VSM_BASE + 0x00000014)
+#define RKISP1_CIF_ISP_VSM_V_SEGMENTS          (RKISP1_CIF_ISP_VSM_BASE + 0x00000018)
+#define RKISP1_CIF_ISP_VSM_DELTA_H             (RKISP1_CIF_ISP_VSM_BASE + 0x0000001C)
+#define RKISP1_CIF_ISP_VSM_DELTA_V             (RKISP1_CIF_ISP_VSM_BASE + 0x00000020)
+
+#endif /* _RKISP1_REGS_H */
diff --git a/drivers/media/platform/rockchip/rkisp1/rkisp1-resizer.c b/drivers/media/platform/rockchip/rkisp1/rkisp1-resizer.c
new file mode 100644 (file)
index 0000000..813670e
--- /dev/null
@@ -0,0 +1,846 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Rockchip ISP1 Driver - V4l resizer device
+ *
+ * Copyright (C) 2019 Collabora, Ltd.
+ *
+ * Based on Rockchip ISP1 driver by Rockchip Electronics Co., Ltd.
+ * Copyright (C) 2017 Rockchip Electronics Co., Ltd.
+ */
+
+#include "rkisp1-common.h"
+
+#define RKISP1_RSZ_SP_DEV_NAME RKISP1_DRIVER_NAME "_resizer_selfpath"
+#define RKISP1_RSZ_MP_DEV_NAME RKISP1_DRIVER_NAME "_resizer_mainpath"
+
+#define RKISP1_DEF_FMT MEDIA_BUS_FMT_YUYV8_2X8
+#define RKISP1_DEF_PIXEL_ENC V4L2_PIXEL_ENC_YUV
+
+struct rkisp1_rsz_yuv_mbus_info {
+       u32 mbus_code;
+       u32 hdiv;
+       u32 vdiv;
+};
+
+static const struct rkisp1_rsz_yuv_mbus_info rkisp1_rsz_yuv_src_formats[] = {
+       {
+               .mbus_code      = MEDIA_BUS_FMT_YUYV8_2X8, /* YUV422 */
+               .hdiv           = 2,
+               .vdiv           = 1,
+       },
+       {
+               .mbus_code      = MEDIA_BUS_FMT_YUYV8_1_5X8, /* YUV420 */
+               .hdiv           = 2,
+               .vdiv           = 2,
+       },
+};
+
+static const struct rkisp1_rsz_yuv_mbus_info *rkisp1_rsz_get_yuv_mbus_info(u32 mbus_code)
+{
+       unsigned int i;
+
+       for (i = 0; i < ARRAY_SIZE(rkisp1_rsz_yuv_src_formats); i++) {
+               if (rkisp1_rsz_yuv_src_formats[i].mbus_code == mbus_code)
+                       return &rkisp1_rsz_yuv_src_formats[i];
+       }
+
+       return NULL;
+}
+
+enum rkisp1_shadow_regs_when {
+       RKISP1_SHADOW_REGS_SYNC,
+       RKISP1_SHADOW_REGS_ASYNC,
+};
+
+struct rkisp1_rsz_config {
+       /* constrains */
+       const int max_rsz_width;
+       const int max_rsz_height;
+       const int min_rsz_width;
+       const int min_rsz_height;
+       /* registers */
+       struct {
+               u32 ctrl;
+               u32 ctrl_shd;
+               u32 scale_hy;
+               u32 scale_hcr;
+               u32 scale_hcb;
+               u32 scale_vy;
+               u32 scale_vc;
+               u32 scale_lut;
+               u32 scale_lut_addr;
+               u32 scale_hy_shd;
+               u32 scale_hcr_shd;
+               u32 scale_hcb_shd;
+               u32 scale_vy_shd;
+               u32 scale_vc_shd;
+               u32 phase_hy;
+               u32 phase_hc;
+               u32 phase_vy;
+               u32 phase_vc;
+               u32 phase_hy_shd;
+               u32 phase_hc_shd;
+               u32 phase_vy_shd;
+               u32 phase_vc_shd;
+       } rsz;
+       struct {
+               u32 ctrl;
+               u32 yuvmode_mask;
+               u32 rawmode_mask;
+               u32 h_offset;
+               u32 v_offset;
+               u32 h_size;
+               u32 v_size;
+       } dual_crop;
+};
+
+static const struct rkisp1_rsz_config rkisp1_rsz_config_mp = {
+       /* constraints */
+       .max_rsz_width = RKISP1_RSZ_MP_SRC_MAX_WIDTH,
+       .max_rsz_height = RKISP1_RSZ_MP_SRC_MAX_HEIGHT,
+       .min_rsz_width = RKISP1_RSZ_SRC_MIN_WIDTH,
+       .min_rsz_height = RKISP1_RSZ_SRC_MIN_HEIGHT,
+       /* registers */
+       .rsz = {
+               .ctrl =                 RKISP1_CIF_MRSZ_CTRL,
+               .scale_hy =             RKISP1_CIF_MRSZ_SCALE_HY,
+               .scale_hcr =            RKISP1_CIF_MRSZ_SCALE_HCR,
+               .scale_hcb =            RKISP1_CIF_MRSZ_SCALE_HCB,
+               .scale_vy =             RKISP1_CIF_MRSZ_SCALE_VY,
+               .scale_vc =             RKISP1_CIF_MRSZ_SCALE_VC,
+               .scale_lut =            RKISP1_CIF_MRSZ_SCALE_LUT,
+               .scale_lut_addr =       RKISP1_CIF_MRSZ_SCALE_LUT_ADDR,
+               .scale_hy_shd =         RKISP1_CIF_MRSZ_SCALE_HY_SHD,
+               .scale_hcr_shd =        RKISP1_CIF_MRSZ_SCALE_HCR_SHD,
+               .scale_hcb_shd =        RKISP1_CIF_MRSZ_SCALE_HCB_SHD,
+               .scale_vy_shd =         RKISP1_CIF_MRSZ_SCALE_VY_SHD,
+               .scale_vc_shd =         RKISP1_CIF_MRSZ_SCALE_VC_SHD,
+               .phase_hy =             RKISP1_CIF_MRSZ_PHASE_HY,
+               .phase_hc =             RKISP1_CIF_MRSZ_PHASE_HC,
+               .phase_vy =             RKISP1_CIF_MRSZ_PHASE_VY,
+               .phase_vc =             RKISP1_CIF_MRSZ_PHASE_VC,
+               .ctrl_shd =             RKISP1_CIF_MRSZ_CTRL_SHD,
+               .phase_hy_shd =         RKISP1_CIF_MRSZ_PHASE_HY_SHD,
+               .phase_hc_shd =         RKISP1_CIF_MRSZ_PHASE_HC_SHD,
+               .phase_vy_shd =         RKISP1_CIF_MRSZ_PHASE_VY_SHD,
+               .phase_vc_shd =         RKISP1_CIF_MRSZ_PHASE_VC_SHD,
+       },
+       .dual_crop = {
+               .ctrl =                 RKISP1_CIF_DUAL_CROP_CTRL,
+               .yuvmode_mask =         RKISP1_CIF_DUAL_CROP_MP_MODE_YUV,
+               .rawmode_mask =         RKISP1_CIF_DUAL_CROP_MP_MODE_RAW,
+               .h_offset =             RKISP1_CIF_DUAL_CROP_M_H_OFFS,
+               .v_offset =             RKISP1_CIF_DUAL_CROP_M_V_OFFS,
+               .h_size =               RKISP1_CIF_DUAL_CROP_M_H_SIZE,
+               .v_size =               RKISP1_CIF_DUAL_CROP_M_V_SIZE,
+       },
+};
+
+static const struct rkisp1_rsz_config rkisp1_rsz_config_sp = {
+       /* constraints */
+       .max_rsz_width = RKISP1_RSZ_SP_SRC_MAX_WIDTH,
+       .max_rsz_height = RKISP1_RSZ_SP_SRC_MAX_HEIGHT,
+       .min_rsz_width = RKISP1_RSZ_SRC_MIN_WIDTH,
+       .min_rsz_height = RKISP1_RSZ_SRC_MIN_HEIGHT,
+       /* registers */
+       .rsz = {
+               .ctrl =                 RKISP1_CIF_SRSZ_CTRL,
+               .scale_hy =             RKISP1_CIF_SRSZ_SCALE_HY,
+               .scale_hcr =            RKISP1_CIF_SRSZ_SCALE_HCR,
+               .scale_hcb =            RKISP1_CIF_SRSZ_SCALE_HCB,
+               .scale_vy =             RKISP1_CIF_SRSZ_SCALE_VY,
+               .scale_vc =             RKISP1_CIF_SRSZ_SCALE_VC,
+               .scale_lut =            RKISP1_CIF_SRSZ_SCALE_LUT,
+               .scale_lut_addr =       RKISP1_CIF_SRSZ_SCALE_LUT_ADDR,
+               .scale_hy_shd =         RKISP1_CIF_SRSZ_SCALE_HY_SHD,
+               .scale_hcr_shd =        RKISP1_CIF_SRSZ_SCALE_HCR_SHD,
+               .scale_hcb_shd =        RKISP1_CIF_SRSZ_SCALE_HCB_SHD,
+               .scale_vy_shd =         RKISP1_CIF_SRSZ_SCALE_VY_SHD,
+               .scale_vc_shd =         RKISP1_CIF_SRSZ_SCALE_VC_SHD,
+               .phase_hy =             RKISP1_CIF_SRSZ_PHASE_HY,
+               .phase_hc =             RKISP1_CIF_SRSZ_PHASE_HC,
+               .phase_vy =             RKISP1_CIF_SRSZ_PHASE_VY,
+               .phase_vc =             RKISP1_CIF_SRSZ_PHASE_VC,
+               .ctrl_shd =             RKISP1_CIF_SRSZ_CTRL_SHD,
+               .phase_hy_shd =         RKISP1_CIF_SRSZ_PHASE_HY_SHD,
+               .phase_hc_shd =         RKISP1_CIF_SRSZ_PHASE_HC_SHD,
+               .phase_vy_shd =         RKISP1_CIF_SRSZ_PHASE_VY_SHD,
+               .phase_vc_shd =         RKISP1_CIF_SRSZ_PHASE_VC_SHD,
+       },
+       .dual_crop = {
+               .ctrl =                 RKISP1_CIF_DUAL_CROP_CTRL,
+               .yuvmode_mask =         RKISP1_CIF_DUAL_CROP_SP_MODE_YUV,
+               .rawmode_mask =         RKISP1_CIF_DUAL_CROP_SP_MODE_RAW,
+               .h_offset =             RKISP1_CIF_DUAL_CROP_S_H_OFFS,
+               .v_offset =             RKISP1_CIF_DUAL_CROP_S_V_OFFS,
+               .h_size =               RKISP1_CIF_DUAL_CROP_S_H_SIZE,
+               .v_size =               RKISP1_CIF_DUAL_CROP_S_V_SIZE,
+       },
+};
+
+static struct v4l2_mbus_framefmt *
+rkisp1_rsz_get_pad_fmt(struct rkisp1_resizer *rsz,
+                      struct v4l2_subdev_pad_config *cfg,
+                      unsigned int pad, u32 which)
+{
+       if (which == V4L2_SUBDEV_FORMAT_TRY)
+               return v4l2_subdev_get_try_format(&rsz->sd, cfg, pad);
+       else
+               return v4l2_subdev_get_try_format(&rsz->sd, rsz->pad_cfg, pad);
+}
+
+static struct v4l2_rect *
+rkisp1_rsz_get_pad_crop(struct rkisp1_resizer *rsz,
+                       struct v4l2_subdev_pad_config *cfg,
+                       unsigned int pad, u32 which)
+{
+       if (which == V4L2_SUBDEV_FORMAT_TRY)
+               return v4l2_subdev_get_try_crop(&rsz->sd, cfg, pad);
+       else
+               return v4l2_subdev_get_try_crop(&rsz->sd, rsz->pad_cfg, pad);
+}
+
+/* ----------------------------------------------------------------------------
+ * Dual crop hw configs
+ */
+
+static void rkisp1_dcrop_disable(struct rkisp1_resizer *rsz,
+                                enum rkisp1_shadow_regs_when when)
+{
+       u32 dc_ctrl = rkisp1_read(rsz->rkisp1, rsz->config->dual_crop.ctrl);
+       u32 mask = ~(rsz->config->dual_crop.yuvmode_mask |
+                    rsz->config->dual_crop.rawmode_mask);
+
+       dc_ctrl &= mask;
+       if (when == RKISP1_SHADOW_REGS_ASYNC)
+               dc_ctrl |= RKISP1_CIF_DUAL_CROP_GEN_CFG_UPD;
+       else
+               dc_ctrl |= RKISP1_CIF_DUAL_CROP_CFG_UPD;
+       rkisp1_write(rsz->rkisp1, dc_ctrl, rsz->config->dual_crop.ctrl);
+}
+
+/* configure dual-crop unit */
+static void rkisp1_dcrop_config(struct rkisp1_resizer *rsz)
+{
+       struct rkisp1_device *rkisp1 = rsz->rkisp1;
+       struct v4l2_mbus_framefmt *sink_fmt;
+       struct v4l2_rect *sink_crop;
+       u32 dc_ctrl;
+
+       sink_crop = rkisp1_rsz_get_pad_crop(rsz, NULL, RKISP1_RSZ_PAD_SINK,
+                                           V4L2_SUBDEV_FORMAT_ACTIVE);
+       sink_fmt = rkisp1_rsz_get_pad_fmt(rsz, NULL, RKISP1_RSZ_PAD_SINK,
+                                         V4L2_SUBDEV_FORMAT_ACTIVE);
+
+       if (sink_crop->width == sink_fmt->width &&
+           sink_crop->height == sink_fmt->height &&
+           sink_crop->left == 0 && sink_crop->top == 0) {
+               rkisp1_dcrop_disable(rsz, RKISP1_SHADOW_REGS_SYNC);
+               dev_dbg(rkisp1->dev, "capture %d crop disabled\n", rsz->id);
+               return;
+       }
+
+       dc_ctrl = rkisp1_read(rkisp1, rsz->config->dual_crop.ctrl);
+       rkisp1_write(rkisp1, sink_crop->left, rsz->config->dual_crop.h_offset);
+       rkisp1_write(rkisp1, sink_crop->top, rsz->config->dual_crop.v_offset);
+       rkisp1_write(rkisp1, sink_crop->width, rsz->config->dual_crop.h_size);
+       rkisp1_write(rkisp1, sink_crop->height, rsz->config->dual_crop.v_size);
+       dc_ctrl |= rsz->config->dual_crop.yuvmode_mask;
+       dc_ctrl |= RKISP1_CIF_DUAL_CROP_CFG_UPD;
+       rkisp1_write(rkisp1, dc_ctrl, rsz->config->dual_crop.ctrl);
+
+       dev_dbg(rkisp1->dev, "stream %d crop: %dx%d -> %dx%d\n", rsz->id,
+               sink_fmt->width, sink_fmt->height,
+               sink_crop->width, sink_crop->height);
+}
+
+/* ----------------------------------------------------------------------------
+ * Resizer hw configs
+ */
+
+static void rkisp1_rsz_dump_regs(struct rkisp1_resizer *rsz)
+{
+       dev_dbg(rsz->rkisp1->dev,
+               "RSZ_CTRL 0x%08x/0x%08x\n"
+               "RSZ_SCALE_HY %d/%d\n"
+               "RSZ_SCALE_HCB %d/%d\n"
+               "RSZ_SCALE_HCR %d/%d\n"
+               "RSZ_SCALE_VY %d/%d\n"
+               "RSZ_SCALE_VC %d/%d\n"
+               "RSZ_PHASE_HY %d/%d\n"
+               "RSZ_PHASE_HC %d/%d\n"
+               "RSZ_PHASE_VY %d/%d\n"
+               "RSZ_PHASE_VC %d/%d\n",
+               rkisp1_read(rsz->rkisp1, rsz->config->rsz.ctrl),
+               rkisp1_read(rsz->rkisp1, rsz->config->rsz.ctrl_shd),
+               rkisp1_read(rsz->rkisp1, rsz->config->rsz.scale_hy),
+               rkisp1_read(rsz->rkisp1, rsz->config->rsz.scale_hy_shd),
+               rkisp1_read(rsz->rkisp1, rsz->config->rsz.scale_hcb),
+               rkisp1_read(rsz->rkisp1, rsz->config->rsz.scale_hcb_shd),
+               rkisp1_read(rsz->rkisp1, rsz->config->rsz.scale_hcr),
+               rkisp1_read(rsz->rkisp1, rsz->config->rsz.scale_hcr_shd),
+               rkisp1_read(rsz->rkisp1, rsz->config->rsz.scale_vy),
+               rkisp1_read(rsz->rkisp1, rsz->config->rsz.scale_vy_shd),
+               rkisp1_read(rsz->rkisp1, rsz->config->rsz.scale_vc),
+               rkisp1_read(rsz->rkisp1, rsz->config->rsz.scale_vc_shd),
+               rkisp1_read(rsz->rkisp1, rsz->config->rsz.phase_hy),
+               rkisp1_read(rsz->rkisp1, rsz->config->rsz.phase_hy_shd),
+               rkisp1_read(rsz->rkisp1, rsz->config->rsz.phase_hc),
+               rkisp1_read(rsz->rkisp1, rsz->config->rsz.phase_hc_shd),
+               rkisp1_read(rsz->rkisp1, rsz->config->rsz.phase_vy),
+               rkisp1_read(rsz->rkisp1, rsz->config->rsz.phase_vy_shd),
+               rkisp1_read(rsz->rkisp1, rsz->config->rsz.phase_vc),
+               rkisp1_read(rsz->rkisp1, rsz->config->rsz.phase_vc_shd));
+}
+
+static void rkisp1_rsz_update_shadow(struct rkisp1_resizer *rsz,
+                                    enum rkisp1_shadow_regs_when when)
+{
+       u32 ctrl_cfg = rkisp1_read(rsz->rkisp1, rsz->config->rsz.ctrl);
+
+       if (when == RKISP1_SHADOW_REGS_ASYNC)
+               ctrl_cfg |= RKISP1_CIF_RSZ_CTRL_CFG_UPD_AUTO;
+       else
+               ctrl_cfg |= RKISP1_CIF_RSZ_CTRL_CFG_UPD;
+
+       rkisp1_write(rsz->rkisp1, ctrl_cfg, rsz->config->rsz.ctrl);
+}
+
+static u32 rkisp1_rsz_calc_ratio(u32 len_sink, u32 len_src)
+{
+       if (len_sink < len_src)
+               return ((len_sink - 1) * RKISP1_CIF_RSZ_SCALER_FACTOR) /
+                      (len_src - 1);
+
+       return ((len_src - 1) * RKISP1_CIF_RSZ_SCALER_FACTOR) /
+              (len_sink - 1) + 1;
+}
+
+static void rkisp1_rsz_disable(struct rkisp1_resizer *rsz,
+                              enum rkisp1_shadow_regs_when when)
+{
+       rkisp1_write(rsz->rkisp1, 0, rsz->config->rsz.ctrl);
+
+       if (when == RKISP1_SHADOW_REGS_SYNC)
+               rkisp1_rsz_update_shadow(rsz, when);
+}
+
+static void rkisp1_rsz_config_regs(struct rkisp1_resizer *rsz,
+                                  struct v4l2_rect *sink_y,
+                                  struct v4l2_rect *sink_c,
+                                  struct v4l2_rect *src_y,
+                                  struct v4l2_rect *src_c,
+                                  enum rkisp1_shadow_regs_when when)
+{
+       struct rkisp1_device *rkisp1 = rsz->rkisp1;
+       u32 ratio, rsz_ctrl = 0;
+       unsigned int i;
+
+       /* No phase offset */
+       rkisp1_write(rkisp1, 0, rsz->config->rsz.phase_hy);
+       rkisp1_write(rkisp1, 0, rsz->config->rsz.phase_hc);
+       rkisp1_write(rkisp1, 0, rsz->config->rsz.phase_vy);
+       rkisp1_write(rkisp1, 0, rsz->config->rsz.phase_vc);
+
+       /* Linear interpolation */
+       for (i = 0; i < 64; i++) {
+               rkisp1_write(rkisp1, i, rsz->config->rsz.scale_lut_addr);
+               rkisp1_write(rkisp1, i, rsz->config->rsz.scale_lut);
+       }
+
+       if (sink_y->width != src_y->width) {
+               rsz_ctrl |= RKISP1_CIF_RSZ_CTRL_SCALE_HY_ENABLE;
+               if (sink_y->width < src_y->width)
+                       rsz_ctrl |= RKISP1_CIF_RSZ_CTRL_SCALE_HY_UP;
+               ratio = rkisp1_rsz_calc_ratio(sink_y->width, src_y->width);
+               rkisp1_write(rkisp1, ratio, rsz->config->rsz.scale_hy);
+       }
+
+       if (sink_c->width != src_c->width) {
+               rsz_ctrl |= RKISP1_CIF_RSZ_CTRL_SCALE_HC_ENABLE;
+               if (sink_c->width < src_c->width)
+                       rsz_ctrl |= RKISP1_CIF_RSZ_CTRL_SCALE_HC_UP;
+               ratio = rkisp1_rsz_calc_ratio(sink_c->width, src_c->width);
+               rkisp1_write(rkisp1, ratio, rsz->config->rsz.scale_hcb);
+               rkisp1_write(rkisp1, ratio, rsz->config->rsz.scale_hcr);
+       }
+
+       if (sink_y->height != src_y->height) {
+               rsz_ctrl |= RKISP1_CIF_RSZ_CTRL_SCALE_VY_ENABLE;
+               if (sink_y->height < src_y->height)
+                       rsz_ctrl |= RKISP1_CIF_RSZ_CTRL_SCALE_VY_UP;
+               ratio = rkisp1_rsz_calc_ratio(sink_y->height, src_y->height);
+               rkisp1_write(rkisp1, ratio, rsz->config->rsz.scale_vy);
+       }
+
+       if (sink_c->height != src_c->height) {
+               rsz_ctrl |= RKISP1_CIF_RSZ_CTRL_SCALE_VC_ENABLE;
+               if (sink_c->height < src_c->height)
+                       rsz_ctrl |= RKISP1_CIF_RSZ_CTRL_SCALE_VC_UP;
+               ratio = rkisp1_rsz_calc_ratio(sink_c->height, src_c->height);
+               rkisp1_write(rkisp1, ratio, rsz->config->rsz.scale_vc);
+       }
+
+       rkisp1_write(rkisp1, rsz_ctrl, rsz->config->rsz.ctrl);
+
+       rkisp1_rsz_update_shadow(rsz, when);
+}
+
+static void rkisp1_rsz_config(struct rkisp1_resizer *rsz,
+                             enum rkisp1_shadow_regs_when when)
+{
+       const struct rkisp1_rsz_yuv_mbus_info *sink_yuv_info, *src_yuv_info;
+       struct v4l2_rect sink_y, sink_c, src_y, src_c;
+       struct v4l2_mbus_framefmt *src_fmt, *sink_fmt;
+       struct v4l2_rect *sink_crop;
+
+       sink_crop = rkisp1_rsz_get_pad_crop(rsz, NULL, RKISP1_RSZ_PAD_SINK,
+                                           V4L2_SUBDEV_FORMAT_ACTIVE);
+       src_fmt = rkisp1_rsz_get_pad_fmt(rsz, NULL, RKISP1_RSZ_PAD_SRC,
+                                        V4L2_SUBDEV_FORMAT_ACTIVE);
+       src_yuv_info = rkisp1_rsz_get_yuv_mbus_info(src_fmt->code);
+       sink_fmt = rkisp1_rsz_get_pad_fmt(rsz, NULL, RKISP1_RSZ_PAD_SINK,
+                                         V4L2_SUBDEV_FORMAT_ACTIVE);
+       sink_yuv_info = rkisp1_rsz_get_yuv_mbus_info(sink_fmt->code);
+
+       /*
+        * The resizer only works on yuv formats,
+        * so return if it is bayer format.
+        */
+       if (rsz->pixel_enc == V4L2_PIXEL_ENC_BAYER) {
+               rkisp1_rsz_disable(rsz, when);
+               return;
+       }
+
+       sink_y.width = sink_crop->width;
+       sink_y.height = sink_crop->height;
+       src_y.width = src_fmt->width;
+       src_y.height = src_fmt->height;
+
+       sink_c.width = sink_y.width / sink_yuv_info->hdiv;
+       sink_c.height = sink_y.height / sink_yuv_info->vdiv;
+
+       /*
+        * The resizer is used not only to change the dimensions of the frame
+        * but also to change the scale for YUV formats,
+        * (4:2:2 -> 4:2:0 for example). So the width/height of the CbCr
+        * streams should be set according to the media bus format in the src pad.
+        */
+       src_c.width = src_y.width / src_yuv_info->hdiv;
+       src_c.height = src_y.height / src_yuv_info->vdiv;
+
+       if (sink_c.width == src_c.width && sink_c.height == src_c.height) {
+               rkisp1_rsz_disable(rsz, when);
+               return;
+       }
+
+       dev_dbg(rsz->rkisp1->dev, "stream %d rsz/scale: %dx%d -> %dx%d\n",
+               rsz->id, sink_crop->width, sink_crop->height,
+               src_fmt->width, src_fmt->height);
+       dev_dbg(rsz->rkisp1->dev, "chroma scaling %dx%d -> %dx%d\n",
+               sink_c.width, sink_c.height, src_c.width, src_c.height);
+
+       /* set values in the hw */
+       rkisp1_rsz_config_regs(rsz, &sink_y, &sink_c, &src_y, &src_c, when);
+
+       rkisp1_rsz_dump_regs(rsz);
+}
+
+/* ----------------------------------------------------------------------------
+ * Subdev pad operations
+ */
+
+static int rkisp1_rsz_enum_mbus_code(struct v4l2_subdev *sd,
+                                    struct v4l2_subdev_pad_config *cfg,
+                                    struct v4l2_subdev_mbus_code_enum *code)
+{
+       struct rkisp1_resizer *rsz =
+               container_of(sd, struct rkisp1_resizer, sd);
+       struct v4l2_subdev_pad_config dummy_cfg;
+       u32 pad = code->pad;
+       int ret;
+
+       if (code->pad == RKISP1_RSZ_PAD_SRC) {
+               /* supported mbus codes on the src are the same as in the capture */
+               struct rkisp1_capture *cap = &rsz->rkisp1->capture_devs[rsz->id];
+
+               return rkisp1_cap_enum_mbus_codes(cap, code);
+       }
+
+       /*
+        * The selfpath capture doesn't support bayer formats. Therefore the selfpath resizer
+        * should support only YUV422 on the sink pad
+        */
+       if (rsz->id == RKISP1_SELFPATH) {
+               if (code->index > 0)
+                       return -EINVAL;
+               code->code = MEDIA_BUS_FMT_YUYV8_2X8;
+               return 0;
+       }
+
+       /* supported mbus codes on the sink pad are the same as isp src pad */
+       code->pad = RKISP1_ISP_PAD_SOURCE_VIDEO;
+       ret = v4l2_subdev_call(&rsz->rkisp1->isp.sd, pad, enum_mbus_code,
+                              &dummy_cfg, code);
+
+       /* restore pad */
+       code->pad = pad;
+       code->flags = 0;
+       return ret;
+}
+
+static int rkisp1_rsz_init_config(struct v4l2_subdev *sd,
+                                 struct v4l2_subdev_pad_config *cfg)
+{
+       struct v4l2_mbus_framefmt *sink_fmt, *src_fmt;
+       struct v4l2_rect *sink_crop;
+
+       sink_fmt = v4l2_subdev_get_try_format(sd, cfg, RKISP1_RSZ_PAD_SRC);
+       sink_fmt->width = RKISP1_DEFAULT_WIDTH;
+       sink_fmt->height = RKISP1_DEFAULT_HEIGHT;
+       sink_fmt->field = V4L2_FIELD_NONE;
+       sink_fmt->code = RKISP1_DEF_FMT;
+
+       sink_crop = v4l2_subdev_get_try_crop(sd, cfg, RKISP1_RSZ_PAD_SINK);
+       sink_crop->width = RKISP1_DEFAULT_WIDTH;
+       sink_crop->height = RKISP1_DEFAULT_HEIGHT;
+       sink_crop->left = 0;
+       sink_crop->top = 0;
+
+       src_fmt = v4l2_subdev_get_try_format(sd, cfg, RKISP1_RSZ_PAD_SINK);
+       *src_fmt = *sink_fmt;
+
+       /* NOTE: there is no crop in the source pad, only in the sink */
+
+       return 0;
+}
+
+static void rkisp1_rsz_set_src_fmt(struct rkisp1_resizer *rsz,
+                                  struct v4l2_subdev_pad_config *cfg,
+                                  struct v4l2_mbus_framefmt *format,
+                                  unsigned int which)
+{
+       const struct rkisp1_isp_mbus_info *mbus_info;
+       struct v4l2_mbus_framefmt *src_fmt;
+
+       src_fmt = rkisp1_rsz_get_pad_fmt(rsz, cfg, RKISP1_RSZ_PAD_SRC, which);
+       mbus_info = rkisp1_isp_mbus_info_get(src_fmt->code);
+
+       /* for YUV formats, userspace can change the mbus code on the src pad if it is supported */
+       if (mbus_info->pixel_enc == V4L2_PIXEL_ENC_YUV &&
+           rkisp1_rsz_get_yuv_mbus_info(format->code))
+               src_fmt->code = format->code;
+
+       src_fmt->width = clamp_t(u32, format->width,
+                                rsz->config->min_rsz_width,
+                                rsz->config->max_rsz_width);
+       src_fmt->height = clamp_t(u32, format->height,
+                                 rsz->config->min_rsz_height,
+                                 rsz->config->max_rsz_height);
+
+       *format = *src_fmt;
+}
+
+static void rkisp1_rsz_set_sink_crop(struct rkisp1_resizer *rsz,
+                                    struct v4l2_subdev_pad_config *cfg,
+                                    struct v4l2_rect *r,
+                                    unsigned int which)
+{
+       const struct rkisp1_isp_mbus_info *mbus_info;
+       struct v4l2_mbus_framefmt *sink_fmt;
+       struct v4l2_rect *sink_crop;
+
+       sink_fmt = rkisp1_rsz_get_pad_fmt(rsz, cfg, RKISP1_RSZ_PAD_SINK, which);
+       sink_crop = rkisp1_rsz_get_pad_crop(rsz, cfg, RKISP1_RSZ_PAD_SINK,
+                                           which);
+
+       /* Not crop for MP bayer raw data */
+       mbus_info = rkisp1_isp_mbus_info_get(sink_fmt->code);
+
+       if (rsz->id == RKISP1_MAINPATH &&
+           mbus_info->pixel_enc == V4L2_PIXEL_ENC_BAYER) {
+               sink_crop->left = 0;
+               sink_crop->top = 0;
+               sink_crop->width = sink_fmt->width;
+               sink_crop->height = sink_fmt->height;
+
+               *r = *sink_crop;
+               return;
+       }
+
+       sink_crop->left = ALIGN(r->left, 2);
+       sink_crop->width = ALIGN(r->width, 2);
+       sink_crop->top = r->top;
+       sink_crop->height = r->height;
+       rkisp1_sd_adjust_crop(sink_crop, sink_fmt);
+
+       *r = *sink_crop;
+}
+
+static void rkisp1_rsz_set_sink_fmt(struct rkisp1_resizer *rsz,
+                                   struct v4l2_subdev_pad_config *cfg,
+                                   struct v4l2_mbus_framefmt *format,
+                                   unsigned int which)
+{
+       const struct rkisp1_isp_mbus_info *mbus_info;
+       struct v4l2_mbus_framefmt *sink_fmt, *src_fmt;
+       struct v4l2_rect *sink_crop;
+
+       sink_fmt = rkisp1_rsz_get_pad_fmt(rsz, cfg, RKISP1_RSZ_PAD_SINK, which);
+       src_fmt = rkisp1_rsz_get_pad_fmt(rsz, cfg, RKISP1_RSZ_PAD_SRC, which);
+       sink_crop = rkisp1_rsz_get_pad_crop(rsz, cfg, RKISP1_RSZ_PAD_SINK,
+                                           which);
+       if (rsz->id == RKISP1_SELFPATH)
+               sink_fmt->code = MEDIA_BUS_FMT_YUYV8_2X8;
+       else
+               sink_fmt->code = format->code;
+
+       mbus_info = rkisp1_isp_mbus_info_get(sink_fmt->code);
+       if (!mbus_info || !(mbus_info->direction & RKISP1_ISP_SD_SRC)) {
+               sink_fmt->code = RKISP1_DEF_FMT;
+               mbus_info = rkisp1_isp_mbus_info_get(sink_fmt->code);
+       }
+       if (which == V4L2_SUBDEV_FORMAT_ACTIVE)
+               rsz->pixel_enc = mbus_info->pixel_enc;
+
+       /* Propagete to source pad */
+       src_fmt->code = sink_fmt->code;
+
+       sink_fmt->width = clamp_t(u32, format->width,
+                                 RKISP1_ISP_MIN_WIDTH,
+                                 RKISP1_ISP_MAX_WIDTH);
+       sink_fmt->height = clamp_t(u32, format->height,
+                                  RKISP1_ISP_MIN_HEIGHT,
+                                  RKISP1_ISP_MAX_HEIGHT);
+
+       *format = *sink_fmt;
+
+       /* Update sink crop */
+       rkisp1_rsz_set_sink_crop(rsz, cfg, sink_crop, which);
+}
+
+static int rkisp1_rsz_get_fmt(struct v4l2_subdev *sd,
+                             struct v4l2_subdev_pad_config *cfg,
+                             struct v4l2_subdev_format *fmt)
+{
+       struct rkisp1_resizer *rsz =
+               container_of(sd, struct rkisp1_resizer, sd);
+
+       mutex_lock(&rsz->ops_lock);
+       fmt->format = *rkisp1_rsz_get_pad_fmt(rsz, cfg, fmt->pad, fmt->which);
+       mutex_unlock(&rsz->ops_lock);
+       return 0;
+}
+
+static int rkisp1_rsz_set_fmt(struct v4l2_subdev *sd,
+                             struct v4l2_subdev_pad_config *cfg,
+                             struct v4l2_subdev_format *fmt)
+{
+       struct rkisp1_resizer *rsz =
+               container_of(sd, struct rkisp1_resizer, sd);
+
+       mutex_lock(&rsz->ops_lock);
+       if (fmt->pad == RKISP1_RSZ_PAD_SINK)
+               rkisp1_rsz_set_sink_fmt(rsz, cfg, &fmt->format, fmt->which);
+       else
+               rkisp1_rsz_set_src_fmt(rsz, cfg, &fmt->format, fmt->which);
+
+       mutex_unlock(&rsz->ops_lock);
+       return 0;
+}
+
+static int rkisp1_rsz_get_selection(struct v4l2_subdev *sd,
+                                   struct v4l2_subdev_pad_config *cfg,
+                                   struct v4l2_subdev_selection *sel)
+{
+       struct rkisp1_resizer *rsz =
+               container_of(sd, struct rkisp1_resizer, sd);
+       struct v4l2_mbus_framefmt *mf_sink;
+       int ret = 0;
+
+       if (sel->pad == RKISP1_RSZ_PAD_SRC)
+               return -EINVAL;
+
+       mutex_lock(&rsz->ops_lock);
+       switch (sel->target) {
+       case V4L2_SEL_TGT_CROP_BOUNDS:
+               mf_sink = rkisp1_rsz_get_pad_fmt(rsz, cfg, RKISP1_RSZ_PAD_SINK,
+                                                sel->which);
+               sel->r.height = mf_sink->height;
+               sel->r.width = mf_sink->width;
+               sel->r.left = 0;
+               sel->r.top = 0;
+               break;
+       case V4L2_SEL_TGT_CROP:
+               sel->r = *rkisp1_rsz_get_pad_crop(rsz, cfg, RKISP1_RSZ_PAD_SINK,
+                                                 sel->which);
+               break;
+       default:
+               ret = -EINVAL;
+       }
+
+       mutex_unlock(&rsz->ops_lock);
+       return ret;
+}
+
+static int rkisp1_rsz_set_selection(struct v4l2_subdev *sd,
+                                   struct v4l2_subdev_pad_config *cfg,
+                                   struct v4l2_subdev_selection *sel)
+{
+       struct rkisp1_resizer *rsz =
+               container_of(sd, struct rkisp1_resizer, sd);
+
+       if (sel->target != V4L2_SEL_TGT_CROP || sel->pad == RKISP1_RSZ_PAD_SRC)
+               return -EINVAL;
+
+       dev_dbg(rsz->rkisp1->dev, "%s: pad: %d sel(%d,%d)/%dx%d\n", __func__,
+               sel->pad, sel->r.left, sel->r.top, sel->r.width, sel->r.height);
+
+       mutex_lock(&rsz->ops_lock);
+       rkisp1_rsz_set_sink_crop(rsz, cfg, &sel->r, sel->which);
+       mutex_unlock(&rsz->ops_lock);
+
+       return 0;
+}
+
+static const struct media_entity_operations rkisp1_rsz_media_ops = {
+       .link_validate = v4l2_subdev_link_validate,
+};
+
+static const struct v4l2_subdev_pad_ops rkisp1_rsz_pad_ops = {
+       .enum_mbus_code = rkisp1_rsz_enum_mbus_code,
+       .get_selection = rkisp1_rsz_get_selection,
+       .set_selection = rkisp1_rsz_set_selection,
+       .init_cfg = rkisp1_rsz_init_config,
+       .get_fmt = rkisp1_rsz_get_fmt,
+       .set_fmt = rkisp1_rsz_set_fmt,
+       .link_validate = v4l2_subdev_link_validate_default,
+};
+
+/* ----------------------------------------------------------------------------
+ * Stream operations
+ */
+
+static int rkisp1_rsz_s_stream(struct v4l2_subdev *sd, int enable)
+{
+       struct rkisp1_resizer *rsz =
+               container_of(sd, struct rkisp1_resizer, sd);
+       struct rkisp1_device *rkisp1 = rsz->rkisp1;
+       struct rkisp1_capture *other = &rkisp1->capture_devs[rsz->id ^ 1];
+       enum rkisp1_shadow_regs_when when = RKISP1_SHADOW_REGS_SYNC;
+
+       if (!enable) {
+               rkisp1_dcrop_disable(rsz, RKISP1_SHADOW_REGS_ASYNC);
+               rkisp1_rsz_disable(rsz, RKISP1_SHADOW_REGS_ASYNC);
+               return 0;
+       }
+
+       if (other->is_streaming)
+               when = RKISP1_SHADOW_REGS_ASYNC;
+
+       mutex_lock(&rsz->ops_lock);
+       rkisp1_rsz_config(rsz, when);
+       rkisp1_dcrop_config(rsz);
+
+       mutex_unlock(&rsz->ops_lock);
+       return 0;
+}
+
+static const struct v4l2_subdev_video_ops rkisp1_rsz_video_ops = {
+       .s_stream = rkisp1_rsz_s_stream,
+};
+
+static const struct v4l2_subdev_ops rkisp1_rsz_ops = {
+       .video = &rkisp1_rsz_video_ops,
+       .pad = &rkisp1_rsz_pad_ops,
+};
+
+static void rkisp1_rsz_unregister(struct rkisp1_resizer *rsz)
+{
+       v4l2_device_unregister_subdev(&rsz->sd);
+       media_entity_cleanup(&rsz->sd.entity);
+}
+
+static int rkisp1_rsz_register(struct rkisp1_resizer *rsz)
+{
+       static const char * const dev_names[] = {
+               RKISP1_RSZ_MP_DEV_NAME,
+               RKISP1_RSZ_SP_DEV_NAME
+       };
+       struct media_pad *pads = rsz->pads;
+       struct v4l2_subdev *sd = &rsz->sd;
+       int ret;
+
+       if (rsz->id == RKISP1_SELFPATH)
+               rsz->config = &rkisp1_rsz_config_sp;
+       else
+               rsz->config = &rkisp1_rsz_config_mp;
+
+       v4l2_subdev_init(sd, &rkisp1_rsz_ops);
+       sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
+       sd->entity.ops = &rkisp1_rsz_media_ops;
+       sd->entity.function = MEDIA_ENT_F_PROC_VIDEO_SCALER;
+       sd->owner = THIS_MODULE;
+       strscpy(sd->name, dev_names[rsz->id], sizeof(sd->name));
+
+       pads[RKISP1_RSZ_PAD_SINK].flags = MEDIA_PAD_FL_SINK |
+                                         MEDIA_PAD_FL_MUST_CONNECT;
+       pads[RKISP1_RSZ_PAD_SRC].flags = MEDIA_PAD_FL_SOURCE |
+                                        MEDIA_PAD_FL_MUST_CONNECT;
+
+       rsz->pixel_enc = RKISP1_DEF_PIXEL_ENC;
+
+       mutex_init(&rsz->ops_lock);
+       ret = media_entity_pads_init(&sd->entity, RKISP1_RSZ_PAD_MAX, pads);
+       if (ret)
+               return ret;
+
+       ret = v4l2_device_register_subdev(&rsz->rkisp1->v4l2_dev, sd);
+       if (ret) {
+               dev_err(sd->dev, "Failed to register resizer subdev\n");
+               goto err_cleanup_media_entity;
+       }
+
+       rkisp1_rsz_init_config(sd, rsz->pad_cfg);
+       return 0;
+
+err_cleanup_media_entity:
+       media_entity_cleanup(&sd->entity);
+
+       return ret;
+}
+
+int rkisp1_resizer_devs_register(struct rkisp1_device *rkisp1)
+{
+       struct rkisp1_resizer *rsz;
+       unsigned int i, j;
+       int ret;
+
+       for (i = 0; i < ARRAY_SIZE(rkisp1->resizer_devs); i++) {
+               rsz = &rkisp1->resizer_devs[i];
+               rsz->rkisp1 = rkisp1;
+               rsz->id = i;
+               ret = rkisp1_rsz_register(rsz);
+               if (ret)
+                       goto err_unreg_resizer_devs;
+       }
+
+       return 0;
+
+err_unreg_resizer_devs:
+       for (j = 0; j < i; j++) {
+               rsz = &rkisp1->resizer_devs[j];
+               rkisp1_rsz_unregister(rsz);
+       }
+
+       return ret;
+}
+
+void rkisp1_resizer_devs_unregister(struct rkisp1_device *rkisp1)
+{
+       struct rkisp1_resizer *mp = &rkisp1->resizer_devs[RKISP1_MAINPATH];
+       struct rkisp1_resizer *sp = &rkisp1->resizer_devs[RKISP1_SELFPATH];
+
+       rkisp1_rsz_unregister(mp);
+       rkisp1_rsz_unregister(sp);
+}
diff --git a/drivers/media/platform/rockchip/rkisp1/rkisp1-stats.c b/drivers/media/platform/rockchip/rkisp1/rkisp1-stats.c
new file mode 100644 (file)
index 0000000..3ddab8f
--- /dev/null
@@ -0,0 +1,415 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Rockchip ISP1 Driver - Stats subdevice
+ *
+ * Copyright (C) 2017 Rockchip Electronics Co., Ltd.
+ */
+
+#include <media/v4l2-common.h>
+#include <media/v4l2-event.h>
+#include <media/v4l2-ioctl.h>
+#include <media/videobuf2-core.h>
+#include <media/videobuf2-vmalloc.h>   /* for ISP statistics */
+
+#include "rkisp1-common.h"
+
+#define RKISP1_STATS_DEV_NAME  RKISP1_DRIVER_NAME "_stats"
+
+#define RKISP1_ISP_STATS_REQ_BUFS_MIN 2
+#define RKISP1_ISP_STATS_REQ_BUFS_MAX 8
+
+static int rkisp1_stats_enum_fmt_meta_cap(struct file *file, void *priv,
+                                         struct v4l2_fmtdesc *f)
+{
+       struct video_device *video = video_devdata(file);
+       struct rkisp1_stats *stats = video_get_drvdata(video);
+
+       if (f->index > 0 || f->type != video->queue->type)
+               return -EINVAL;
+
+       f->pixelformat = stats->vdev_fmt.fmt.meta.dataformat;
+       return 0;
+}
+
+static int rkisp1_stats_g_fmt_meta_cap(struct file *file, void *priv,
+                                      struct v4l2_format *f)
+{
+       struct video_device *video = video_devdata(file);
+       struct rkisp1_stats *stats = video_get_drvdata(video);
+       struct v4l2_meta_format *meta = &f->fmt.meta;
+
+       if (f->type != video->queue->type)
+               return -EINVAL;
+
+       memset(meta, 0, sizeof(*meta));
+       meta->dataformat = stats->vdev_fmt.fmt.meta.dataformat;
+       meta->buffersize = stats->vdev_fmt.fmt.meta.buffersize;
+
+       return 0;
+}
+
+static int rkisp1_stats_querycap(struct file *file,
+                                void *priv, struct v4l2_capability *cap)
+{
+       struct video_device *vdev = video_devdata(file);
+
+       strscpy(cap->driver, RKISP1_DRIVER_NAME, sizeof(cap->driver));
+       strscpy(cap->card, vdev->name, sizeof(cap->card));
+       strscpy(cap->bus_info, RKISP1_BUS_INFO, sizeof(cap->bus_info));
+
+       return 0;
+}
+
+/* ISP video device IOCTLs */
+static const struct v4l2_ioctl_ops rkisp1_stats_ioctl = {
+       .vidioc_reqbufs = vb2_ioctl_reqbufs,
+       .vidioc_querybuf = vb2_ioctl_querybuf,
+       .vidioc_create_bufs = vb2_ioctl_create_bufs,
+       .vidioc_qbuf = vb2_ioctl_qbuf,
+       .vidioc_dqbuf = vb2_ioctl_dqbuf,
+       .vidioc_prepare_buf = vb2_ioctl_prepare_buf,
+       .vidioc_expbuf = vb2_ioctl_expbuf,
+       .vidioc_streamon = vb2_ioctl_streamon,
+       .vidioc_streamoff = vb2_ioctl_streamoff,
+       .vidioc_enum_fmt_meta_cap = rkisp1_stats_enum_fmt_meta_cap,
+       .vidioc_g_fmt_meta_cap = rkisp1_stats_g_fmt_meta_cap,
+       .vidioc_s_fmt_meta_cap = rkisp1_stats_g_fmt_meta_cap,
+       .vidioc_try_fmt_meta_cap = rkisp1_stats_g_fmt_meta_cap,
+       .vidioc_querycap = rkisp1_stats_querycap,
+       .vidioc_subscribe_event = v4l2_ctrl_subscribe_event,
+       .vidioc_unsubscribe_event = v4l2_event_unsubscribe,
+};
+
+static const struct v4l2_file_operations rkisp1_stats_fops = {
+       .mmap = vb2_fop_mmap,
+       .unlocked_ioctl = video_ioctl2,
+       .poll = vb2_fop_poll,
+       .open = v4l2_fh_open,
+       .release = vb2_fop_release
+};
+
+static int rkisp1_stats_vb2_queue_setup(struct vb2_queue *vq,
+                                       unsigned int *num_buffers,
+                                       unsigned int *num_planes,
+                                       unsigned int sizes[],
+                                       struct device *alloc_devs[])
+{
+       *num_planes = 1;
+
+       *num_buffers = clamp_t(u32, *num_buffers, RKISP1_ISP_STATS_REQ_BUFS_MIN,
+                              RKISP1_ISP_STATS_REQ_BUFS_MAX);
+
+       sizes[0] = sizeof(struct rkisp1_stat_buffer);
+
+       return 0;
+}
+
+static void rkisp1_stats_vb2_buf_queue(struct vb2_buffer *vb)
+{
+       struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
+       struct rkisp1_buffer *stats_buf =
+               container_of(vbuf, struct rkisp1_buffer, vb);
+       struct vb2_queue *vq = vb->vb2_queue;
+       struct rkisp1_stats *stats_dev = vq->drv_priv;
+
+       stats_buf->vaddr = vb2_plane_vaddr(vb, 0);
+
+       spin_lock_irq(&stats_dev->lock);
+       list_add_tail(&stats_buf->queue, &stats_dev->stat);
+       spin_unlock_irq(&stats_dev->lock);
+}
+
+static int rkisp1_stats_vb2_buf_prepare(struct vb2_buffer *vb)
+{
+       if (vb2_plane_size(vb, 0) < sizeof(struct rkisp1_stat_buffer))
+               return -EINVAL;
+
+       vb2_set_plane_payload(vb, 0, sizeof(struct rkisp1_stat_buffer));
+
+       return 0;
+}
+
+static void rkisp1_stats_vb2_stop_streaming(struct vb2_queue *vq)
+{
+       struct rkisp1_stats *stats = vq->drv_priv;
+       struct rkisp1_buffer *buf;
+       unsigned int i;
+
+       spin_lock_irq(&stats->lock);
+       for (i = 0; i < RKISP1_ISP_STATS_REQ_BUFS_MAX; i++) {
+               if (list_empty(&stats->stat))
+                       break;
+               buf = list_first_entry(&stats->stat,
+                                      struct rkisp1_buffer, queue);
+               list_del(&buf->queue);
+               vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_ERROR);
+       }
+       spin_unlock_irq(&stats->lock);
+}
+
+static const struct vb2_ops rkisp1_stats_vb2_ops = {
+       .queue_setup = rkisp1_stats_vb2_queue_setup,
+       .buf_queue = rkisp1_stats_vb2_buf_queue,
+       .buf_prepare = rkisp1_stats_vb2_buf_prepare,
+       .wait_prepare = vb2_ops_wait_prepare,
+       .wait_finish = vb2_ops_wait_finish,
+       .stop_streaming = rkisp1_stats_vb2_stop_streaming,
+};
+
+static int
+rkisp1_stats_init_vb2_queue(struct vb2_queue *q, struct rkisp1_stats *stats)
+{
+       struct rkisp1_vdev_node *node;
+
+       node = container_of(q, struct rkisp1_vdev_node, buf_queue);
+
+       q->type = V4L2_BUF_TYPE_META_CAPTURE;
+       q->io_modes = VB2_MMAP | VB2_USERPTR | VB2_DMABUF;
+       q->drv_priv = stats;
+       q->ops = &rkisp1_stats_vb2_ops;
+       q->mem_ops = &vb2_vmalloc_memops;
+       q->buf_struct_size = sizeof(struct rkisp1_buffer);
+       q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
+       q->lock = &node->vlock;
+
+       return vb2_queue_init(q);
+}
+
+static void rkisp1_stats_get_awb_meas(struct rkisp1_stats *stats,
+                                     struct rkisp1_stat_buffer *pbuf)
+{
+       /* Protect against concurrent access from ISR? */
+       struct rkisp1_device *rkisp1 = stats->rkisp1;
+       u32 reg_val;
+
+       pbuf->meas_type |= RKISP1_CIF_ISP_STAT_AWB;
+       reg_val = rkisp1_read(rkisp1, RKISP1_CIF_ISP_AWB_WHITE_CNT);
+       pbuf->params.awb.awb_mean[0].cnt =
+                               RKISP1_CIF_ISP_AWB_GET_PIXEL_CNT(reg_val);
+       reg_val = rkisp1_read(rkisp1, RKISP1_CIF_ISP_AWB_MEAN);
+
+       pbuf->params.awb.awb_mean[0].mean_cr_or_r =
+                               RKISP1_CIF_ISP_AWB_GET_MEAN_CR_R(reg_val);
+       pbuf->params.awb.awb_mean[0].mean_cb_or_b =
+                               RKISP1_CIF_ISP_AWB_GET_MEAN_CB_B(reg_val);
+       pbuf->params.awb.awb_mean[0].mean_y_or_g =
+                               RKISP1_CIF_ISP_AWB_GET_MEAN_Y_G(reg_val);
+}
+
+static void rkisp1_stats_get_aec_meas(struct rkisp1_stats *stats,
+                                     struct rkisp1_stat_buffer *pbuf)
+{
+       struct rkisp1_device *rkisp1 = stats->rkisp1;
+       unsigned int i;
+
+       pbuf->meas_type |= RKISP1_CIF_ISP_STAT_AUTOEXP;
+       for (i = 0; i < RKISP1_CIF_ISP_AE_MEAN_MAX; i++)
+               pbuf->params.ae.exp_mean[i] =
+                       (u8)rkisp1_read(rkisp1,
+                                       RKISP1_CIF_ISP_EXP_MEAN_00 + i * 4);
+}
+
+static void rkisp1_stats_get_afc_meas(struct rkisp1_stats *stats,
+                                     struct rkisp1_stat_buffer *pbuf)
+{
+       struct rkisp1_device *rkisp1 = stats->rkisp1;
+       struct rkisp1_cif_isp_af_stat *af;
+
+       pbuf->meas_type |= RKISP1_CIF_ISP_STAT_AFM;
+
+       af = &pbuf->params.af;
+       af->window[0].sum = rkisp1_read(rkisp1, RKISP1_CIF_ISP_AFM_SUM_A);
+       af->window[0].lum = rkisp1_read(rkisp1, RKISP1_CIF_ISP_AFM_LUM_A);
+       af->window[1].sum = rkisp1_read(rkisp1, RKISP1_CIF_ISP_AFM_SUM_B);
+       af->window[1].lum = rkisp1_read(rkisp1, RKISP1_CIF_ISP_AFM_LUM_B);
+       af->window[2].sum = rkisp1_read(rkisp1, RKISP1_CIF_ISP_AFM_SUM_C);
+       af->window[2].lum = rkisp1_read(rkisp1, RKISP1_CIF_ISP_AFM_LUM_C);
+}
+
+static void rkisp1_stats_get_hst_meas(struct rkisp1_stats *stats,
+                                     struct rkisp1_stat_buffer *pbuf)
+{
+       struct rkisp1_device *rkisp1 = stats->rkisp1;
+       unsigned int i;
+
+       pbuf->meas_type |= RKISP1_CIF_ISP_STAT_HIST;
+       for (i = 0; i < RKISP1_CIF_ISP_HIST_BIN_N_MAX; i++)
+               pbuf->params.hist.hist_bins[i] =
+                       (u8)rkisp1_read(rkisp1,
+                                       RKISP1_CIF_ISP_HIST_BIN_0 + i * 4);
+}
+
+static void rkisp1_stats_get_bls_meas(struct rkisp1_stats *stats,
+                                     struct rkisp1_stat_buffer *pbuf)
+{
+       struct rkisp1_device *rkisp1 = stats->rkisp1;
+       const struct rkisp1_isp_mbus_info *in_fmt = rkisp1->isp.sink_fmt;
+       struct rkisp1_cif_isp_bls_meas_val *bls_val;
+
+       bls_val = &pbuf->params.ae.bls_val;
+       if (in_fmt->bayer_pat == RKISP1_RAW_BGGR) {
+               bls_val->meas_b =
+                       rkisp1_read(rkisp1, RKISP1_CIF_ISP_BLS_A_MEASURED);
+               bls_val->meas_gb =
+                       rkisp1_read(rkisp1, RKISP1_CIF_ISP_BLS_B_MEASURED);
+               bls_val->meas_gr =
+                       rkisp1_read(rkisp1, RKISP1_CIF_ISP_BLS_C_MEASURED);
+               bls_val->meas_r =
+                       rkisp1_read(rkisp1, RKISP1_CIF_ISP_BLS_D_MEASURED);
+       } else if (in_fmt->bayer_pat == RKISP1_RAW_GBRG) {
+               bls_val->meas_gb =
+                       rkisp1_read(rkisp1, RKISP1_CIF_ISP_BLS_A_MEASURED);
+               bls_val->meas_b =
+                       rkisp1_read(rkisp1, RKISP1_CIF_ISP_BLS_B_MEASURED);
+               bls_val->meas_r =
+                       rkisp1_read(rkisp1, RKISP1_CIF_ISP_BLS_C_MEASURED);
+               bls_val->meas_gr =
+                       rkisp1_read(rkisp1, RKISP1_CIF_ISP_BLS_D_MEASURED);
+       } else if (in_fmt->bayer_pat == RKISP1_RAW_GRBG) {
+               bls_val->meas_gr =
+                       rkisp1_read(rkisp1, RKISP1_CIF_ISP_BLS_A_MEASURED);
+               bls_val->meas_r =
+                       rkisp1_read(rkisp1, RKISP1_CIF_ISP_BLS_B_MEASURED);
+               bls_val->meas_b =
+                       rkisp1_read(rkisp1, RKISP1_CIF_ISP_BLS_C_MEASURED);
+               bls_val->meas_gb =
+                       rkisp1_read(rkisp1, RKISP1_CIF_ISP_BLS_D_MEASURED);
+       } else if (in_fmt->bayer_pat == RKISP1_RAW_RGGB) {
+               bls_val->meas_r =
+                       rkisp1_read(rkisp1, RKISP1_CIF_ISP_BLS_A_MEASURED);
+               bls_val->meas_gr =
+                       rkisp1_read(rkisp1, RKISP1_CIF_ISP_BLS_B_MEASURED);
+               bls_val->meas_gb =
+                       rkisp1_read(rkisp1, RKISP1_CIF_ISP_BLS_C_MEASURED);
+               bls_val->meas_b =
+                       rkisp1_read(rkisp1, RKISP1_CIF_ISP_BLS_D_MEASURED);
+       }
+}
+
+static void
+rkisp1_stats_send_measurement(struct rkisp1_stats *stats, u32 isp_ris)
+{
+       struct rkisp1_stat_buffer *cur_stat_buf;
+       struct rkisp1_buffer *cur_buf = NULL;
+       unsigned int frame_sequence = stats->rkisp1->isp.frame_sequence;
+       u64 timestamp = ktime_get_ns();
+
+       /* get one empty buffer */
+       if (!list_empty(&stats->stat)) {
+               cur_buf = list_first_entry(&stats->stat,
+                                          struct rkisp1_buffer, queue);
+               list_del(&cur_buf->queue);
+       }
+
+       if (!cur_buf)
+               return;
+
+       cur_stat_buf =
+               (struct rkisp1_stat_buffer *)(cur_buf->vaddr);
+
+       if (isp_ris & RKISP1_CIF_ISP_AWB_DONE)
+               rkisp1_stats_get_awb_meas(stats, cur_stat_buf);
+
+       if (isp_ris & RKISP1_CIF_ISP_AFM_FIN)
+               rkisp1_stats_get_afc_meas(stats, cur_stat_buf);
+
+       if (isp_ris & RKISP1_CIF_ISP_EXP_END) {
+               rkisp1_stats_get_aec_meas(stats, cur_stat_buf);
+               rkisp1_stats_get_bls_meas(stats, cur_stat_buf);
+       }
+
+       if (isp_ris & RKISP1_CIF_ISP_HIST_MEASURE_RDY)
+               rkisp1_stats_get_hst_meas(stats, cur_stat_buf);
+
+       vb2_set_plane_payload(&cur_buf->vb.vb2_buf, 0,
+                             sizeof(struct rkisp1_stat_buffer));
+       cur_buf->vb.sequence = frame_sequence;
+       cur_buf->vb.vb2_buf.timestamp = timestamp;
+       vb2_buffer_done(&cur_buf->vb.vb2_buf, VB2_BUF_STATE_DONE);
+}
+
+void rkisp1_stats_isr(struct rkisp1_stats *stats, u32 isp_ris)
+{
+       struct rkisp1_device *rkisp1 = stats->rkisp1;
+       unsigned int isp_mis_tmp = 0;
+
+       spin_lock(&stats->lock);
+
+       rkisp1_write(rkisp1, RKISP1_STATS_MEAS_MASK, RKISP1_CIF_ISP_ICR);
+
+       isp_mis_tmp = rkisp1_read(rkisp1, RKISP1_CIF_ISP_MIS);
+       if (isp_mis_tmp & RKISP1_STATS_MEAS_MASK)
+               rkisp1->debug.stats_error++;
+
+       if (isp_ris & RKISP1_STATS_MEAS_MASK)
+               rkisp1_stats_send_measurement(stats, isp_ris);
+
+       spin_unlock(&stats->lock);
+}
+
+static void rkisp1_init_stats(struct rkisp1_stats *stats)
+{
+       stats->vdev_fmt.fmt.meta.dataformat =
+               V4L2_META_FMT_RK_ISP1_STAT_3A;
+       stats->vdev_fmt.fmt.meta.buffersize =
+               sizeof(struct rkisp1_stat_buffer);
+}
+
+int rkisp1_stats_register(struct rkisp1_device *rkisp1)
+{
+       struct rkisp1_stats *stats = &rkisp1->stats;
+       struct rkisp1_vdev_node *node = &stats->vnode;
+       struct video_device *vdev = &node->vdev;
+       int ret;
+
+       stats->rkisp1 = rkisp1;
+       mutex_init(&node->vlock);
+       INIT_LIST_HEAD(&stats->stat);
+       spin_lock_init(&stats->lock);
+
+       strscpy(vdev->name, RKISP1_STATS_DEV_NAME, sizeof(vdev->name));
+
+       video_set_drvdata(vdev, stats);
+       vdev->ioctl_ops = &rkisp1_stats_ioctl;
+       vdev->fops = &rkisp1_stats_fops;
+       vdev->release = video_device_release_empty;
+       vdev->lock = &node->vlock;
+       vdev->v4l2_dev = &rkisp1->v4l2_dev;
+       vdev->queue = &node->buf_queue;
+       vdev->device_caps = V4L2_CAP_META_CAPTURE | V4L2_CAP_STREAMING;
+       vdev->vfl_dir =  VFL_DIR_RX;
+       rkisp1_stats_init_vb2_queue(vdev->queue, stats);
+       rkisp1_init_stats(stats);
+       video_set_drvdata(vdev, stats);
+
+       node->pad.flags = MEDIA_PAD_FL_SINK;
+       ret = media_entity_pads_init(&vdev->entity, 1, &node->pad);
+       if (ret)
+               goto err_mutex_destroy;
+
+       ret = video_register_device(vdev, VFL_TYPE_VIDEO, -1);
+       if (ret) {
+               dev_err(&vdev->dev,
+                       "failed to register %s, ret=%d\n", vdev->name, ret);
+               goto err_cleanup_media_entity;
+       }
+
+       return 0;
+
+err_cleanup_media_entity:
+       media_entity_cleanup(&vdev->entity);
+err_mutex_destroy:
+       mutex_destroy(&node->vlock);
+       return ret;
+}
+
+void rkisp1_stats_unregister(struct rkisp1_device *rkisp1)
+{
+       struct rkisp1_stats *stats = &rkisp1->stats;
+       struct rkisp1_vdev_node *node = &stats->vnode;
+       struct video_device *vdev = &node->vdev;
+
+       vb2_video_unregister_device(vdev);
+       media_entity_cleanup(&vdev->entity);
+       mutex_destroy(&node->vlock);
+}
index 422fd54..4c3c00d 100644 (file)
@@ -131,11 +131,13 @@ static int camif_get_scaler_factor(u32 src, u32 tar, u32 *ratio, u32 *shift)
        while (sh--) {
                unsigned int tmp = 1 << sh;
                if (src >= tar * tmp) {
-                       *shift = sh, *ratio = tmp;
+                       *shift = sh;
+                       *ratio = tmp;
                        return 0;
                }
        }
-       *shift = 0, *ratio = 1;
+       *shift = 0;
+       *ratio = 1;
        return 0;
 }
 
index dbe7788..5ceb366 100644 (file)
@@ -765,7 +765,7 @@ static int c8sectpfe_probe(struct platform_device *pdev)
 
                if (!fei->channel_data[index]) {
                        ret = -ENOMEM;
-                       goto err_clk_disable;
+                       goto err_node_put;
                }
 
                tsin = fei->channel_data[index];
@@ -775,7 +775,7 @@ static int c8sectpfe_probe(struct platform_device *pdev)
                ret = of_property_read_u32(child, "tsin-num", &tsin->tsin_id);
                if (ret) {
                        dev_err(&pdev->dev, "No tsin_num found\n");
-                       goto err_clk_disable;
+                       goto err_node_put;
                }
 
                /* sanity check value */
@@ -784,7 +784,7 @@ static int c8sectpfe_probe(struct platform_device *pdev)
                                "tsin-num %d specified greater than number\n\tof input block hw in SoC! (%d)",
                                tsin->tsin_id, fei->hw_stats.num_ib);
                        ret = -EINVAL;
-                       goto err_clk_disable;
+                       goto err_node_put;
                }
 
                tsin->invert_ts_clk = of_property_read_bool(child,
@@ -800,14 +800,14 @@ static int c8sectpfe_probe(struct platform_device *pdev)
                                        &tsin->dvb_card);
                if (ret) {
                        dev_err(&pdev->dev, "No dvb-card found\n");
-                       goto err_clk_disable;
+                       goto err_node_put;
                }
 
                i2c_bus = of_parse_phandle(child, "i2c-bus", 0);
                if (!i2c_bus) {
                        dev_err(&pdev->dev, "No i2c-bus found\n");
                        ret = -ENODEV;
-                       goto err_clk_disable;
+                       goto err_node_put;
                }
                tsin->i2c_adapter =
                        of_find_i2c_adapter_by_node(i2c_bus);
@@ -815,7 +815,7 @@ static int c8sectpfe_probe(struct platform_device *pdev)
                        dev_err(&pdev->dev, "No i2c adapter found\n");
                        of_node_put(i2c_bus);
                        ret = -ENODEV;
-                       goto err_clk_disable;
+                       goto err_node_put;
                }
                of_node_put(i2c_bus);
 
@@ -826,7 +826,7 @@ static int c8sectpfe_probe(struct platform_device *pdev)
                        dev_err(dev,
                                "reset gpio for tsin%d not valid (gpio=%d)\n",
                                tsin->tsin_id, tsin->rst_gpio);
-                       goto err_clk_disable;
+                       goto err_node_put;
                }
 
                ret = devm_gpio_request_one(dev, tsin->rst_gpio,
@@ -834,7 +834,7 @@ static int c8sectpfe_probe(struct platform_device *pdev)
                if (ret && ret != -EBUSY) {
                        dev_err(dev, "Can't request tsin%d reset gpio\n"
                                , fei->channel_data[index]->tsin_id);
-                       goto err_clk_disable;
+                       goto err_node_put;
                }
 
                if (!ret) {
@@ -877,6 +877,8 @@ static int c8sectpfe_probe(struct platform_device *pdev)
 
        return 0;
 
+err_node_put:
+       of_node_put(child);
 err_clk_disable:
        clk_disable_unprepare(fei->c8sectpfeclk);
        return ret;
@@ -1032,9 +1034,8 @@ static void load_imem_segment(struct c8sectpfei *fei, Elf32_Phdr *phdr,
 
        dev_dbg(fei->dev,
                "Loading IMEM segment %d 0x%08x\n\t (0x%x bytes) -> 0x%p (0x%x bytes)\n",
-seg_num,
-               phdr->p_paddr, phdr->p_filesz,
-               dest, phdr->p_memsz + phdr->p_memsz / 3);
+               seg_num, phdr->p_paddr, phdr->p_filesz, dest,
+               phdr->p_memsz + phdr->p_memsz / 3);
 
        for (i = 0; i < phdr->p_filesz; i++) {
 
index fd1c41c..b745f13 100644 (file)
@@ -157,6 +157,7 @@ struct stm32_dcmi {
        struct vb2_queue                queue;
 
        struct v4l2_fwnode_bus_parallel bus;
+       enum v4l2_mbus_type             bus_type;
        struct completion               complete;
        struct clk                      *mclk;
        enum state                      state;
@@ -324,7 +325,7 @@ static int dcmi_start_dma(struct stm32_dcmi *dcmi,
        }
 
        /*
-        * Avoid call of dmaengine_terminate_all() between
+        * Avoid call of dmaengine_terminate_sync() between
         * dmaengine_prep_slave_single() and dmaengine_submit()
         * by locking the whole DMA submission sequence
         */
@@ -438,7 +439,7 @@ static void dcmi_process_jpeg(struct stm32_dcmi *dcmi)
        }
 
        /* Abort DMA operation */
-       dmaengine_terminate_all(dcmi->dma_chan);
+       dmaengine_terminate_sync(dcmi->dma_chan);
 
        /* Restart capture */
        if (dcmi_restart_capture(dcmi))
@@ -777,6 +778,23 @@ static int dcmi_start_streaming(struct vb2_queue *vq, unsigned int count)
        if (dcmi->bus.flags & V4L2_MBUS_PCLK_SAMPLE_RISING)
                val |= CR_PCKPOL;
 
+       /*
+        * BT656 embedded synchronisation bus mode.
+        *
+        * Default SAV/EAV mode is supported here with default codes
+        * SAV=0xff000080 & EAV=0xff00009d.
+        * With DCMI this means LSC=SAV=0x80 & LEC=EAV=0x9d.
+        */
+       if (dcmi->bus_type == V4L2_MBUS_BT656) {
+               val |= CR_ESS;
+
+               /* Unmask all codes */
+               reg_write(dcmi->regs, DCMI_ESUR, 0xffffffff);/* FEC:LEC:LSC:FSC */
+
+               /* Trig on LSC=0x80 & LEC=0x9d codes, ignore FSC and FEC */
+               reg_write(dcmi->regs, DCMI_ESCR, 0xff9d80ff);/* FEC:LEC:LSC:FSC */
+       }
+
        reg_write(dcmi->regs, DCMI_CR, val);
 
        /* Set crop */
@@ -882,7 +900,7 @@ static void dcmi_stop_streaming(struct vb2_queue *vq)
 
        /* Stop all pending DMA operations */
        mutex_lock(&dcmi->dma_lock);
-       dmaengine_terminate_all(dcmi->dma_chan);
+       dmaengine_terminate_sync(dcmi->dma_chan);
        mutex_unlock(&dcmi->dma_lock);
 
        pm_runtime_put(dcmi->dev);
@@ -1067,8 +1085,9 @@ static int dcmi_set_fmt(struct stm32_dcmi *dcmi, struct v4l2_format *f)
        if (ret)
                return ret;
 
-       /* Disable crop if JPEG is requested */
-       if (pix->pixelformat == V4L2_PIX_FMT_JPEG)
+       /* Disable crop if JPEG is requested or BT656 bus is selected */
+       if (pix->pixelformat == V4L2_PIX_FMT_JPEG &&
+           dcmi->bus_type != V4L2_MBUS_BT656)
                dcmi->do_crop = false;
 
        /* pix to mbus format */
@@ -1574,6 +1593,22 @@ static const struct dcmi_format dcmi_formats[] = {
                .fourcc = V4L2_PIX_FMT_JPEG,
                .mbus_code = MEDIA_BUS_FMT_JPEG_1X8,
                .bpp = 1,
+       }, {
+               .fourcc = V4L2_PIX_FMT_SBGGR8,
+               .mbus_code = MEDIA_BUS_FMT_SBGGR8_1X8,
+               .bpp = 1,
+       }, {
+               .fourcc = V4L2_PIX_FMT_SGBRG8,
+               .mbus_code = MEDIA_BUS_FMT_SGBRG8_1X8,
+               .bpp = 1,
+       }, {
+               .fourcc = V4L2_PIX_FMT_SGRBG8,
+               .mbus_code = MEDIA_BUS_FMT_SGRBG8_1X8,
+               .bpp = 1,
+       }, {
+               .fourcc = V4L2_PIX_FMT_SRGGB8,
+               .mbus_code = MEDIA_BUS_FMT_SRGGB8_1X8,
+               .bpp = 1,
        },
 };
 
@@ -1592,6 +1627,11 @@ static int dcmi_formats_init(struct stm32_dcmi *dcmi)
                        if (dcmi_formats[i].mbus_code != mbus_code.code)
                                continue;
 
+                       /* Exclude JPEG if BT656 bus is selected */
+                       if (dcmi_formats[i].fourcc == V4L2_PIX_FMT_JPEG &&
+                           dcmi->bus_type == V4L2_MBUS_BT656)
+                               continue;
+
                        /* Code supported, have we got this fourcc yet? */
                        for (j = 0; j < num_fmts; j++)
                                if (sd_fmts[j]->fourcc ==
@@ -1851,7 +1891,9 @@ static int dcmi_probe(struct platform_device *pdev)
 
        dcmi->rstc = devm_reset_control_get_exclusive(&pdev->dev, NULL);
        if (IS_ERR(dcmi->rstc)) {
-               dev_err(&pdev->dev, "Could not get reset control\n");
+               if (PTR_ERR(dcmi->rstc) != -EPROBE_DEFER)
+                       dev_err(&pdev->dev, "Could not get reset control\n");
+
                return PTR_ERR(dcmi->rstc);
        }
 
@@ -1873,9 +1915,18 @@ static int dcmi_probe(struct platform_device *pdev)
                dev_err(&pdev->dev, "CSI bus not supported\n");
                return -ENODEV;
        }
+
+       if (ep.bus_type == V4L2_MBUS_BT656 &&
+           ep.bus.parallel.bus_width != 8) {
+               dev_err(&pdev->dev, "BT656 bus conflicts with %u bits bus width (8 bits required)\n",
+                       ep.bus.parallel.bus_width);
+               return -ENODEV;
+       }
+
        dcmi->bus.flags = ep.bus.parallel.flags;
        dcmi->bus.bus_width = ep.bus.parallel.bus_width;
        dcmi->bus.data_shift = ep.bus.parallel.data_shift;
+       dcmi->bus_type = ep.bus_type;
 
        irq = platform_get_irq(pdev, 0);
        if (irq <= 0)
index 8f4e254..1a2f65d 100644 (file)
@@ -363,7 +363,7 @@ int sun4i_csi_v4l2_register(struct sun4i_csi *csi)
        vdev->lock = &csi->lock;
 
        /* Set a default format */
-       csi->fmt.pixelformat = sun4i_csi_formats[0].fourcc,
+       csi->fmt.pixelformat = sun4i_csi_formats[0].fourcc;
        csi->fmt.width = CSI_DEFAULT_WIDTH;
        csi->fmt.height = CSI_DEFAULT_HEIGHT;
        _sun4i_csi_try_fmt(csi, &csi->fmt);
index bd323e6..0388894 100644 (file)
@@ -215,7 +215,7 @@ static int fmr2_probe(struct fmr2 *fmr2, struct device *pdev, int io)
                        return -EBUSY;
 
        strscpy(fmr2->v4l2_dev.name, "radio-sf16fmr2",
-               sizeof(fmr2->v4l2_dev.name)),
+               sizeof(fmr2->v4l2_dev.name));
        fmr2->io = io;
 
        if (!request_region(fmr2->io, 2, fmr2->v4l2_dev.name)) {
index aaa1bf8..1c4d6be 100644 (file)
@@ -60,6 +60,7 @@ obj-$(CONFIG_RC_MAP) += rc-adstech-dvb-t-pci.o \
                        rc-it913x-v2.o \
                        rc-kaiomy.o \
                        rc-khadas.o \
+                       rc-khamsin.o \
                        rc-kworld-315u.o \
                        rc-kworld-pc150u.o \
                        rc-kworld-plus-tv-analog.o \
diff --git a/drivers/media/rc/keymaps/rc-khamsin.c b/drivers/media/rc/keymaps/rc-khamsin.c
new file mode 100644 (file)
index 0000000..0c98c2f
--- /dev/null
@@ -0,0 +1,75 @@
+// SPDX-License-Identifier: GPL-2.0+
+// Copyright (c) 2020 Christian Hewitt
+
+#include <media/rc-map.h>
+#include <linux/module.h>
+
+/*
+ * KHAMSIN is an IR/Bluetooth RCU supplied with the SmartLabs
+ * SML-5442TW DVB-S/VOD box. The RCU has separate IR (TV) and
+ * BT (STB) modes. This keymap suppors the IR controls.
+ */
+
+static struct rc_map_table khamsin[] = {
+       { 0x70702, KEY_POWER},
+
+       { 0x70701, KEY_VIDEO}, // source
+
+       { 0x7076c, KEY_RED},
+       { 0x70714, KEY_GREEN},
+       { 0x70715, KEY_YELLOW},
+       { 0x70716, KEY_BLUE},
+
+       { 0x7071a, KEY_MENU},
+       { 0x7074f, KEY_EPG},
+
+       { 0x70760, KEY_UP },
+       { 0x70761, KEY_DOWN },
+       { 0x70765, KEY_LEFT },
+       { 0x70762, KEY_RIGHT },
+       { 0x70768, KEY_ENTER },
+
+       { 0x7072d, KEY_ESC }, // back
+
+       { 0x70707, KEY_VOLUMEUP },
+       { 0x7070b, KEY_VOLUMEDOWN },
+       { 0x7070f, KEY_MUTE },
+       { 0x70712, KEY_CHANNELUP },
+       { 0x70710, KEY_CHANNELDOWN },
+
+       { 0x70704, KEY_1 },
+       { 0x70705, KEY_2 },
+       { 0x70706, KEY_3 },
+       { 0x70708, KEY_4 },
+       { 0x70709, KEY_5 },
+       { 0x7070a, KEY_6 },
+       { 0x7070c, KEY_7 },
+       { 0x7070d, KEY_8 },
+       { 0x7070e, KEY_9 },
+       { 0x70711, KEY_0 },
+};
+
+static struct rc_map_list khamsin_map = {
+       .map = {
+               .scan     = khamsin,
+               .size     = ARRAY_SIZE(khamsin),
+               .rc_proto = RC_PROTO_NECX,
+               .name     = RC_MAP_KHAMSIN,
+       }
+};
+
+static int __init init_rc_map_khamsin(void)
+{
+       return rc_map_register(&khamsin_map);
+}
+
+static void __exit exit_rc_map_khamsin(void)
+{
+       rc_map_unregister(&khamsin_map);
+}
+
+module_init(init_rc_map_khamsin)
+module_exit(exit_rc_map_khamsin)
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Christian Hewitt <christianshewitt@gmail.com>");
index 220363b..116daf9 100644 (file)
@@ -263,7 +263,8 @@ static ssize_t lirc_transmit(struct file *file, const char __user *buf,
                        goto out_unlock;
                }
 
-               if (scan.flags || scan.keycode || scan.timestamp) {
+               if (scan.flags || scan.keycode || scan.timestamp ||
+                   scan.rc_proto > RC_PROTO_MAX) {
                        ret = -EINVAL;
                        goto out_unlock;
                }
index ddee6ee..8555c77 100644 (file)
 #define SUNXI_IR_BASE_CLK     8000000
 /* Noise threshold in samples  */
 #define SUNXI_IR_RXNOISE      1
-/* Idle Threshold in samples */
-#define SUNXI_IR_RXIDLE       20
-/* Time after which device stops sending data in ms */
-#define SUNXI_IR_TIMEOUT      120
 
 /**
  * struct sunxi_ir_quirks - Differences between SoC variants.
@@ -137,6 +133,8 @@ static irqreturn_t sunxi_ir_irq(int irqno, void *dev_id)
        } else if (status & REG_RXSTA_RPE) {
                ir_raw_event_set_idle(ir->rc, true);
                ir_raw_event_handle(ir->rc);
+       } else {
+               ir_raw_event_handle(ir->rc);
        }
 
        spin_unlock(&ir->ir_lock);
@@ -144,6 +142,41 @@ static irqreturn_t sunxi_ir_irq(int irqno, void *dev_id)
        return IRQ_HANDLED;
 }
 
+/* Convert idle threshold to usec */
+static unsigned int sunxi_ithr_to_usec(unsigned int base_clk, unsigned int ithr)
+{
+       return DIV_ROUND_CLOSEST(USEC_PER_SEC * (ithr + 1),
+                                base_clk / (128 * 64));
+}
+
+/* Convert usec to idle threshold */
+static unsigned int sunxi_usec_to_ithr(unsigned int base_clk, unsigned int usec)
+{
+       /* make sure we don't end up with a timeout less than requested */
+       return DIV_ROUND_UP((base_clk / (128 * 64)) * usec,  USEC_PER_SEC) - 1;
+}
+
+static int sunxi_ir_set_timeout(struct rc_dev *rc_dev, unsigned int timeout)
+{
+       struct sunxi_ir *ir = rc_dev->priv;
+       unsigned int base_clk = clk_get_rate(ir->clk);
+       unsigned long flags;
+
+       unsigned int ithr = sunxi_usec_to_ithr(base_clk, timeout);
+
+       dev_dbg(rc_dev->dev.parent, "setting idle threshold to %u\n", ithr);
+
+       spin_lock_irqsave(&ir->ir_lock, flags);
+       /* Set noise threshold and idle threshold */
+       writel(REG_CIR_NTHR(SUNXI_IR_RXNOISE) | REG_CIR_ITHR(ithr),
+              ir->base + SUNXI_IR_CIR_REG);
+       spin_unlock_irqrestore(&ir->ir_lock, flags);
+
+       rc_dev->timeout = sunxi_ithr_to_usec(base_clk, ithr);
+
+       return 0;
+}
+
 static int sunxi_ir_probe(struct platform_device *pdev)
 {
        int ret = 0;
@@ -240,9 +273,11 @@ static int sunxi_ir_probe(struct platform_device *pdev)
        ir->rc->map_name = ir->map_name ?: RC_MAP_EMPTY;
        ir->rc->dev.parent = dev;
        ir->rc->allowed_protocols = RC_PROTO_BIT_ALL_IR_DECODER;
-       /* Frequency after IR internal divider with sample period in ns */
+       /* Frequency after IR internal divider with sample period in us */
        ir->rc->rx_resolution = (USEC_PER_SEC / (b_clk_freq / 64));
-       ir->rc->timeout = MS_TO_US(SUNXI_IR_TIMEOUT);
+       ir->rc->min_timeout = sunxi_ithr_to_usec(b_clk_freq, 0);
+       ir->rc->max_timeout = sunxi_ithr_to_usec(b_clk_freq, 255);
+       ir->rc->s_timeout = sunxi_ir_set_timeout;
        ir->rc->driver_name = SUNXI_IR_DEV;
 
        ret = rc_register_device(ir->rc);
@@ -270,8 +305,7 @@ static int sunxi_ir_probe(struct platform_device *pdev)
        writel(REG_CTL_MD, ir->base+SUNXI_IR_CTL_REG);
 
        /* Set noise threshold and idle threshold */
-       writel(REG_CIR_NTHR(SUNXI_IR_RXNOISE)|REG_CIR_ITHR(SUNXI_IR_RXIDLE),
-              ir->base + SUNXI_IR_CIR_REG);
+       sunxi_ir_set_timeout(ir->rc, IR_DEFAULT_TIMEOUT);
 
        /* Invert Input Signal */
        writel(REG_RXCTL_RPPI, ir->base + SUNXI_IR_RXCTL_REG);
index a776bb8..331a905 100644 (file)
@@ -1325,12 +1325,6 @@ static int vim2m_probe(struct platform_device *pdev)
        vfd->lock = &dev->dev_mutex;
        vfd->v4l2_dev = &dev->v4l2_dev;
 
-       ret = video_register_device(vfd, VFL_TYPE_VIDEO, 0);
-       if (ret) {
-               v4l2_err(&dev->v4l2_dev, "Failed to register video device\n");
-               goto error_v4l2;
-       }
-
        video_set_drvdata(vfd, dev);
        v4l2_info(&dev->v4l2_dev,
                  "Device registered as /dev/video%d\n", vfd->num);
@@ -1345,6 +1339,12 @@ static int vim2m_probe(struct platform_device *pdev)
                goto error_dev;
        }
 
+       ret = video_register_device(vfd, VFL_TYPE_VIDEO, 0);
+       if (ret) {
+               v4l2_err(&dev->v4l2_dev, "Failed to register video device\n");
+               goto error_m2m;
+       }
+
 #ifdef CONFIG_MEDIA_CONTROLLER
        dev->mdev.dev = &pdev->dev;
        strscpy(dev->mdev.model, "vim2m", sizeof(dev->mdev.model));
@@ -1358,7 +1358,7 @@ static int vim2m_probe(struct platform_device *pdev)
                                                 MEDIA_ENT_F_PROC_VIDEO_SCALER);
        if (ret) {
                v4l2_err(&dev->v4l2_dev, "Failed to init mem2mem media controller\n");
-               goto error_dev;
+               goto error_v4l2;
        }
 
        ret = media_device_register(&dev->mdev);
@@ -1373,11 +1373,13 @@ static int vim2m_probe(struct platform_device *pdev)
 error_m2m_mc:
        v4l2_m2m_unregister_media_controller(dev->m2m_dev);
 #endif
-error_dev:
+error_v4l2:
        video_unregister_device(&dev->vfd);
        /* vim2m_device_release called by video_unregister_device to release various objects */
        return ret;
-error_v4l2:
+error_m2m:
+       v4l2_m2m_release(dev->m2m_dev);
+error_dev:
        v4l2_device_unregister(&dev->v4l2_dev);
 error_free:
        kfree(dev);
index 01a9d67..67fb3c0 100644 (file)
@@ -819,7 +819,7 @@ static int vivid_thread_vid_cap(void *data)
                        break;
 
                if (!mutex_trylock(&dev->mutex)) {
-                       schedule_timeout_uninterruptible(1);
+                       schedule();
                        continue;
                }
 
@@ -888,7 +888,9 @@ static int vivid_thread_vid_cap(void *data)
                        next_jiffies_since_start = jiffies_since_start;
 
                wait_jiffies = next_jiffies_since_start - jiffies_since_start;
-               schedule_timeout_interruptible(wait_jiffies ? wait_jiffies : 1);
+               while (jiffies - cur_jiffies < wait_jiffies &&
+                      !kthread_should_stop())
+                       schedule();
        }
        dprintk(dev, 1, "Video Capture Thread End\n");
        return 0;
index 6780687..79c57d1 100644 (file)
@@ -167,7 +167,7 @@ static int vivid_thread_vid_out(void *data)
                        break;
 
                if (!mutex_trylock(&dev->mutex)) {
-                       schedule_timeout_uninterruptible(1);
+                       schedule();
                        continue;
                }
 
@@ -233,7 +233,9 @@ static int vivid_thread_vid_out(void *data)
                        next_jiffies_since_start = jiffies_since_start;
 
                wait_jiffies = next_jiffies_since_start - jiffies_since_start;
-               schedule_timeout_interruptible(wait_jiffies ? wait_jiffies : 1);
+               while (jiffies - cur_jiffies < wait_jiffies &&
+                      !kthread_should_stop())
+                       schedule();
        }
        dprintk(dev, 1, "Video Output Thread End\n");
        return 0;
index 674507b..38fdfee 100644 (file)
@@ -69,7 +69,7 @@ static int vivid_thread_touch_cap(void *data)
                        break;
 
                if (!mutex_trylock(&dev->mutex)) {
-                       schedule_timeout_uninterruptible(1);
+                       schedule();
                        continue;
                }
                cur_jiffies = jiffies;
@@ -128,7 +128,9 @@ static int vivid_thread_touch_cap(void *data)
                        next_jiffies_since_start = jiffies_since_start;
 
                wait_jiffies = next_jiffies_since_start - jiffies_since_start;
-               schedule_timeout_interruptible(wait_jiffies ? wait_jiffies : 1);
+               while (jiffies - cur_jiffies < wait_jiffies &&
+                      !kthread_should_stop())
+                       schedule();
        }
        dprintk(dev, 1, "Touch Capture Thread End\n");
        return 0;
index 2b7522e..a1e5270 100644 (file)
@@ -142,7 +142,7 @@ static int vivid_thread_sdr_cap(void *data)
                        break;
 
                if (!mutex_trylock(&dev->mutex)) {
-                       schedule_timeout_uninterruptible(1);
+                       schedule();
                        continue;
                }
 
@@ -201,7 +201,9 @@ static int vivid_thread_sdr_cap(void *data)
                        next_jiffies_since_start = jiffies_since_start;
 
                wait_jiffies = next_jiffies_since_start - jiffies_since_start;
-               schedule_timeout_interruptible(wait_jiffies ? wait_jiffies : 1);
+               while (jiffies - cur_jiffies < wait_jiffies &&
+                      !kthread_should_stop())
+                       schedule();
        }
        dprintk(dev, 1, "SDR Capture Thread End\n");
        return 0;
index eadf28a..b9caa4b 100644 (file)
@@ -1107,11 +1107,9 @@ int vidioc_g_fmt_vid_overlay(struct file *file, void *priv,
                    ((compose->width + 7) / 8) * compose->height))
                        return -EFAULT;
        }
-       if (clipcount && win->clips) {
-               if (copy_to_user(win->clips, dev->clips_cap,
-                                clipcount * sizeof(dev->clips_cap[0])))
-                       return -EFAULT;
-       }
+       if (clipcount && win->clips)
+               memcpy(win->clips, dev->clips_cap,
+                      clipcount * sizeof(dev->clips_cap[0]));
        return 0;
 }
 
@@ -1141,9 +1139,8 @@ int vidioc_try_fmt_vid_overlay(struct file *file, void *priv,
        if (win->clipcount > MAX_CLIPS)
                win->clipcount = MAX_CLIPS;
        if (win->clipcount) {
-               if (copy_from_user(dev->try_clips_cap, win->clips,
-                                  win->clipcount * sizeof(dev->clips_cap[0])))
-                       return -EFAULT;
+               memcpy(dev->try_clips_cap, win->clips,
+                      win->clipcount * sizeof(dev->clips_cap[0]));
                for (i = 0; i < win->clipcount; i++) {
                        struct v4l2_rect *r = &dev->try_clips_cap[i].c;
 
@@ -1166,9 +1163,8 @@ int vidioc_try_fmt_vid_overlay(struct file *file, void *priv,
                                        return -EINVAL;
                        }
                }
-               if (copy_to_user(win->clips, dev->try_clips_cap,
-                                win->clipcount * sizeof(dev->clips_cap[0])))
-                       return -EFAULT;
+               memcpy(win->clips, dev->try_clips_cap,
+                      win->clipcount * sizeof(dev->clips_cap[0]));
        }
        return 0;
 }
index ee3446e..ac1e981 100644 (file)
@@ -857,11 +857,9 @@ int vidioc_g_fmt_vid_out_overlay(struct file *file, void *priv,
                    ((dev->compose_out.width + 7) / 8) * dev->compose_out.height))
                        return -EFAULT;
        }
-       if (clipcount && win->clips) {
-               if (copy_to_user(win->clips, dev->clips_out,
-                                clipcount * sizeof(dev->clips_out[0])))
-                       return -EFAULT;
-       }
+       if (clipcount && win->clips)
+               memcpy(win->clips, dev->clips_out,
+                      clipcount * sizeof(dev->clips_out[0]));
        return 0;
 }
 
@@ -891,9 +889,8 @@ int vidioc_try_fmt_vid_out_overlay(struct file *file, void *priv,
        if (win->clipcount > MAX_CLIPS)
                win->clipcount = MAX_CLIPS;
        if (win->clipcount) {
-               if (copy_from_user(dev->try_clips_out, win->clips,
-                                  win->clipcount * sizeof(dev->clips_out[0])))
-                       return -EFAULT;
+               memcpy(dev->try_clips_out, win->clips,
+                      win->clipcount * sizeof(dev->clips_out[0]));
                for (i = 0; i < win->clipcount; i++) {
                        struct v4l2_rect *r = &dev->try_clips_out[i].c;
 
@@ -916,9 +913,8 @@ int vidioc_try_fmt_vid_out_overlay(struct file *file, void *priv,
                                        return -EINVAL;
                        }
                }
-               if (copy_to_user(win->clips, dev->try_clips_out,
-                                win->clipcount * sizeof(dev->clips_out[0])))
-                       return -EFAULT;
+               memcpy(win->clips, dev->try_clips_out,
+                      win->clipcount * sizeof(dev->clips_out[0]));
        }
        return 0;
 }
index 0e7ac2b..204e618 100644 (file)
@@ -215,7 +215,7 @@ static int mt2060_set_params(struct dvb_frontend *fe)
        f_lo2 = f_lo1 - freq - IF2;
        // From the Comtech datasheet, the step used is 50kHz. The tuner chip could be more precise
        f_lo2 = ((f_lo2 + 25) / 50) * 50;
-       priv->frequency =  (f_lo1 - f_lo2 - IF2) * 1000,
+       priv->frequency =  (f_lo1 - f_lo2 - IF2) * 1000;
 
 #ifdef MT2060_SPURCHECK
        // LO-related spurs detection and correction
index 2240d21..d105431 100644 (file)
@@ -1849,7 +1849,6 @@ static int mt2063_init(struct dvb_frontend *fe)
 
        default:
                return -ENODEV;
-               break;
        }
 
        while (status >= 0 && *def) {
index 1c07e22..f6e82a8 100644 (file)
@@ -3926,15 +3926,26 @@ static int mxl5005s_reconfigure(struct dvb_frontend *fe, u32 mod_type,
        u32 bandwidth)
 {
        struct mxl5005s_state *state = fe->tuner_priv;
-
-       u8 AddrTable[MXL5005S_REG_WRITING_TABLE_LEN_MAX];
-       u8 ByteTable[MXL5005S_REG_WRITING_TABLE_LEN_MAX];
+       u8 *AddrTable;
+       u8 *ByteTable;
        int TableLen;
 
        dprintk(1, "%s(type=%d, bw=%d)\n", __func__, mod_type, bandwidth);
 
        mxl5005s_reset(fe);
 
+       AddrTable = kcalloc(MXL5005S_REG_WRITING_TABLE_LEN_MAX, sizeof(u8),
+                           GFP_KERNEL);
+       if (!AddrTable)
+               return -ENOMEM;
+
+       ByteTable = kcalloc(MXL5005S_REG_WRITING_TABLE_LEN_MAX, sizeof(u8),
+                           GFP_KERNEL);
+       if (!ByteTable) {
+               kfree(AddrTable);
+               return -ENOMEM;
+       }
+
        /* Tuner initialization stage 0 */
        MXL_GetMasterControl(ByteTable, MC_SYNTH_RESET);
        AddrTable[0] = MASTER_CONTROL_ADDR;
@@ -3949,6 +3960,9 @@ static int mxl5005s_reconfigure(struct dvb_frontend *fe, u32 mod_type,
 
        mxl5005s_writeregs(fe, AddrTable, ByteTable, TableLen);
 
+       kfree(AddrTable);
+       kfree(ByteTable);
+
        return 0;
 }
 
index aa5bc6a..c0f1185 100644 (file)
@@ -231,6 +231,7 @@ static int au0828_init_isoc(struct au0828_dev *dev, int max_packets,
        for (i = 0; i < dev->isoc_ctl.num_bufs; i++) {
                urb = usb_alloc_urb(max_packets, GFP_KERNEL);
                if (!urb) {
+                       au0828_isocdbg("cannot allocate URB\n");
                        au0828_uninit_isoc(dev);
                        return -ENOMEM;
                }
@@ -239,16 +240,14 @@ static int au0828_init_isoc(struct au0828_dev *dev, int max_packets,
                dev->isoc_ctl.transfer_buffer[i] = usb_alloc_coherent(dev->usbdev,
                        sb_size, GFP_KERNEL, &urb->transfer_dma);
                if (!dev->isoc_ctl.transfer_buffer[i]) {
-                       printk("unable to allocate %i bytes for transfer buffer %i%s\n",
-                                       sb_size, i,
-                                       in_interrupt() ? " while in int" : "");
+                       au0828_isocdbg("cannot allocate transfer buffer\n");
                        au0828_uninit_isoc(dev);
                        return -ENOMEM;
                }
                memset(dev->isoc_ctl.transfer_buffer[i], 0, sb_size);
 
                pipe = usb_rcvisocpipe(dev->usbdev,
-                                      dev->isoc_in_endpointaddr),
+                                      dev->isoc_in_endpointaddr);
 
                usb_fill_int_urb(urb, dev->usbdev, pipe,
                                 dev->isoc_ctl.transfer_buffer[i], sb_size,
index de42db6..9c71b32 100644 (file)
@@ -670,7 +670,7 @@ static int cx231xx_audio_fini(struct cx231xx *dev)
        }
 
        if (dev->adev.sndcard) {
-               snd_card_free(dev->adev.sndcard);
+               snd_card_free_when_closed(dev->adev.sndcard);
                kfree(dev->adev.alt_max_pkt_size);
                dev->adev.sndcard = NULL;
        }
index 05d91ca..727e626 100644 (file)
@@ -1061,9 +1061,8 @@ int cx231xx_init_isoc(struct cx231xx *dev, int max_packets,
                                       &urb->transfer_dma);
                if (!dev->video_mode.isoc_ctl.transfer_buffer[i]) {
                        dev_err(dev->dev,
-                               "unable to allocate %i bytes for transfer buffer %i%s\n",
-                               sb_size, i,
-                               in_interrupt() ? " while in int" : "");
+                               "unable to allocate %i bytes for transfer buffer %i\n",
+                               sb_size, i);
                        cx231xx_uninit_isoc(dev);
                        return -ENOMEM;
                }
@@ -1197,9 +1196,8 @@ int cx231xx_init_bulk(struct cx231xx *dev, int max_packets,
                                     &urb->transfer_dma);
                if (!dev->video_mode.bulk_ctl.transfer_buffer[i]) {
                        dev_err(dev->dev,
-                               "unable to allocate %i bytes for transfer buffer %i%s\n",
-                               sb_size, i,
-                               in_interrupt() ? " while in int" : "");
+                               "unable to allocate %i bytes for transfer buffer %i\n",
+                               sb_size, i);
                        cx231xx_uninit_bulk(dev);
                        return -ENOMEM;
                }
index d2f143a..fdc8b7f 100644 (file)
@@ -408,9 +408,8 @@ int cx231xx_init_vbi_isoc(struct cx231xx *dev, int max_packets,
                    kzalloc(sb_size, GFP_KERNEL);
                if (!dev->vbi_mode.bulk_ctl.transfer_buffer[i]) {
                        dev_err(dev->dev,
-                               "unable to allocate %i bytes for transfer buffer %i%s\n",
-                               sb_size, i,
-                               in_interrupt() ? " while in int" : "");
+                               "unable to allocate %i bytes for transfer buffer %i\n",
+                               sb_size, i);
                        cx231xx_uninit_vbi_isoc(dev);
                        return -ENOMEM;
                }
index 0d9657f..689829f 100644 (file)
@@ -287,8 +287,8 @@ static int dvbsky_s960_attach(struct dvb_usb_adapter *adap)
        m88ds3103_pdata.ts_clk = 16000;
        m88ds3103_pdata.ts_clk_pol = 0;
        m88ds3103_pdata.agc = 0x99;
-       m88ds3103_pdata.lnb_hv_pol = 1,
-       m88ds3103_pdata.lnb_en_pol = 1,
+       m88ds3103_pdata.lnb_hv_pol = 1;
+       m88ds3103_pdata.lnb_en_pol = 1;
 
        state->i2c_client_demod = dvb_module_probe("m88ds3103", NULL,
                                                   &d->i2c_adap,
@@ -383,15 +383,15 @@ static int dvbsky_s960c_attach(struct dvb_usb_adapter *adap)
        struct sp2_config sp2_config = {};
 
        /* attach demod */
-       m88ds3103_pdata.clk = 27000000,
-       m88ds3103_pdata.i2c_wr_max = 33,
-       m88ds3103_pdata.clk_out = 0,
-       m88ds3103_pdata.ts_mode = M88DS3103_TS_CI,
-       m88ds3103_pdata.ts_clk = 10000,
-       m88ds3103_pdata.ts_clk_pol = 1,
-       m88ds3103_pdata.agc = 0x99,
-       m88ds3103_pdata.lnb_hv_pol = 0,
-       m88ds3103_pdata.lnb_en_pol = 1,
+       m88ds3103_pdata.clk = 27000000;
+       m88ds3103_pdata.i2c_wr_max = 33;
+       m88ds3103_pdata.clk_out = 0;
+       m88ds3103_pdata.ts_mode = M88DS3103_TS_CI;
+       m88ds3103_pdata.ts_clk = 10000;
+       m88ds3103_pdata.ts_clk_pol = 1;
+       m88ds3103_pdata.agc = 0x99;
+       m88ds3103_pdata.lnb_hv_pol = 0;
+       m88ds3103_pdata.lnb_en_pol = 1;
 
        state->i2c_client_demod = dvb_module_probe("m88ds3103", NULL,
                                                   &d->i2c_adap,
index 91460e4..3952cc5 100644 (file)
@@ -955,7 +955,7 @@ static int rtl2832u_frontend_attach(struct dvb_usb_adapter *adap)
                        struct mn88472_config mn88472_config = {};
 
                        mn88472_config.fe = &adap->fe[1];
-                       mn88472_config.i2c_wr_max = 22,
+                       mn88472_config.i2c_wr_max = 22;
                        strscpy(info.type, "mn88472", I2C_NAME_SIZE);
                        mn88472_config.xtal = 20500000;
                        mn88472_config.ts_mode = SERIAL_TS_MODE;
@@ -980,7 +980,7 @@ static int rtl2832u_frontend_attach(struct dvb_usb_adapter *adap)
                        struct mn88473_config mn88473_config = {};
 
                        mn88473_config.fe = &adap->fe[1];
-                       mn88473_config.i2c_wr_max = 22,
+                       mn88473_config.i2c_wr_max = 22;
                        strscpy(info.type, "mn88473", I2C_NAME_SIZE);
                        info.addr = 0x18;
                        info.platform_data = &mn88473_config;
index ba2c1b0..72aa6a9 100644 (file)
@@ -150,7 +150,7 @@ static int zd1301_frontend_attach(struct dvb_usb_adapter *adap)
        }
        if (!pdev->dev.driver) {
                ret = -ENODEV;
-               goto err;
+               goto err_platform_device_unregister;
        }
        if (!try_module_get(pdev->dev.driver->owner)) {
                ret = -ENODEV;
index d3288c1..710c1af 100644 (file)
@@ -3074,8 +3074,8 @@ static int nim7090_tuner_attach(struct dvb_usb_adapter *adap)
        struct dib0700_adapter_state *st = adap->priv;
        struct i2c_adapter *tun_i2c = st->dib7000p_ops.get_i2c_tuner(adap->fe_adap[0].fe);
 
-       nim7090_dib0090_config.reset = st->dib7000p_ops.tuner_sleep,
-       nim7090_dib0090_config.sleep = st->dib7000p_ops.tuner_sleep,
+       nim7090_dib0090_config.reset = st->dib7000p_ops.tuner_sleep;
+       nim7090_dib0090_config.sleep = st->dib7000p_ops.tuner_sleep;
        nim7090_dib0090_config.get_adc_power = st->dib7000p_ops.get_adc_power;
 
        if (dvb_attach(dib0090_register, adap->fe_adap[0].fe, tun_i2c, &nim7090_dib0090_config) == NULL)
index a27a684..f0e686b 100644 (file)
@@ -1770,6 +1770,7 @@ enum dw2102_table_entry {
        TEVII_S660,
        PROF_7500,
        GENIATECH_SU3000,
+       HAUPPAUGE_MAX_S2,
        TERRATEC_CINERGY_S2,
        TEVII_S480_1,
        TEVII_S480_2,
@@ -1802,6 +1803,7 @@ static struct usb_device_id dw2102_table[] = {
        [TEVII_S660] = {USB_DEVICE(0x9022, USB_PID_TEVII_S660)},
        [PROF_7500] = {USB_DEVICE(0x3034, 0x7500)},
        [GENIATECH_SU3000] = {USB_DEVICE(0x1f4d, 0x3000)},
+       [HAUPPAUGE_MAX_S2] = {USB_DEVICE(0x2040, 0xd900)},
        [TERRATEC_CINERGY_S2] = {USB_DEVICE(USB_VID_TERRATEC, USB_PID_TERRATEC_CINERGY_S2_R1)},
        [TEVII_S480_1] = {USB_DEVICE(0x9022, USB_PID_TEVII_S480_1)},
        [TEVII_S480_2] = {USB_DEVICE(0x9022, USB_PID_TEVII_S480_2)},
@@ -2230,12 +2232,16 @@ static struct dvb_usb_device_properties su3000_properties = {
                }},
                }
        },
-       .num_device_descs = 8,
+       .num_device_descs = 9,
        .devices = {
                { "SU3000HD DVB-S USB2.0",
                        { &dw2102_table[GENIATECH_SU3000], NULL },
                        { NULL },
                },
+               { "Hauppauge MAX S2 or WinTV NOVA HD USB2.0",
+                       { &dw2102_table[HAUPPAUGE_MAX_S2], NULL },
+                       { NULL },
+               },
                { "Terratec Cinergy S2 USB HD",
                        { &dw2102_table[TERRATEC_CINERGY_S2], NULL },
                        { NULL },
index c07f46f..b4f661b 100644 (file)
@@ -182,7 +182,7 @@ out_rel_fw:
 
 static int gp8psk_power_ctrl(struct dvb_usb_device *d, int onoff)
 {
-       u8 status, buf;
+       u8 status = 0, buf;
        int gp_product_id = le16_to_cpu(d->udev->descriptor.idProduct);
 
        if (onoff) {
index dc968fd..4d5ab14 100644 (file)
@@ -583,9 +583,9 @@ static int em28xx_cvol_new(struct snd_card *card, struct em28xx *dev,
        struct snd_kcontrol_new tmp;
 
        memset(&tmp, 0, sizeof(tmp));
-       tmp.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
-       tmp.private_value = id,
-       tmp.name  = ctl_name,
+       tmp.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
+       tmp.private_value = id;
+       tmp.name  = ctl_name;
 
        /* Add Mute Control */
        sprintf(ctl_name, "%s Switch", name);
@@ -600,16 +600,16 @@ static int em28xx_cvol_new(struct snd_card *card, struct em28xx *dev,
                ctl_name, id);
 
        memset(&tmp, 0, sizeof(tmp));
-       tmp.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
-       tmp.private_value = id,
-       tmp.name  = ctl_name,
+       tmp.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
+       tmp.private_value = id;
+       tmp.name  = ctl_name;
 
        /* Add Volume Control */
        sprintf(ctl_name, "%s Volume", name);
        tmp.get   = em28xx_vol_get;
        tmp.put   = em28xx_vol_put;
        tmp.info  = em28xx_vol_info;
-       tmp.tlv.p = em28xx_db_scale,
+       tmp.tlv.p = em28xx_db_scale;
        kctl = snd_ctl_new1(&tmp, dev);
        err = snd_ctl_add(card, kctl);
        if (err < 0)
index 9a11158..8b6a57f 100644 (file)
@@ -1220,9 +1220,9 @@ static int sd_init_controls(struct gspca_dev *gspca_dev)
        int hflip_def;
 
        if (sd->sensor == SENSOR_OV767x) {
-               saturation_min = 0,
-               saturation_max = 6,
-               saturation_def = 3,
+               saturation_min = 0;
+               saturation_max = 6;
+               saturation_def = 3;
                brightness_min = -127;
                brightness_max = 127;
                brightness_def = 0;
@@ -1233,9 +1233,9 @@ static int sd_init_controls(struct gspca_dev *gspca_dev)
                exposure_def = 0x13;
                hflip_def = 1;
        } else {
-               saturation_min = 0,
-               saturation_max = 255,
-               saturation_def = 64,
+               saturation_min = 0;
+               saturation_max = 255;
+               saturation_def = 64;
                brightness_min = 0;
                brightness_max = 255;
                brightness_def = 0;
index 65be6f1..63882a5 100644 (file)
@@ -867,7 +867,7 @@ static void msi2500_stop_streaming(struct vb2_queue *vq)
 
        /* according to tests, at least 700us delay is required  */
        msleep(20);
-       if (!msi2500_ctrl_msg(dev, CMD_STOP_STREAMING, 0)) {
+       if (dev->udev && !msi2500_ctrl_msg(dev, CMD_STOP_STREAMING, 0)) {
                /* sleep USB IF / ADC */
                msi2500_ctrl_msg(dev, CMD_WREG, 0x01000003);
        }
@@ -1230,7 +1230,7 @@ static int msi2500_probe(struct usb_interface *intf,
        }
 
        dev->master = master;
-       master->bus_num = 0;
+       master->bus_num = -1;
        master->num_chipselect = 1;
        master->transfer_one_message = msi2500_transfer_one_message;
        spi_master_set_devdata(master, dev);
index 1fcf632..d1b984e 100644 (file)
@@ -594,7 +594,7 @@ static int pvr2_lgdt3306a_attach(struct pvr2_dvb_adapter *adap)
        lgdt3306a_config.mpeg_mode = LGDT3306A_MPEG_PARALLEL;
        lgdt3306a_config.tpclk_edge = LGDT3306A_TPCLK_FALLING_EDGE;
        lgdt3306a_config.tpvalid_polarity = LGDT3306A_TP_VALID_LOW;
-       lgdt3306a_config.xtalMHz = 25, /* demod clock MHz; 24/25 supported */
+       lgdt3306a_config.xtalMHz = 25; /* demod clock MHz; 24/25 supported */
 
        adap->i2c_client_demod[0] = dvb_module_probe("lgdt3306a", NULL,
                                                     &adap->channel.hdw->i2c_adap,
index bfba06e..3f650ed 100644 (file)
@@ -461,11 +461,12 @@ static int tm6000_alloc_urb_buffers(struct tm6000_core *dev)
        if (dev->urb_buffer)
                return 0;
 
-       dev->urb_buffer = kmalloc_array(num_bufs, sizeof(void *), GFP_KERNEL);
+       dev->urb_buffer = kmalloc_array(num_bufs, sizeof(*dev->urb_buffer),
+                                       GFP_KERNEL);
        if (!dev->urb_buffer)
                return -ENOMEM;
 
-       dev->urb_dma = kmalloc_array(num_bufs, sizeof(dma_addr_t *),
+       dev->urb_dma = kmalloc_array(num_bufs, sizeof(*dev->urb_dma),
                                     GFP_KERNEL);
        if (!dev->urb_dma)
                return -ENOMEM;
@@ -692,8 +693,6 @@ static void free_buffer(struct videobuf_queue *vq, struct tm6000_buffer *buf)
        struct tm6000_core   *dev = fh->dev;
        unsigned long flags;
 
-       BUG_ON(in_interrupt());
-
        /* We used to wait for the buffer to finish here, but this didn't work
           because, as we were keeping the state as VIDEOBUF_QUEUED,
           videobuf_queue_cancel marked it as finished for us.
index f479d89..011e694 100644 (file)
@@ -1608,8 +1608,8 @@ int uvc_ctrl_set(struct uvc_fh *handle,
                if (step == 0)
                        step = 1;
 
-               xctrl->value = min + ((u32)(xctrl->value - min) + step / 2)
-                            / step * step;
+               xctrl->value = min + DIV_ROUND_CLOSEST((u32)(xctrl->value - min),
+                                                       step) * step;
                if (mapping->data_type == UVC_CTRL_DATA_TYPE_SIGNED)
                        xctrl->value = clamp(xctrl->value, min, max);
                else
index 8c67093..1e1c6b4 100644 (file)
@@ -357,8 +357,6 @@ static void free_buffer(struct videobuf_queue *vq, struct zr364xx_buffer *buf)
 {
        _DBG("%s\n", __func__);
 
-       BUG_ON(in_interrupt());
-
        videobuf_vmalloc_free(&buf->vb);
        buf->vb.state = VIDEOBUF_NEEDS_INIT;
 }
@@ -1327,6 +1325,7 @@ static int zr364xx_board_init(struct zr364xx_camera *cam)
 {
        struct zr364xx_pipeinfo *pipe = cam->pipe;
        unsigned long i;
+       int err;
 
        DBG("board init: %p\n", cam);
        memset(pipe, 0, sizeof(*pipe));
@@ -1359,9 +1358,8 @@ static int zr364xx_board_init(struct zr364xx_camera *cam)
 
        if (i == 0) {
                printk(KERN_INFO KBUILD_MODNAME ": out of memory. Aborting\n");
-               kfree(cam->pipe->transfer_buffer);
-               cam->pipe->transfer_buffer = NULL;
-               return -ENOMEM;
+               err = -ENOMEM;
+               goto err_free;
        } else
                cam->buffer.dwFrames = i;
 
@@ -1376,9 +1374,17 @@ static int zr364xx_board_init(struct zr364xx_camera *cam)
        /*** end create system buffers ***/
 
        /* start read pipe */
-       zr364xx_start_readpipe(cam);
+       err = zr364xx_start_readpipe(cam);
+       if (err)
+               goto err_free;
+
        DBG(": board initialized\n");
        return 0;
+
+err_free:
+       kfree(cam->pipe->transfer_buffer);
+       cam->pipe->transfer_buffer = NULL;
+       return err;
 }
 
 static int zr364xx_probe(struct usb_interface *intf,
@@ -1575,10 +1581,19 @@ static int zr364xx_resume(struct usb_interface *intf)
        if (!cam->was_streaming)
                return 0;
 
-       zr364xx_start_readpipe(cam);
+       res = zr364xx_start_readpipe(cam);
+       if (res)
+               return res;
+
        res = zr364xx_prepare(cam);
-       if (!res)
-               zr364xx_start_acquire(cam);
+       if (res)
+               goto err_prepare;
+
+       zr364xx_start_acquire(cam);
+       return 0;
+
+err_prepare:
+       zr364xx_stop_readpipe(cam);
        return res;
 }
 #endif
index 3dc17eb..78007db 100644 (file)
@@ -441,3 +441,36 @@ int v4l2_fill_pixfmt(struct v4l2_pix_format *pixfmt, u32 pixelformat,
        return 0;
 }
 EXPORT_SYMBOL_GPL(v4l2_fill_pixfmt);
+
+s64 v4l2_get_link_rate(struct v4l2_ctrl_handler *handler, unsigned int mul,
+                      unsigned int div)
+{
+       struct v4l2_ctrl *ctrl;
+       s64 freq;
+
+       ctrl = v4l2_ctrl_find(handler, V4L2_CID_LINK_FREQ);
+       if (ctrl) {
+               struct v4l2_querymenu qm = { .id = V4L2_CID_LINK_FREQ };
+               int ret;
+
+               qm.index = v4l2_ctrl_g_ctrl(ctrl);
+
+               ret = v4l2_querymenu(handler, &qm);
+               if (ret)
+                       return -ENOENT;
+
+               freq = qm.value;
+       } else {
+               if (!mul || !div)
+                       return -ENOENT;
+
+               ctrl = v4l2_ctrl_find(handler, V4L2_CID_PIXEL_RATE);
+               if (!ctrl)
+                       return -ENOENT;
+
+               freq = div_u64(v4l2_ctrl_g_ctrl_int64(ctrl) * mul, div);
+       }
+
+       return freq > 0 ? freq : -EINVAL;
+}
+EXPORT_SYMBOL_GPL(v4l2_get_link_rate);
index a99e82e..0ca75f6 100644 (file)
 #include <media/v4l2-ctrls.h>
 #include <media/v4l2-ioctl.h>
 
-/**
- * assign_in_user() - Copy from one __user var to another one
- *
- * @to: __user var where data will be stored
- * @from: __user var where data will be retrieved.
- *
- * As this code very often needs to allocate userspace memory, it is easier
- * to have a macro that will do both get_user() and put_user() at once.
- *
- * This function complements the macros defined at asm-generic/uaccess.h.
- * It uses the same argument order as copy_in_user()
- */
-#define assign_in_user(to, from)                                       \
-({                                                                     \
-       typeof(*from) __assign_tmp;                                     \
-                                                                       \
-       get_user(__assign_tmp, from) || put_user(__assign_tmp, to);     \
-})
-
-/**
- * get_user_cast() - Stores at a kernelspace local var the contents from a
- *             pointer with userspace data that is not tagged with __user.
- *
- * @__x: var where data will be stored
- * @__ptr: var where data will be retrieved.
- *
- * Sometimes we need to declare a pointer without __user because it
- * comes from a pointer struct field that will be retrieved from userspace
- * by the 64-bit native ioctl handler. This function ensures that the
- * @__ptr will be cast to __user before calling get_user() in order to
- * avoid warnings with static code analyzers like smatch.
- */
-#define get_user_cast(__x, __ptr)                                      \
-({                                                                     \
-       get_user(__x, (typeof(*__ptr) __user *)(__ptr));                \
-})
-
-/**
- * put_user_force() - Stores the contents of a kernelspace local var
- *                   into a userspace pointer, removing any __user cast.
- *
- * @__x: var where data will be stored
- * @__ptr: var where data will be retrieved.
- *
- * Sometimes we need to remove the __user attribute from some data,
- * by passing the __force macro. This function ensures that the
- * @__ptr will be cast with __force before calling put_user(), in order to
- * avoid warnings with static code analyzers like smatch.
- */
-#define put_user_force(__x, __ptr)                                     \
-({                                                                     \
-       put_user((typeof(*__x) __force *)(__x), __ptr);                 \
-})
-
-/**
- * assign_in_user_cast() - Copy from one __user var to another one
- *
- * @to: __user var where data will be stored
- * @from: var where data will be retrieved that needs to be cast to __user.
- *
- * As this code very often needs to allocate userspace memory, it is easier
- * to have a macro that will do both get_user_cast() and put_user() at once.
- *
- * This function should be used instead of assign_in_user() when the @from
- * variable was not declared as __user. See get_user_cast() for more details.
- *
- * This function complements the macros defined at asm-generic/uaccess.h.
- * It uses the same argument order as copy_in_user()
- */
-#define assign_in_user_cast(to, from)                                  \
-({                                                                     \
-       typeof(*from) __assign_tmp;                                     \
-                                                                       \
-       get_user_cast(__assign_tmp, from) || put_user(__assign_tmp, to);\
-})
-
-/**
- * native_ioctl - Ancillary function that calls the native 64 bits ioctl
- * handler.
- *
- * @file: pointer to &struct file with the file handler
- * @cmd: ioctl to be called
- * @arg: arguments passed from/to the ioctl handler
- *
- * This function calls the native ioctl handler at v4l2-dev, e. g. v4l2_ioctl()
- */
-static long native_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
-{
-       long ret = -ENOIOCTLCMD;
-
-       if (file->f_op->unlocked_ioctl)
-               ret = file->f_op->unlocked_ioctl(file, cmd, arg);
-
-       return ret;
-}
-
-
 /*
  * Per-ioctl data copy handlers.
  *
@@ -150,77 +53,54 @@ struct v4l2_window32 {
        __u8                    global_alpha;
 };
 
-static int get_v4l2_window32(struct v4l2_window __user *p64,
-                            struct v4l2_window32 __user *p32,
-                            void __user *aux_buf, u32 aux_space)
+static int get_v4l2_window32(struct v4l2_window *p64,
+                            struct v4l2_window32 __user *p32)
 {
-       struct v4l2_clip32 __user *uclips;
-       struct v4l2_clip __user *kclips;
-       compat_caddr_t p;
-       u32 clipcount;
-
-       if (!access_ok(p32, sizeof(*p32)) ||
-           copy_in_user(&p64->w, &p32->w, sizeof(p32->w)) ||
-           assign_in_user(&p64->field, &p32->field) ||
-           assign_in_user(&p64->chromakey, &p32->chromakey) ||
-           assign_in_user(&p64->global_alpha, &p32->global_alpha) ||
-           get_user(clipcount, &p32->clipcount) ||
-           put_user(clipcount, &p64->clipcount))
-               return -EFAULT;
-       if (clipcount > 2048)
-               return -EINVAL;
-       if (!clipcount)
-               return put_user(NULL, &p64->clips);
+       struct v4l2_window32 w32;
 
-       if (get_user(p, &p32->clips))
-               return -EFAULT;
-       uclips = compat_ptr(p);
-       if (aux_space < clipcount * sizeof(*kclips))
-               return -EFAULT;
-       kclips = aux_buf;
-       if (put_user(kclips, &p64->clips))
+       if (copy_from_user(&w32, p32, sizeof(w32)))
                return -EFAULT;
 
-       while (clipcount--) {
-               if (copy_in_user(&kclips->c, &uclips->c, sizeof(uclips->c)))
-                       return -EFAULT;
-               if (put_user(clipcount ? kclips + 1 : NULL, &kclips->next))
-                       return -EFAULT;
-               uclips++;
-               kclips++;
-       }
+       *p64 = (struct v4l2_window) {
+               .w              = w32.w,
+               .field          = w32.field,
+               .chromakey      = w32.chromakey,
+               .clips          = (void __force *)compat_ptr(w32.clips),
+               .clipcount      = w32.clipcount,
+               .bitmap         = compat_ptr(w32.bitmap),
+               .global_alpha   = w32.global_alpha,
+       };
+
+       if (p64->clipcount > 2048)
+               return -EINVAL;
+       if (!p64->clipcount)
+               p64->clips = NULL;
+
        return 0;
 }
 
-static int put_v4l2_window32(struct v4l2_window __user *p64,
+static int put_v4l2_window32(struct v4l2_window *p64,
                             struct v4l2_window32 __user *p32)
 {
-       struct v4l2_clip __user *kclips;
-       struct v4l2_clip32 __user *uclips;
-       compat_caddr_t p;
-       u32 clipcount;
-
-       if (copy_in_user(&p32->w, &p64->w, sizeof(p64->w)) ||
-           assign_in_user(&p32->field, &p64->field) ||
-           assign_in_user(&p32->chromakey, &p64->chromakey) ||
-           assign_in_user(&p32->global_alpha, &p64->global_alpha) ||
-           get_user(clipcount, &p64->clipcount) ||
-           put_user(clipcount, &p32->clipcount))
-               return -EFAULT;
-       if (!clipcount)
-               return 0;
+       struct v4l2_window32 w32;
+
+       memset(&w32, 0, sizeof(w32));
+       w32 = (struct v4l2_window32) {
+               .w              = p64->w,
+               .field          = p64->field,
+               .chromakey      = p64->chromakey,
+               .clips          = (uintptr_t)p64->clips,
+               .clipcount      = p64->clipcount,
+               .bitmap         = ptr_to_compat(p64->bitmap),
+               .global_alpha   = p64->global_alpha,
+       };
 
-       if (get_user(kclips, &p64->clips))
+       /* copy everything except the clips pointer */
+       if (copy_to_user(p32, &w32, offsetof(struct v4l2_window32, clips)) ||
+           copy_to_user(&p32->clipcount, &w32.clipcount,
+                        sizeof(w32) - offsetof(struct v4l2_window32, clipcount)))
                return -EFAULT;
-       if (get_user(p, &p32->clips))
-               return -EFAULT;
-       uclips = compat_ptr(p);
-       while (clipcount--) {
-               if (copy_in_user(&uclips->c, &kclips->c, sizeof(uclips->c)))
-                       return -EFAULT;
-               uclips++;
-               kclips++;
-       }
+
        return 0;
 }
 
@@ -257,169 +137,99 @@ struct v4l2_create_buffers32 {
        __u32                   reserved[7];
 };
 
-static int __bufsize_v4l2_format(struct v4l2_format32 __user *p32, u32 *size)
-{
-       u32 type;
-
-       if (get_user(type, &p32->type))
-               return -EFAULT;
-
-       switch (type) {
-       case V4L2_BUF_TYPE_VIDEO_OVERLAY:
-       case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY: {
-               u32 clipcount;
-
-               if (get_user(clipcount, &p32->fmt.win.clipcount))
-                       return -EFAULT;
-               if (clipcount > 2048)
-                       return -EINVAL;
-               *size = clipcount * sizeof(struct v4l2_clip);
-               return 0;
-       }
-       default:
-               *size = 0;
-               return 0;
-       }
-}
-
-static int bufsize_v4l2_format(struct v4l2_format32 __user *p32, u32 *size)
-{
-       if (!access_ok(p32, sizeof(*p32)))
-               return -EFAULT;
-       return __bufsize_v4l2_format(p32, size);
-}
-
-static int __get_v4l2_format32(struct v4l2_format __user *p64,
-                              struct v4l2_format32 __user *p32,
-                              void __user *aux_buf, u32 aux_space)
+static int get_v4l2_format32(struct v4l2_format *p64,
+                            struct v4l2_format32 __user *p32)
 {
-       u32 type;
-
-       if (get_user(type, &p32->type) || put_user(type, &p64->type))
+       if (get_user(p64->type, &p32->type))
                return -EFAULT;
 
-       switch (type) {
+       switch (p64->type) {
        case V4L2_BUF_TYPE_VIDEO_CAPTURE:
        case V4L2_BUF_TYPE_VIDEO_OUTPUT:
-               return copy_in_user(&p64->fmt.pix, &p32->fmt.pix,
-                                   sizeof(p64->fmt.pix)) ? -EFAULT : 0;
+               return copy_from_user(&p64->fmt.pix, &p32->fmt.pix,
+                                     sizeof(p64->fmt.pix)) ? -EFAULT : 0;
        case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
        case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
-               return copy_in_user(&p64->fmt.pix_mp, &p32->fmt.pix_mp,
-                                   sizeof(p64->fmt.pix_mp)) ? -EFAULT : 0;
+               return copy_from_user(&p64->fmt.pix_mp, &p32->fmt.pix_mp,
+                                     sizeof(p64->fmt.pix_mp)) ? -EFAULT : 0;
        case V4L2_BUF_TYPE_VIDEO_OVERLAY:
        case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
-               return get_v4l2_window32(&p64->fmt.win, &p32->fmt.win,
-                                        aux_buf, aux_space);
+               return get_v4l2_window32(&p64->fmt.win, &p32->fmt.win);
        case V4L2_BUF_TYPE_VBI_CAPTURE:
        case V4L2_BUF_TYPE_VBI_OUTPUT:
-               return copy_in_user(&p64->fmt.vbi, &p32->fmt.vbi,
-                                   sizeof(p64->fmt.vbi)) ? -EFAULT : 0;
+               return copy_from_user(&p64->fmt.vbi, &p32->fmt.vbi,
+                                     sizeof(p64->fmt.vbi)) ? -EFAULT : 0;
        case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
        case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
-               return copy_in_user(&p64->fmt.sliced, &p32->fmt.sliced,
-                                   sizeof(p64->fmt.sliced)) ? -EFAULT : 0;
+               return copy_from_user(&p64->fmt.sliced, &p32->fmt.sliced,
+                                     sizeof(p64->fmt.sliced)) ? -EFAULT : 0;
        case V4L2_BUF_TYPE_SDR_CAPTURE:
        case V4L2_BUF_TYPE_SDR_OUTPUT:
-               return copy_in_user(&p64->fmt.sdr, &p32->fmt.sdr,
-                                   sizeof(p64->fmt.sdr)) ? -EFAULT : 0;
+               return copy_from_user(&p64->fmt.sdr, &p32->fmt.sdr,
+                                     sizeof(p64->fmt.sdr)) ? -EFAULT : 0;
        case V4L2_BUF_TYPE_META_CAPTURE:
        case V4L2_BUF_TYPE_META_OUTPUT:
-               return copy_in_user(&p64->fmt.meta, &p32->fmt.meta,
-                                   sizeof(p64->fmt.meta)) ? -EFAULT : 0;
+               return copy_from_user(&p64->fmt.meta, &p32->fmt.meta,
+                                     sizeof(p64->fmt.meta)) ? -EFAULT : 0;
        default:
                return -EINVAL;
        }
 }
 
-static int get_v4l2_format32(struct v4l2_format __user *p64,
-                            struct v4l2_format32 __user *p32,
-                            void __user *aux_buf, u32 aux_space)
-{
-       if (!access_ok(p32, sizeof(*p32)))
-               return -EFAULT;
-       return __get_v4l2_format32(p64, p32, aux_buf, aux_space);
-}
-
-static int bufsize_v4l2_create(struct v4l2_create_buffers32 __user *p32,
-                              u32 *size)
-{
-       if (!access_ok(p32, sizeof(*p32)))
-               return -EFAULT;
-       return __bufsize_v4l2_format(&p32->format, size);
-}
-
-static int get_v4l2_create32(struct v4l2_create_buffers __user *p64,
-                            struct v4l2_create_buffers32 __user *p32,
-                            void __user *aux_buf, u32 aux_space)
+static int get_v4l2_create32(struct v4l2_create_buffers *p64,
+                            struct v4l2_create_buffers32 __user *p32)
 {
-       if (!access_ok(p32, sizeof(*p32)) ||
-           copy_in_user(p64, p32,
-                        offsetof(struct v4l2_create_buffers32, format)))
+       if (copy_from_user(p64, p32,
+                          offsetof(struct v4l2_create_buffers32, format)))
                return -EFAULT;
-       return __get_v4l2_format32(&p64->format, &p32->format,
-                                  aux_buf, aux_space);
+       return get_v4l2_format32(&p64->format, &p32->format);
 }
 
-static int __put_v4l2_format32(struct v4l2_format __user *p64,
-                              struct v4l2_format32 __user *p32)
+static int put_v4l2_format32(struct v4l2_format *p64,
+                            struct v4l2_format32 __user *p32)
 {
-       u32 type;
-
-       if (get_user(type, &p64->type))
-               return -EFAULT;
-
-       switch (type) {
+       switch (p64->type) {
        case V4L2_BUF_TYPE_VIDEO_CAPTURE:
        case V4L2_BUF_TYPE_VIDEO_OUTPUT:
-               return copy_in_user(&p32->fmt.pix, &p64->fmt.pix,
+               return copy_to_user(&p32->fmt.pix, &p64->fmt.pix,
                                    sizeof(p64->fmt.pix)) ? -EFAULT : 0;
        case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
        case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
-               return copy_in_user(&p32->fmt.pix_mp, &p64->fmt.pix_mp,
+               return copy_to_user(&p32->fmt.pix_mp, &p64->fmt.pix_mp,
                                    sizeof(p64->fmt.pix_mp)) ? -EFAULT : 0;
        case V4L2_BUF_TYPE_VIDEO_OVERLAY:
        case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
                return put_v4l2_window32(&p64->fmt.win, &p32->fmt.win);
        case V4L2_BUF_TYPE_VBI_CAPTURE:
        case V4L2_BUF_TYPE_VBI_OUTPUT:
-               return copy_in_user(&p32->fmt.vbi, &p64->fmt.vbi,
+               return copy_to_user(&p32->fmt.vbi, &p64->fmt.vbi,
                                    sizeof(p64->fmt.vbi)) ? -EFAULT : 0;
        case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
        case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
-               return copy_in_user(&p32->fmt.sliced, &p64->fmt.sliced,
+               return copy_to_user(&p32->fmt.sliced, &p64->fmt.sliced,
                                    sizeof(p64->fmt.sliced)) ? -EFAULT : 0;
        case V4L2_BUF_TYPE_SDR_CAPTURE:
        case V4L2_BUF_TYPE_SDR_OUTPUT:
-               return copy_in_user(&p32->fmt.sdr, &p64->fmt.sdr,
+               return copy_to_user(&p32->fmt.sdr, &p64->fmt.sdr,
                                    sizeof(p64->fmt.sdr)) ? -EFAULT : 0;
        case V4L2_BUF_TYPE_META_CAPTURE:
        case V4L2_BUF_TYPE_META_OUTPUT:
-               return copy_in_user(&p32->fmt.meta, &p64->fmt.meta,
+               return copy_to_user(&p32->fmt.meta, &p64->fmt.meta,
                                    sizeof(p64->fmt.meta)) ? -EFAULT : 0;
        default:
                return -EINVAL;
        }
 }
 
-static int put_v4l2_format32(struct v4l2_format __user *p64,
-                            struct v4l2_format32 __user *p32)
-{
-       if (!access_ok(p32, sizeof(*p32)))
-               return -EFAULT;
-       return __put_v4l2_format32(p64, p32);
-}
-
-static int put_v4l2_create32(struct v4l2_create_buffers __user *p64,
+static int put_v4l2_create32(struct v4l2_create_buffers *p64,
                             struct v4l2_create_buffers32 __user *p32)
 {
-       if (!access_ok(p32, sizeof(*p32)) ||
-           copy_in_user(p32, p64,
+       if (copy_to_user(p32, p64,
                         offsetof(struct v4l2_create_buffers32, format)) ||
-           assign_in_user(&p32->capabilities, &p64->capabilities) ||
-           copy_in_user(p32->reserved, p64->reserved, sizeof(p64->reserved)))
+           put_user(p64->capabilities, &p32->capabilities) ||
+           copy_to_user(p32->reserved, p64->reserved, sizeof(p64->reserved)))
                return -EFAULT;
-       return __put_v4l2_format32(&p64->format, &p32->format);
+       return put_v4l2_format32(&p64->format, &p32->format);
 }
 
 struct v4l2_standard32 {
@@ -431,27 +241,23 @@ struct v4l2_standard32 {
        __u32                reserved[4];
 };
 
-static int get_v4l2_standard32(struct v4l2_standard __user *p64,
+static int get_v4l2_standard32(struct v4l2_standard *p64,
                               struct v4l2_standard32 __user *p32)
 {
        /* other fields are not set by the user, nor used by the driver */
-       if (!access_ok(p32, sizeof(*p32)) ||
-           assign_in_user(&p64->index, &p32->index))
-               return -EFAULT;
-       return 0;
+       return get_user(p64->index, &p32->index);
 }
 
-static int put_v4l2_standard32(struct v4l2_standard __user *p64,
+static int put_v4l2_standard32(struct v4l2_standard *p64,
                               struct v4l2_standard32 __user *p32)
 {
-       if (!access_ok(p32, sizeof(*p32)) ||
-           assign_in_user(&p32->index, &p64->index) ||
-           assign_in_user(&p32->id, &p64->id) ||
-           copy_in_user(p32->name, p64->name, sizeof(p32->name)) ||
-           copy_in_user(&p32->frameperiod, &p64->frameperiod,
+       if (put_user(p64->index, &p32->index) ||
+           put_user(p64->id, &p32->id) ||
+           copy_to_user(p32->name, p64->name, sizeof(p32->name)) ||
+           copy_to_user(&p32->frameperiod, &p64->frameperiod,
                         sizeof(p32->frameperiod)) ||
-           assign_in_user(&p32->framelines, &p64->framelines) ||
-           copy_in_user(p32->reserved, p64->reserved, sizeof(p32->reserved)))
+           put_user(p64->framelines, &p32->framelines) ||
+           copy_to_user(p32->reserved, p64->reserved, sizeof(p32->reserved)))
                return -EFAULT;
        return 0;
 }
@@ -498,6 +304,7 @@ struct v4l2_buffer32 {
        __s32                   request_fd;
 };
 
+#ifdef CONFIG_COMPAT_32BIT_TIME
 struct v4l2_buffer32_time32 {
        __u32                   index;
        __u32                   type;   /* enum v4l2_buf_type */
@@ -520,481 +327,252 @@ struct v4l2_buffer32_time32 {
        __u32                   reserved2;
        __s32                   request_fd;
 };
+#endif
 
-static int get_v4l2_plane32(struct v4l2_plane __user *p64,
+static int get_v4l2_plane32(struct v4l2_plane *p64,
                            struct v4l2_plane32 __user *p32,
                            enum v4l2_memory memory)
 {
-       compat_ulong_t p;
+       struct v4l2_plane32 plane32;
+       typeof(p64->m) m = {};
 
-       if (copy_in_user(p64, p32, 2 * sizeof(__u32)) ||
-           copy_in_user(&p64->data_offset, &p32->data_offset,
-                        sizeof(p64->data_offset)))
+       if (copy_from_user(&plane32, p32, sizeof(plane32)))
                return -EFAULT;
 
        switch (memory) {
        case V4L2_MEMORY_MMAP:
        case V4L2_MEMORY_OVERLAY:
-               if (copy_in_user(&p64->m.mem_offset, &p32->m.mem_offset,
-                                sizeof(p32->m.mem_offset)))
-                       return -EFAULT;
+               m.mem_offset = plane32.m.mem_offset;
                break;
        case V4L2_MEMORY_USERPTR:
-               if (get_user(p, &p32->m.userptr) ||
-                   put_user((unsigned long)compat_ptr(p), &p64->m.userptr))
-                       return -EFAULT;
+               m.userptr = (unsigned long)compat_ptr(plane32.m.userptr);
                break;
        case V4L2_MEMORY_DMABUF:
-               if (copy_in_user(&p64->m.fd, &p32->m.fd, sizeof(p32->m.fd)))
-                       return -EFAULT;
+               m.fd = plane32.m.fd;
                break;
        }
 
+       memset(p64, 0, sizeof(*p64));
+       *p64 = (struct v4l2_plane) {
+               .bytesused      = plane32.bytesused,
+               .length         = plane32.length,
+               .m              = m,
+               .data_offset    = plane32.data_offset,
+       };
+
        return 0;
 }
 
-static int put_v4l2_plane32(struct v4l2_plane __user *p64,
+static int put_v4l2_plane32(struct v4l2_plane *p64,
                            struct v4l2_plane32 __user *p32,
                            enum v4l2_memory memory)
 {
-       unsigned long p;
+       struct v4l2_plane32 plane32;
 
-       if (copy_in_user(p32, p64, 2 * sizeof(__u32)) ||
-           copy_in_user(&p32->data_offset, &p64->data_offset,
-                        sizeof(p64->data_offset)))
-               return -EFAULT;
+       memset(&plane32, 0, sizeof(plane32));
+       plane32 = (struct v4l2_plane32) {
+               .bytesused      = p64->bytesused,
+               .length         = p64->length,
+               .data_offset    = p64->data_offset,
+       };
 
        switch (memory) {
        case V4L2_MEMORY_MMAP:
        case V4L2_MEMORY_OVERLAY:
-               if (copy_in_user(&p32->m.mem_offset, &p64->m.mem_offset,
-                                sizeof(p64->m.mem_offset)))
-                       return -EFAULT;
+               plane32.m.mem_offset = p64->m.mem_offset;
                break;
        case V4L2_MEMORY_USERPTR:
-               if (get_user(p, &p64->m.userptr) ||
-                   put_user((compat_ulong_t)ptr_to_compat((void __user *)p),
-                            &p32->m.userptr))
-                       return -EFAULT;
+               plane32.m.userptr = (uintptr_t)(p64->m.userptr);
                break;
        case V4L2_MEMORY_DMABUF:
-               if (copy_in_user(&p32->m.fd, &p64->m.fd, sizeof(p64->m.fd)))
-                       return -EFAULT;
+               plane32.m.fd = p64->m.fd;
                break;
        }
 
-       return 0;
-}
-
-static int bufsize_v4l2_buffer(struct v4l2_buffer32 __user *p32, u32 *size)
-{
-       u32 type;
-       u32 length;
-
-       if (!access_ok(p32, sizeof(*p32)) ||
-           get_user(type, &p32->type) ||
-           get_user(length, &p32->length))
+       if (copy_to_user(p32, &plane32, sizeof(plane32)))
                return -EFAULT;
 
-       if (V4L2_TYPE_IS_MULTIPLANAR(type)) {
-               if (length > VIDEO_MAX_PLANES)
-                       return -EINVAL;
-
-               /*
-                * We don't really care if userspace decides to kill itself
-                * by passing a very big length value
-                */
-               *size = length * sizeof(struct v4l2_plane);
-       } else {
-               *size = 0;
-       }
        return 0;
 }
 
-static int bufsize_v4l2_buffer_time32(struct v4l2_buffer32_time32 __user *p32, u32 *size)
+static int get_v4l2_buffer32(struct v4l2_buffer *vb,
+                            struct v4l2_buffer32 __user *arg)
 {
-       u32 type;
-       u32 length;
+       struct v4l2_buffer32 vb32;
 
-       if (!access_ok(p32, sizeof(*p32)) ||
-           get_user(type, &p32->type) ||
-           get_user(length, &p32->length))
+       if (copy_from_user(&vb32, arg, sizeof(vb32)))
                return -EFAULT;
 
-       if (V4L2_TYPE_IS_MULTIPLANAR(type)) {
-               if (length > VIDEO_MAX_PLANES)
-                       return -EINVAL;
+       memset(vb, 0, sizeof(*vb));
+       *vb = (struct v4l2_buffer) {
+               .index          = vb32.index,
+               .type           = vb32.type,
+               .bytesused      = vb32.bytesused,
+               .flags          = vb32.flags,
+               .field          = vb32.field,
+               .timestamp.tv_sec       = vb32.timestamp.tv_sec,
+               .timestamp.tv_usec      = vb32.timestamp.tv_usec,
+               .timecode       = vb32.timecode,
+               .sequence       = vb32.sequence,
+               .memory         = vb32.memory,
+               .m.offset       = vb32.m.offset,
+               .length         = vb32.length,
+               .request_fd     = vb32.request_fd,
+       };
 
-               /*
-                * We don't really care if userspace decides to kill itself
-                * by passing a very big length value
-                */
-               *size = length * sizeof(struct v4l2_plane);
-       } else {
-               *size = 0;
+       switch (vb->memory) {
+       case V4L2_MEMORY_MMAP:
+       case V4L2_MEMORY_OVERLAY:
+               vb->m.offset = vb32.m.offset;
+               break;
+       case V4L2_MEMORY_USERPTR:
+               vb->m.userptr = (unsigned long)compat_ptr(vb32.m.userptr);
+               break;
+       case V4L2_MEMORY_DMABUF:
+               vb->m.fd = vb32.m.fd;
+               break;
        }
-       return 0;
-}
-
-static int get_v4l2_buffer32(struct v4l2_buffer __user *p64,
-                            struct v4l2_buffer32 __user *p32,
-                            void __user *aux_buf, u32 aux_space)
-{
-       u32 type;
-       u32 length;
-       s32 request_fd;
-       enum v4l2_memory memory;
-       struct v4l2_plane32 __user *uplane32;
-       struct v4l2_plane __user *uplane;
-       compat_caddr_t p;
-       int ret;
-
-       if (!access_ok(p32, sizeof(*p32)) ||
-           assign_in_user(&p64->index, &p32->index) ||
-           get_user(type, &p32->type) ||
-           put_user(type, &p64->type) ||
-           assign_in_user(&p64->flags, &p32->flags) ||
-           get_user(memory, &p32->memory) ||
-           put_user(memory, &p64->memory) ||
-           get_user(length, &p32->length) ||
-           put_user(length, &p64->length) ||
-           get_user(request_fd, &p32->request_fd) ||
-           put_user(request_fd, &p64->request_fd))
-               return -EFAULT;
-
-       if (V4L2_TYPE_IS_OUTPUT(type))
-               if (assign_in_user(&p64->bytesused, &p32->bytesused) ||
-                   assign_in_user(&p64->field, &p32->field) ||
-                   assign_in_user(&p64->timestamp.tv_sec,
-                                  &p32->timestamp.tv_sec) ||
-                   assign_in_user(&p64->timestamp.tv_usec,
-                                  &p32->timestamp.tv_usec))
-                       return -EFAULT;
-
-       if (V4L2_TYPE_IS_MULTIPLANAR(type)) {
-               u32 num_planes = length;
 
-               if (num_planes == 0) {
-                       /*
-                        * num_planes == 0 is legal, e.g. when userspace doesn't
-                        * need planes array on DQBUF
-                        */
-                       return put_user(NULL, &p64->m.planes);
-               }
-               if (num_planes > VIDEO_MAX_PLANES)
-                       return -EINVAL;
-
-               if (get_user(p, &p32->m.planes))
-                       return -EFAULT;
-
-               uplane32 = compat_ptr(p);
-               if (!access_ok(uplane32,
-                              num_planes * sizeof(*uplane32)))
-                       return -EFAULT;
-
-               /*
-                * We don't really care if userspace decides to kill itself
-                * by passing a very big num_planes value
-                */
-               if (aux_space < num_planes * sizeof(*uplane))
-                       return -EFAULT;
-
-               uplane = aux_buf;
-               if (put_user_force(uplane, &p64->m.planes))
-                       return -EFAULT;
-
-               while (num_planes--) {
-                       ret = get_v4l2_plane32(uplane, uplane32, memory);
-                       if (ret)
-                               return ret;
-                       uplane++;
-                       uplane32++;
-               }
-       } else {
-               switch (memory) {
-               case V4L2_MEMORY_MMAP:
-               case V4L2_MEMORY_OVERLAY:
-                       if (assign_in_user(&p64->m.offset, &p32->m.offset))
-                               return -EFAULT;
-                       break;
-               case V4L2_MEMORY_USERPTR: {
-                       compat_ulong_t userptr;
-
-                       if (get_user(userptr, &p32->m.userptr) ||
-                           put_user((unsigned long)compat_ptr(userptr),
-                                    &p64->m.userptr))
-                               return -EFAULT;
-                       break;
-               }
-               case V4L2_MEMORY_DMABUF:
-                       if (assign_in_user(&p64->m.fd, &p32->m.fd))
-                               return -EFAULT;
-                       break;
-               }
-       }
+       if (V4L2_TYPE_IS_MULTIPLANAR(vb->type))
+               vb->m.planes = (void __force *)
+                               compat_ptr(vb32.m.planes);
 
        return 0;
 }
 
-static int get_v4l2_buffer32_time32(struct v4l2_buffer_time32 __user *p64,
-                                   struct v4l2_buffer32_time32 __user *p32,
-                                   void __user *aux_buf, u32 aux_space)
+#ifdef CONFIG_COMPAT_32BIT_TIME
+static int get_v4l2_buffer32_time32(struct v4l2_buffer *vb,
+                                   struct v4l2_buffer32_time32 __user *arg)
 {
-       u32 type;
-       u32 length;
-       s32 request_fd;
-       enum v4l2_memory memory;
-       struct v4l2_plane32 __user *uplane32;
-       struct v4l2_plane __user *uplane;
-       compat_caddr_t p;
-       int ret;
-
-       if (!access_ok(p32, sizeof(*p32)) ||
-           assign_in_user(&p64->index, &p32->index) ||
-           get_user(type, &p32->type) ||
-           put_user(type, &p64->type) ||
-           assign_in_user(&p64->flags, &p32->flags) ||
-           get_user(memory, &p32->memory) ||
-           put_user(memory, &p64->memory) ||
-           get_user(length, &p32->length) ||
-           put_user(length, &p64->length) ||
-           get_user(request_fd, &p32->request_fd) ||
-           put_user(request_fd, &p64->request_fd))
-               return -EFAULT;
+       struct v4l2_buffer32_time32 vb32;
 
-       if (V4L2_TYPE_IS_OUTPUT(type))
-               if (assign_in_user(&p64->bytesused, &p32->bytesused) ||
-                   assign_in_user(&p64->field, &p32->field) ||
-                   assign_in_user(&p64->timestamp.tv_sec,
-                                  &p32->timestamp.tv_sec) ||
-                   assign_in_user(&p64->timestamp.tv_usec,
-                                  &p32->timestamp.tv_usec))
-                       return -EFAULT;
-
-       if (V4L2_TYPE_IS_MULTIPLANAR(type)) {
-               u32 num_planes = length;
-
-               if (num_planes == 0) {
-                       /*
-                        * num_planes == 0 is legal, e.g. when userspace doesn't
-                        * need planes array on DQBUF
-                        */
-                       return put_user(NULL, &p64->m.planes);
-               }
-               if (num_planes > VIDEO_MAX_PLANES)
-                       return -EINVAL;
-
-               if (get_user(p, &p32->m.planes))
-                       return -EFAULT;
-
-               uplane32 = compat_ptr(p);
-               if (!access_ok(uplane32,
-                              num_planes * sizeof(*uplane32)))
-                       return -EFAULT;
-
-               /*
-                * We don't really care if userspace decides to kill itself
-                * by passing a very big num_planes value
-                */
-               if (aux_space < num_planes * sizeof(*uplane))
-                       return -EFAULT;
-
-               uplane = aux_buf;
-               if (put_user_force(uplane, &p64->m.planes))
-                       return -EFAULT;
-
-               while (num_planes--) {
-                       ret = get_v4l2_plane32(uplane, uplane32, memory);
-                       if (ret)
-                               return ret;
-                       uplane++;
-                       uplane32++;
-               }
-       } else {
-               switch (memory) {
-               case V4L2_MEMORY_MMAP:
-               case V4L2_MEMORY_OVERLAY:
-                       if (assign_in_user(&p64->m.offset, &p32->m.offset))
-                               return -EFAULT;
-                       break;
-               case V4L2_MEMORY_USERPTR: {
-                       compat_ulong_t userptr;
+       if (copy_from_user(&vb32, arg, sizeof(vb32)))
+               return -EFAULT;
 
-                       if (get_user(userptr, &p32->m.userptr) ||
-                           put_user((unsigned long)compat_ptr(userptr),
-                                    &p64->m.userptr))
-                               return -EFAULT;
-                       break;
-               }
-               case V4L2_MEMORY_DMABUF:
-                       if (assign_in_user(&p64->m.fd, &p32->m.fd))
-                               return -EFAULT;
-                       break;
-               }
+       *vb = (struct v4l2_buffer) {
+               .index          = vb32.index,
+               .type           = vb32.type,
+               .bytesused      = vb32.bytesused,
+               .flags          = vb32.flags,
+               .field          = vb32.field,
+               .timestamp.tv_sec       = vb32.timestamp.tv_sec,
+               .timestamp.tv_usec      = vb32.timestamp.tv_usec,
+               .timecode       = vb32.timecode,
+               .sequence       = vb32.sequence,
+               .memory         = vb32.memory,
+               .m.offset       = vb32.m.offset,
+               .length         = vb32.length,
+               .request_fd     = vb32.request_fd,
+       };
+       switch (vb->memory) {
+       case V4L2_MEMORY_MMAP:
+       case V4L2_MEMORY_OVERLAY:
+               vb->m.offset = vb32.m.offset;
+               break;
+       case V4L2_MEMORY_USERPTR:
+               vb->m.userptr = (unsigned long)compat_ptr(vb32.m.userptr);
+               break;
+       case V4L2_MEMORY_DMABUF:
+               vb->m.fd = vb32.m.fd;
+               break;
        }
 
+       if (V4L2_TYPE_IS_MULTIPLANAR(vb->type))
+               vb->m.planes = (void __force *)
+                               compat_ptr(vb32.m.planes);
+
        return 0;
 }
+#endif
 
-static int put_v4l2_buffer32(struct v4l2_buffer __user *p64,
-                            struct v4l2_buffer32 __user *p32)
+static int put_v4l2_buffer32(struct v4l2_buffer *vb,
+                            struct v4l2_buffer32 __user *arg)
 {
-       u32 type;
-       u32 length;
-       enum v4l2_memory memory;
-       struct v4l2_plane32 __user *uplane32;
-       struct v4l2_plane *uplane;
-       compat_caddr_t p;
-       int ret;
-
-       if (!access_ok(p32, sizeof(*p32)) ||
-           assign_in_user(&p32->index, &p64->index) ||
-           get_user(type, &p64->type) ||
-           put_user(type, &p32->type) ||
-           assign_in_user(&p32->flags, &p64->flags) ||
-           get_user(memory, &p64->memory) ||
-           put_user(memory, &p32->memory))
-               return -EFAULT;
+       struct v4l2_buffer32 vb32;
+
+       memset(&vb32, 0, sizeof(vb32));
+       vb32 = (struct v4l2_buffer32) {
+               .index          = vb->index,
+               .type           = vb->type,
+               .bytesused      = vb->bytesused,
+               .flags          = vb->flags,
+               .field          = vb->field,
+               .timestamp.tv_sec       = vb->timestamp.tv_sec,
+               .timestamp.tv_usec      = vb->timestamp.tv_usec,
+               .timecode       = vb->timecode,
+               .sequence       = vb->sequence,
+               .memory         = vb->memory,
+               .m.offset       = vb->m.offset,
+               .length         = vb->length,
+               .request_fd     = vb->request_fd,
+       };
 
-       if (assign_in_user(&p32->bytesused, &p64->bytesused) ||
-           assign_in_user(&p32->field, &p64->field) ||
-           assign_in_user(&p32->timestamp.tv_sec, &p64->timestamp.tv_sec) ||
-           assign_in_user(&p32->timestamp.tv_usec, &p64->timestamp.tv_usec) ||
-           copy_in_user(&p32->timecode, &p64->timecode, sizeof(p64->timecode)) ||
-           assign_in_user(&p32->sequence, &p64->sequence) ||
-           assign_in_user(&p32->reserved2, &p64->reserved2) ||
-           assign_in_user(&p32->request_fd, &p64->request_fd) ||
-           get_user(length, &p64->length) ||
-           put_user(length, &p32->length))
-               return -EFAULT;
+       switch (vb->memory) {
+       case V4L2_MEMORY_MMAP:
+       case V4L2_MEMORY_OVERLAY:
+               vb32.m.offset = vb->m.offset;
+               break;
+       case V4L2_MEMORY_USERPTR:
+               vb32.m.userptr = (uintptr_t)(vb->m.userptr);
+               break;
+       case V4L2_MEMORY_DMABUF:
+               vb32.m.fd = vb->m.fd;
+               break;
+       }
 
-       if (V4L2_TYPE_IS_MULTIPLANAR(type)) {
-               u32 num_planes = length;
+       if (V4L2_TYPE_IS_MULTIPLANAR(vb->type))
+               vb32.m.planes = (uintptr_t)vb->m.planes;
 
-               if (num_planes == 0)
-                       return 0;
-               /* We need to define uplane without __user, even though
-                * it does point to data in userspace here. The reason is
-                * that v4l2-ioctl.c copies it from userspace to kernelspace,
-                * so its definition in videodev2.h doesn't have a
-                * __user markup. Defining uplane with __user causes
-                * smatch warnings, so instead declare it without __user
-                * and cast it as a userspace pointer to put_v4l2_plane32().
-                */
-               if (get_user(uplane, &p64->m.planes))
-                       return -EFAULT;
-               if (get_user(p, &p32->m.planes))
-                       return -EFAULT;
-               uplane32 = compat_ptr(p);
-
-               while (num_planes--) {
-                       ret = put_v4l2_plane32((void __user *)uplane,
-                                              uplane32, memory);
-                       if (ret)
-                               return ret;
-                       ++uplane;
-                       ++uplane32;
-               }
-       } else {
-               switch (memory) {
-               case V4L2_MEMORY_MMAP:
-               case V4L2_MEMORY_OVERLAY:
-                       if (assign_in_user(&p32->m.offset, &p64->m.offset))
-                               return -EFAULT;
-                       break;
-               case V4L2_MEMORY_USERPTR:
-                       if (assign_in_user(&p32->m.userptr, &p64->m.userptr))
-                               return -EFAULT;
-                       break;
-               case V4L2_MEMORY_DMABUF:
-                       if (assign_in_user(&p32->m.fd, &p64->m.fd))
-                               return -EFAULT;
-                       break;
-               }
-       }
+       if (copy_to_user(arg, &vb32, sizeof(vb32)))
+               return -EFAULT;
 
        return 0;
 }
 
-static int put_v4l2_buffer32_time32(struct v4l2_buffer_time32 __user *p64,
-                                   struct v4l2_buffer32_time32 __user *p32)
+#ifdef CONFIG_COMPAT_32BIT_TIME
+static int put_v4l2_buffer32_time32(struct v4l2_buffer *vb,
+                                   struct v4l2_buffer32_time32 __user *arg)
 {
-       u32 type;
-       u32 length;
-       enum v4l2_memory memory;
-       struct v4l2_plane32 __user *uplane32;
-       struct v4l2_plane *uplane;
-       compat_caddr_t p;
-       int ret;
-
-       if (!access_ok(p32, sizeof(*p32)) ||
-           assign_in_user(&p32->index, &p64->index) ||
-           get_user(type, &p64->type) ||
-           put_user(type, &p32->type) ||
-           assign_in_user(&p32->flags, &p64->flags) ||
-           get_user(memory, &p64->memory) ||
-           put_user(memory, &p32->memory))
-               return -EFAULT;
-
-       if (assign_in_user(&p32->bytesused, &p64->bytesused) ||
-           assign_in_user(&p32->field, &p64->field) ||
-           assign_in_user(&p32->timestamp.tv_sec, &p64->timestamp.tv_sec) ||
-           assign_in_user(&p32->timestamp.tv_usec, &p64->timestamp.tv_usec) ||
-           copy_in_user(&p32->timecode, &p64->timecode, sizeof(p64->timecode)) ||
-           assign_in_user(&p32->sequence, &p64->sequence) ||
-           assign_in_user(&p32->reserved2, &p64->reserved2) ||
-           assign_in_user(&p32->request_fd, &p64->request_fd) ||
-           get_user(length, &p64->length) ||
-           put_user(length, &p32->length))
-               return -EFAULT;
+       struct v4l2_buffer32_time32 vb32;
+
+       memset(&vb32, 0, sizeof(vb32));
+       vb32 = (struct v4l2_buffer32_time32) {
+               .index          = vb->index,
+               .type           = vb->type,
+               .bytesused      = vb->bytesused,
+               .flags          = vb->flags,
+               .field          = vb->field,
+               .timestamp.tv_sec       = vb->timestamp.tv_sec,
+               .timestamp.tv_usec      = vb->timestamp.tv_usec,
+               .timecode       = vb->timecode,
+               .sequence       = vb->sequence,
+               .memory         = vb->memory,
+               .m.offset       = vb->m.offset,
+               .length         = vb->length,
+               .request_fd     = vb->request_fd,
+       };
+       switch (vb->memory) {
+       case V4L2_MEMORY_MMAP:
+       case V4L2_MEMORY_OVERLAY:
+               vb32.m.offset = vb->m.offset;
+               break;
+       case V4L2_MEMORY_USERPTR:
+               vb32.m.userptr = (uintptr_t)(vb->m.userptr);
+               break;
+       case V4L2_MEMORY_DMABUF:
+               vb32.m.fd = vb->m.fd;
+               break;
+       }
 
-       if (V4L2_TYPE_IS_MULTIPLANAR(type)) {
-               u32 num_planes = length;
+       if (V4L2_TYPE_IS_MULTIPLANAR(vb->type))
+               vb32.m.planes = (uintptr_t)vb->m.planes;
 
-               if (num_planes == 0)
-                       return 0;
-               /* We need to define uplane without __user, even though
-                * it does point to data in userspace here. The reason is
-                * that v4l2-ioctl.c copies it from userspace to kernelspace,
-                * so its definition in videodev2.h doesn't have a
-                * __user markup. Defining uplane with __user causes
-                * smatch warnings, so instead declare it without __user
-                * and cast it as a userspace pointer to put_v4l2_plane32().
-                */
-               if (get_user(uplane, &p64->m.planes))
-                       return -EFAULT;
-               if (get_user(p, &p32->m.planes))
-                       return -EFAULT;
-               uplane32 = compat_ptr(p);
-
-               while (num_planes--) {
-                       ret = put_v4l2_plane32((void __user *)uplane,
-                                              uplane32, memory);
-                       if (ret)
-                               return ret;
-                       ++uplane;
-                       ++uplane32;
-               }
-       } else {
-               switch (memory) {
-               case V4L2_MEMORY_MMAP:
-               case V4L2_MEMORY_OVERLAY:
-                       if (assign_in_user(&p32->m.offset, &p64->m.offset))
-                               return -EFAULT;
-                       break;
-               case V4L2_MEMORY_USERPTR:
-                       if (assign_in_user(&p32->m.userptr, &p64->m.userptr))
-                               return -EFAULT;
-                       break;
-               case V4L2_MEMORY_DMABUF:
-                       if (assign_in_user(&p32->m.fd, &p64->m.fd))
-                               return -EFAULT;
-                       break;
-               }
-       }
+       if (copy_to_user(arg, &vb32, sizeof(vb32)))
+               return -EFAULT;
 
        return 0;
 }
+#endif
 
 struct v4l2_framebuffer32 {
        __u32                   capability;
@@ -1012,33 +590,30 @@ struct v4l2_framebuffer32 {
        } fmt;
 };
 
-static int get_v4l2_framebuffer32(struct v4l2_framebuffer __user *p64,
+static int get_v4l2_framebuffer32(struct v4l2_framebuffer *p64,
                                  struct v4l2_framebuffer32 __user *p32)
 {
        compat_caddr_t tmp;
 
-       if (!access_ok(p32, sizeof(*p32)) ||
-           get_user(tmp, &p32->base) ||
-           put_user_force(compat_ptr(tmp), &p64->base) ||
-           assign_in_user(&p64->capability, &p32->capability) ||
-           assign_in_user(&p64->flags, &p32->flags) ||
-           copy_in_user(&p64->fmt, &p32->fmt, sizeof(p64->fmt)))
+       if (get_user(tmp, &p32->base) ||
+           get_user(p64->capability, &p32->capability) ||
+           get_user(p64->flags, &p32->flags) ||
+           copy_from_user(&p64->fmt, &p32->fmt, sizeof(p64->fmt)))
                return -EFAULT;
+       p64->base = (void __force *)compat_ptr(tmp);
+
        return 0;
 }
 
-static int put_v4l2_framebuffer32(struct v4l2_framebuffer __user *p64,
+static int put_v4l2_framebuffer32(struct v4l2_framebuffer *p64,
                                  struct v4l2_framebuffer32 __user *p32)
 {
-       void *base;
-
-       if (!access_ok(p32, sizeof(*p32)) ||
-           get_user(base, &p64->base) ||
-           put_user(ptr_to_compat((void __user *)base), &p32->base) ||
-           assign_in_user(&p32->capability, &p64->capability) ||
-           assign_in_user(&p32->flags, &p64->flags) ||
-           copy_in_user(&p32->fmt, &p64->fmt, sizeof(p64->fmt)))
+       if (put_user((uintptr_t)p64->base, &p32->base) ||
+           put_user(p64->capability, &p32->capability) ||
+           put_user(p64->flags, &p32->flags) ||
+           copy_to_user(&p32->fmt, &p64->fmt, sizeof(p64->fmt)))
                return -EFAULT;
+
        return 0;
 }
 
@@ -1058,18 +633,18 @@ struct v4l2_input32 {
  * The 64-bit v4l2_input struct has extra padding at the end of the struct.
  * Otherwise it is identical to the 32-bit version.
  */
-static inline int get_v4l2_input32(struct v4l2_input __user *p64,
+static inline int get_v4l2_input32(struct v4l2_input *p64,
                                   struct v4l2_input32 __user *p32)
 {
-       if (copy_in_user(p64, p32, sizeof(*p32)))
+       if (copy_from_user(p64, p32, sizeof(*p32)))
                return -EFAULT;
        return 0;
 }
 
-static inline int put_v4l2_input32(struct v4l2_input __user *p64,
+static inline int put_v4l2_input32(struct v4l2_input *p64,
                                   struct v4l2_input32 __user *p32)
 {
-       if (copy_in_user(p32, p64, sizeof(*p32)))
+       if (copy_to_user(p32, p64, sizeof(*p32)))
                return -EFAULT;
        return 0;
 }
@@ -1124,142 +699,44 @@ static inline bool ctrl_is_pointer(struct file *file, u32 id)
                (qec.flags & V4L2_CTRL_FLAG_HAS_PAYLOAD);
 }
 
-static int bufsize_v4l2_ext_controls(struct v4l2_ext_controls32 __user *p32,
-                                    u32 *size)
-{
-       u32 count;
-
-       if (!access_ok(p32, sizeof(*p32)) ||
-           get_user(count, &p32->count))
-               return -EFAULT;
-       if (count > V4L2_CID_MAX_CTRLS)
-               return -EINVAL;
-       *size = count * sizeof(struct v4l2_ext_control);
-       return 0;
-}
-
-static int get_v4l2_ext_controls32(struct file *file,
-                                  struct v4l2_ext_controls __user *p64,
-                                  struct v4l2_ext_controls32 __user *p32,
-                                  void __user *aux_buf, u32 aux_space)
+static int get_v4l2_ext_controls32(struct v4l2_ext_controls *p64,
+                                  struct v4l2_ext_controls32 __user *p32)
 {
-       struct v4l2_ext_control32 __user *ucontrols;
-       struct v4l2_ext_control __user *kcontrols;
-       u32 count;
-       u32 n;
-       compat_caddr_t p;
-
-       if (!access_ok(p32, sizeof(*p32)) ||
-           assign_in_user(&p64->which, &p32->which) ||
-           get_user(count, &p32->count) ||
-           put_user(count, &p64->count) ||
-           assign_in_user(&p64->error_idx, &p32->error_idx) ||
-           assign_in_user(&p64->request_fd, &p32->request_fd) ||
-           copy_in_user(p64->reserved, p32->reserved, sizeof(p64->reserved)))
-               return -EFAULT;
+       struct v4l2_ext_controls32 ec32;
 
-       if (count == 0)
-               return put_user(NULL, &p64->controls);
-       if (count > V4L2_CID_MAX_CTRLS)
-               return -EINVAL;
-       if (get_user(p, &p32->controls))
-               return -EFAULT;
-       ucontrols = compat_ptr(p);
-       if (!access_ok(ucontrols, count * sizeof(*ucontrols)))
+       if (copy_from_user(&ec32, p32, sizeof(ec32)))
                return -EFAULT;
-       if (aux_space < count * sizeof(*kcontrols))
-               return -EFAULT;
-       kcontrols = aux_buf;
-       if (put_user_force(kcontrols, &p64->controls))
-               return -EFAULT;
-
-       for (n = 0; n < count; n++) {
-               u32 id;
-
-               if (copy_in_user(kcontrols, ucontrols, sizeof(*ucontrols)))
-                       return -EFAULT;
 
-               if (get_user(id, &kcontrols->id))
-                       return -EFAULT;
-
-               if (ctrl_is_pointer(file, id)) {
-                       void __user *s;
+       *p64 = (struct v4l2_ext_controls) {
+               .which          = ec32.which,
+               .count          = ec32.count,
+               .error_idx      = ec32.error_idx,
+               .request_fd     = ec32.request_fd,
+               .reserved[0]    = ec32.reserved[0],
+               .controls       = (void __force *)compat_ptr(ec32.controls),
+       };
 
-                       if (get_user(p, &ucontrols->string))
-                               return -EFAULT;
-                       s = compat_ptr(p);
-                       if (put_user(s, &kcontrols->string))
-                               return -EFAULT;
-               }
-               ucontrols++;
-               kcontrols++;
-       }
        return 0;
 }
 
-static int put_v4l2_ext_controls32(struct file *file,
-                                  struct v4l2_ext_controls __user *p64,
+static int put_v4l2_ext_controls32(struct v4l2_ext_controls *p64,
                                   struct v4l2_ext_controls32 __user *p32)
 {
-       struct v4l2_ext_control32 __user *ucontrols;
-       struct v4l2_ext_control *kcontrols;
-       u32 count;
-       u32 n;
-       compat_caddr_t p;
-
-       /*
-        * We need to define kcontrols without __user, even though it does
-        * point to data in userspace here. The reason is that v4l2-ioctl.c
-        * copies it from userspace to kernelspace, so its definition in
-        * videodev2.h doesn't have a __user markup. Defining kcontrols
-        * with __user causes smatch warnings, so instead declare it
-        * without __user and cast it as a userspace pointer where needed.
-        */
-       if (!access_ok(p32, sizeof(*p32)) ||
-           assign_in_user(&p32->which, &p64->which) ||
-           get_user(count, &p64->count) ||
-           put_user(count, &p32->count) ||
-           assign_in_user(&p32->error_idx, &p64->error_idx) ||
-           assign_in_user(&p32->request_fd, &p64->request_fd) ||
-           copy_in_user(p32->reserved, p64->reserved, sizeof(p32->reserved)) ||
-           get_user(kcontrols, &p64->controls))
-               return -EFAULT;
+       struct v4l2_ext_controls32 ec32;
+
+       memset(&ec32, 0, sizeof(ec32));
+       ec32 = (struct v4l2_ext_controls32) {
+               .which          = p64->which,
+               .count          = p64->count,
+               .error_idx      = p64->error_idx,
+               .request_fd     = p64->request_fd,
+               .reserved[0]    = p64->reserved[0],
+               .controls       = (uintptr_t)p64->controls,
+       };
 
-       if (!count || count > (U32_MAX/sizeof(*ucontrols)))
-               return 0;
-       if (get_user(p, &p32->controls))
-               return -EFAULT;
-       ucontrols = compat_ptr(p);
-       if (!access_ok(ucontrols, count * sizeof(*ucontrols)))
+       if (copy_to_user(p32, &ec32, sizeof(ec32)))
                return -EFAULT;
 
-       for (n = 0; n < count; n++) {
-               unsigned int size = sizeof(*ucontrols);
-               u32 id;
-
-               if (get_user_cast(id, &kcontrols->id) ||
-                   put_user(id, &ucontrols->id) ||
-                   assign_in_user_cast(&ucontrols->size, &kcontrols->size) ||
-                   copy_in_user(&ucontrols->reserved2,
-                                (void __user *)&kcontrols->reserved2,
-                                sizeof(ucontrols->reserved2)))
-                       return -EFAULT;
-
-               /*
-                * Do not modify the pointer when copying a pointer control.
-                * The contents of the pointer was changed, not the pointer
-                * itself.
-                */
-               if (ctrl_is_pointer(file, id))
-                       size -= sizeof(ucontrols->value64);
-
-               if (copy_in_user(ucontrols,
-                                (void __user *)kcontrols, size))
-                       return -EFAULT;
-
-               ucontrols++;
-               kcontrols++;
-       }
        return 0;
 }
 
@@ -1288,6 +765,7 @@ struct v4l2_event32 {
        __u32                           reserved[8];
 };
 
+#ifdef CONFIG_COMPAT_32BIT_TIME
 struct v4l2_event32_time32 {
        __u32                           type;
        union {
@@ -1300,39 +778,40 @@ struct v4l2_event32_time32 {
        __u32                           id;
        __u32                           reserved[8];
 };
+#endif
 
-static int put_v4l2_event32(struct v4l2_event __user *p64,
+static int put_v4l2_event32(struct v4l2_event *p64,
                            struct v4l2_event32 __user *p32)
 {
-       if (!access_ok(p32, sizeof(*p32)) ||
-           assign_in_user(&p32->type, &p64->type) ||
-           copy_in_user(&p32->u, &p64->u, sizeof(p64->u)) ||
-           assign_in_user(&p32->pending, &p64->pending) ||
-           assign_in_user(&p32->sequence, &p64->sequence) ||
-           assign_in_user(&p32->timestamp.tv_sec, &p64->timestamp.tv_sec) ||
-           assign_in_user(&p32->timestamp.tv_nsec, &p64->timestamp.tv_nsec) ||
-           assign_in_user(&p32->id, &p64->id) ||
-           copy_in_user(p32->reserved, p64->reserved, sizeof(p32->reserved)))
+       if (put_user(p64->type, &p32->type) ||
+           copy_to_user(&p32->u, &p64->u, sizeof(p64->u)) ||
+           put_user(p64->pending, &p32->pending) ||
+           put_user(p64->sequence, &p32->sequence) ||
+           put_user(p64->timestamp.tv_sec, &p32->timestamp.tv_sec) ||
+           put_user(p64->timestamp.tv_nsec, &p32->timestamp.tv_nsec) ||
+           put_user(p64->id, &p32->id) ||
+           copy_to_user(p32->reserved, p64->reserved, sizeof(p32->reserved)))
                return -EFAULT;
        return 0;
 }
 
-static int put_v4l2_event32_time32(struct v4l2_event_time32 __user *p64,
+#ifdef CONFIG_COMPAT_32BIT_TIME
+static int put_v4l2_event32_time32(struct v4l2_event *p64,
                                   struct v4l2_event32_time32 __user *p32)
 {
-       if (!access_ok(p32, sizeof(*p32)) ||
-           assign_in_user(&p32->type, &p64->type) ||
-           copy_in_user(&p32->u, &p64->u, sizeof(p64->u)) ||
-           assign_in_user(&p32->pending, &p64->pending) ||
-           assign_in_user(&p32->sequence, &p64->sequence) ||
-           assign_in_user(&p32->timestamp.tv_sec, &p64->timestamp.tv_sec) ||
-           assign_in_user(&p32->timestamp.tv_nsec, &p64->timestamp.tv_nsec) ||
-           assign_in_user(&p32->id, &p64->id) ||
-           copy_in_user(p32->reserved, p64->reserved, sizeof(p32->reserved)))
+       if (put_user(p64->type, &p32->type) ||
+           copy_to_user(&p32->u, &p64->u, sizeof(p64->u)) ||
+           put_user(p64->pending, &p32->pending) ||
+           put_user(p64->sequence, &p32->sequence) ||
+           put_user(p64->timestamp.tv_sec, &p32->timestamp.tv_sec) ||
+           put_user(p64->timestamp.tv_nsec, &p32->timestamp.tv_nsec) ||
+           put_user(p64->id, &p32->id) ||
+           copy_to_user(p32->reserved, p64->reserved, sizeof(p32->reserved)))
                return -EFAULT;
        return 0;
 }
 #endif
+#endif
 
 struct v4l2_edid32 {
        __u32 pad;
@@ -1342,34 +821,23 @@ struct v4l2_edid32 {
        compat_caddr_t edid;
 };
 
-static int get_v4l2_edid32(struct v4l2_edid __user *p64,
+static int get_v4l2_edid32(struct v4l2_edid *p64,
                           struct v4l2_edid32 __user *p32)
 {
-       compat_uptr_t tmp;
-
-       if (!access_ok(p32, sizeof(*p32)) ||
-           assign_in_user(&p64->pad, &p32->pad) ||
-           assign_in_user(&p64->start_block, &p32->start_block) ||
-           assign_in_user_cast(&p64->blocks, &p32->blocks) ||
-           get_user(tmp, &p32->edid) ||
-           put_user_force(compat_ptr(tmp), &p64->edid) ||
-           copy_in_user(p64->reserved, p32->reserved, sizeof(p64->reserved)))
+       compat_uptr_t edid;
+
+       if (copy_from_user(p64, p32, offsetof(struct v4l2_edid32, edid)) ||
+           get_user(edid, &p32->edid))
                return -EFAULT;
+
+       p64->edid = (void __force *)compat_ptr(edid);
        return 0;
 }
 
-static int put_v4l2_edid32(struct v4l2_edid __user *p64,
+static int put_v4l2_edid32(struct v4l2_edid *p64,
                           struct v4l2_edid32 __user *p32)
 {
-       void *edid;
-
-       if (!access_ok(p32, sizeof(*p32)) ||
-           assign_in_user(&p32->pad, &p64->pad) ||
-           assign_in_user(&p32->start_block, &p64->start_block) ||
-           assign_in_user(&p32->blocks, &p64->blocks) ||
-           get_user(edid, &p64->edid) ||
-           put_user(ptr_to_compat((void __user *)edid), &p32->edid) ||
-           copy_in_user(p32->reserved, p64->reserved, sizeof(p32->reserved)))
+       if (copy_to_user(p32, p64, offsetof(struct v4l2_edid32, edid)))
                return -EFAULT;
        return 0;
 }
@@ -1385,13 +853,10 @@ static int put_v4l2_edid32(struct v4l2_edid __user *p64,
 #define VIDIOC_G_FMT32         _IOWR('V',  4, struct v4l2_format32)
 #define VIDIOC_S_FMT32         _IOWR('V',  5, struct v4l2_format32)
 #define VIDIOC_QUERYBUF32      _IOWR('V',  9, struct v4l2_buffer32)
-#define VIDIOC_QUERYBUF32_TIME32 _IOWR('V',  9, struct v4l2_buffer32_time32)
 #define VIDIOC_G_FBUF32                _IOR ('V', 10, struct v4l2_framebuffer32)
 #define VIDIOC_S_FBUF32                _IOW ('V', 11, struct v4l2_framebuffer32)
 #define VIDIOC_QBUF32          _IOWR('V', 15, struct v4l2_buffer32)
-#define VIDIOC_QBUF32_TIME32   _IOWR('V', 15, struct v4l2_buffer32_time32)
 #define VIDIOC_DQBUF32         _IOWR('V', 17, struct v4l2_buffer32)
-#define VIDIOC_DQBUF32_TIME32  _IOWR('V', 17, struct v4l2_buffer32_time32)
 #define VIDIOC_ENUMSTD32       _IOWR('V', 25, struct v4l2_standard32)
 #define VIDIOC_ENUMINPUT32     _IOWR('V', 26, struct v4l2_input32)
 #define VIDIOC_G_EDID32                _IOWR('V', 40, struct v4l2_edid32)
@@ -1401,366 +866,359 @@ static int put_v4l2_edid32(struct v4l2_edid __user *p64,
 #define VIDIOC_S_EXT_CTRLS32    _IOWR('V', 72, struct v4l2_ext_controls32)
 #define VIDIOC_TRY_EXT_CTRLS32  _IOWR('V', 73, struct v4l2_ext_controls32)
 #define        VIDIOC_DQEVENT32        _IOR ('V', 89, struct v4l2_event32)
-#define        VIDIOC_DQEVENT32_TIME32 _IOR ('V', 89, struct v4l2_event32_time32)
 #define VIDIOC_CREATE_BUFS32   _IOWR('V', 92, struct v4l2_create_buffers32)
 #define VIDIOC_PREPARE_BUF32   _IOWR('V', 93, struct v4l2_buffer32)
-#define VIDIOC_PREPARE_BUF32_TIME32 _IOWR('V', 93, struct v4l2_buffer32_time32)
 
-#define VIDIOC_OVERLAY32       _IOW ('V', 14, s32)
-#define VIDIOC_STREAMON32      _IOW ('V', 18, s32)
-#define VIDIOC_STREAMOFF32     _IOW ('V', 19, s32)
-#define VIDIOC_G_INPUT32       _IOR ('V', 38, s32)
-#define VIDIOC_S_INPUT32       _IOWR('V', 39, s32)
-#define VIDIOC_G_OUTPUT32      _IOR ('V', 46, s32)
-#define VIDIOC_S_OUTPUT32      _IOWR('V', 47, s32)
-
-/**
- * alloc_userspace() - Allocates a 64-bits userspace pointer compatible
- *     for calling the native 64-bits version of an ioctl.
- *
- * @size:      size of the structure itself to be allocated.
- * @aux_space: extra size needed to store "extra" data, e.g. space for
- *             other __user data that is pointed to fields inside the
- *             structure.
- * @new_p64:   pointer to a pointer to be filled with the allocated struct.
- *
- * Return:
- *
- * if it can't allocate memory, either -ENOMEM or -EFAULT will be returned.
- * Zero otherwise.
- */
-static int alloc_userspace(unsigned int size, u32 aux_space,
-                          void __user **new_p64)
-{
-       *new_p64 = compat_alloc_user_space(size + aux_space);
-       if (!*new_p64)
-               return -ENOMEM;
-       if (clear_user(*new_p64, size))
-               return -EFAULT;
-       return 0;
-}
+#ifdef CONFIG_COMPAT_32BIT_TIME
+#define VIDIOC_QUERYBUF32_TIME32       _IOWR('V',  9, struct v4l2_buffer32_time32)
+#define VIDIOC_QBUF32_TIME32           _IOWR('V', 15, struct v4l2_buffer32_time32)
+#define VIDIOC_DQBUF32_TIME32          _IOWR('V', 17, struct v4l2_buffer32_time32)
+#ifdef CONFIG_X86_64
+#define        VIDIOC_DQEVENT32_TIME32         _IOR ('V', 89, struct v4l2_event32_time32)
+#endif
+#define VIDIOC_PREPARE_BUF32_TIME32    _IOWR('V', 93, struct v4l2_buffer32_time32)
+#endif
 
-/**
- * do_video_ioctl() - Ancillary function with handles a compat32 ioctl call
- *
- * @file: pointer to &struct file with the file handler
- * @cmd: ioctl to be called
- * @arg: arguments passed from/to the ioctl handler
- *
- * This function is called when a 32 bits application calls a V4L2 ioctl
- * and the Kernel is compiled with 64 bits.
- *
- * This function is called by v4l2_compat_ioctl32() when the function is
- * not private to some specific driver.
- *
- * It converts a 32-bits struct into a 64 bits one, calls the native 64-bits
- * ioctl handler and fills back the 32-bits struct with the results of the
- * native call.
- */
-static long do_video_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
+unsigned int v4l2_compat_translate_cmd(unsigned int cmd)
 {
-       void __user *p32 = compat_ptr(arg);
-       void __user *new_p64 = NULL;
-       void __user *aux_buf;
-       u32 aux_space;
-       int compatible_arg = 1;
-       long err = 0;
-       unsigned int ncmd;
-
-       /*
-        * 1. When struct size is different, converts the command.
-        */
        switch (cmd) {
-       case VIDIOC_G_FMT32: ncmd = VIDIOC_G_FMT; break;
-       case VIDIOC_S_FMT32: ncmd = VIDIOC_S_FMT; break;
-       case VIDIOC_QUERYBUF32: ncmd = VIDIOC_QUERYBUF; break;
-       case VIDIOC_QUERYBUF32_TIME32: ncmd = VIDIOC_QUERYBUF_TIME32; break;
-       case VIDIOC_G_FBUF32: ncmd = VIDIOC_G_FBUF; break;
-       case VIDIOC_S_FBUF32: ncmd = VIDIOC_S_FBUF; break;
-       case VIDIOC_QBUF32: ncmd = VIDIOC_QBUF; break;
-       case VIDIOC_QBUF32_TIME32: ncmd = VIDIOC_QBUF_TIME32; break;
-       case VIDIOC_DQBUF32: ncmd = VIDIOC_DQBUF; break;
-       case VIDIOC_DQBUF32_TIME32: ncmd = VIDIOC_DQBUF_TIME32; break;
-       case VIDIOC_ENUMSTD32: ncmd = VIDIOC_ENUMSTD; break;
-       case VIDIOC_ENUMINPUT32: ncmd = VIDIOC_ENUMINPUT; break;
-       case VIDIOC_TRY_FMT32: ncmd = VIDIOC_TRY_FMT; break;
-       case VIDIOC_G_EXT_CTRLS32: ncmd = VIDIOC_G_EXT_CTRLS; break;
-       case VIDIOC_S_EXT_CTRLS32: ncmd = VIDIOC_S_EXT_CTRLS; break;
-       case VIDIOC_TRY_EXT_CTRLS32: ncmd = VIDIOC_TRY_EXT_CTRLS; break;
+       case VIDIOC_G_FMT32:
+               return VIDIOC_G_FMT;
+       case VIDIOC_S_FMT32:
+               return VIDIOC_S_FMT;
+       case VIDIOC_TRY_FMT32:
+               return VIDIOC_TRY_FMT;
+       case VIDIOC_G_FBUF32:
+               return VIDIOC_G_FBUF;
+       case VIDIOC_S_FBUF32:
+               return VIDIOC_S_FBUF;
+#ifdef CONFIG_COMPAT_32BIT_TIME
+       case VIDIOC_QUERYBUF32_TIME32:
+               return VIDIOC_QUERYBUF;
+       case VIDIOC_QBUF32_TIME32:
+               return VIDIOC_QBUF;
+       case VIDIOC_DQBUF32_TIME32:
+               return VIDIOC_DQBUF;
+       case VIDIOC_PREPARE_BUF32_TIME32:
+               return VIDIOC_PREPARE_BUF;
+#endif
+       case VIDIOC_QUERYBUF32:
+               return VIDIOC_QUERYBUF;
+       case VIDIOC_QBUF32:
+               return VIDIOC_QBUF;
+       case VIDIOC_DQBUF32:
+               return VIDIOC_DQBUF;
+       case VIDIOC_CREATE_BUFS32:
+               return VIDIOC_CREATE_BUFS;
+       case VIDIOC_G_EXT_CTRLS32:
+               return VIDIOC_G_EXT_CTRLS;
+       case VIDIOC_S_EXT_CTRLS32:
+               return VIDIOC_S_EXT_CTRLS;
+       case VIDIOC_TRY_EXT_CTRLS32:
+               return VIDIOC_TRY_EXT_CTRLS;
+       case VIDIOC_PREPARE_BUF32:
+               return VIDIOC_PREPARE_BUF;
+       case VIDIOC_ENUMSTD32:
+               return VIDIOC_ENUMSTD;
+       case VIDIOC_ENUMINPUT32:
+               return VIDIOC_ENUMINPUT;
+       case VIDIOC_G_EDID32:
+               return VIDIOC_G_EDID;
+       case VIDIOC_S_EDID32:
+               return VIDIOC_S_EDID;
 #ifdef CONFIG_X86_64
-       case VIDIOC_DQEVENT32: ncmd = VIDIOC_DQEVENT; break;
-       case VIDIOC_DQEVENT32_TIME32: ncmd = VIDIOC_DQEVENT_TIME32; break;
+       case VIDIOC_DQEVENT32:
+               return VIDIOC_DQEVENT;
+#ifdef CONFIG_COMPAT_32BIT_TIME
+       case VIDIOC_DQEVENT32_TIME32:
+               return VIDIOC_DQEVENT;
+#endif
 #endif
-       case VIDIOC_OVERLAY32: ncmd = VIDIOC_OVERLAY; break;
-       case VIDIOC_STREAMON32: ncmd = VIDIOC_STREAMON; break;
-       case VIDIOC_STREAMOFF32: ncmd = VIDIOC_STREAMOFF; break;
-       case VIDIOC_G_INPUT32: ncmd = VIDIOC_G_INPUT; break;
-       case VIDIOC_S_INPUT32: ncmd = VIDIOC_S_INPUT; break;
-       case VIDIOC_G_OUTPUT32: ncmd = VIDIOC_G_OUTPUT; break;
-       case VIDIOC_S_OUTPUT32: ncmd = VIDIOC_S_OUTPUT; break;
-       case VIDIOC_CREATE_BUFS32: ncmd = VIDIOC_CREATE_BUFS; break;
-       case VIDIOC_PREPARE_BUF32: ncmd = VIDIOC_PREPARE_BUF; break;
-       case VIDIOC_PREPARE_BUF32_TIME32: ncmd = VIDIOC_PREPARE_BUF_TIME32; break;
-       case VIDIOC_G_EDID32: ncmd = VIDIOC_G_EDID; break;
-       case VIDIOC_S_EDID32: ncmd = VIDIOC_S_EDID; break;
-       default: ncmd = cmd; break;
        }
+       return cmd;
+}
 
-       /*
-        * 2. Allocates a 64-bits userspace pointer to store the
-        * values of the ioctl and copy data from the 32-bits __user
-        * argument into it.
-        */
+int v4l2_compat_get_user(void __user *arg, void *parg, unsigned int cmd)
+{
        switch (cmd) {
-       case VIDIOC_OVERLAY32:
-       case VIDIOC_STREAMON32:
-       case VIDIOC_STREAMOFF32:
-       case VIDIOC_S_INPUT32:
-       case VIDIOC_S_OUTPUT32:
-               err = alloc_userspace(sizeof(unsigned int), 0, &new_p64);
-               if (!err && assign_in_user((unsigned int __user *)new_p64,
-                                          (compat_uint_t __user *)p32))
-                       err = -EFAULT;
-               compatible_arg = 0;
-               break;
+       case VIDIOC_G_FMT32:
+       case VIDIOC_S_FMT32:
+       case VIDIOC_TRY_FMT32:
+               return get_v4l2_format32(parg, arg);
 
-       case VIDIOC_G_INPUT32:
-       case VIDIOC_G_OUTPUT32:
-               err = alloc_userspace(sizeof(unsigned int), 0, &new_p64);
-               compatible_arg = 0;
-               break;
+       case VIDIOC_S_FBUF32:
+               return get_v4l2_framebuffer32(parg, arg);
+#ifdef CONFIG_COMPAT_32BIT_TIME
+       case VIDIOC_QUERYBUF32_TIME32:
+       case VIDIOC_QBUF32_TIME32:
+       case VIDIOC_DQBUF32_TIME32:
+       case VIDIOC_PREPARE_BUF32_TIME32:
+               return get_v4l2_buffer32_time32(parg, arg);
+#endif
+       case VIDIOC_QUERYBUF32:
+       case VIDIOC_QBUF32:
+       case VIDIOC_DQBUF32:
+       case VIDIOC_PREPARE_BUF32:
+               return get_v4l2_buffer32(parg, arg);
+
+       case VIDIOC_G_EXT_CTRLS32:
+       case VIDIOC_S_EXT_CTRLS32:
+       case VIDIOC_TRY_EXT_CTRLS32:
+               return get_v4l2_ext_controls32(parg, arg);
+
+       case VIDIOC_CREATE_BUFS32:
+               return get_v4l2_create32(parg, arg);
+
+       case VIDIOC_ENUMSTD32:
+               return get_v4l2_standard32(parg, arg);
+
+       case VIDIOC_ENUMINPUT32:
+               return get_v4l2_input32(parg, arg);
 
        case VIDIOC_G_EDID32:
        case VIDIOC_S_EDID32:
-               err = alloc_userspace(sizeof(struct v4l2_edid), 0, &new_p64);
-               if (!err)
-                       err = get_v4l2_edid32(new_p64, p32);
-               compatible_arg = 0;
-               break;
+               return get_v4l2_edid32(parg, arg);
+       }
+       return 0;
+}
 
+int v4l2_compat_put_user(void __user *arg, void *parg, unsigned int cmd)
+{
+       switch (cmd) {
        case VIDIOC_G_FMT32:
        case VIDIOC_S_FMT32:
        case VIDIOC_TRY_FMT32:
-               err = bufsize_v4l2_format(p32, &aux_space);
-               if (!err)
-                       err = alloc_userspace(sizeof(struct v4l2_format),
-                                             aux_space, &new_p64);
-               if (!err) {
-                       aux_buf = new_p64 + sizeof(struct v4l2_format);
-                       err = get_v4l2_format32(new_p64, p32,
-                                               aux_buf, aux_space);
-               }
-               compatible_arg = 0;
-               break;
-
-       case VIDIOC_CREATE_BUFS32:
-               err = bufsize_v4l2_create(p32, &aux_space);
-               if (!err)
-                       err = alloc_userspace(sizeof(struct v4l2_create_buffers),
-                                             aux_space, &new_p64);
-               if (!err) {
-                       aux_buf = new_p64 + sizeof(struct v4l2_create_buffers);
-                       err = get_v4l2_create32(new_p64, p32,
-                                               aux_buf, aux_space);
-               }
-               compatible_arg = 0;
-               break;
+               return put_v4l2_format32(parg, arg);
 
-       case VIDIOC_PREPARE_BUF32:
-       case VIDIOC_QUERYBUF32:
-       case VIDIOC_QBUF32:
-       case VIDIOC_DQBUF32:
-               err = bufsize_v4l2_buffer(p32, &aux_space);
-               if (!err)
-                       err = alloc_userspace(sizeof(struct v4l2_buffer),
-                                             aux_space, &new_p64);
-               if (!err) {
-                       aux_buf = new_p64 + sizeof(struct v4l2_buffer);
-                       err = get_v4l2_buffer32(new_p64, p32,
-                                               aux_buf, aux_space);
-               }
-               compatible_arg = 0;
-               break;
-
-       case VIDIOC_PREPARE_BUF32_TIME32:
+       case VIDIOC_G_FBUF32:
+               return put_v4l2_framebuffer32(parg, arg);
+#ifdef CONFIG_COMPAT_32BIT_TIME
        case VIDIOC_QUERYBUF32_TIME32:
        case VIDIOC_QBUF32_TIME32:
        case VIDIOC_DQBUF32_TIME32:
-               err = bufsize_v4l2_buffer_time32(p32, &aux_space);
-               if (!err)
-                       err = alloc_userspace(sizeof(struct v4l2_buffer),
-                                             aux_space, &new_p64);
-               if (!err) {
-                       aux_buf = new_p64 + sizeof(struct v4l2_buffer);
-                       err = get_v4l2_buffer32_time32(new_p64, p32,
-                                                      aux_buf, aux_space);
-               }
-               compatible_arg = 0;
-               break;
+       case VIDIOC_PREPARE_BUF32_TIME32:
+               return put_v4l2_buffer32_time32(parg, arg);
+#endif
+       case VIDIOC_QUERYBUF32:
+       case VIDIOC_QBUF32:
+       case VIDIOC_DQBUF32:
+       case VIDIOC_PREPARE_BUF32:
+               return put_v4l2_buffer32(parg, arg);
 
-       case VIDIOC_S_FBUF32:
-               err = alloc_userspace(sizeof(struct v4l2_framebuffer), 0,
-                                     &new_p64);
-               if (!err)
-                       err = get_v4l2_framebuffer32(new_p64, p32);
-               compatible_arg = 0;
-               break;
+       case VIDIOC_G_EXT_CTRLS32:
+       case VIDIOC_S_EXT_CTRLS32:
+       case VIDIOC_TRY_EXT_CTRLS32:
+               return put_v4l2_ext_controls32(parg, arg);
 
-       case VIDIOC_G_FBUF32:
-               err = alloc_userspace(sizeof(struct v4l2_framebuffer), 0,
-                                     &new_p64);
-               compatible_arg = 0;
-               break;
+       case VIDIOC_CREATE_BUFS32:
+               return put_v4l2_create32(parg, arg);
 
        case VIDIOC_ENUMSTD32:
-               err = alloc_userspace(sizeof(struct v4l2_standard), 0,
-                                     &new_p64);
-               if (!err)
-                       err = get_v4l2_standard32(new_p64, p32);
-               compatible_arg = 0;
-               break;
+               return put_v4l2_standard32(parg, arg);
 
        case VIDIOC_ENUMINPUT32:
-               err = alloc_userspace(sizeof(struct v4l2_input), 0, &new_p64);
-               if (!err)
-                       err = get_v4l2_input32(new_p64, p32);
-               compatible_arg = 0;
-               break;
+               return put_v4l2_input32(parg, arg);
 
-       case VIDIOC_G_EXT_CTRLS32:
-       case VIDIOC_S_EXT_CTRLS32:
-       case VIDIOC_TRY_EXT_CTRLS32:
-               err = bufsize_v4l2_ext_controls(p32, &aux_space);
-               if (!err)
-                       err = alloc_userspace(sizeof(struct v4l2_ext_controls),
-                                             aux_space, &new_p64);
-               if (!err) {
-                       aux_buf = new_p64 + sizeof(struct v4l2_ext_controls);
-                       err = get_v4l2_ext_controls32(file, new_p64, p32,
-                                                     aux_buf, aux_space);
-               }
-               compatible_arg = 0;
-               break;
+       case VIDIOC_G_EDID32:
+       case VIDIOC_S_EDID32:
+               return put_v4l2_edid32(parg, arg);
 #ifdef CONFIG_X86_64
        case VIDIOC_DQEVENT32:
-               err = alloc_userspace(sizeof(struct v4l2_event), 0, &new_p64);
-               compatible_arg = 0;
-               break;
+               return put_v4l2_event32(parg, arg);
+#ifdef CONFIG_COMPAT_32BIT_TIME
        case VIDIOC_DQEVENT32_TIME32:
-               err = alloc_userspace(sizeof(struct v4l2_event_time32), 0, &new_p64);
-               compatible_arg = 0;
-               break;
+               return put_v4l2_event32_time32(parg, arg);
+#endif
 #endif
        }
-       if (err)
-               return err;
-
-       /*
-        * 3. Calls the native 64-bits ioctl handler.
-        *
-        * For the functions where a conversion was not needed,
-        * compatible_arg is true, and it will call it with the arguments
-        * provided by userspace and stored at @p32 var.
-        *
-        * Otherwise, it will pass the newly allocated @new_p64 argument.
-        */
-       if (compatible_arg)
-               err = native_ioctl(file, ncmd, (unsigned long)p32);
-       else
-               err = native_ioctl(file, ncmd, (unsigned long)new_p64);
-
-       if (err == -ENOTTY)
-               return err;
-
-       /*
-        * 4. Special case: even after an error we need to put the
-        * results back for some ioctls.
-        *
-        * In the case of EXT_CTRLS, the error_idx will contain information
-        * on which control failed.
-        *
-        * In the case of S_EDID, the driver can return E2BIG and set
-        * the blocks to maximum allowed value.
-        */
+       return 0;
+}
+
+int v4l2_compat_get_array_args(struct file *file, void *mbuf,
+                              void __user *user_ptr, size_t array_size,
+                              unsigned int cmd, void *arg)
+{
+       int err = 0;
+
        switch (cmd) {
-       case VIDIOC_G_EXT_CTRLS32:
-       case VIDIOC_S_EXT_CTRLS32:
-       case VIDIOC_TRY_EXT_CTRLS32:
-               if (put_v4l2_ext_controls32(file, new_p64, p32))
-                       err = -EFAULT;
+       case VIDIOC_G_FMT32:
+       case VIDIOC_S_FMT32:
+       case VIDIOC_TRY_FMT32: {
+               struct v4l2_format *f64 = arg;
+               struct v4l2_clip *c64 = mbuf;
+               struct v4l2_clip32 __user *c32 = user_ptr;
+               u32 clipcount = f64->fmt.win.clipcount;
+
+               if ((f64->type != V4L2_BUF_TYPE_VIDEO_OVERLAY &&
+                    f64->type != V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY) ||
+                   clipcount == 0)
+                       return 0;
+               if (clipcount > 2048)
+                       return -EINVAL;
+               while (clipcount--) {
+                       if (copy_from_user(c64, c32, sizeof(c64->c)))
+                               return -EFAULT;
+                       c64->next = NULL;
+                       c64++;
+                       c32++;
+               }
                break;
-       case VIDIOC_S_EDID32:
-               if (put_v4l2_edid32(new_p64, p32))
-                       err = -EFAULT;
+       }
+#ifdef CONFIG_COMPAT_32BIT_TIME
+       case VIDIOC_QUERYBUF32_TIME32:
+       case VIDIOC_QBUF32_TIME32:
+       case VIDIOC_DQBUF32_TIME32:
+       case VIDIOC_PREPARE_BUF32_TIME32:
+#endif
+       case VIDIOC_QUERYBUF32:
+       case VIDIOC_QBUF32:
+       case VIDIOC_DQBUF32:
+       case VIDIOC_PREPARE_BUF32: {
+               struct v4l2_buffer *b64 = arg;
+               struct v4l2_plane *p64 = mbuf;
+               struct v4l2_plane32 __user *p32 = user_ptr;
+
+               if (V4L2_TYPE_IS_MULTIPLANAR(b64->type)) {
+                       u32 num_planes = b64->length;
+
+                       if (num_planes == 0)
+                               return 0;
+
+                       while (num_planes--) {
+                               err = get_v4l2_plane32(p64, p32, b64->memory);
+                               if (err)
+                                       return err;
+                               ++p64;
+                               ++p32;
+                       }
+               }
                break;
        }
-       if (err)
-               return err;
+       case VIDIOC_G_EXT_CTRLS32:
+       case VIDIOC_S_EXT_CTRLS32:
+       case VIDIOC_TRY_EXT_CTRLS32: {
+               struct v4l2_ext_controls *ecs64 = arg;
+               struct v4l2_ext_control *ec64 = mbuf;
+               struct v4l2_ext_control32 __user *ec32 = user_ptr;
+               int n;
+
+               for (n = 0; n < ecs64->count; n++) {
+                       if (copy_from_user(ec64, ec32, sizeof(*ec32)))
+                               return -EFAULT;
 
-       /*
-        * 5. Copy the data returned at the 64 bits userspace pointer to
-        * the original 32 bits structure.
-        */
-       switch (cmd) {
-       case VIDIOC_S_INPUT32:
-       case VIDIOC_S_OUTPUT32:
-       case VIDIOC_G_INPUT32:
-       case VIDIOC_G_OUTPUT32:
-               if (assign_in_user((compat_uint_t __user *)p32,
-                                  ((unsigned int __user *)new_p64)))
-                       err = -EFAULT;
-               break;
+                       if (ctrl_is_pointer(file, ec64->id)) {
+                               compat_uptr_t p;
 
-       case VIDIOC_G_FBUF32:
-               err = put_v4l2_framebuffer32(new_p64, p32);
+                               if (get_user(p, &ec32->string))
+                                       return -EFAULT;
+                               ec64->string = compat_ptr(p);
+                       }
+                       ec32++;
+                       ec64++;
+               }
                break;
-
-#ifdef CONFIG_X86_64
-       case VIDIOC_DQEVENT32:
-               err = put_v4l2_event32(new_p64, p32);
+       }
+       default:
+               if (copy_from_user(mbuf, user_ptr, array_size))
+                       err = -EFAULT;
                break;
+       }
 
-       case VIDIOC_DQEVENT32_TIME32:
-               err = put_v4l2_event32_time32(new_p64, p32);
-               break;
-#endif
+       return err;
+}
 
-       case VIDIOC_G_EDID32:
-               err = put_v4l2_edid32(new_p64, p32);
-               break;
+int v4l2_compat_put_array_args(struct file *file, void __user *user_ptr,
+                              void *mbuf, size_t array_size,
+                              unsigned int cmd, void *arg)
+{
+       int err = 0;
 
+       switch (cmd) {
        case VIDIOC_G_FMT32:
        case VIDIOC_S_FMT32:
-       case VIDIOC_TRY_FMT32:
-               err = put_v4l2_format32(new_p64, p32);
-               break;
-
-       case VIDIOC_CREATE_BUFS32:
-               err = put_v4l2_create32(new_p64, p32);
+       case VIDIOC_TRY_FMT32: {
+               struct v4l2_format *f64 = arg;
+               struct v4l2_clip *c64 = mbuf;
+               struct v4l2_clip32 __user *c32 = user_ptr;
+               u32 clipcount = f64->fmt.win.clipcount;
+
+               if ((f64->type != V4L2_BUF_TYPE_VIDEO_OVERLAY &&
+                    f64->type != V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY) ||
+                   clipcount == 0)
+                       return 0;
+               if (clipcount > 2048)
+                       return -EINVAL;
+               while (clipcount--) {
+                       if (copy_to_user(c32, c64, sizeof(c64->c)))
+                               return -EFAULT;
+                       c64++;
+                       c32++;
+               }
                break;
-
-       case VIDIOC_PREPARE_BUF32:
+       }
+#ifdef CONFIG_COMPAT_32BIT_TIME
+       case VIDIOC_QUERYBUF32_TIME32:
+       case VIDIOC_QBUF32_TIME32:
+       case VIDIOC_DQBUF32_TIME32:
+       case VIDIOC_PREPARE_BUF32_TIME32:
+#endif
        case VIDIOC_QUERYBUF32:
        case VIDIOC_QBUF32:
        case VIDIOC_DQBUF32:
-               err = put_v4l2_buffer32(new_p64, p32);
+       case VIDIOC_PREPARE_BUF32: {
+               struct v4l2_buffer *b64 = arg;
+               struct v4l2_plane *p64 = mbuf;
+               struct v4l2_plane32 __user *p32 = user_ptr;
+
+               if (V4L2_TYPE_IS_MULTIPLANAR(b64->type)) {
+                       u32 num_planes = b64->length;
+
+                       if (num_planes == 0)
+                               return 0;
+
+                       while (num_planes--) {
+                               err = put_v4l2_plane32(p64, p32, b64->memory);
+                               if (err)
+                                       return err;
+                               ++p64;
+                               ++p32;
+                       }
+               }
                break;
+       }
+       case VIDIOC_G_EXT_CTRLS32:
+       case VIDIOC_S_EXT_CTRLS32:
+       case VIDIOC_TRY_EXT_CTRLS32: {
+               struct v4l2_ext_controls *ecs64 = arg;
+               struct v4l2_ext_control *ec64 = mbuf;
+               struct v4l2_ext_control32 __user *ec32 = user_ptr;
+               int n;
+
+               for (n = 0; n < ecs64->count; n++) {
+                       unsigned int size = sizeof(*ec32);
+                       /*
+                        * Do not modify the pointer when copying a pointer
+                        * control.  The contents of the pointer was changed,
+                        * not the pointer itself.
+                        * The structures are otherwise compatible.
+                        */
+                       if (ctrl_is_pointer(file, ec64->id))
+                               size -= sizeof(ec32->value64);
 
-       case VIDIOC_PREPARE_BUF32_TIME32:
-       case VIDIOC_QUERYBUF32_TIME32:
-       case VIDIOC_QBUF32_TIME32:
-       case VIDIOC_DQBUF32_TIME32:
-               err = put_v4l2_buffer32_time32(new_p64, p32);
-               break;
+                       if (copy_to_user(ec32, ec64, size))
+                               return -EFAULT;
 
-       case VIDIOC_ENUMSTD32:
-               err = put_v4l2_standard32(new_p64, p32);
+                       ec32++;
+                       ec64++;
+               }
                break;
-
-       case VIDIOC_ENUMINPUT32:
-               err = put_v4l2_input32(new_p64, p32);
+       }
+       default:
+               if (copy_to_user(user_ptr, mbuf, array_size))
+                       err = -EFAULT;
                break;
        }
+
        return err;
 }
 
@@ -1787,7 +1245,8 @@ long v4l2_compat_ioctl32(struct file *file, unsigned int cmd, unsigned long arg)
                return ret;
 
        if (_IOC_TYPE(cmd) == 'V' && _IOC_NR(cmd) < BASE_VIDIOC_PRIVATE)
-               ret = do_video_ioctl(file, cmd, arg);
+               ret = file->f_op->unlocked_ioctl(file, cmd,
+                                       (unsigned long)compat_ptr(arg));
        else if (vdev->fops->compat_ioctl32)
                ret = vdev->fops->compat_ioctl32(file, cmd, arg);
 
index bd7f330..ad47d00 100644 (file)
@@ -3363,9 +3363,6 @@ static int v4l2_ctrl_request_clone(struct v4l2_ctrl_handler *hdl,
                /* Skip refs inherited from other devices */
                if (ref->from_other_dev)
                        continue;
-               /* And buttons */
-               if (ctrl->type == V4L2_CTRL_TYPE_BUTTON)
-                       continue;
                err = handler_new_ref(hdl, ctrl, &new_ref, false, true);
                if (err)
                        break;
@@ -4447,8 +4444,7 @@ int v4l2_ctrl_request_setup(struct media_request *req,
                 * Skip if this control was already handled by a cluster.
                 * Skip button controls and read-only controls.
                 */
-               if (ref->req_done || ctrl->type == V4L2_CTRL_TYPE_BUTTON ||
-                   (ctrl->flags & V4L2_CTRL_FLAG_READ_ONLY))
+               if (ref->req_done || (ctrl->flags & V4L2_CTRL_FLAG_READ_ONLY))
                        continue;
 
                v4l2_ctrl_lock(master);
index d7bbe33..44dd04b 100644 (file)
@@ -93,7 +93,7 @@ v4l2_fwnode_bus_type_to_mbus(enum v4l2_fwnode_bus_type type)
        const struct v4l2_fwnode_bus_conv *conv =
                get_v4l2_fwnode_bus_conv_by_fwnode_bus(type);
 
-       return conv ? conv->mbus_type : V4L2_MBUS_UNKNOWN;
+       return conv ? conv->mbus_type : V4L2_MBUS_INVALID;
 }
 
 static const char *
@@ -416,26 +416,18 @@ static int __v4l2_fwnode_endpoint_parse(struct fwnode_handle *fwnode,
        enum v4l2_mbus_type mbus_type;
        int rval;
 
-       if (vep->bus_type == V4L2_MBUS_UNKNOWN) {
-               /* Zero fields from bus union to until the end */
-               memset(&vep->bus, 0,
-                      sizeof(*vep) - offsetof(typeof(*vep), bus));
-       }
-
        pr_debug("===== begin parsing endpoint %pfw\n", fwnode);
 
-       /*
-        * Zero the fwnode graph endpoint memory in case we don't end up parsing
-        * the endpoint.
-        */
-       memset(&vep->base, 0, sizeof(vep->base));
-
        fwnode_property_read_u32(fwnode, "bus-type", &bus_type);
        pr_debug("fwnode video bus type %s (%u), mbus type %s (%u)\n",
                 v4l2_fwnode_bus_type_to_string(bus_type), bus_type,
                 v4l2_fwnode_mbus_type_to_string(vep->bus_type),
                 vep->bus_type);
        mbus_type = v4l2_fwnode_bus_type_to_mbus(bus_type);
+       if (mbus_type == V4L2_MBUS_INVALID) {
+               pr_debug("unsupported bus type %u\n", bus_type);
+               return -EINVAL;
+       }
 
        if (vep->bus_type != V4L2_MBUS_UNKNOWN) {
                if (mbus_type != V4L2_MBUS_UNKNOWN &&
index eeff398..3198abd 100644 (file)
@@ -8,6 +8,7 @@
  *              Mauro Carvalho Chehab <mchehab@kernel.org> (version 2)
  */
 
+#include <linux/compat.h>
 #include <linux/mm.h>
 #include <linux/module.h>
 #include <linux/slab.h>
@@ -1402,6 +1403,8 @@ static void v4l_fill_fmtdesc(struct v4l2_fmtdesc *fmt)
        case V4L2_META_FMT_UVC:         descr = "UVC Payload Header Metadata"; break;
        case V4L2_META_FMT_D4XX:        descr = "Intel D4xx UVC Metadata"; break;
        case V4L2_META_FMT_VIVID:       descr = "Vivid Metadata"; break;
+       case V4L2_META_FMT_RK_ISP1_PARAMS:      descr = "Rockchip ISP1 3A Parameters"; break;
+       case V4L2_META_FMT_RK_ISP1_STAT_3A:     descr = "Rockchip ISP1 3A Statistics"; break;
 
        default:
                /* Compressed formats */
@@ -1581,7 +1584,7 @@ static int v4l_g_fmt(const struct v4l2_ioctl_ops *ops,
        switch (p->type) {
        case V4L2_BUF_TYPE_VIDEO_OVERLAY:
        case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY: {
-               struct v4l2_clip __user *clips = p->fmt.win.clips;
+               struct v4l2_clip *clips = p->fmt.win.clips;
                u32 clipcount = p->fmt.win.clipcount;
                void __user *bitmap = p->fmt.win.bitmap;
 
@@ -3083,6 +3086,27 @@ static int check_array_args(unsigned int cmd, void *parg, size_t *array_size,
                }
                break;
        }
+       case VIDIOC_G_FMT:
+       case VIDIOC_S_FMT:
+       case VIDIOC_TRY_FMT: {
+               struct v4l2_format *fmt = parg;
+
+               if (fmt->type != V4L2_BUF_TYPE_VIDEO_OVERLAY &&
+                   fmt->type != V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY)
+                       break;
+               if (fmt->fmt.win.clipcount > 2048)
+                       return -EINVAL;
+               if (!fmt->fmt.win.clipcount)
+                       break;
+
+               *user_ptr = (void __user *)fmt->fmt.win.clips;
+               *kernel_ptr = (void **)&fmt->fmt.win.clips;
+               *array_size = sizeof(struct v4l2_clip)
+                               * fmt->fmt.win.clipcount;
+
+               ret = 1;
+               break;
+       }
        }
 
        return ret;
@@ -3104,14 +3128,18 @@ static unsigned int video_translate_cmd(unsigned int cmd)
                return VIDIOC_PREPARE_BUF;
 #endif
        }
+       if (in_compat_syscall())
+               return v4l2_compat_translate_cmd(cmd);
 
        return cmd;
 }
 
-static int video_get_user(void __user *arg, void *parg, unsigned int cmd,
+static int video_get_user(void __user *arg, void *parg,
+                         unsigned int real_cmd, unsigned int cmd,
                          bool *always_copy)
 {
-       unsigned int n = _IOC_SIZE(cmd);
+       unsigned int n = _IOC_SIZE(real_cmd);
+       int err = 0;
 
        if (!(_IOC_DIR(cmd) & _IOC_WRITE)) {
                /* read-only ioctl */
@@ -3119,73 +3147,82 @@ static int video_get_user(void __user *arg, void *parg, unsigned int cmd,
                return 0;
        }
 
-       switch (cmd) {
-#ifdef CONFIG_COMPAT_32BIT_TIME
-       case VIDIOC_QUERYBUF_TIME32:
-       case VIDIOC_QBUF_TIME32:
-       case VIDIOC_DQBUF_TIME32:
-       case VIDIOC_PREPARE_BUF_TIME32: {
-               struct v4l2_buffer_time32 vb32;
-               struct v4l2_buffer *vb = parg;
-
-               if (copy_from_user(&vb32, arg, sizeof(vb32)))
-                       return -EFAULT;
-
-               *vb = (struct v4l2_buffer) {
-                       .index          = vb32.index,
-                       .type           = vb32.type,
-                       .bytesused      = vb32.bytesused,
-                       .flags          = vb32.flags,
-                       .field          = vb32.field,
-                       .timestamp.tv_sec       = vb32.timestamp.tv_sec,
-                       .timestamp.tv_usec      = vb32.timestamp.tv_usec,
-                       .timecode       = vb32.timecode,
-                       .sequence       = vb32.sequence,
-                       .memory         = vb32.memory,
-                       .m.userptr      = vb32.m.userptr,
-                       .length         = vb32.length,
-                       .request_fd     = vb32.request_fd,
-               };
-
-               if (cmd == VIDIOC_QUERYBUF_TIME32)
-                       vb->request_fd = 0;
+       /*
+        * In some cases, only a few fields are used as input,
+        * i.e. when the app sets "index" and then the driver
+        * fills in the rest of the structure for the thing
+        * with that index.  We only need to copy up the first
+        * non-input field.
+        */
+       if (v4l2_is_known_ioctl(real_cmd)) {
+               u32 flags = v4l2_ioctls[_IOC_NR(real_cmd)].flags;
 
-               break;
+               if (flags & INFO_FL_CLEAR_MASK)
+                       n = (flags & INFO_FL_CLEAR_MASK) >> 16;
+               *always_copy = flags & INFO_FL_ALWAYS_COPY;
        }
-#endif
-       default:
-               /*
-                * In some cases, only a few fields are used as input,
-                * i.e. when the app sets "index" and then the driver
-                * fills in the rest of the structure for the thing
-                * with that index.  We only need to copy up the first
-                * non-input field.
-                */
-               if (v4l2_is_known_ioctl(cmd)) {
-                       u32 flags = v4l2_ioctls[_IOC_NR(cmd)].flags;
-
-                       if (flags & INFO_FL_CLEAR_MASK)
-                               n = (flags & INFO_FL_CLEAR_MASK) >> 16;
-                       *always_copy = flags & INFO_FL_ALWAYS_COPY;
-               }
 
+       if (cmd == real_cmd) {
                if (copy_from_user(parg, (void __user *)arg, n))
-                       return -EFAULT;
-
-               /* zero out anything we don't copy from userspace */
-               if (n < _IOC_SIZE(cmd))
-                       memset((u8 *)parg + n, 0, _IOC_SIZE(cmd) - n);
-               break;
+                       err = -EFAULT;
+       } else if (in_compat_syscall()) {
+               err = v4l2_compat_get_user(arg, parg, cmd);
+       } else {
+               switch (cmd) {
+#ifdef CONFIG_COMPAT_32BIT_TIME
+               case VIDIOC_QUERYBUF_TIME32:
+               case VIDIOC_QBUF_TIME32:
+               case VIDIOC_DQBUF_TIME32:
+               case VIDIOC_PREPARE_BUF_TIME32: {
+                       struct v4l2_buffer_time32 vb32;
+                       struct v4l2_buffer *vb = parg;
+
+                       if (copy_from_user(&vb32, arg, sizeof(vb32)))
+                               return -EFAULT;
+
+                       *vb = (struct v4l2_buffer) {
+                               .index          = vb32.index,
+                                       .type           = vb32.type,
+                                       .bytesused      = vb32.bytesused,
+                                       .flags          = vb32.flags,
+                                       .field          = vb32.field,
+                                       .timestamp.tv_sec       = vb32.timestamp.tv_sec,
+                                       .timestamp.tv_usec      = vb32.timestamp.tv_usec,
+                                       .timecode       = vb32.timecode,
+                                       .sequence       = vb32.sequence,
+                                       .memory         = vb32.memory,
+                                       .m.userptr      = vb32.m.userptr,
+                                       .length         = vb32.length,
+                                       .request_fd     = vb32.request_fd,
+                       };
+                       break;
+               }
+#endif
+               }
        }
 
-       return 0;
+       /* zero out anything we don't copy from userspace */
+       if (!err && n < _IOC_SIZE(real_cmd))
+               memset((u8 *)parg + n, 0, _IOC_SIZE(real_cmd) - n);
+       return err;
 }
 
-static int video_put_user(void __user *arg, void *parg, unsigned int cmd)
+static int video_put_user(void __user *arg, void *parg,
+                         unsigned int real_cmd, unsigned int cmd)
 {
        if (!(_IOC_DIR(cmd) & _IOC_READ))
                return 0;
 
+       if (cmd == real_cmd) {
+               /*  Copy results into user buffer  */
+               if (copy_to_user(arg, parg, _IOC_SIZE(cmd)))
+                       return -EFAULT;
+               return 0;
+       }
+
+       if (in_compat_syscall())
+               return v4l2_compat_put_user(arg, parg, cmd);
+
        switch (cmd) {
 #ifdef CONFIG_COMPAT_32BIT_TIME
        case VIDIOC_DQEVENT_TIME32: {
@@ -3236,11 +3273,6 @@ static int video_put_user(void __user *arg, void *parg, unsigned int cmd)
                break;
        }
 #endif
-       default:
-               /*  Copy results into user buffer  */
-               if (copy_to_user(arg, parg, _IOC_SIZE(cmd)))
-                       return -EFAULT;
-               break;
        }
 
        return 0;
@@ -3274,8 +3306,8 @@ video_usercopy(struct file *file, unsigned int orig_cmd, unsigned long arg,
                        parg = mbuf;
                }
 
-               err = video_get_user((void __user *)arg, parg, orig_cmd,
-                                    &always_copy);
+               err = video_get_user((void __user *)arg, parg, cmd,
+                                    orig_cmd, &always_copy);
                if (err)
                        goto out;
        }
@@ -3297,7 +3329,14 @@ video_usercopy(struct file *file, unsigned int orig_cmd, unsigned long arg,
                if (NULL == mbuf)
                        goto out_array_args;
                err = -EFAULT;
-               if (copy_from_user(mbuf, user_ptr, array_size))
+               if (in_compat_syscall())
+                       err = v4l2_compat_get_array_args(file, mbuf, user_ptr,
+                                                        array_size, orig_cmd,
+                                                        parg);
+               else
+                       err = copy_from_user(mbuf, user_ptr, array_size) ?
+                                                               -EFAULT : 0;
+               if (err)
                        goto out_array_args;
                *kernel_ptr = mbuf;
        }
@@ -3318,8 +3357,17 @@ video_usercopy(struct file *file, unsigned int orig_cmd, unsigned long arg,
 
        if (has_array_args) {
                *kernel_ptr = (void __force *)user_ptr;
-               if (copy_to_user(user_ptr, mbuf, array_size))
+               if (in_compat_syscall()) {
+                       int put_err;
+
+                       put_err = v4l2_compat_put_array_args(file, user_ptr, mbuf,
+                                                            array_size, orig_cmd,
+                                                            parg);
+                       if (put_err)
+                               err = put_err;
+               } else if (copy_to_user(user_ptr, mbuf, array_size)) {
                        err = -EFAULT;
+               }
                goto out_array_args;
        }
        /*
@@ -3330,7 +3378,7 @@ video_usercopy(struct file *file, unsigned int orig_cmd, unsigned long arg,
                goto out;
 
 out_array_args:
-       if (video_put_user((void __user *)arg, parg, orig_cmd))
+       if (video_put_user((void __user *)arg, parg, cmd, orig_cmd))
                err = -EFAULT;
 out:
        kvfree(mbuf);
index a7d508e..956dafa 100644 (file)
@@ -792,21 +792,55 @@ int v4l2_subdev_link_validate_default(struct v4l2_subdev *sd,
                                      struct v4l2_subdev_format *source_fmt,
                                      struct v4l2_subdev_format *sink_fmt)
 {
+       bool pass = true;
+
        /* The width, height and code must match. */
-       if (source_fmt->format.width != sink_fmt->format.width
-           || source_fmt->format.height != sink_fmt->format.height
-           || source_fmt->format.code != sink_fmt->format.code)
-               return -EPIPE;
+       if (source_fmt->format.width != sink_fmt->format.width) {
+               dev_dbg(sd->entity.graph_obj.mdev->dev,
+                       "%s: width does not match (source %u, sink %u)\n",
+                       __func__,
+                       source_fmt->format.width, sink_fmt->format.width);
+               pass = false;
+       }
+
+       if (source_fmt->format.height != sink_fmt->format.height) {
+               dev_dbg(sd->entity.graph_obj.mdev->dev,
+                       "%s: height does not match (source %u, sink %u)\n",
+                       __func__,
+                       source_fmt->format.height, sink_fmt->format.height);
+               pass = false;
+       }
+
+       if (source_fmt->format.code != sink_fmt->format.code) {
+               dev_dbg(sd->entity.graph_obj.mdev->dev,
+                       "%s: media bus code does not match (source 0x%8.8x, sink 0x%8.8x)\n",
+                       __func__,
+                       source_fmt->format.code, sink_fmt->format.code);
+               pass = false;
+       }
 
        /* The field order must match, or the sink field order must be NONE
         * to support interlaced hardware connected to bridges that support
         * progressive formats only.
         */
        if (source_fmt->format.field != sink_fmt->format.field &&
-           sink_fmt->format.field != V4L2_FIELD_NONE)
-               return -EPIPE;
+           sink_fmt->format.field != V4L2_FIELD_NONE) {
+               dev_dbg(sd->entity.graph_obj.mdev->dev,
+                       "%s: field does not match (source %u, sink %u)\n",
+                       __func__,
+                       source_fmt->format.field, sink_fmt->format.field);
+               pass = false;
+       }
 
-       return 0;
+       if (pass)
+               return 0;
+
+       dev_dbg(sd->entity.graph_obj.mdev->dev,
+               "%s: link was \"%s\":%u -> \"%s\":%u\n", __func__,
+               link->source->entity->name, link->source->index,
+               link->sink->entity->name, link->sink->index);
+
+       return -EPIPE;
 }
 EXPORT_SYMBOL_GPL(v4l2_subdev_link_validate_default);
 
index 747c6cf..e8996b1 100644 (file)
@@ -44,6 +44,4 @@ source "drivers/staging/media/tegra-video/Kconfig"
 
 source "drivers/staging/media/ipu3/Kconfig"
 
-source "drivers/staging/media/rkisp1/Kconfig"
-
 endif
index b595718..24b5873 100644 (file)
@@ -10,5 +10,4 @@ obj-$(CONFIG_VIDEO_TEGRA)     += tegra-video/
 obj-$(CONFIG_TEGRA_VDE)                += tegra-vde/
 obj-$(CONFIG_VIDEO_HANTRO)     += hantro/
 obj-$(CONFIG_VIDEO_IPU3_IMGU)  += ipu3/
-obj-$(CONFIG_VIDEO_ROCKCHIP_ISP1)      += rkisp1/
 obj-$(CONFIG_VIDEO_ZORAN)      += zoran/
index 21ebf77..db77fef 100644 (file)
@@ -1123,7 +1123,6 @@ static int csi_link_validate(struct v4l2_subdev *sd,
        priv->upstream_ep = upstream_ep;
        is_csi2 = !is_parallel_bus(&upstream_ep);
        if (is_csi2) {
-               int vc_num = 0;
                /*
                 * NOTE! It seems the virtual channels from the mipi csi-2
                 * receiver are used only for routing by the video mux's,
@@ -1131,14 +1130,7 @@ static int csi_link_validate(struct v4l2_subdev *sd,
                 * enters the CSI's however, they are treated internally
                 * in the IPU as virtual channel 0.
                 */
-#if 0
-               mutex_unlock(&priv->lock);
-               vc_num = imx_media_find_mipi_csi2_channel(&priv->sd.entity);
-               if (vc_num < 0)
-                       return vc_num;
-               mutex_lock(&priv->lock);
-#endif
-               ipu_csi_set_mipi_datatype(priv->csi, vc_num,
+               ipu_csi_set_mipi_datatype(priv->csi, 0,
                                          &priv->format_mbus[CSI_SINK_PAD]);
        }
 
index 3a45c1f..edd8edd 100644 (file)
@@ -418,7 +418,7 @@ struct ipu3_uapi_af_config_s {
         IPU3_UAPI_AWB_FR_SPARE_FOR_BUBBLES) * IPU3_UAPI_MAX_STRIPES)
 
 /**
- * struct ipu3_uapi_awb_fr_meta_data - AWB filter response meta data
+ * struct ipu3_uapi_awb_fr_raw_buffer - AWB filter response meta data
  *
  * @meta_data: Statistics output on the grid after convolving with 1D filter.
  */
@@ -1506,7 +1506,7 @@ struct ipu3_uapi_sharp_cfg {
 } __packed;
 
 /**
- * struct struct ipu3_uapi_far_w - Sharpening config for far sub-group
+ * struct ipu3_uapi_far_w - Sharpening config for far sub-group
  *
  * @dir_shrp:  Weight of wide direct sharpening, u1.6, range [0, 64], default 64.
  * @reserved0: reserved
@@ -1526,7 +1526,7 @@ struct ipu3_uapi_far_w {
 } __packed;
 
 /**
- * struct struct ipu3_uapi_unsharp_cfg - Unsharp config
+ * struct ipu3_uapi_unsharp_cfg - Unsharp config
  *
  * @unsharp_weight: Unsharp mask blending weight.
  *                 u1.6, range [0, 64], default 16.
@@ -1772,7 +1772,7 @@ struct ipu3_uapi_vss_lut_y {
 } __packed;
 
 /**
- * struct ipu3_uapi_yuvp1_iefd_vssnlm_cf - IEFd Vssnlm Lookup table
+ * struct ipu3_uapi_yuvp1_iefd_vssnlm_cfg - IEFd Vssnlm Lookup table
  *
  * @vss_lut_x: vss lookup table. See &ipu3_uapi_vss_lut_x description
  * @vss_lut_y: vss lookup table. See &ipu3_uapi_vss_lut_y description
diff --git a/drivers/staging/media/rkisp1/Documentation/devicetree/bindings/media/rockchip-isp1.yaml b/drivers/staging/media/rkisp1/Documentation/devicetree/bindings/media/rockchip-isp1.yaml
deleted file mode 100644 (file)
index af246b7..0000000
+++ /dev/null
@@ -1,192 +0,0 @@
-# SPDX-License-Identifier: (GPL-2.0+ OR MIT)
-%YAML 1.2
----
-$id: http://devicetree.org/schemas/media/rockchip-isp1.yaml#
-$schema: http://devicetree.org/meta-schemas/core.yaml#
-
-title: Rockchip SoC Image Signal Processing unit v1
-
-maintainers:
-  - Helen Koike <helen.koike@collabora.com>
-
-description: |
-  Rockchip ISP1 is the Camera interface for the Rockchip series of SoCs
-  which contains image processing, scaling, and compression functions.
-
-properties:
-  compatible:
-    const: rockchip,rk3399-cif-isp
-
-  reg:
-    maxItems: 1
-
-  interrupts:
-    maxItems: 1
-
-  iommus:
-    maxItems: 1
-
-  power-domains:
-    maxItems: 1
-
-  phys:
-    maxItems: 1
-    description: phandle for the PHY port
-
-  phy-names:
-    const: dphy
-
-  clocks:
-    items:
-      - description: ISP clock
-      - description: ISP AXI clock clock
-      - description: ISP AXI clock  wrapper clock
-      - description: ISP AHB clock clock
-      - description: ISP AHB wrapper clock
-
-  clock-names:
-    items:
-      - const: clk_isp
-      - const: aclk_isp
-      - const: aclk_isp_wrap
-      - const: hclk_isp
-      - const: hclk_isp_wrap
-
-  # See ./video-interfaces.txt for details
-  ports:
-    type: object
-    additionalProperties: false
-
-    properties:
-      "#address-cells":
-        const: 1
-
-      "#size-cells":
-        const: 0
-
-      port@0:
-        type: object
-        description: connection point for sensors at MIPI-DPHY RX0
-        additionalProperties: false
-
-        properties:
-          "#address-cells":
-            const: 1
-
-          "#size-cells":
-            const: 0
-
-          reg:
-            const: 0
-
-        patternProperties:
-          endpoint:
-            type: object
-            additionalProperties: false
-
-            properties:
-              reg:
-                maxItems: 1
-
-              data-lanes:
-                minItems: 1
-                maxItems: 4
-
-              remote-endpoint: true
-
-    required:
-      - port@0
-
-required:
-  - compatible
-  - interrupts
-  - clocks
-  - clock-names
-  - power-domains
-  - iommus
-  - phys
-  - phy-names
-  - ports
-
-additionalProperties: false
-
-examples:
-  - |
-
-    #include <dt-bindings/clock/rk3399-cru.h>
-    #include <dt-bindings/interrupt-controller/arm-gic.h>
-    #include <dt-bindings/power/rk3399-power.h>
-
-    parent0: parent@0 {
-        #address-cells = <2>;
-        #size-cells = <2>;
-
-        isp0: isp0@ff910000 {
-            compatible = "rockchip,rk3399-cif-isp";
-            reg = <0x0 0xff910000 0x0 0x4000>;
-            interrupts = <GIC_SPI 43 IRQ_TYPE_LEVEL_HIGH 0>;
-            clocks = <&cru SCLK_ISP0>,
-                     <&cru ACLK_ISP0>, <&cru ACLK_ISP0_WRAPPER>,
-                     <&cru HCLK_ISP0>, <&cru HCLK_ISP0_WRAPPER>;
-            clock-names = "clk_isp",
-                          "aclk_isp", "aclk_isp_wrap",
-                          "hclk_isp", "hclk_isp_wrap";
-            power-domains = <&power RK3399_PD_ISP0>;
-            iommus = <&isp0_mmu>;
-            phys = <&dphy>;
-            phy-names = "dphy";
-
-            ports {
-                #address-cells = <1>;
-                #size-cells = <0>;
-
-                port@0 {
-                    #address-cells = <1>;
-                    #size-cells = <0>;
-                    reg = <0>;
-
-                    mipi_in_wcam: endpoint@0 {
-                        reg = <0>;
-                        remote-endpoint = <&wcam_out>;
-                        data-lanes = <1 2>;
-                    };
-
-                    mipi_in_ucam: endpoint@1 {
-                        reg = <1>;
-                        remote-endpoint = <&ucam_out>;
-                        data-lanes = <1>;
-                    };
-                };
-            };
-        };
-
-        i2c7: i2c@ff160000 {
-            clock-frequency = <400000>;
-            #address-cells = <1>;
-            #size-cells = <0>;
-
-            wcam: camera@36 {
-                compatible = "ovti,ov5695";
-                reg = <0x36>;
-
-                port {
-                    wcam_out: endpoint {
-                        remote-endpoint = <&mipi_in_wcam>;
-                        data-lanes = <1 2>;
-                    };
-                };
-            };
-
-            ucam: camera@3c {
-                compatible = "ovti,ov2685";
-                reg = <0x3c>;
-
-                  port {
-                      ucam_out: endpoint {
-                          remote-endpoint = <&mipi_in_ucam>;
-                          data-lanes = <1>;
-                      };
-                  };
-            };
-        };
-    };
diff --git a/drivers/staging/media/rkisp1/Kconfig b/drivers/staging/media/rkisp1/Kconfig
deleted file mode 100644 (file)
index 41f5def..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0-only
-
-config VIDEO_ROCKCHIP_ISP1
-       tristate "Rockchip Image Signal Processing v1 Unit driver"
-       depends on VIDEO_V4L2 && OF
-       depends on ARCH_ROCKCHIP || COMPILE_TEST
-       select MEDIA_CONTROLLER
-       select VIDEO_V4L2_SUBDEV_API
-       select VIDEOBUF2_DMA_CONTIG
-       select VIDEOBUF2_VMALLOC
-       select V4L2_FWNODE
-       select GENERIC_PHY_MIPI_DPHY
-       default n
-       help
-         Enable this to support the Image Signal Processing (ISP) module
-         present in RK3399 SoCs.
-
-         To compile this driver as a module, choose M here: the module
-         will be called rockchip-isp1.
diff --git a/drivers/staging/media/rkisp1/Makefile b/drivers/staging/media/rkisp1/Makefile
deleted file mode 100644 (file)
index ab32a77..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0
-
-obj-$(CONFIG_VIDEO_ROCKCHIP_ISP1) += rockchip-isp1.o
-rockchip-isp1-objs +=  rkisp1-capture.o \
-                       rkisp1-common.o \
-                       rkisp1-dev.o \
-                       rkisp1-isp.o \
-                       rkisp1-resizer.o \
-                       rkisp1-stats.o \
-                       rkisp1-params.o
diff --git a/drivers/staging/media/rkisp1/TODO b/drivers/staging/media/rkisp1/TODO
deleted file mode 100644 (file)
index e7c8398..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-* Fix pad format size for statistics and parameters entities.
-* Fix checkpatch errors.
-* Add uapi docs. Remember to add documentation of how quantization is handled.
-* streaming paths (mainpath and selfpath) check if the other path is streaming
-in several places of the code, review this, specially that it doesn't seem it
-supports streaming from both paths at the same time.
-
-NOTES:
-* All v4l2-compliance test must pass.
-* Stats and params can be tested with libcamera and ChromiumOS stack.
-
-Please CC patches to Linux Media <linux-media@vger.kernel.org> and
-Helen Koike <helen.koike@collabora.com>.
diff --git a/drivers/staging/media/rkisp1/rkisp1-capture.c b/drivers/staging/media/rkisp1/rkisp1-capture.c
deleted file mode 100644 (file)
index b6f497c..0000000
+++ /dev/null
@@ -1,1427 +0,0 @@
-// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
-/*
- * Rockchip ISP1 Driver - V4l capture device
- *
- * Copyright (C) 2019 Collabora, Ltd.
- *
- * Based on Rockchip ISP1 driver by Rockchip Electronics Co., Ltd.
- * Copyright (C) 2017 Rockchip Electronics Co., Ltd.
- */
-
-#include <linux/delay.h>
-#include <linux/pm_runtime.h>
-#include <media/v4l2-common.h>
-#include <media/v4l2-event.h>
-#include <media/v4l2-fh.h>
-#include <media/v4l2-ioctl.h>
-#include <media/v4l2-mc.h>
-#include <media/v4l2-subdev.h>
-#include <media/videobuf2-dma-contig.h>
-
-#include "rkisp1-common.h"
-
-/*
- * NOTE: There are two capture video devices in rkisp1, selfpath and mainpath.
- *
- * differences between selfpath and mainpath
- * available mp sink input: isp
- * available sp sink input : isp, dma(TODO)
- * available mp sink pad fmts: yuv422, raw
- * available sp sink pad fmts: yuv422, yuv420......
- * available mp source fmts: yuv, raw, jpeg(TODO)
- * available sp source fmts: yuv, rgb
- */
-
-#define RKISP1_SP_DEV_NAME     RKISP1_DRIVER_NAME "_selfpath"
-#define RKISP1_MP_DEV_NAME     RKISP1_DRIVER_NAME "_mainpath"
-
-#define RKISP1_MIN_BUFFERS_NEEDED 3
-
-enum rkisp1_plane {
-       RKISP1_PLANE_Y  = 0,
-       RKISP1_PLANE_CB = 1,
-       RKISP1_PLANE_CR = 2
-};
-
-/*
- * @fourcc: pixel format
- * @fmt_type: helper filed for pixel format
- * @uv_swap: if cb cr swaped, for yuv
- * @write_format: defines how YCbCr self picture data is written to memory
- * @output_format: defines sp output format
- * @mbus: the mbus code on the src resizer pad that matches the pixel format
- */
-struct rkisp1_capture_fmt_cfg {
-       u32 fourcc;
-       u8 uv_swap;
-       u32 write_format;
-       u32 output_format;
-       u32 mbus;
-};
-
-struct rkisp1_capture_ops {
-       void (*config)(struct rkisp1_capture *cap);
-       void (*stop)(struct rkisp1_capture *cap);
-       void (*enable)(struct rkisp1_capture *cap);
-       void (*disable)(struct rkisp1_capture *cap);
-       void (*set_data_path)(struct rkisp1_capture *cap);
-       bool (*is_stopped)(struct rkisp1_capture *cap);
-};
-
-struct rkisp1_capture_config {
-       const struct rkisp1_capture_fmt_cfg *fmts;
-       int fmt_size;
-       struct {
-               u32 y_size_init;
-               u32 cb_size_init;
-               u32 cr_size_init;
-               u32 y_base_ad_init;
-               u32 cb_base_ad_init;
-               u32 cr_base_ad_init;
-               u32 y_offs_cnt_init;
-               u32 cb_offs_cnt_init;
-               u32 cr_offs_cnt_init;
-       } mi;
-};
-
-/*
- * The supported pixel formats for mainpath. NOTE, pixel formats with identical 'mbus'
- * are grouped together. This is assumed and used by the function rkisp1_cap_enum_mbus_codes
- */
-static const struct rkisp1_capture_fmt_cfg rkisp1_mp_fmts[] = {
-       /* yuv422 */
-       {
-               .fourcc = V4L2_PIX_FMT_YUYV,
-               .uv_swap = 0,
-               .write_format = RKISP1_MI_CTRL_MP_WRITE_YUVINT,
-               .mbus = MEDIA_BUS_FMT_YUYV8_2X8,
-       }, {
-               .fourcc = V4L2_PIX_FMT_YUV422P,
-               .uv_swap = 0,
-               .write_format = RKISP1_MI_CTRL_MP_WRITE_YUV_PLA_OR_RAW8,
-               .mbus = MEDIA_BUS_FMT_YUYV8_2X8,
-       }, {
-               .fourcc = V4L2_PIX_FMT_NV16,
-               .uv_swap = 0,
-               .write_format = RKISP1_MI_CTRL_MP_WRITE_YUV_SPLA,
-               .mbus = MEDIA_BUS_FMT_YUYV8_2X8,
-       }, {
-               .fourcc = V4L2_PIX_FMT_NV61,
-               .uv_swap = 1,
-               .write_format = RKISP1_MI_CTRL_MP_WRITE_YUV_SPLA,
-               .mbus = MEDIA_BUS_FMT_YUYV8_2X8,
-       }, {
-               .fourcc = V4L2_PIX_FMT_YVU422M,
-               .uv_swap = 1,
-               .write_format = RKISP1_MI_CTRL_MP_WRITE_YUV_PLA_OR_RAW8,
-               .mbus = MEDIA_BUS_FMT_YUYV8_2X8,
-       },
-       /* yuv400 */
-       {
-               .fourcc = V4L2_PIX_FMT_GREY,
-               .uv_swap = 0,
-               .write_format = RKISP1_MI_CTRL_MP_WRITE_YUV_PLA_OR_RAW8,
-               .mbus = MEDIA_BUS_FMT_YUYV8_2X8,
-       },
-       /* yuv420 */
-       {
-               .fourcc = V4L2_PIX_FMT_NV21,
-               .uv_swap = 1,
-               .write_format = RKISP1_MI_CTRL_MP_WRITE_YUV_SPLA,
-               .mbus = MEDIA_BUS_FMT_YUYV8_1_5X8,
-       }, {
-               .fourcc = V4L2_PIX_FMT_NV12,
-               .uv_swap = 0,
-               .write_format = RKISP1_MI_CTRL_MP_WRITE_YUV_SPLA,
-               .mbus = MEDIA_BUS_FMT_YUYV8_1_5X8,
-       }, {
-               .fourcc = V4L2_PIX_FMT_NV21M,
-               .uv_swap = 1,
-               .write_format = RKISP1_MI_CTRL_MP_WRITE_YUV_SPLA,
-               .mbus = MEDIA_BUS_FMT_YUYV8_1_5X8,
-       }, {
-               .fourcc = V4L2_PIX_FMT_NV12M,
-               .uv_swap = 0,
-               .write_format = RKISP1_MI_CTRL_MP_WRITE_YUV_SPLA,
-               .mbus = MEDIA_BUS_FMT_YUYV8_1_5X8,
-       }, {
-               .fourcc = V4L2_PIX_FMT_YUV420,
-               .uv_swap = 0,
-               .write_format = RKISP1_MI_CTRL_MP_WRITE_YUV_PLA_OR_RAW8,
-               .mbus = MEDIA_BUS_FMT_YUYV8_1_5X8,
-       }, {
-               .fourcc = V4L2_PIX_FMT_YVU420,
-               .uv_swap = 1,
-               .write_format = RKISP1_MI_CTRL_MP_WRITE_YUV_PLA_OR_RAW8,
-               .mbus = MEDIA_BUS_FMT_YUYV8_1_5X8,
-       },
-       /* raw */
-       {
-               .fourcc = V4L2_PIX_FMT_SRGGB8,
-               .write_format = RKISP1_MI_CTRL_MP_WRITE_YUV_PLA_OR_RAW8,
-               .mbus = MEDIA_BUS_FMT_SRGGB8_1X8,
-       }, {
-               .fourcc = V4L2_PIX_FMT_SGRBG8,
-               .write_format = RKISP1_MI_CTRL_MP_WRITE_YUV_PLA_OR_RAW8,
-               .mbus = MEDIA_BUS_FMT_SGRBG8_1X8,
-       }, {
-               .fourcc = V4L2_PIX_FMT_SGBRG8,
-               .write_format = RKISP1_MI_CTRL_MP_WRITE_YUV_PLA_OR_RAW8,
-               .mbus = MEDIA_BUS_FMT_SGBRG8_1X8,
-       }, {
-               .fourcc = V4L2_PIX_FMT_SBGGR8,
-               .write_format = RKISP1_MI_CTRL_MP_WRITE_YUV_PLA_OR_RAW8,
-               .mbus = MEDIA_BUS_FMT_SBGGR8_1X8,
-       }, {
-               .fourcc = V4L2_PIX_FMT_SRGGB10,
-               .write_format = RKISP1_MI_CTRL_MP_WRITE_RAW12,
-               .mbus = MEDIA_BUS_FMT_SRGGB10_1X10,
-       }, {
-               .fourcc = V4L2_PIX_FMT_SGRBG10,
-               .write_format = RKISP1_MI_CTRL_MP_WRITE_RAW12,
-               .mbus = MEDIA_BUS_FMT_SGRBG10_1X10,
-       }, {
-               .fourcc = V4L2_PIX_FMT_SGBRG10,
-               .write_format = RKISP1_MI_CTRL_MP_WRITE_RAW12,
-               .mbus = MEDIA_BUS_FMT_SGBRG10_1X10,
-       }, {
-               .fourcc = V4L2_PIX_FMT_SBGGR10,
-               .write_format = RKISP1_MI_CTRL_MP_WRITE_RAW12,
-               .mbus = MEDIA_BUS_FMT_SBGGR10_1X10,
-       }, {
-               .fourcc = V4L2_PIX_FMT_SRGGB12,
-               .write_format = RKISP1_MI_CTRL_MP_WRITE_RAW12,
-               .mbus = MEDIA_BUS_FMT_SRGGB12_1X12,
-       }, {
-               .fourcc = V4L2_PIX_FMT_SGRBG12,
-               .write_format = RKISP1_MI_CTRL_MP_WRITE_RAW12,
-               .mbus = MEDIA_BUS_FMT_SGRBG12_1X12,
-       }, {
-               .fourcc = V4L2_PIX_FMT_SGBRG12,
-               .write_format = RKISP1_MI_CTRL_MP_WRITE_RAW12,
-               .mbus = MEDIA_BUS_FMT_SGBRG12_1X12,
-       }, {
-               .fourcc = V4L2_PIX_FMT_SBGGR12,
-               .write_format = RKISP1_MI_CTRL_MP_WRITE_RAW12,
-               .mbus = MEDIA_BUS_FMT_SBGGR12_1X12,
-       },
-};
-
-/*
- * The supported pixel formats for selfpath. NOTE, pixel formats with identical 'mbus'
- * are grouped together. This is assumed and used by the function rkisp1_cap_enum_mbus_codes
- */
-static const struct rkisp1_capture_fmt_cfg rkisp1_sp_fmts[] = {
-       /* yuv422 */
-       {
-               .fourcc = V4L2_PIX_FMT_YUYV,
-               .uv_swap = 0,
-               .write_format = RKISP1_MI_CTRL_SP_WRITE_INT,
-               .output_format = RKISP1_MI_CTRL_SP_OUTPUT_YUV422,
-               .mbus = MEDIA_BUS_FMT_YUYV8_2X8,
-       }, {
-               .fourcc = V4L2_PIX_FMT_YUV422P,
-               .uv_swap = 0,
-               .write_format = RKISP1_MI_CTRL_SP_WRITE_PLA,
-               .output_format = RKISP1_MI_CTRL_SP_OUTPUT_YUV422,
-               .mbus = MEDIA_BUS_FMT_YUYV8_2X8,
-       }, {
-               .fourcc = V4L2_PIX_FMT_NV16,
-               .uv_swap = 0,
-               .write_format = RKISP1_MI_CTRL_SP_WRITE_SPLA,
-               .output_format = RKISP1_MI_CTRL_SP_OUTPUT_YUV422,
-               .mbus = MEDIA_BUS_FMT_YUYV8_2X8,
-       }, {
-               .fourcc = V4L2_PIX_FMT_NV61,
-               .uv_swap = 1,
-               .write_format = RKISP1_MI_CTRL_SP_WRITE_SPLA,
-               .output_format = RKISP1_MI_CTRL_SP_OUTPUT_YUV422,
-               .mbus = MEDIA_BUS_FMT_YUYV8_2X8,
-       }, {
-               .fourcc = V4L2_PIX_FMT_YVU422M,
-               .uv_swap = 1,
-               .write_format = RKISP1_MI_CTRL_SP_WRITE_PLA,
-               .output_format = RKISP1_MI_CTRL_SP_OUTPUT_YUV422,
-               .mbus = MEDIA_BUS_FMT_YUYV8_2X8,
-       },
-       /* yuv400 */
-       {
-               .fourcc = V4L2_PIX_FMT_GREY,
-               .uv_swap = 0,
-               .write_format = RKISP1_MI_CTRL_SP_WRITE_PLA,
-               .output_format = RKISP1_MI_CTRL_SP_OUTPUT_YUV400,
-               .mbus = MEDIA_BUS_FMT_YUYV8_2X8,
-       },
-       /* rgb */
-       {
-               .fourcc = V4L2_PIX_FMT_XBGR32,
-               .write_format = RKISP1_MI_CTRL_SP_WRITE_PLA,
-               .output_format = RKISP1_MI_CTRL_SP_OUTPUT_RGB888,
-               .mbus = MEDIA_BUS_FMT_YUYV8_2X8,
-       }, {
-               .fourcc = V4L2_PIX_FMT_RGB565,
-               .write_format = RKISP1_MI_CTRL_SP_WRITE_PLA,
-               .output_format = RKISP1_MI_CTRL_SP_OUTPUT_RGB565,
-               .mbus = MEDIA_BUS_FMT_YUYV8_2X8,
-       },
-       /* yuv420 */
-       {
-               .fourcc = V4L2_PIX_FMT_NV21,
-               .uv_swap = 1,
-               .write_format = RKISP1_MI_CTRL_SP_WRITE_SPLA,
-               .output_format = RKISP1_MI_CTRL_SP_OUTPUT_YUV420,
-               .mbus = MEDIA_BUS_FMT_YUYV8_1_5X8,
-       }, {
-               .fourcc = V4L2_PIX_FMT_NV12,
-               .uv_swap = 0,
-               .write_format = RKISP1_MI_CTRL_SP_WRITE_SPLA,
-               .output_format = RKISP1_MI_CTRL_SP_OUTPUT_YUV420,
-               .mbus = MEDIA_BUS_FMT_YUYV8_1_5X8,
-       }, {
-               .fourcc = V4L2_PIX_FMT_NV21M,
-               .uv_swap = 1,
-               .write_format = RKISP1_MI_CTRL_SP_WRITE_SPLA,
-               .output_format = RKISP1_MI_CTRL_SP_OUTPUT_YUV420,
-               .mbus = MEDIA_BUS_FMT_YUYV8_1_5X8,
-       }, {
-               .fourcc = V4L2_PIX_FMT_NV12M,
-               .uv_swap = 0,
-               .write_format = RKISP1_MI_CTRL_SP_WRITE_SPLA,
-               .output_format = RKISP1_MI_CTRL_SP_OUTPUT_YUV420,
-               .mbus = MEDIA_BUS_FMT_YUYV8_1_5X8,
-       }, {
-               .fourcc = V4L2_PIX_FMT_YUV420,
-               .uv_swap = 0,
-               .write_format = RKISP1_MI_CTRL_SP_WRITE_PLA,
-               .output_format = RKISP1_MI_CTRL_SP_OUTPUT_YUV420,
-               .mbus = MEDIA_BUS_FMT_YUYV8_1_5X8,
-       }, {
-               .fourcc = V4L2_PIX_FMT_YVU420,
-               .uv_swap = 1,
-               .write_format = RKISP1_MI_CTRL_SP_WRITE_PLA,
-               .output_format = RKISP1_MI_CTRL_SP_OUTPUT_YUV420,
-               .mbus = MEDIA_BUS_FMT_YUYV8_1_5X8,
-       },
-};
-
-static const struct rkisp1_capture_config rkisp1_capture_config_mp = {
-       .fmts = rkisp1_mp_fmts,
-       .fmt_size = ARRAY_SIZE(rkisp1_mp_fmts),
-       .mi = {
-               .y_size_init =          RKISP1_CIF_MI_MP_Y_SIZE_INIT,
-               .cb_size_init =         RKISP1_CIF_MI_MP_CB_SIZE_INIT,
-               .cr_size_init =         RKISP1_CIF_MI_MP_CR_SIZE_INIT,
-               .y_base_ad_init =       RKISP1_CIF_MI_MP_Y_BASE_AD_INIT,
-               .cb_base_ad_init =      RKISP1_CIF_MI_MP_CB_BASE_AD_INIT,
-               .cr_base_ad_init =      RKISP1_CIF_MI_MP_CR_BASE_AD_INIT,
-               .y_offs_cnt_init =      RKISP1_CIF_MI_MP_Y_OFFS_CNT_INIT,
-               .cb_offs_cnt_init =     RKISP1_CIF_MI_MP_CB_OFFS_CNT_INIT,
-               .cr_offs_cnt_init =     RKISP1_CIF_MI_MP_CR_OFFS_CNT_INIT,
-       },
-};
-
-static const struct rkisp1_capture_config rkisp1_capture_config_sp = {
-       .fmts = rkisp1_sp_fmts,
-       .fmt_size = ARRAY_SIZE(rkisp1_sp_fmts),
-       .mi = {
-               .y_size_init =          RKISP1_CIF_MI_SP_Y_SIZE_INIT,
-               .cb_size_init =         RKISP1_CIF_MI_SP_CB_SIZE_INIT,
-               .cr_size_init =         RKISP1_CIF_MI_SP_CR_SIZE_INIT,
-               .y_base_ad_init =       RKISP1_CIF_MI_SP_Y_BASE_AD_INIT,
-               .cb_base_ad_init =      RKISP1_CIF_MI_SP_CB_BASE_AD_INIT,
-               .cr_base_ad_init =      RKISP1_CIF_MI_SP_CR_BASE_AD_INIT,
-               .y_offs_cnt_init =      RKISP1_CIF_MI_SP_Y_OFFS_CNT_INIT,
-               .cb_offs_cnt_init =     RKISP1_CIF_MI_SP_CB_OFFS_CNT_INIT,
-               .cr_offs_cnt_init =     RKISP1_CIF_MI_SP_CR_OFFS_CNT_INIT,
-       },
-};
-
-static inline struct rkisp1_vdev_node *
-rkisp1_vdev_to_node(struct video_device *vdev)
-{
-       return container_of(vdev, struct rkisp1_vdev_node, vdev);
-}
-
-int rkisp1_cap_enum_mbus_codes(struct rkisp1_capture *cap,
-                              struct v4l2_subdev_mbus_code_enum *code)
-{
-       const struct rkisp1_capture_fmt_cfg *fmts = cap->config->fmts;
-       /*
-        * initialize curr_mbus to non existing mbus code 0 to ensure it is
-        * different from fmts[0].mbus
-        */
-       u32 curr_mbus = 0;
-       int i, n = 0;
-
-       for (i = 0; i < cap->config->fmt_size; i++) {
-               if (fmts[i].mbus == curr_mbus)
-                       continue;
-
-               curr_mbus = fmts[i].mbus;
-               if (n++ == code->index) {
-                       code->code = curr_mbus;
-                       return 0;
-               }
-       }
-       return -EINVAL;
-}
-
-/* ----------------------------------------------------------------------------
- * Stream operations for self-picture path (sp) and main-picture path (mp)
- */
-
-static void rkisp1_mi_config_ctrl(struct rkisp1_capture *cap)
-{
-       u32 mi_ctrl = rkisp1_read(cap->rkisp1, RKISP1_CIF_MI_CTRL);
-
-       mi_ctrl &= ~GENMASK(17, 16);
-       mi_ctrl |= RKISP1_CIF_MI_CTRL_BURST_LEN_LUM_64;
-
-       mi_ctrl &= ~GENMASK(19, 18);
-       mi_ctrl |= RKISP1_CIF_MI_CTRL_BURST_LEN_CHROM_64;
-
-       mi_ctrl |= RKISP1_CIF_MI_CTRL_INIT_BASE_EN |
-                  RKISP1_CIF_MI_CTRL_INIT_OFFSET_EN;
-
-       rkisp1_write(cap->rkisp1, mi_ctrl, RKISP1_CIF_MI_CTRL);
-}
-
-static u32 rkisp1_pixfmt_comp_size(const struct v4l2_pix_format_mplane *pixm,
-                                  unsigned int component)
-{
-       /*
-        * If packed format, then plane_fmt[0].sizeimage is the sum of all
-        * components, so we need to calculate just the size of Y component.
-        * See rkisp1_fill_pixfmt().
-        */
-       if (!component && pixm->num_planes == 1)
-               return pixm->plane_fmt[0].bytesperline * pixm->height;
-       return pixm->plane_fmt[component].sizeimage;
-}
-
-static void rkisp1_irq_frame_end_enable(struct rkisp1_capture *cap)
-{
-       u32 mi_imsc = rkisp1_read(cap->rkisp1, RKISP1_CIF_MI_IMSC);
-
-       mi_imsc |= RKISP1_CIF_MI_FRAME(cap);
-       rkisp1_write(cap->rkisp1, mi_imsc, RKISP1_CIF_MI_IMSC);
-}
-
-static void rkisp1_mp_config(struct rkisp1_capture *cap)
-{
-       const struct v4l2_pix_format_mplane *pixm = &cap->pix.fmt;
-       struct rkisp1_device *rkisp1 = cap->rkisp1;
-       u32 reg;
-
-       rkisp1_write(rkisp1, rkisp1_pixfmt_comp_size(pixm, RKISP1_PLANE_Y),
-                    cap->config->mi.y_size_init);
-       rkisp1_write(rkisp1, rkisp1_pixfmt_comp_size(pixm, RKISP1_PLANE_CB),
-                    cap->config->mi.cb_size_init);
-       rkisp1_write(rkisp1, rkisp1_pixfmt_comp_size(pixm, RKISP1_PLANE_CR),
-                    cap->config->mi.cr_size_init);
-
-       rkisp1_irq_frame_end_enable(cap);
-
-       /* set uv swapping for semiplanar formats */
-       if (cap->pix.info->comp_planes == 2) {
-               reg = rkisp1_read(rkisp1, RKISP1_CIF_MI_XTD_FORMAT_CTRL);
-               if (cap->pix.cfg->uv_swap)
-                       reg |= RKISP1_CIF_MI_XTD_FMT_CTRL_MP_CB_CR_SWAP;
-               else
-                       reg &= ~RKISP1_CIF_MI_XTD_FMT_CTRL_MP_CB_CR_SWAP;
-               rkisp1_write(rkisp1, reg, RKISP1_CIF_MI_XTD_FORMAT_CTRL);
-       }
-
-       rkisp1_mi_config_ctrl(cap);
-
-       reg = rkisp1_read(rkisp1, RKISP1_CIF_MI_CTRL);
-       reg &= ~RKISP1_MI_CTRL_MP_FMT_MASK;
-       reg |= cap->pix.cfg->write_format;
-       rkisp1_write(rkisp1, reg, RKISP1_CIF_MI_CTRL);
-
-       reg = rkisp1_read(rkisp1, RKISP1_CIF_MI_CTRL);
-       reg |= RKISP1_CIF_MI_MP_AUTOUPDATE_ENABLE;
-       rkisp1_write(rkisp1, reg, RKISP1_CIF_MI_CTRL);
-}
-
-static void rkisp1_sp_config(struct rkisp1_capture *cap)
-{
-       const struct v4l2_pix_format_mplane *pixm = &cap->pix.fmt;
-       struct rkisp1_device *rkisp1 = cap->rkisp1;
-       u32 mi_ctrl, reg;
-
-       rkisp1_write(rkisp1, rkisp1_pixfmt_comp_size(pixm, RKISP1_PLANE_Y),
-                    cap->config->mi.y_size_init);
-       rkisp1_write(rkisp1, rkisp1_pixfmt_comp_size(pixm, RKISP1_PLANE_CB),
-                    cap->config->mi.cb_size_init);
-       rkisp1_write(rkisp1, rkisp1_pixfmt_comp_size(pixm, RKISP1_PLANE_CR),
-                    cap->config->mi.cr_size_init);
-
-       rkisp1_write(rkisp1, pixm->width, RKISP1_CIF_MI_SP_Y_PIC_WIDTH);
-       rkisp1_write(rkisp1, pixm->height, RKISP1_CIF_MI_SP_Y_PIC_HEIGHT);
-       rkisp1_write(rkisp1, cap->sp_y_stride, RKISP1_CIF_MI_SP_Y_LLENGTH);
-
-       rkisp1_irq_frame_end_enable(cap);
-
-       /* set uv swapping for semiplanar formats */
-       if (cap->pix.info->comp_planes == 2) {
-               reg = rkisp1_read(rkisp1, RKISP1_CIF_MI_XTD_FORMAT_CTRL);
-               if (cap->pix.cfg->uv_swap)
-                       reg |= RKISP1_CIF_MI_XTD_FMT_CTRL_SP_CB_CR_SWAP;
-               else
-                       reg &= ~RKISP1_CIF_MI_XTD_FMT_CTRL_SP_CB_CR_SWAP;
-               rkisp1_write(rkisp1, reg, RKISP1_CIF_MI_XTD_FORMAT_CTRL);
-       }
-
-       rkisp1_mi_config_ctrl(cap);
-
-       mi_ctrl = rkisp1_read(rkisp1, RKISP1_CIF_MI_CTRL);
-       mi_ctrl &= ~RKISP1_MI_CTRL_SP_FMT_MASK;
-       mi_ctrl |= cap->pix.cfg->write_format |
-                  RKISP1_MI_CTRL_SP_INPUT_YUV422 |
-                  cap->pix.cfg->output_format |
-                  RKISP1_CIF_MI_SP_AUTOUPDATE_ENABLE;
-       rkisp1_write(rkisp1, mi_ctrl, RKISP1_CIF_MI_CTRL);
-}
-
-static void rkisp1_mp_disable(struct rkisp1_capture *cap)
-{
-       u32 mi_ctrl = rkisp1_read(cap->rkisp1, RKISP1_CIF_MI_CTRL);
-
-       mi_ctrl &= ~(RKISP1_CIF_MI_CTRL_MP_ENABLE |
-                    RKISP1_CIF_MI_CTRL_RAW_ENABLE);
-       rkisp1_write(cap->rkisp1, mi_ctrl, RKISP1_CIF_MI_CTRL);
-}
-
-static void rkisp1_sp_disable(struct rkisp1_capture *cap)
-{
-       u32 mi_ctrl = rkisp1_read(cap->rkisp1, RKISP1_CIF_MI_CTRL);
-
-       mi_ctrl &= ~RKISP1_CIF_MI_CTRL_SP_ENABLE;
-       rkisp1_write(cap->rkisp1, mi_ctrl, RKISP1_CIF_MI_CTRL);
-}
-
-static void rkisp1_mp_enable(struct rkisp1_capture *cap)
-{
-       u32 mi_ctrl;
-
-       rkisp1_mp_disable(cap);
-
-       mi_ctrl = rkisp1_read(cap->rkisp1, RKISP1_CIF_MI_CTRL);
-       if (v4l2_is_format_bayer(cap->pix.info))
-               mi_ctrl |= RKISP1_CIF_MI_CTRL_RAW_ENABLE;
-       /* YUV */
-       else
-               mi_ctrl |= RKISP1_CIF_MI_CTRL_MP_ENABLE;
-
-       rkisp1_write(cap->rkisp1, mi_ctrl, RKISP1_CIF_MI_CTRL);
-}
-
-static void rkisp1_sp_enable(struct rkisp1_capture *cap)
-{
-       u32 mi_ctrl = rkisp1_read(cap->rkisp1, RKISP1_CIF_MI_CTRL);
-
-       mi_ctrl |= RKISP1_CIF_MI_CTRL_SP_ENABLE;
-       rkisp1_write(cap->rkisp1, mi_ctrl, RKISP1_CIF_MI_CTRL);
-}
-
-static void rkisp1_mp_sp_stop(struct rkisp1_capture *cap)
-{
-       if (!cap->is_streaming)
-               return;
-       rkisp1_write(cap->rkisp1,
-                    RKISP1_CIF_MI_FRAME(cap), RKISP1_CIF_MI_ICR);
-       cap->ops->disable(cap);
-}
-
-static bool rkisp1_mp_is_stopped(struct rkisp1_capture *cap)
-{
-       u32 en = RKISP1_CIF_MI_CTRL_SHD_MP_IN_ENABLED |
-                RKISP1_CIF_MI_CTRL_SHD_RAW_OUT_ENABLED;
-
-       return !(rkisp1_read(cap->rkisp1, RKISP1_CIF_MI_CTRL_SHD) & en);
-}
-
-static bool rkisp1_sp_is_stopped(struct rkisp1_capture *cap)
-{
-       return !(rkisp1_read(cap->rkisp1, RKISP1_CIF_MI_CTRL_SHD) &
-                RKISP1_CIF_MI_CTRL_SHD_SP_IN_ENABLED);
-}
-
-static void rkisp1_mp_set_data_path(struct rkisp1_capture *cap)
-{
-       u32 dpcl = rkisp1_read(cap->rkisp1, RKISP1_CIF_VI_DPCL);
-
-       dpcl = dpcl | RKISP1_CIF_VI_DPCL_CHAN_MODE_MP |
-              RKISP1_CIF_VI_DPCL_MP_MUX_MRSZ_MI;
-       rkisp1_write(cap->rkisp1, dpcl, RKISP1_CIF_VI_DPCL);
-}
-
-static void rkisp1_sp_set_data_path(struct rkisp1_capture *cap)
-{
-       u32 dpcl = rkisp1_read(cap->rkisp1, RKISP1_CIF_VI_DPCL);
-
-       dpcl |= RKISP1_CIF_VI_DPCL_CHAN_MODE_SP;
-       rkisp1_write(cap->rkisp1, dpcl, RKISP1_CIF_VI_DPCL);
-}
-
-static struct rkisp1_capture_ops rkisp1_capture_ops_mp = {
-       .config = rkisp1_mp_config,
-       .enable = rkisp1_mp_enable,
-       .disable = rkisp1_mp_disable,
-       .stop = rkisp1_mp_sp_stop,
-       .set_data_path = rkisp1_mp_set_data_path,
-       .is_stopped = rkisp1_mp_is_stopped,
-};
-
-static struct rkisp1_capture_ops rkisp1_capture_ops_sp = {
-       .config = rkisp1_sp_config,
-       .enable = rkisp1_sp_enable,
-       .disable = rkisp1_sp_disable,
-       .stop = rkisp1_mp_sp_stop,
-       .set_data_path = rkisp1_sp_set_data_path,
-       .is_stopped = rkisp1_sp_is_stopped,
-};
-
-/* ----------------------------------------------------------------------------
- * Frame buffer operations
- */
-
-static int rkisp1_dummy_buf_create(struct rkisp1_capture *cap)
-{
-       const struct v4l2_pix_format_mplane *pixm = &cap->pix.fmt;
-       struct rkisp1_dummy_buffer *dummy_buf = &cap->buf.dummy;
-
-       dummy_buf->size = max3(rkisp1_pixfmt_comp_size(pixm, RKISP1_PLANE_Y),
-                              rkisp1_pixfmt_comp_size(pixm, RKISP1_PLANE_CB),
-                              rkisp1_pixfmt_comp_size(pixm, RKISP1_PLANE_CR));
-
-       /* The driver never access vaddr, no mapping is required */
-       dummy_buf->vaddr = dma_alloc_attrs(cap->rkisp1->dev,
-                                          dummy_buf->size,
-                                          &dummy_buf->dma_addr,
-                                          GFP_KERNEL,
-                                          DMA_ATTR_NO_KERNEL_MAPPING);
-       if (!dummy_buf->vaddr)
-               return -ENOMEM;
-
-       return 0;
-}
-
-static void rkisp1_dummy_buf_destroy(struct rkisp1_capture *cap)
-{
-       dma_free_attrs(cap->rkisp1->dev,
-                      cap->buf.dummy.size, cap->buf.dummy.vaddr,
-                      cap->buf.dummy.dma_addr, DMA_ATTR_NO_KERNEL_MAPPING);
-}
-
-static void rkisp1_set_next_buf(struct rkisp1_capture *cap)
-{
-       cap->buf.curr = cap->buf.next;
-       cap->buf.next = NULL;
-
-       if (!list_empty(&cap->buf.queue)) {
-               u32 *buff_addr;
-
-               cap->buf.next = list_first_entry(&cap->buf.queue, struct rkisp1_buffer, queue);
-               list_del(&cap->buf.next->queue);
-
-               buff_addr = cap->buf.next->buff_addr;
-
-               rkisp1_write(cap->rkisp1,
-                            buff_addr[RKISP1_PLANE_Y],
-                            cap->config->mi.y_base_ad_init);
-               rkisp1_write(cap->rkisp1,
-                            buff_addr[RKISP1_PLANE_CB],
-                            cap->config->mi.cb_base_ad_init);
-               rkisp1_write(cap->rkisp1,
-                            buff_addr[RKISP1_PLANE_CR],
-                            cap->config->mi.cr_base_ad_init);
-       } else {
-               /*
-                * Use the dummy space allocated by dma_alloc_coherent to
-                * throw data if there is no available buffer.
-                */
-               rkisp1_write(cap->rkisp1,
-                            cap->buf.dummy.dma_addr,
-                            cap->config->mi.y_base_ad_init);
-               rkisp1_write(cap->rkisp1,
-                            cap->buf.dummy.dma_addr,
-                            cap->config->mi.cb_base_ad_init);
-               rkisp1_write(cap->rkisp1,
-                            cap->buf.dummy.dma_addr,
-                            cap->config->mi.cr_base_ad_init);
-       }
-
-       /* Set plane offsets */
-       rkisp1_write(cap->rkisp1, 0, cap->config->mi.y_offs_cnt_init);
-       rkisp1_write(cap->rkisp1, 0, cap->config->mi.cb_offs_cnt_init);
-       rkisp1_write(cap->rkisp1, 0, cap->config->mi.cr_offs_cnt_init);
-}
-
-/*
- * This function is called when a frame end comes. The next frame
- * is processing and we should set up buffer for next-next frame,
- * otherwise it will overflow.
- */
-static void rkisp1_handle_buffer(struct rkisp1_capture *cap)
-{
-       struct rkisp1_isp *isp = &cap->rkisp1->isp;
-       struct rkisp1_buffer *curr_buf;
-
-       spin_lock(&cap->buf.lock);
-       curr_buf = cap->buf.curr;
-
-       if (curr_buf) {
-               curr_buf->vb.sequence = isp->frame_sequence;
-               curr_buf->vb.vb2_buf.timestamp = ktime_get_boottime_ns();
-               curr_buf->vb.field = V4L2_FIELD_NONE;
-               vb2_buffer_done(&curr_buf->vb.vb2_buf, VB2_BUF_STATE_DONE);
-       } else {
-               cap->rkisp1->debug.frame_drop[cap->id]++;
-       }
-
-       rkisp1_set_next_buf(cap);
-       spin_unlock(&cap->buf.lock);
-}
-
-void rkisp1_capture_isr(struct rkisp1_device *rkisp1)
-{
-       unsigned int i;
-       u32 status;
-
-       status = rkisp1_read(rkisp1, RKISP1_CIF_MI_MIS);
-       rkisp1_write(rkisp1, status, RKISP1_CIF_MI_ICR);
-
-       for (i = 0; i < ARRAY_SIZE(rkisp1->capture_devs); ++i) {
-               struct rkisp1_capture *cap = &rkisp1->capture_devs[i];
-
-               if (!(status & RKISP1_CIF_MI_FRAME(cap)))
-                       continue;
-               if (!cap->is_stopping) {
-                       rkisp1_handle_buffer(cap);
-                       continue;
-               }
-               /*
-                * Make sure stream is actually stopped, whose state
-                * can be read from the shadow register, before
-                * wake_up() thread which would immediately free all
-                * frame buffers. stop() takes effect at the next
-                * frame end that sync the configurations to shadow
-                * regs.
-                */
-               if (!cap->ops->is_stopped(cap)) {
-                       cap->ops->stop(cap);
-                       continue;
-               }
-               cap->is_stopping = false;
-               cap->is_streaming = false;
-               wake_up(&cap->done);
-       }
-}
-
-/* ----------------------------------------------------------------------------
- * Vb2 operations
- */
-
-static int rkisp1_vb2_queue_setup(struct vb2_queue *queue,
-                                 unsigned int *num_buffers,
-                                 unsigned int *num_planes,
-                                 unsigned int sizes[],
-                                 struct device *alloc_devs[])
-{
-       struct rkisp1_capture *cap = queue->drv_priv;
-       const struct v4l2_pix_format_mplane *pixm = &cap->pix.fmt;
-       unsigned int i;
-
-       if (*num_planes) {
-               if (*num_planes != pixm->num_planes)
-                       return -EINVAL;
-
-               for (i = 0; i < pixm->num_planes; i++)
-                       if (sizes[i] < pixm->plane_fmt[i].sizeimage)
-                               return -EINVAL;
-       } else {
-               *num_planes = pixm->num_planes;
-               for (i = 0; i < pixm->num_planes; i++)
-                       sizes[i] = pixm->plane_fmt[i].sizeimage;
-       }
-
-       return 0;
-}
-
-static void rkisp1_vb2_buf_queue(struct vb2_buffer *vb)
-{
-       struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
-       struct rkisp1_buffer *ispbuf =
-               container_of(vbuf, struct rkisp1_buffer, vb);
-       struct rkisp1_capture *cap = vb->vb2_queue->drv_priv;
-       const struct v4l2_pix_format_mplane *pixm = &cap->pix.fmt;
-       unsigned int i;
-
-       memset(ispbuf->buff_addr, 0, sizeof(ispbuf->buff_addr));
-       for (i = 0; i < pixm->num_planes; i++)
-               ispbuf->buff_addr[i] = vb2_dma_contig_plane_dma_addr(vb, i);
-
-       /* Convert to non-MPLANE */
-       if (pixm->num_planes == 1) {
-               ispbuf->buff_addr[RKISP1_PLANE_CB] =
-                       ispbuf->buff_addr[RKISP1_PLANE_Y] +
-                       rkisp1_pixfmt_comp_size(pixm, RKISP1_PLANE_Y);
-               ispbuf->buff_addr[RKISP1_PLANE_CR] =
-                       ispbuf->buff_addr[RKISP1_PLANE_CB] +
-                       rkisp1_pixfmt_comp_size(pixm, RKISP1_PLANE_CB);
-       }
-
-       /*
-        * uv swap can be supported for planar formats by switching
-        * the address of cb and cr
-        */
-       if (cap->pix.info->comp_planes == 3 && cap->pix.cfg->uv_swap)
-               swap(ispbuf->buff_addr[RKISP1_PLANE_CR],
-                    ispbuf->buff_addr[RKISP1_PLANE_CB]);
-
-       spin_lock_irq(&cap->buf.lock);
-       list_add_tail(&ispbuf->queue, &cap->buf.queue);
-       spin_unlock_irq(&cap->buf.lock);
-}
-
-static int rkisp1_vb2_buf_prepare(struct vb2_buffer *vb)
-{
-       struct rkisp1_capture *cap = vb->vb2_queue->drv_priv;
-       unsigned int i;
-
-       for (i = 0; i < cap->pix.fmt.num_planes; i++) {
-               unsigned long size = cap->pix.fmt.plane_fmt[i].sizeimage;
-
-               if (vb2_plane_size(vb, i) < size) {
-                       dev_err(cap->rkisp1->dev,
-                               "User buffer too small (%ld < %ld)\n",
-                               vb2_plane_size(vb, i), size);
-                       return -EINVAL;
-               }
-               vb2_set_plane_payload(vb, i, size);
-       }
-
-       return 0;
-}
-
-static void rkisp1_return_all_buffers(struct rkisp1_capture *cap,
-                                     enum vb2_buffer_state state)
-{
-       struct rkisp1_buffer *buf;
-
-       spin_lock_irq(&cap->buf.lock);
-       if (cap->buf.curr) {
-               vb2_buffer_done(&cap->buf.curr->vb.vb2_buf, state);
-               cap->buf.curr = NULL;
-       }
-       if (cap->buf.next) {
-               vb2_buffer_done(&cap->buf.next->vb.vb2_buf, state);
-               cap->buf.next = NULL;
-       }
-       while (!list_empty(&cap->buf.queue)) {
-               buf = list_first_entry(&cap->buf.queue,
-                                      struct rkisp1_buffer, queue);
-               list_del(&buf->queue);
-               vb2_buffer_done(&buf->vb.vb2_buf, state);
-       }
-       spin_unlock_irq(&cap->buf.lock);
-}
-
-/*
- * rkisp1_pipeline_sink_walk - Walk through the pipeline and call cb
- * @from: entity at which to start pipeline walk
- * @until: entity at which to stop pipeline walk
- *
- * Walk the entities chain starting at the pipeline video node and stop
- * all subdevices in the chain.
- *
- * If the until argument isn't NULL, stop the pipeline walk when reaching the
- * until entity. This is used to disable a partially started pipeline due to a
- * subdev start error.
- */
-static int rkisp1_pipeline_sink_walk(struct media_entity *from,
-                                    struct media_entity *until,
-                                    int (*cb)(struct media_entity *from,
-                                              struct media_entity *curr))
-{
-       struct media_entity *entity = from;
-       struct media_pad *pad;
-       unsigned int i;
-       int ret;
-
-       while (1) {
-               pad = NULL;
-               /* Find remote source pad */
-               for (i = 0; i < entity->num_pads; i++) {
-                       struct media_pad *spad = &entity->pads[i];
-
-                       if (!(spad->flags & MEDIA_PAD_FL_SINK))
-                               continue;
-                       pad = media_entity_remote_pad(spad);
-                       if (pad && is_media_entity_v4l2_subdev(pad->entity))
-                               break;
-               }
-               if (!pad || !is_media_entity_v4l2_subdev(pad->entity))
-                       break;
-
-               entity = pad->entity;
-               if (entity == until)
-                       break;
-
-               ret = cb(from, entity);
-               if (ret)
-                       return ret;
-       }
-
-       return 0;
-}
-
-static int rkisp1_pipeline_disable_cb(struct media_entity *from,
-                                     struct media_entity *curr)
-{
-       struct v4l2_subdev *sd = media_entity_to_v4l2_subdev(curr);
-
-       return v4l2_subdev_call(sd, video, s_stream, false);
-}
-
-static int rkisp1_pipeline_enable_cb(struct media_entity *from,
-                                    struct media_entity *curr)
-{
-       struct v4l2_subdev *sd = media_entity_to_v4l2_subdev(curr);
-
-       return v4l2_subdev_call(sd, video, s_stream, true);
-}
-
-static void rkisp1_stream_stop(struct rkisp1_capture *cap)
-{
-       int ret;
-
-       /* Stream should stop in interrupt. If it dosn't, stop it by force. */
-       cap->is_stopping = true;
-       ret = wait_event_timeout(cap->done,
-                                !cap->is_streaming,
-                                msecs_to_jiffies(1000));
-       if (!ret) {
-               cap->rkisp1->debug.stop_timeout[cap->id]++;
-               cap->ops->stop(cap);
-               cap->is_stopping = false;
-               cap->is_streaming = false;
-       }
-}
-
-static void rkisp1_vb2_stop_streaming(struct vb2_queue *queue)
-{
-       struct rkisp1_capture *cap = queue->drv_priv;
-       struct rkisp1_vdev_node *node = &cap->vnode;
-       struct rkisp1_device *rkisp1 = cap->rkisp1;
-       int ret;
-
-       mutex_lock(&cap->rkisp1->stream_lock);
-
-       rkisp1_stream_stop(cap);
-       media_pipeline_stop(&node->vdev.entity);
-       ret = rkisp1_pipeline_sink_walk(&node->vdev.entity, NULL,
-                                       rkisp1_pipeline_disable_cb);
-       if (ret)
-               dev_err(rkisp1->dev,
-                       "pipeline stream-off failed error:%d\n", ret);
-
-       rkisp1_return_all_buffers(cap, VB2_BUF_STATE_ERROR);
-
-       v4l2_pipeline_pm_put(&node->vdev.entity);
-       ret = pm_runtime_put(rkisp1->dev);
-       if (ret < 0)
-               dev_err(rkisp1->dev, "power down failed error:%d\n", ret);
-
-       rkisp1_dummy_buf_destroy(cap);
-
-       mutex_unlock(&cap->rkisp1->stream_lock);
-}
-
-/*
- * Most of registers inside rockchip ISP1 have shadow register since
- * they must be not be changed during processing a frame.
- * Usually, each sub-module updates its shadow register after
- * processing the last pixel of a frame.
- */
-static void rkisp1_stream_start(struct rkisp1_capture *cap)
-{
-       struct rkisp1_device *rkisp1 = cap->rkisp1;
-       struct rkisp1_capture *other = &rkisp1->capture_devs[cap->id ^ 1];
-
-       cap->ops->set_data_path(cap);
-       cap->ops->config(cap);
-
-       /* Setup a buffer for the next frame */
-       spin_lock_irq(&cap->buf.lock);
-       rkisp1_set_next_buf(cap);
-       cap->ops->enable(cap);
-       /* It's safe to config ACTIVE and SHADOW regs for the
-        * first stream. While when the second is starting, do NOT
-        * force update because it also update the first one.
-        *
-        * The latter case would drop one more buf(that is 2) since
-        * there's not buf in shadow when the second FE received. This's
-        * also required because the second FE maybe corrupt especially
-        * when run at 120fps.
-        */
-       if (!other->is_streaming) {
-               /* force cfg update */
-               rkisp1_write(rkisp1,
-                            RKISP1_CIF_MI_INIT_SOFT_UPD, RKISP1_CIF_MI_INIT);
-               rkisp1_set_next_buf(cap);
-       }
-       spin_unlock_irq(&cap->buf.lock);
-       cap->is_streaming = true;
-}
-
-static int
-rkisp1_vb2_start_streaming(struct vb2_queue *queue, unsigned int count)
-{
-       struct rkisp1_capture *cap = queue->drv_priv;
-       struct media_entity *entity = &cap->vnode.vdev.entity;
-       int ret;
-
-       mutex_lock(&cap->rkisp1->stream_lock);
-
-       ret = rkisp1_dummy_buf_create(cap);
-       if (ret)
-               goto err_ret_buffers;
-
-       ret = pm_runtime_get_sync(cap->rkisp1->dev);
-       if (ret < 0) {
-               dev_err(cap->rkisp1->dev, "power up failed %d\n", ret);
-               goto err_destroy_dummy;
-       }
-       ret = v4l2_pipeline_pm_get(entity);
-       if (ret) {
-               dev_err(cap->rkisp1->dev, "open cif pipeline failed %d\n", ret);
-               goto err_pipe_pm_put;
-       }
-
-       rkisp1_stream_start(cap);
-
-       /* start sub-devices */
-       ret = rkisp1_pipeline_sink_walk(entity, NULL,
-                                       rkisp1_pipeline_enable_cb);
-       if (ret)
-               goto err_stop_stream;
-
-       ret = media_pipeline_start(entity, &cap->rkisp1->pipe);
-       if (ret) {
-               dev_err(cap->rkisp1->dev, "start pipeline failed %d\n", ret);
-               goto err_pipe_disable;
-       }
-
-       mutex_unlock(&cap->rkisp1->stream_lock);
-
-       return 0;
-
-err_pipe_disable:
-       rkisp1_pipeline_sink_walk(entity, NULL, rkisp1_pipeline_disable_cb);
-err_stop_stream:
-       rkisp1_stream_stop(cap);
-       v4l2_pipeline_pm_put(entity);
-err_pipe_pm_put:
-       pm_runtime_put(cap->rkisp1->dev);
-err_destroy_dummy:
-       rkisp1_dummy_buf_destroy(cap);
-err_ret_buffers:
-       rkisp1_return_all_buffers(cap, VB2_BUF_STATE_QUEUED);
-       mutex_unlock(&cap->rkisp1->stream_lock);
-
-       return ret;
-}
-
-static struct vb2_ops rkisp1_vb2_ops = {
-       .queue_setup = rkisp1_vb2_queue_setup,
-       .buf_queue = rkisp1_vb2_buf_queue,
-       .buf_prepare = rkisp1_vb2_buf_prepare,
-       .wait_prepare = vb2_ops_wait_prepare,
-       .wait_finish = vb2_ops_wait_finish,
-       .stop_streaming = rkisp1_vb2_stop_streaming,
-       .start_streaming = rkisp1_vb2_start_streaming,
-};
-
-/* ----------------------------------------------------------------------------
- * IOCTLs operations
- */
-
-static const struct v4l2_format_info *
-rkisp1_fill_pixfmt(struct v4l2_pix_format_mplane *pixm,
-                  enum rkisp1_stream_id id)
-{
-       struct v4l2_plane_pix_format *plane_y = &pixm->plane_fmt[0];
-       const struct v4l2_format_info *info;
-       unsigned int i;
-       u32 stride;
-
-       memset(pixm->plane_fmt, 0, sizeof(pixm->plane_fmt));
-       info = v4l2_format_info(pixm->pixelformat);
-       pixm->num_planes = info->mem_planes;
-       stride = info->bpp[0] * pixm->width;
-       /* Self path supports custom stride but Main path doesn't */
-       if (id == RKISP1_MAINPATH || plane_y->bytesperline < stride)
-               plane_y->bytesperline = stride;
-       plane_y->sizeimage = plane_y->bytesperline * pixm->height;
-
-       /* normalize stride to pixels per line */
-       stride = DIV_ROUND_UP(plane_y->bytesperline, info->bpp[0]);
-
-       for (i = 1; i < info->comp_planes; i++) {
-               struct v4l2_plane_pix_format *plane = &pixm->plane_fmt[i];
-
-               /* bytesperline for other components derive from Y component */
-               plane->bytesperline = DIV_ROUND_UP(stride, info->hdiv) *
-                                     info->bpp[i];
-               plane->sizeimage = plane->bytesperline *
-                                  DIV_ROUND_UP(pixm->height, info->vdiv);
-       }
-
-       /*
-        * If pixfmt is packed, then plane_fmt[0] should contain the total size
-        * considering all components. plane_fmt[i] for i > 0 should be ignored
-        * by userspace as mem_planes == 1, but we are keeping information there
-        * for convenience.
-        */
-       if (info->mem_planes == 1)
-               for (i = 1; i < info->comp_planes; i++)
-                       plane_y->sizeimage += pixm->plane_fmt[i].sizeimage;
-
-       return info;
-}
-
-static const struct rkisp1_capture_fmt_cfg *
-rkisp1_find_fmt_cfg(const struct rkisp1_capture *cap, const u32 pixelfmt)
-{
-       unsigned int i;
-
-       for (i = 0; i < cap->config->fmt_size; i++) {
-               if (cap->config->fmts[i].fourcc == pixelfmt)
-                       return &cap->config->fmts[i];
-       }
-       return NULL;
-}
-
-static void rkisp1_try_fmt(const struct rkisp1_capture *cap,
-                          struct v4l2_pix_format_mplane *pixm,
-                          const struct rkisp1_capture_fmt_cfg **fmt_cfg,
-                          const struct v4l2_format_info **fmt_info)
-{
-       const struct rkisp1_capture_config *config = cap->config;
-       const struct rkisp1_capture_fmt_cfg *fmt;
-       const struct v4l2_format_info *info;
-       const unsigned int max_widths[] = { RKISP1_RSZ_MP_SRC_MAX_WIDTH,
-                                           RKISP1_RSZ_SP_SRC_MAX_WIDTH };
-       const unsigned int max_heights[] = { RKISP1_RSZ_MP_SRC_MAX_HEIGHT,
-                                            RKISP1_RSZ_SP_SRC_MAX_HEIGHT};
-
-       fmt = rkisp1_find_fmt_cfg(cap, pixm->pixelformat);
-       if (!fmt) {
-               fmt = config->fmts;
-               pixm->pixelformat = fmt->fourcc;
-       }
-
-       pixm->width = clamp_t(u32, pixm->width,
-                             RKISP1_RSZ_SRC_MIN_WIDTH, max_widths[cap->id]);
-       pixm->height = clamp_t(u32, pixm->height,
-                              RKISP1_RSZ_SRC_MIN_HEIGHT, max_heights[cap->id]);
-
-       pixm->field = V4L2_FIELD_NONE;
-       pixm->colorspace = V4L2_COLORSPACE_DEFAULT;
-       pixm->ycbcr_enc = V4L2_YCBCR_ENC_DEFAULT;
-
-       info = rkisp1_fill_pixfmt(pixm, cap->id);
-
-       if (fmt_cfg)
-               *fmt_cfg = fmt;
-       if (fmt_info)
-               *fmt_info = info;
-}
-
-static void rkisp1_set_fmt(struct rkisp1_capture *cap,
-                          struct v4l2_pix_format_mplane *pixm)
-{
-       rkisp1_try_fmt(cap, pixm, &cap->pix.cfg, &cap->pix.info);
-       cap->pix.fmt = *pixm;
-
-       /* SP supports custom stride in number of pixels of the Y plane */
-       if (cap->id == RKISP1_SELFPATH)
-               cap->sp_y_stride = pixm->plane_fmt[0].bytesperline /
-                                  cap->pix.info->bpp[0];
-}
-
-static int rkisp1_try_fmt_vid_cap_mplane(struct file *file, void *fh,
-                                        struct v4l2_format *f)
-{
-       struct rkisp1_capture *cap = video_drvdata(file);
-
-       rkisp1_try_fmt(cap, &f->fmt.pix_mp, NULL, NULL);
-
-       return 0;
-}
-
-static int rkisp1_enum_fmt_vid_cap_mplane(struct file *file, void *priv,
-                                         struct v4l2_fmtdesc *f)
-{
-       struct rkisp1_capture *cap = video_drvdata(file);
-       const struct rkisp1_capture_fmt_cfg *fmt = NULL;
-       unsigned int i, n = 0;
-
-       if (!f->mbus_code) {
-               if (f->index >= cap->config->fmt_size)
-                       return -EINVAL;
-
-               fmt = &cap->config->fmts[f->index];
-               f->pixelformat = fmt->fourcc;
-               return 0;
-       }
-
-       for (i = 0; i < cap->config->fmt_size; i++) {
-               if (cap->config->fmts[i].mbus != f->mbus_code)
-                       continue;
-
-               if (n++ == f->index) {
-                       f->pixelformat = cap->config->fmts[i].fourcc;
-                       return 0;
-               }
-       }
-       return -EINVAL;
-}
-
-static int rkisp1_s_fmt_vid_cap_mplane(struct file *file,
-                                      void *priv, struct v4l2_format *f)
-{
-       struct rkisp1_capture *cap = video_drvdata(file);
-       struct rkisp1_vdev_node *node =
-                               rkisp1_vdev_to_node(&cap->vnode.vdev);
-
-       if (vb2_is_busy(&node->buf_queue))
-               return -EBUSY;
-
-       rkisp1_set_fmt(cap, &f->fmt.pix_mp);
-
-       return 0;
-}
-
-static int rkisp1_g_fmt_vid_cap_mplane(struct file *file, void *fh,
-                                      struct v4l2_format *f)
-{
-       struct rkisp1_capture *cap = video_drvdata(file);
-
-       f->fmt.pix_mp = cap->pix.fmt;
-
-       return 0;
-}
-
-static int
-rkisp1_querycap(struct file *file, void *priv, struct v4l2_capability *cap)
-{
-       struct rkisp1_capture *cap_dev = video_drvdata(file);
-       struct rkisp1_device *rkisp1 = cap_dev->rkisp1;
-
-       strscpy(cap->driver, rkisp1->dev->driver->name, sizeof(cap->driver));
-       strscpy(cap->card, rkisp1->dev->driver->name, sizeof(cap->card));
-       strscpy(cap->bus_info, RKISP1_BUS_INFO, sizeof(cap->bus_info));
-
-       return 0;
-}
-
-static const struct v4l2_ioctl_ops rkisp1_v4l2_ioctl_ops = {
-       .vidioc_reqbufs = vb2_ioctl_reqbufs,
-       .vidioc_querybuf = vb2_ioctl_querybuf,
-       .vidioc_create_bufs = vb2_ioctl_create_bufs,
-       .vidioc_qbuf = vb2_ioctl_qbuf,
-       .vidioc_expbuf = vb2_ioctl_expbuf,
-       .vidioc_dqbuf = vb2_ioctl_dqbuf,
-       .vidioc_prepare_buf = vb2_ioctl_prepare_buf,
-       .vidioc_streamon = vb2_ioctl_streamon,
-       .vidioc_streamoff = vb2_ioctl_streamoff,
-       .vidioc_try_fmt_vid_cap_mplane = rkisp1_try_fmt_vid_cap_mplane,
-       .vidioc_s_fmt_vid_cap_mplane = rkisp1_s_fmt_vid_cap_mplane,
-       .vidioc_g_fmt_vid_cap_mplane = rkisp1_g_fmt_vid_cap_mplane,
-       .vidioc_enum_fmt_vid_cap = rkisp1_enum_fmt_vid_cap_mplane,
-       .vidioc_querycap = rkisp1_querycap,
-       .vidioc_subscribe_event = v4l2_ctrl_subscribe_event,
-       .vidioc_unsubscribe_event = v4l2_event_unsubscribe,
-};
-
-static int rkisp1_capture_link_validate(struct media_link *link)
-{
-       struct video_device *vdev =
-               media_entity_to_video_device(link->sink->entity);
-       struct v4l2_subdev *sd =
-               media_entity_to_v4l2_subdev(link->source->entity);
-       struct rkisp1_capture *cap = video_get_drvdata(vdev);
-       const struct rkisp1_capture_fmt_cfg *fmt =
-               rkisp1_find_fmt_cfg(cap, cap->pix.fmt.pixelformat);
-       struct v4l2_subdev_format sd_fmt;
-       int ret;
-
-       sd_fmt.which = V4L2_SUBDEV_FORMAT_ACTIVE;
-       sd_fmt.pad = link->source->index;
-       ret = v4l2_subdev_call(sd, pad, get_fmt, NULL, &sd_fmt);
-       if (ret)
-               return ret;
-
-       if (sd_fmt.format.height != cap->pix.fmt.height ||
-           sd_fmt.format.width != cap->pix.fmt.width ||
-           sd_fmt.format.code != fmt->mbus)
-               return -EPIPE;
-
-       return 0;
-}
-
-/* ----------------------------------------------------------------------------
- * core functions
- */
-
-static const struct media_entity_operations rkisp1_media_ops = {
-       .link_validate = rkisp1_capture_link_validate,
-};
-
-static const struct v4l2_file_operations rkisp1_fops = {
-       .open = v4l2_fh_open,
-       .release = vb2_fop_release,
-       .unlocked_ioctl = video_ioctl2,
-       .poll = vb2_fop_poll,
-       .mmap = vb2_fop_mmap,
-};
-
-static void rkisp1_unregister_capture(struct rkisp1_capture *cap)
-{
-       media_entity_cleanup(&cap->vnode.vdev.entity);
-       vb2_video_unregister_device(&cap->vnode.vdev);
-}
-
-void rkisp1_capture_devs_unregister(struct rkisp1_device *rkisp1)
-{
-       struct rkisp1_capture *mp = &rkisp1->capture_devs[RKISP1_MAINPATH];
-       struct rkisp1_capture *sp = &rkisp1->capture_devs[RKISP1_SELFPATH];
-
-       rkisp1_unregister_capture(mp);
-       rkisp1_unregister_capture(sp);
-}
-
-static int rkisp1_register_capture(struct rkisp1_capture *cap)
-{
-       const char * const dev_names[] = {RKISP1_MP_DEV_NAME,
-                                         RKISP1_SP_DEV_NAME};
-       struct v4l2_device *v4l2_dev = &cap->rkisp1->v4l2_dev;
-       struct video_device *vdev = &cap->vnode.vdev;
-       struct rkisp1_vdev_node *node;
-       struct vb2_queue *q;
-       int ret;
-
-       strscpy(vdev->name, dev_names[cap->id], sizeof(vdev->name));
-       node = rkisp1_vdev_to_node(vdev);
-       mutex_init(&node->vlock);
-
-       vdev->ioctl_ops = &rkisp1_v4l2_ioctl_ops;
-       vdev->release = video_device_release_empty;
-       vdev->fops = &rkisp1_fops;
-       vdev->minor = -1;
-       vdev->v4l2_dev = v4l2_dev;
-       vdev->lock = &node->vlock;
-       vdev->device_caps = V4L2_CAP_VIDEO_CAPTURE_MPLANE |
-                           V4L2_CAP_STREAMING | V4L2_CAP_IO_MC;
-       vdev->entity.ops = &rkisp1_media_ops;
-       video_set_drvdata(vdev, cap);
-       vdev->vfl_dir = VFL_DIR_RX;
-       node->pad.flags = MEDIA_PAD_FL_SINK;
-
-       q = &node->buf_queue;
-       q->type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
-       q->io_modes = VB2_MMAP | VB2_DMABUF;
-       q->drv_priv = cap;
-       q->ops = &rkisp1_vb2_ops;
-       q->mem_ops = &vb2_dma_contig_memops;
-       q->buf_struct_size = sizeof(struct rkisp1_buffer);
-       q->min_buffers_needed = RKISP1_MIN_BUFFERS_NEEDED;
-       q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
-       q->lock = &node->vlock;
-       q->dev = cap->rkisp1->dev;
-       ret = vb2_queue_init(q);
-       if (ret) {
-               dev_err(cap->rkisp1->dev,
-                       "vb2 queue init failed (err=%d)\n", ret);
-               return ret;
-       }
-
-       vdev->queue = q;
-
-       ret = video_register_device(vdev, VFL_TYPE_VIDEO, -1);
-       if (ret) {
-               dev_err(cap->rkisp1->dev,
-                       "failed to register %s, ret=%d\n", vdev->name, ret);
-               return ret;
-       }
-       v4l2_info(v4l2_dev, "registered %s as /dev/video%d\n", vdev->name,
-                 vdev->num);
-
-       ret = media_entity_pads_init(&vdev->entity, 1, &node->pad);
-       if (ret) {
-               video_unregister_device(vdev);
-               return ret;
-       }
-
-       return 0;
-}
-
-static void
-rkisp1_capture_init(struct rkisp1_device *rkisp1, enum rkisp1_stream_id id)
-{
-       struct rkisp1_capture *cap = &rkisp1->capture_devs[id];
-       struct v4l2_pix_format_mplane pixm;
-
-       memset(cap, 0, sizeof(*cap));
-       cap->id = id;
-       cap->rkisp1 = rkisp1;
-
-       INIT_LIST_HEAD(&cap->buf.queue);
-       init_waitqueue_head(&cap->done);
-       spin_lock_init(&cap->buf.lock);
-       if (cap->id == RKISP1_SELFPATH) {
-               cap->ops = &rkisp1_capture_ops_sp;
-               cap->config = &rkisp1_capture_config_sp;
-       } else {
-               cap->ops = &rkisp1_capture_ops_mp;
-               cap->config = &rkisp1_capture_config_mp;
-       }
-
-       cap->is_streaming = false;
-
-       memset(&pixm, 0, sizeof(pixm));
-       pixm.pixelformat = V4L2_PIX_FMT_YUYV;
-       pixm.width = RKISP1_DEFAULT_WIDTH;
-       pixm.height = RKISP1_DEFAULT_HEIGHT;
-       rkisp1_set_fmt(cap, &pixm);
-}
-
-int rkisp1_capture_devs_register(struct rkisp1_device *rkisp1)
-{
-       struct rkisp1_capture *cap;
-       unsigned int i, j;
-       int ret;
-
-       for (i = 0; i < ARRAY_SIZE(rkisp1->capture_devs); i++) {
-               rkisp1_capture_init(rkisp1, i);
-               cap = &rkisp1->capture_devs[i];
-               cap->rkisp1 = rkisp1;
-               ret = rkisp1_register_capture(cap);
-               if (ret)
-                       goto err_unreg_capture_devs;
-       }
-
-       return 0;
-
-err_unreg_capture_devs:
-       for (j = 0; j < i; j++) {
-               cap = &rkisp1->capture_devs[j];
-               rkisp1_unregister_capture(cap);
-       }
-
-       return ret;
-}
diff --git a/drivers/staging/media/rkisp1/rkisp1-common.c b/drivers/staging/media/rkisp1/rkisp1-common.c
deleted file mode 100644 (file)
index cf88966..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
-// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
-/*
- * Rockchip ISP1 Driver - Common definitions
- *
- * Copyright (C) 2019 Collabora, Ltd.
- */
-
-#include <media/v4l2-rect.h>
-
-#include "rkisp1-common.h"
-
-static const struct v4l2_rect rkisp1_sd_min_crop = {
-       .width = RKISP1_ISP_MIN_WIDTH,
-       .height = RKISP1_ISP_MIN_HEIGHT,
-       .top = 0,
-       .left = 0,
-};
-
-void rkisp1_sd_adjust_crop_rect(struct v4l2_rect *crop,
-                               const struct v4l2_rect *bounds)
-{
-       v4l2_rect_set_min_size(crop, &rkisp1_sd_min_crop);
-       v4l2_rect_map_inside(crop, bounds);
-}
-
-void rkisp1_sd_adjust_crop(struct v4l2_rect *crop,
-                          const struct v4l2_mbus_framefmt *bounds)
-{
-       struct v4l2_rect crop_bounds = {
-               .left = 0,
-               .top = 0,
-               .width = bounds->width,
-               .height = bounds->height,
-       };
-
-       rkisp1_sd_adjust_crop_rect(crop, &crop_bounds);
-}
diff --git a/drivers/staging/media/rkisp1/rkisp1-common.h b/drivers/staging/media/rkisp1/rkisp1-common.h
deleted file mode 100644 (file)
index 45abacd..0000000
+++ /dev/null
@@ -1,489 +0,0 @@
-/* SPDX-License-Identifier: (GPL-2.0+ OR MIT) */
-/*
- * Rockchip ISP1 Driver - Common definitions
- *
- * Copyright (C) 2019 Collabora, Ltd.
- *
- * Based on Rockchip ISP1 driver by Rockchip Electronics Co., Ltd.
- * Copyright (C) 2017 Rockchip Electronics Co., Ltd.
- */
-
-#ifndef _RKISP1_COMMON_H
-#define _RKISP1_COMMON_H
-
-#include <linux/clk.h>
-#include <linux/mutex.h>
-#include <media/media-device.h>
-#include <media/media-entity.h>
-#include <media/v4l2-ctrls.h>
-#include <media/v4l2-device.h>
-#include <media/videobuf2-v4l2.h>
-
-#include "rkisp1-regs.h"
-#include "uapi/rkisp1-config.h"
-
-/*
- * flags on the 'direction' field in struct 'rkisp1_isp_mbus_info' that indicate
- * on which pad the media bus format is supported
- */
-#define RKISP1_ISP_SD_SRC BIT(0)
-#define RKISP1_ISP_SD_SINK BIT(1)
-
-/* min and max values for the widths and heights of the entities */
-#define RKISP1_ISP_MAX_WIDTH           4032
-#define RKISP1_ISP_MAX_HEIGHT          3024
-#define RKISP1_ISP_MIN_WIDTH           32
-#define RKISP1_ISP_MIN_HEIGHT          32
-
-#define RKISP1_RSZ_MP_SRC_MAX_WIDTH            4416
-#define RKISP1_RSZ_MP_SRC_MAX_HEIGHT           3312
-#define RKISP1_RSZ_SP_SRC_MAX_WIDTH            1920
-#define RKISP1_RSZ_SP_SRC_MAX_HEIGHT           1920
-#define RKISP1_RSZ_SRC_MIN_WIDTH               32
-#define RKISP1_RSZ_SRC_MIN_HEIGHT              16
-
-/* the default width and height of all the entities */
-#define RKISP1_DEFAULT_WIDTH           800
-#define RKISP1_DEFAULT_HEIGHT          600
-
-#define RKISP1_DRIVER_NAME     "rkisp1"
-#define RKISP1_BUS_INFO                "platform:" RKISP1_DRIVER_NAME
-
-/* maximum number of clocks */
-#define RKISP1_MAX_BUS_CLK     8
-
-/* a bitmask of the ready stats */
-#define RKISP1_STATS_MEAS_MASK         (RKISP1_CIF_ISP_AWB_DONE |      \
-                                        RKISP1_CIF_ISP_AFM_FIN |       \
-                                        RKISP1_CIF_ISP_EXP_END |       \
-                                        RKISP1_CIF_ISP_HIST_MEASURE_RDY)
-
-/* enum for the resizer pads */
-enum rkisp1_rsz_pad {
-       RKISP1_RSZ_PAD_SINK,
-       RKISP1_RSZ_PAD_SRC,
-       RKISP1_RSZ_PAD_MAX
-};
-
-/* enum for the capture id */
-enum rkisp1_stream_id {
-       RKISP1_MAINPATH,
-       RKISP1_SELFPATH,
-};
-
-/* bayer patterns */
-enum rkisp1_fmt_raw_pat_type {
-       RKISP1_RAW_RGGB = 0,
-       RKISP1_RAW_GRBG,
-       RKISP1_RAW_GBRG,
-       RKISP1_RAW_BGGR,
-};
-
-/* enum for the isp pads */
-enum rkisp1_isp_pad {
-       RKISP1_ISP_PAD_SINK_VIDEO,
-       RKISP1_ISP_PAD_SINK_PARAMS,
-       RKISP1_ISP_PAD_SOURCE_VIDEO,
-       RKISP1_ISP_PAD_SOURCE_STATS,
-       RKISP1_ISP_PAD_MAX
-};
-
-/*
- * struct rkisp1_sensor_async - A container for the v4l2_async_subdev to add to the notifier
- *                             of the v4l2-async API
- *
- * @asd:               async_subdev variable for the sensor
- * @lanes:             number of lanes
- * @mbus_type:         type of bus (currently only CSI2 is supported)
- * @mbus_flags:                media bus (V4L2_MBUS_*) flags
- * @sd:                        a pointer to v4l2_subdev struct of the sensor
- * @pixel_rate_ctrl:   pixel rate of the sensor, used to initialize the phy
- * @dphy:              a pointer to the phy
- */
-struct rkisp1_sensor_async {
-       struct v4l2_async_subdev asd;
-       unsigned int lanes;
-       enum v4l2_mbus_type mbus_type;
-       unsigned int mbus_flags;
-       struct v4l2_subdev *sd;
-       struct v4l2_ctrl *pixel_rate_ctrl;
-       struct phy *dphy;
-};
-
-/*
- * struct rkisp1_isp - ISP subdev entity
- *
- * @sd:                                v4l2_subdev variable
- * @rkisp1:                    pointer to rkisp1_device
- * @pads:                      media pads
- * @pad_cfg:                   pads configurations
- * @sink_fmt:                  input format
- * @src_fmt:                   output format
- * @ops_lock:                  ops serialization
- * @is_dphy_errctrl_disabled:  if dphy errctrl is disabled (avoid endless interrupt)
- * @frame_sequence:            used to synchronize frame_id between video devices.
- */
-struct rkisp1_isp {
-       struct v4l2_subdev sd;
-       struct media_pad pads[RKISP1_ISP_PAD_MAX];
-       struct v4l2_subdev_pad_config pad_cfg[RKISP1_ISP_PAD_MAX];
-       const struct rkisp1_isp_mbus_info *sink_fmt;
-       const struct rkisp1_isp_mbus_info *src_fmt;
-       struct mutex ops_lock; /* serialize the subdevice ops */
-       bool is_dphy_errctrl_disabled;
-       __u32 frame_sequence;
-};
-
-/*
- * struct rkisp1_vdev_node - Container for the video nodes: params, stats, mainpath, selfpath
- *
- * @buf_queue: queue of buffers
- * @vlock:     lock of the video node
- * @vdev:      video node
- * @pad:       media pad
- */
-struct rkisp1_vdev_node {
-       struct vb2_queue buf_queue;
-       struct mutex vlock; /* ioctl serialization mutex */
-       struct video_device vdev;
-       struct media_pad pad;
-};
-
-/*
- * struct rkisp1_buffer - A container for the vb2 buffers used by the video devices:
- *                       params, stats, mainpath, selfpath
- *
- * @vb:                vb2 buffer
- * @queue:     entry of the buffer in the queue
- * @buff_addr: dma addresses of each plane, used only by the capture devices: selfpath, mainpath
- * @vaddr:     virtual address for buffers used by params and stats devices
- */
-struct rkisp1_buffer {
-       struct vb2_v4l2_buffer vb;
-       struct list_head queue;
-       union {
-               u32 buff_addr[VIDEO_MAX_PLANES];
-               void *vaddr;
-       };
-};
-
-/*
- * struct rkisp1_dummy_buffer - A buffer to write the next frame to in case
- *                             there are no vb2 buffers available.
- *
- * @vaddr:     return value of call to dma_alloc_attrs.
- * @dma_addr:  dma address of the buffer.
- * @size:      size of the buffer.
- */
-struct rkisp1_dummy_buffer {
-       void *vaddr;
-       dma_addr_t dma_addr;
-       u32 size;
-};
-
-struct rkisp1_device;
-
-/*
- * struct rkisp1_capture - ISP capture video device
- *
- * @vnode:       video node
- * @rkisp1:      pointer to rkisp1_device
- * @id:                  id of the capture, one of RKISP1_SELFPATH, RKISP1_MAINPATH
- * @ops:         list of callbacks to configure the capture device.
- * @config:      a pointer to the list of registers to configure the capture format.
- * @is_streaming: device is streaming
- * @is_stopping:  stop_streaming callback was called and the device is in the process of
- *               stopping the streaming.
- * @done:        when stop_streaming callback is called, the device waits for the next irq
- *               handler to stop the streaming by waiting on the 'done' wait queue.
- *               If the irq handler is not called, the stream is stopped by the callback
- *               after timeout.
- * @sp_y_stride:  the selfpath allows to configure a y stride that is longer than the image width.
- * @buf.lock:    lock to protect buf.queue
- * @buf.queue:   queued buffer list
- * @buf.dummy:   dummy space to store dropped data
- *
- * rkisp1 uses shadow registers, so it needs two buffers at a time
- * @buf.curr:    the buffer used for current frame
- * @buf.next:    the buffer used for next frame
- * @pix.cfg:     pixel configuration
- * @pix.info:    a pointer to the v4l2_format_info of the pixel format
- * @pix.fmt:     buffer format
- */
-struct rkisp1_capture {
-       struct rkisp1_vdev_node vnode;
-       struct rkisp1_device *rkisp1;
-       enum rkisp1_stream_id id;
-       struct rkisp1_capture_ops *ops;
-       const struct rkisp1_capture_config *config;
-       bool is_streaming;
-       bool is_stopping;
-       wait_queue_head_t done;
-       unsigned int sp_y_stride;
-       struct {
-               /* protects queue, curr and next */
-               spinlock_t lock;
-               struct list_head queue;
-               struct rkisp1_dummy_buffer dummy;
-               struct rkisp1_buffer *curr;
-               struct rkisp1_buffer *next;
-       } buf;
-       struct {
-               const struct rkisp1_capture_fmt_cfg *cfg;
-               const struct v4l2_format_info *info;
-               struct v4l2_pix_format_mplane fmt;
-       } pix;
-};
-
-/*
- * struct rkisp1_stats - ISP Statistics device
- *
- * @vnode:       video node
- * @rkisp1:      pointer to the rkisp1 device
- * @lock:        locks the buffer list 'stat' and 'is_streaming'
- * @stat:        queue of rkisp1_buffer
- * @vdev_fmt:    v4l2_format of the metadata format
- * @is_streaming: device is streaming
- */
-struct rkisp1_stats {
-       struct rkisp1_vdev_node vnode;
-       struct rkisp1_device *rkisp1;
-
-       spinlock_t lock; /* locks the buffers list 'stats' and 'is_streaming' */
-       struct list_head stat;
-       struct v4l2_format vdev_fmt;
-       bool is_streaming;
-};
-
-/*
- * struct rkisp1_params - ISP input parameters device
- *
- * @vnode:             video node
- * @rkisp1:            pointer to the rkisp1 device
- * @config_lock:       locks the buffer list 'params' and 'is_streaming'
- * @params:            queue of rkisp1_buffer
- * @vdev_fmt:          v4l2_format of the metadata format
- * @is_streaming:      device is streaming
- * @quantization:      the quantization configured on the isp's src pad
- * @raw_type:          the bayer pattern on the isp video sink pad
- */
-struct rkisp1_params {
-       struct rkisp1_vdev_node vnode;
-       struct rkisp1_device *rkisp1;
-
-       spinlock_t config_lock; /* locks the buffers list 'params' and 'is_streaming' */
-       struct list_head params;
-       struct v4l2_format vdev_fmt;
-       bool is_streaming;
-
-       enum v4l2_quantization quantization;
-       enum rkisp1_fmt_raw_pat_type raw_type;
-};
-
-/*
- * struct rkisp1_resizer - Resizer subdev
- *
- * @sd:               v4l2_subdev variable
- * @id:               id of the resizer, one of RKISP1_SELFPATH, RKISP1_MAINPATH
- * @rkisp1:    pointer to the rkisp1 device
- * @pads:      media pads
- * @pad_cfg:   configurations for the pads
- * @config:    the set of registers to configure the resizer
- * @pixel_enc: pixel encoding of the resizer
- * @ops_lock:  a lock for the subdev ops
- */
-struct rkisp1_resizer {
-       struct v4l2_subdev sd;
-       enum rkisp1_stream_id id;
-       struct rkisp1_device *rkisp1;
-       struct media_pad pads[RKISP1_RSZ_PAD_MAX];
-       struct v4l2_subdev_pad_config pad_cfg[RKISP1_RSZ_PAD_MAX];
-       const struct rkisp1_rsz_config *config;
-       enum v4l2_pixel_encoding pixel_enc;
-       struct mutex ops_lock; /* serialize the subdevice ops */
-};
-
-/*
- * struct rkisp1_debug - Values to be exposed on debugfs.
- *                      The parameters are counters of the number of times the
- *                      event occurred since the driver was loaded.
- *
- * @data_loss:                   loss of data occurred within a line, processing failure
- * @outform_size_error:                  size error is generated in outmux submodule
- * @img_stabilization_size_error: size error is generated in image stabilization submodule
- * @inform_size_err:             size error is generated in inform submodule
- * @mipi_error:                          mipi error occurred
- * @stats_error:                 writing to the 'Interrupt clear register' did not clear
- *                               it in the register 'Masked interrupt status'
- * @stop_timeout:                upon stream stop, the capture waits 1 second for the isr to stop
- *                               the stream. This param is incremented in case of timeout.
- * @frame_drop:                          a frame was ready but the buffer queue was empty so the frame
- *                               was not sent to userspace
- */
-struct rkisp1_debug {
-       struct dentry *debugfs_dir;
-       unsigned long data_loss;
-       unsigned long outform_size_error;
-       unsigned long img_stabilization_size_error;
-       unsigned long inform_size_error;
-       unsigned long irq_delay;
-       unsigned long mipi_error;
-       unsigned long stats_error;
-       unsigned long stop_timeout[2];
-       unsigned long frame_drop[2];
-};
-
-/*
- * struct rkisp1_device - ISP platform device
- *
- * @base_addr:    base register address
- * @irq:          the irq number
- * @dev:          a pointer to the struct device
- * @clk_size:     number of clocks
- * @clks:         array of clocks
- * @v4l2_dev:     v4l2_device variable
- * @media_dev:    media_device variable
- * @notifier:     a notifier to register on the v4l2-async API to be notified on the sensor
- * @active_sensor: sensor in-use, set when streaming on
- * @isp:          ISP sub-device
- * @resizer_devs:  resizer sub-devices
- * @capture_devs:  capture devices
- * @stats:        ISP statistics metadata capture device
- * @params:       ISP parameters metadata output device
- * @pipe:         media pipeline
- * @stream_lock:   serializes {start/stop}_streaming callbacks between the capture devices.
- * @debug:        debug params to be exposed on debugfs
- */
-struct rkisp1_device {
-       void __iomem *base_addr;
-       int irq;
-       struct device *dev;
-       unsigned int clk_size;
-       struct clk_bulk_data clks[RKISP1_MAX_BUS_CLK];
-       struct v4l2_device v4l2_dev;
-       struct media_device media_dev;
-       struct v4l2_async_notifier notifier;
-       struct rkisp1_sensor_async *active_sensor;
-       struct rkisp1_isp isp;
-       struct rkisp1_resizer resizer_devs[2];
-       struct rkisp1_capture capture_devs[2];
-       struct rkisp1_stats stats;
-       struct rkisp1_params params;
-       struct media_pipeline pipe;
-       struct mutex stream_lock; /* serialize {start/stop}_streaming cb between capture devices */
-       struct rkisp1_debug debug;
-};
-
-/*
- * struct rkisp1_isp_mbus_info - ISP media bus info, Translates media bus code to hardware
- *                              format values
- *
- * @mbus_code: media bus code
- * @pixel_enc: pixel encoding
- * @mipi_dt:   mipi data type
- * @yuv_seq:   the order of the Y, Cb, Cr values
- * @bus_width: bus width
- * @bayer_pat: bayer pattern
- * @direction: a bitmask of the flags indicating on which pad the format is supported on
- */
-struct rkisp1_isp_mbus_info {
-       u32 mbus_code;
-       enum v4l2_pixel_encoding pixel_enc;
-       u32 mipi_dt;
-       u32 yuv_seq;
-       u8 bus_width;
-       enum rkisp1_fmt_raw_pat_type bayer_pat;
-       unsigned int direction;
-};
-
-static inline void
-rkisp1_write(struct rkisp1_device *rkisp1, u32 val, unsigned int addr)
-{
-       writel(val, rkisp1->base_addr + addr);
-}
-
-static inline u32 rkisp1_read(struct rkisp1_device *rkisp1, unsigned int addr)
-{
-       return readl(rkisp1->base_addr + addr);
-}
-
-/*
- * rkisp1_cap_enum_mbus_codes - A helper function that return the i'th supported mbus code
- *                             of the capture entity. This is used to enumerate the supported
- *                             mbus codes on the source pad of the resizer.
- *
- * @cap:  the capture entity
- * @code: the mbus code, the function reads the code->index and fills the code->code
- */
-int rkisp1_cap_enum_mbus_codes(struct rkisp1_capture *cap,
-                              struct v4l2_subdev_mbus_code_enum *code);
-
-/*
- * rkisp1_sd_adjust_crop_rect - adjust a rectangle to fit into another rectangle.
- *
- * @crop:   rectangle to adjust.
- * @bounds: rectangle used as bounds.
- */
-void rkisp1_sd_adjust_crop_rect(struct v4l2_rect *crop,
-                               const struct v4l2_rect *bounds);
-
-/*
- * rkisp1_sd_adjust_crop - adjust a rectangle to fit into media bus format
- *
- * @crop:   rectangle to adjust.
- * @bounds: media bus format used as bounds.
- */
-void rkisp1_sd_adjust_crop(struct v4l2_rect *crop,
-                          const struct v4l2_mbus_framefmt *bounds);
-
-/*
- * rkisp1_isp_mbus_info - get the isp info of the media bus code
- *
- * @mbus_code: the media bus code
- */
-const struct rkisp1_isp_mbus_info *rkisp1_isp_mbus_info_get(u32 mbus_code);
-
-/* rkisp1_params_configure - configure the params when stream starts.
- *                          This function is called by the isp entity upon stream starts.
- *                          The function applies the initial configuration of the parameters.
- *
- * @params:      pointer to rkisp1_params.
- * @bayer_pat:   the bayer pattern on the isp video sink pad
- * @quantization: the quantization configured on the isp's src pad
- */
-void rkisp1_params_configure(struct rkisp1_params *params,
-                            enum rkisp1_fmt_raw_pat_type bayer_pat,
-                            enum v4l2_quantization quantization);
-
-/* rkisp1_params_disable - disable all parameters.
- *                        This function is called by the isp entity upon stream start
- *                        when capturing bayer format.
- *
- * @params: pointer to rkisp1_params.
- */
-void rkisp1_params_disable(struct rkisp1_params *params);
-
-/* irq handlers */
-void rkisp1_isp_isr(struct rkisp1_device *rkisp1);
-void rkisp1_mipi_isr(struct rkisp1_device *rkisp1);
-void rkisp1_capture_isr(struct rkisp1_device *rkisp1);
-void rkisp1_stats_isr(struct rkisp1_stats *stats, u32 isp_ris);
-void rkisp1_params_isr(struct rkisp1_device *rkisp1);
-
-/* register/unregisters functions of the entities */
-int rkisp1_capture_devs_register(struct rkisp1_device *rkisp1);
-void rkisp1_capture_devs_unregister(struct rkisp1_device *rkisp1);
-
-int rkisp1_isp_register(struct rkisp1_device *rkisp1);
-void rkisp1_isp_unregister(struct rkisp1_device *rkisp1);
-
-int rkisp1_resizer_devs_register(struct rkisp1_device *rkisp1);
-void rkisp1_resizer_devs_unregister(struct rkisp1_device *rkisp1);
-
-int rkisp1_stats_register(struct rkisp1_device *rkisp1);
-void rkisp1_stats_unregister(struct rkisp1_device *rkisp1);
-
-int rkisp1_params_register(struct rkisp1_device *rkisp1);
-void rkisp1_params_unregister(struct rkisp1_device *rkisp1);
-
-#endif /* _RKISP1_COMMON_H */
diff --git a/drivers/staging/media/rkisp1/rkisp1-dev.c b/drivers/staging/media/rkisp1/rkisp1-dev.c
deleted file mode 100644 (file)
index 9158469..0000000
+++ /dev/null
@@ -1,582 +0,0 @@
-// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
-/*
- * Rockchip ISP1 Driver - Base driver
- *
- * Copyright (C) 2019 Collabora, Ltd.
- *
- * Based on Rockchip ISP1 driver by Rockchip Electronics Co., Ltd.
- * Copyright (C) 2017 Rockchip Electronics Co., Ltd.
- */
-
-#include <linux/clk.h>
-#include <linux/debugfs.h>
-#include <linux/interrupt.h>
-#include <linux/module.h>
-#include <linux/of.h>
-#include <linux/of_graph.h>
-#include <linux/of_platform.h>
-#include <linux/pinctrl/consumer.h>
-#include <linux/phy/phy.h>
-#include <linux/phy/phy-mipi-dphy.h>
-#include <media/v4l2-fwnode.h>
-
-#include "rkisp1-common.h"
-
-/*
- * ISP Details
- * -----------
- *
- * ISP Comprises with:
- *     MIPI serial camera interface
- *     Image Signal Processing
- *     Many Image Enhancement Blocks
- *     Crop
- *     Resizer
- *     RBG display ready image
- *     Image Rotation
- *
- * ISP Block Diagram
- * -----------------
- *                                                             rkisp1-resizer.c          rkisp1-capture.c
- *                                                          |====================|  |=======================|
- *                                rkisp1-isp.c                              Main Picture Path
- *                        |==========================|      |===============================================|
- *                        +-----------+  +--+--+--+--+      +--------+  +--------+              +-----------+
- *                        |           |  |  |  |  |  |      |        |  |        |              |           |
- * +--------+    |\       |           |  |  |  |  |  |   -->|  Crop  |->|  RSZ   |------------->|           |
- * |  MIPI  |--->|  \     |           |  |  |  |  |  |   |  |        |  |        |              |           |
- * +--------+    |   |    |           |  |IE|IE|IE|IE|   |  +--------+  +--------+              |  Memory   |
- *               |MUX|--->|    ISP    |->|0 |1 |2 |3 |---+                                      | Interface |
- * +--------+    |   |    |           |  |  |  |  |  |   |  +--------+  +--------+  +--------+  |           |
- * |Parallel|--->|  /     |           |  |  |  |  |  |   |  |        |  |        |  |        |  |           |
- * +--------+    |/       |           |  |  |  |  |  |   -->|  Crop  |->|  RSZ   |->|  RGB   |->|           |
- *                        |           |  |  |  |  |  |      |        |  |        |  | Rotate |  |           |
- *                        +-----------+  +--+--+--+--+      +--------+  +--------+  +--------+  +-----------+
- *                                               ^
- * +--------+                                    |          |===============================================|
- * |  DMA   |------------------------------------+                          Self Picture Path
- * +--------+
- *
- *         rkisp1-stats.c        rkisp1-params.c
- *       |===============|      |===============|
- *       +---------------+      +---------------+
- *       |               |      |               |
- *       |      ISP      |      |      ISP      |
- *       |               |      |               |
- *       +---------------+      +---------------+
- *
- *
- * Media Topology
- * --------------
- *      +----------+     +----------+
- *      | Sensor 2 |     | Sensor X |
- *      ------------ ... ------------
- *      |    0     |     |    0     |
- *      +----------+     +----------+      +-----------+
- *                  \      |               |  params   |
- *                   \     |               | (output)  |
- *    +----------+    \    |               +-----------+
- *    | Sensor 1 |     v   v                     |
- *    ------------      +------+------+          |
- *    |    0     |----->|  0   |  1   |<---------+
- *    +----------+      |------+------|
- *                      |     ISP     |
- *                      |------+------|
- *        +-------------|  2   |  3   |----------+
- *        |             +------+------+          |
- *        |                |                     |
- *        v                v                     v
- *  +- ---------+    +-----------+         +-----------+
- *  |     0     |    |     0     |         |   stats   |
- *  -------------    -------------         | (capture) |
- *  |  Resizer  |    |  Resizer  |         +-----------+
- *  ------------|    ------------|
- *  |     1     |    |     1     |
- *  +-----------+    +-----------+
- *        |                |
- *        v                v
- *  +-----------+    +-----------+
- *  | selfpath  |    | mainpath  |
- *  | (capture) |    | (capture) |
- *  +-----------+    +-----------+
- */
-
-struct rkisp1_match_data {
-       const char * const *clks;
-       unsigned int size;
-};
-
-/* ----------------------------------------------------------------------------
- * Sensor DT bindings
- */
-
-static int rkisp1_create_links(struct rkisp1_device *rkisp1)
-{
-       struct media_entity *source, *sink;
-       unsigned int flags, source_pad;
-       struct v4l2_subdev *sd;
-       unsigned int i;
-       int ret;
-
-       /* sensor links */
-       flags = MEDIA_LNK_FL_ENABLED;
-       list_for_each_entry(sd, &rkisp1->v4l2_dev.subdevs, list) {
-               if (sd == &rkisp1->isp.sd ||
-                   sd == &rkisp1->resizer_devs[RKISP1_MAINPATH].sd ||
-                   sd == &rkisp1->resizer_devs[RKISP1_SELFPATH].sd)
-                       continue;
-
-               ret = media_entity_get_fwnode_pad(&sd->entity, sd->fwnode,
-                                                 MEDIA_PAD_FL_SOURCE);
-               if (ret < 0) {
-                       dev_err(rkisp1->dev, "failed to find src pad for %s\n",
-                               sd->name);
-                       return ret;
-               }
-               source_pad = ret;
-
-               ret = media_create_pad_link(&sd->entity, source_pad,
-                                           &rkisp1->isp.sd.entity,
-                                           RKISP1_ISP_PAD_SINK_VIDEO,
-                                           flags);
-               if (ret)
-                       return ret;
-
-               flags = 0;
-       }
-
-       flags = MEDIA_LNK_FL_ENABLED | MEDIA_LNK_FL_IMMUTABLE;
-
-       /* create ISP->RSZ->CAP links */
-       for (i = 0; i < 2; i++) {
-               source = &rkisp1->isp.sd.entity;
-               sink = &rkisp1->resizer_devs[i].sd.entity;
-               ret = media_create_pad_link(source, RKISP1_ISP_PAD_SOURCE_VIDEO,
-                                           sink, RKISP1_RSZ_PAD_SINK,
-                                           MEDIA_LNK_FL_ENABLED);
-               if (ret)
-                       return ret;
-
-               source = sink;
-               sink = &rkisp1->capture_devs[i].vnode.vdev.entity;
-               ret = media_create_pad_link(source, RKISP1_RSZ_PAD_SRC,
-                                           sink, 0, flags);
-               if (ret)
-                       return ret;
-       }
-
-       /* params links */
-       source = &rkisp1->params.vnode.vdev.entity;
-       sink = &rkisp1->isp.sd.entity;
-       ret = media_create_pad_link(source, 0, sink,
-                                   RKISP1_ISP_PAD_SINK_PARAMS, flags);
-       if (ret)
-               return ret;
-
-       /* 3A stats links */
-       source = &rkisp1->isp.sd.entity;
-       sink = &rkisp1->stats.vnode.vdev.entity;
-       return media_create_pad_link(source, RKISP1_ISP_PAD_SOURCE_STATS,
-                                    sink, 0, flags);
-}
-
-static int rkisp1_subdev_notifier_bound(struct v4l2_async_notifier *notifier,
-                                       struct v4l2_subdev *sd,
-                                       struct v4l2_async_subdev *asd)
-{
-       struct rkisp1_device *rkisp1 =
-               container_of(notifier, struct rkisp1_device, notifier);
-       struct rkisp1_sensor_async *s_asd =
-               container_of(asd, struct rkisp1_sensor_async, asd);
-
-       s_asd->pixel_rate_ctrl = v4l2_ctrl_find(sd->ctrl_handler,
-                                               V4L2_CID_PIXEL_RATE);
-       s_asd->sd = sd;
-       s_asd->dphy = devm_phy_get(rkisp1->dev, "dphy");
-       if (IS_ERR(s_asd->dphy)) {
-               if (PTR_ERR(s_asd->dphy) != -EPROBE_DEFER)
-                       dev_err(rkisp1->dev, "Couldn't get the MIPI D-PHY\n");
-               return PTR_ERR(s_asd->dphy);
-       }
-
-       phy_init(s_asd->dphy);
-
-       return 0;
-}
-
-static void rkisp1_subdev_notifier_unbind(struct v4l2_async_notifier *notifier,
-                                         struct v4l2_subdev *sd,
-                                         struct v4l2_async_subdev *asd)
-{
-       struct rkisp1_sensor_async *s_asd =
-               container_of(asd, struct rkisp1_sensor_async, asd);
-
-       phy_exit(s_asd->dphy);
-}
-
-static int rkisp1_subdev_notifier_complete(struct v4l2_async_notifier *notifier)
-{
-       struct rkisp1_device *rkisp1 =
-               container_of(notifier, struct rkisp1_device, notifier);
-       int ret;
-
-       ret = rkisp1_create_links(rkisp1);
-       if (ret)
-               return ret;
-
-       ret = v4l2_device_register_subdev_nodes(&rkisp1->v4l2_dev);
-       if (ret)
-               return ret;
-
-       dev_dbg(rkisp1->dev, "Async subdev notifier completed\n");
-
-       return 0;
-}
-
-static const struct v4l2_async_notifier_operations rkisp1_subdev_notifier_ops = {
-       .bound = rkisp1_subdev_notifier_bound,
-       .unbind = rkisp1_subdev_notifier_unbind,
-       .complete = rkisp1_subdev_notifier_complete,
-};
-
-static int rkisp1_subdev_notifier(struct rkisp1_device *rkisp1)
-{
-       struct v4l2_async_notifier *ntf = &rkisp1->notifier;
-       unsigned int next_id = 0;
-       int ret;
-
-       v4l2_async_notifier_init(ntf);
-
-       while (1) {
-               struct v4l2_fwnode_endpoint vep = {
-                       .bus_type = V4L2_MBUS_CSI2_DPHY
-               };
-               struct rkisp1_sensor_async *rk_asd = NULL;
-               struct fwnode_handle *ep;
-
-               ep = fwnode_graph_get_endpoint_by_id(dev_fwnode(rkisp1->dev),
-                       0, next_id, FWNODE_GRAPH_ENDPOINT_NEXT);
-               if (!ep)
-                       break;
-
-               ret = v4l2_fwnode_endpoint_parse(ep, &vep);
-               if (ret)
-                       goto err_parse;
-
-               rk_asd = kzalloc(sizeof(*rk_asd), GFP_KERNEL);
-               if (!rk_asd) {
-                       ret = -ENOMEM;
-                       goto err_parse;
-               }
-
-               rk_asd->mbus_type = vep.bus_type;
-               rk_asd->mbus_flags = vep.bus.mipi_csi2.flags;
-               rk_asd->lanes = vep.bus.mipi_csi2.num_data_lanes;
-
-               ret = v4l2_async_notifier_add_fwnode_remote_subdev(ntf, ep,
-                                                                  &rk_asd->asd);
-               if (ret)
-                       goto err_parse;
-
-               dev_dbg(rkisp1->dev, "registered ep id %d with %d lanes\n",
-                       vep.base.id, rk_asd->lanes);
-
-               next_id = vep.base.id + 1;
-
-               fwnode_handle_put(ep);
-
-               continue;
-err_parse:
-               fwnode_handle_put(ep);
-               kfree(rk_asd);
-               v4l2_async_notifier_cleanup(ntf);
-               return ret;
-       }
-
-       if (next_id == 0)
-               dev_dbg(rkisp1->dev, "no remote subdevice found\n");
-       ntf->ops = &rkisp1_subdev_notifier_ops;
-       ret = v4l2_async_notifier_register(&rkisp1->v4l2_dev, ntf);
-       if (ret) {
-               v4l2_async_notifier_cleanup(ntf);
-               return ret;
-       }
-       return 0;
-}
-
-/* ----------------------------------------------------------------------------
- * Power
- */
-
-static int __maybe_unused rkisp1_runtime_suspend(struct device *dev)
-{
-       struct rkisp1_device *rkisp1 = dev_get_drvdata(dev);
-
-       clk_bulk_disable_unprepare(rkisp1->clk_size, rkisp1->clks);
-       return pinctrl_pm_select_sleep_state(dev);
-}
-
-static int __maybe_unused rkisp1_runtime_resume(struct device *dev)
-{
-       struct rkisp1_device *rkisp1 = dev_get_drvdata(dev);
-       int ret;
-
-       ret = pinctrl_pm_select_default_state(dev);
-       if (ret)
-               return ret;
-       ret = clk_bulk_prepare_enable(rkisp1->clk_size, rkisp1->clks);
-       if (ret)
-               return ret;
-
-       return 0;
-}
-
-static const struct dev_pm_ops rkisp1_pm_ops = {
-       SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend,
-                               pm_runtime_force_resume)
-       SET_RUNTIME_PM_OPS(rkisp1_runtime_suspend, rkisp1_runtime_resume, NULL)
-};
-
-/* ----------------------------------------------------------------------------
- * Core
- */
-
-static int rkisp1_entities_register(struct rkisp1_device *rkisp1)
-{
-       int ret;
-
-       ret = rkisp1_isp_register(rkisp1);
-       if (ret)
-               return ret;
-
-       ret = rkisp1_resizer_devs_register(rkisp1);
-       if (ret)
-               goto err_unreg_isp_subdev;
-
-       ret = rkisp1_capture_devs_register(rkisp1);
-       if (ret)
-               goto err_unreg_resizer_devs;
-
-       ret = rkisp1_stats_register(rkisp1);
-       if (ret)
-               goto err_unreg_capture_devs;
-
-       ret = rkisp1_params_register(rkisp1);
-       if (ret)
-               goto err_unreg_stats;
-
-       ret = rkisp1_subdev_notifier(rkisp1);
-       if (ret) {
-               dev_err(rkisp1->dev,
-                       "Failed to register subdev notifier(%d)\n", ret);
-               goto err_unreg_params;
-       }
-
-       return 0;
-err_unreg_params:
-       rkisp1_params_unregister(rkisp1);
-err_unreg_stats:
-       rkisp1_stats_unregister(rkisp1);
-err_unreg_capture_devs:
-       rkisp1_capture_devs_unregister(rkisp1);
-err_unreg_resizer_devs:
-       rkisp1_resizer_devs_unregister(rkisp1);
-err_unreg_isp_subdev:
-       rkisp1_isp_unregister(rkisp1);
-       return ret;
-}
-
-static irqreturn_t rkisp1_isr(int irq, void *ctx)
-{
-       struct device *dev = ctx;
-       struct rkisp1_device *rkisp1 = dev_get_drvdata(dev);
-
-       /*
-        * Call rkisp1_capture_isr() first to handle the frame that
-        * potentially completed using the current frame_sequence number before
-        * it is potentially incremented by rkisp1_isp_isr() in the vertical
-        * sync.
-        */
-       rkisp1_capture_isr(rkisp1);
-       rkisp1_isp_isr(rkisp1);
-       rkisp1_mipi_isr(rkisp1);
-
-       return IRQ_HANDLED;
-}
-
-static const char * const rk3399_isp_clks[] = {
-       "clk_isp",
-       "aclk_isp",
-       "hclk_isp",
-       "aclk_isp_wrap",
-       "hclk_isp_wrap",
-};
-
-static const struct rkisp1_match_data rk3399_isp_clk_data = {
-       .clks = rk3399_isp_clks,
-       .size = ARRAY_SIZE(rk3399_isp_clks),
-};
-
-static const struct of_device_id rkisp1_of_match[] = {
-       {
-               .compatible = "rockchip,rk3399-cif-isp",
-               .data = &rk3399_isp_clk_data,
-       },
-       {},
-};
-MODULE_DEVICE_TABLE(of, rkisp1_of_match);
-
-static void rkisp1_debug_init(struct rkisp1_device *rkisp1)
-{
-       struct rkisp1_debug *debug = &rkisp1->debug;
-
-       debug->debugfs_dir = debugfs_create_dir(RKISP1_DRIVER_NAME, NULL);
-       if (!debug->debugfs_dir) {
-               dev_dbg(rkisp1->dev, "failed to create debugfs directory\n");
-               return;
-       }
-       debugfs_create_ulong("data_loss", 0444, debug->debugfs_dir,
-                            &debug->data_loss);
-       debugfs_create_ulong("outform_size_err", 0444,  debug->debugfs_dir,
-                            &debug->outform_size_error);
-       debugfs_create_ulong("img_stabilization_size_error", 0444,
-                            debug->debugfs_dir,
-                            &debug->img_stabilization_size_error);
-       debugfs_create_ulong("inform_size_error", 0444,  debug->debugfs_dir,
-                            &debug->inform_size_error);
-       debugfs_create_ulong("irq_delay", 0444,  debug->debugfs_dir,
-                            &debug->irq_delay);
-       debugfs_create_ulong("mipi_error", 0444, debug->debugfs_dir,
-                            &debug->mipi_error);
-       debugfs_create_ulong("stats_error", 0444, debug->debugfs_dir,
-                            &debug->stats_error);
-       debugfs_create_ulong("mp_stop_timeout", 0444, debug->debugfs_dir,
-                            &debug->stop_timeout[RKISP1_MAINPATH]);
-       debugfs_create_ulong("sp_stop_timeout", 0444, debug->debugfs_dir,
-                            &debug->stop_timeout[RKISP1_SELFPATH]);
-       debugfs_create_ulong("mp_frame_drop", 0444, debug->debugfs_dir,
-                            &debug->frame_drop[RKISP1_MAINPATH]);
-       debugfs_create_ulong("sp_frame_drop", 0444, debug->debugfs_dir,
-                            &debug->frame_drop[RKISP1_SELFPATH]);
-}
-
-static int rkisp1_probe(struct platform_device *pdev)
-{
-       const struct rkisp1_match_data *clk_data;
-       struct device *dev = &pdev->dev;
-       struct rkisp1_device *rkisp1;
-       struct v4l2_device *v4l2_dev;
-       unsigned int i;
-       int ret, irq;
-
-       clk_data = of_device_get_match_data(&pdev->dev);
-       if (!clk_data)
-               return -ENODEV;
-
-       rkisp1 = devm_kzalloc(dev, sizeof(*rkisp1), GFP_KERNEL);
-       if (!rkisp1)
-               return -ENOMEM;
-
-       dev_set_drvdata(dev, rkisp1);
-       rkisp1->dev = dev;
-
-       mutex_init(&rkisp1->stream_lock);
-
-       rkisp1->base_addr = devm_platform_ioremap_resource(pdev, 0);
-       if (IS_ERR(rkisp1->base_addr))
-               return PTR_ERR(rkisp1->base_addr);
-
-       irq = platform_get_irq(pdev, 0);
-       if (irq < 0)
-               return irq;
-
-       ret = devm_request_irq(dev, irq, rkisp1_isr, IRQF_SHARED,
-                              dev_driver_string(dev), dev);
-       if (ret) {
-               dev_err(dev, "request irq failed: %d\n", ret);
-               return ret;
-       }
-
-       rkisp1->irq = irq;
-
-       for (i = 0; i < clk_data->size; i++)
-               rkisp1->clks[i].id = clk_data->clks[i];
-       ret = devm_clk_bulk_get(dev, clk_data->size, rkisp1->clks);
-       if (ret)
-               return ret;
-       rkisp1->clk_size = clk_data->size;
-
-       pm_runtime_enable(&pdev->dev);
-
-       strscpy(rkisp1->media_dev.model, RKISP1_DRIVER_NAME,
-               sizeof(rkisp1->media_dev.model));
-       rkisp1->media_dev.dev = &pdev->dev;
-       strscpy(rkisp1->media_dev.bus_info, RKISP1_BUS_INFO,
-               sizeof(rkisp1->media_dev.bus_info));
-       media_device_init(&rkisp1->media_dev);
-
-       v4l2_dev = &rkisp1->v4l2_dev;
-       v4l2_dev->mdev = &rkisp1->media_dev;
-       strscpy(v4l2_dev->name, RKISP1_DRIVER_NAME, sizeof(v4l2_dev->name));
-
-       ret = v4l2_device_register(rkisp1->dev, &rkisp1->v4l2_dev);
-       if (ret)
-               return ret;
-
-       ret = media_device_register(&rkisp1->media_dev);
-       if (ret) {
-               dev_err(dev, "Failed to register media device: %d\n", ret);
-               goto err_unreg_v4l2_dev;
-       }
-
-       ret = rkisp1_entities_register(rkisp1);
-       if (ret)
-               goto err_unreg_media_dev;
-
-       rkisp1_debug_init(rkisp1);
-
-       return 0;
-
-err_unreg_media_dev:
-       media_device_unregister(&rkisp1->media_dev);
-err_unreg_v4l2_dev:
-       v4l2_device_unregister(&rkisp1->v4l2_dev);
-       pm_runtime_disable(&pdev->dev);
-       return ret;
-}
-
-static int rkisp1_remove(struct platform_device *pdev)
-{
-       struct rkisp1_device *rkisp1 = platform_get_drvdata(pdev);
-
-       v4l2_async_notifier_unregister(&rkisp1->notifier);
-       v4l2_async_notifier_cleanup(&rkisp1->notifier);
-
-       rkisp1_params_unregister(rkisp1);
-       rkisp1_stats_unregister(rkisp1);
-       rkisp1_capture_devs_unregister(rkisp1);
-       rkisp1_resizer_devs_unregister(rkisp1);
-       rkisp1_isp_unregister(rkisp1);
-
-       media_device_unregister(&rkisp1->media_dev);
-       v4l2_device_unregister(&rkisp1->v4l2_dev);
-
-       pm_runtime_disable(&pdev->dev);
-
-       debugfs_remove_recursive(rkisp1->debug.debugfs_dir);
-       return 0;
-}
-
-static struct platform_driver rkisp1_drv = {
-       .driver = {
-               .name = RKISP1_DRIVER_NAME,
-               .of_match_table = of_match_ptr(rkisp1_of_match),
-               .pm = &rkisp1_pm_ops,
-       },
-       .probe = rkisp1_probe,
-       .remove = rkisp1_remove,
-};
-
-module_platform_driver(rkisp1_drv);
-MODULE_DESCRIPTION("Rockchip ISP1 platform driver");
-MODULE_LICENSE("Dual MIT/GPL");
diff --git a/drivers/staging/media/rkisp1/rkisp1-isp.c b/drivers/staging/media/rkisp1/rkisp1-isp.c
deleted file mode 100644 (file)
index a9715b0..0000000
+++ /dev/null
@@ -1,1161 +0,0 @@
-// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
-/*
- * Rockchip ISP1 Driver - ISP Subdevice
- *
- * Copyright (C) 2019 Collabora, Ltd.
- *
- * Based on Rockchip ISP1 driver by Rockchip Electronics Co., Ltd.
- * Copyright (C) 2017 Rockchip Electronics Co., Ltd.
- */
-
-#include <linux/iopoll.h>
-#include <linux/phy/phy.h>
-#include <linux/phy/phy-mipi-dphy.h>
-#include <linux/pm_runtime.h>
-#include <linux/videodev2.h>
-#include <linux/vmalloc.h>
-#include <media/v4l2-event.h>
-
-#include "rkisp1-common.h"
-
-#define RKISP1_DEF_SINK_PAD_FMT MEDIA_BUS_FMT_SRGGB10_1X10
-#define RKISP1_DEF_SRC_PAD_FMT MEDIA_BUS_FMT_YUYV8_2X8
-
-#define RKISP1_ISP_DEV_NAME    RKISP1_DRIVER_NAME "_isp"
-
-/*
- * NOTE: MIPI controller and input MUX are also configured in this file.
- * This is because ISP Subdev describes not only ISP submodule (input size,
- * format, output size, format), but also a virtual route device.
- */
-
-/*
- * There are many variables named with format/frame in below code,
- * please see here for their meaning.
- * Cropping in the sink pad defines the image region from the sensor.
- * Cropping in the source pad defines the region for the Image Stabilizer (IS)
- *
- * Cropping regions of ISP
- *
- * +---------------------------------------------------------+
- * | Sensor image                                            |
- * | +---------------------------------------------------+   |
- * | | CIF_ISP_ACQ (for black level)                     |   |
- * | | sink pad format                                   |   |
- * | | +--------------------------------------------+    |   |
- * | | |    CIF_ISP_OUT                             |    |   |
- * | | |    sink pad crop                           |    |   |
- * | | |    +---------------------------------+     |    |   |
- * | | |    |   CIF_ISP_IS                    |     |    |   |
- * | | |    |   source pad crop and format    |     |    |   |
- * | | |    +---------------------------------+     |    |   |
- * | | +--------------------------------------------+    |   |
- * | +---------------------------------------------------+   |
- * +---------------------------------------------------------+
- */
-
-static const struct rkisp1_isp_mbus_info rkisp1_isp_formats[] = {
-       {
-               .mbus_code      = MEDIA_BUS_FMT_YUYV8_2X8,
-               .pixel_enc      = V4L2_PIXEL_ENC_YUV,
-               .direction      = RKISP1_ISP_SD_SRC,
-       }, {
-               .mbus_code      = MEDIA_BUS_FMT_SRGGB10_1X10,
-               .pixel_enc      = V4L2_PIXEL_ENC_BAYER,
-               .mipi_dt        = RKISP1_CIF_CSI2_DT_RAW10,
-               .bayer_pat      = RKISP1_RAW_RGGB,
-               .bus_width      = 10,
-               .direction      = RKISP1_ISP_SD_SINK | RKISP1_ISP_SD_SRC,
-       }, {
-               .mbus_code      = MEDIA_BUS_FMT_SBGGR10_1X10,
-               .pixel_enc      = V4L2_PIXEL_ENC_BAYER,
-               .mipi_dt        = RKISP1_CIF_CSI2_DT_RAW10,
-               .bayer_pat      = RKISP1_RAW_BGGR,
-               .bus_width      = 10,
-               .direction      = RKISP1_ISP_SD_SINK | RKISP1_ISP_SD_SRC,
-       }, {
-               .mbus_code      = MEDIA_BUS_FMT_SGBRG10_1X10,
-               .pixel_enc      = V4L2_PIXEL_ENC_BAYER,
-               .mipi_dt        = RKISP1_CIF_CSI2_DT_RAW10,
-               .bayer_pat      = RKISP1_RAW_GBRG,
-               .bus_width      = 10,
-               .direction      = RKISP1_ISP_SD_SINK | RKISP1_ISP_SD_SRC,
-       }, {
-               .mbus_code      = MEDIA_BUS_FMT_SGRBG10_1X10,
-               .pixel_enc      = V4L2_PIXEL_ENC_BAYER,
-               .mipi_dt        = RKISP1_CIF_CSI2_DT_RAW10,
-               .bayer_pat      = RKISP1_RAW_GRBG,
-               .bus_width      = 10,
-               .direction      = RKISP1_ISP_SD_SINK | RKISP1_ISP_SD_SRC,
-       }, {
-               .mbus_code      = MEDIA_BUS_FMT_SRGGB12_1X12,
-               .pixel_enc      = V4L2_PIXEL_ENC_BAYER,
-               .mipi_dt        = RKISP1_CIF_CSI2_DT_RAW12,
-               .bayer_pat      = RKISP1_RAW_RGGB,
-               .bus_width      = 12,
-               .direction      = RKISP1_ISP_SD_SINK | RKISP1_ISP_SD_SRC,
-       }, {
-               .mbus_code      = MEDIA_BUS_FMT_SBGGR12_1X12,
-               .pixel_enc      = V4L2_PIXEL_ENC_BAYER,
-               .mipi_dt        = RKISP1_CIF_CSI2_DT_RAW12,
-               .bayer_pat      = RKISP1_RAW_BGGR,
-               .bus_width      = 12,
-               .direction      = RKISP1_ISP_SD_SINK | RKISP1_ISP_SD_SRC,
-       }, {
-               .mbus_code      = MEDIA_BUS_FMT_SGBRG12_1X12,
-               .pixel_enc      = V4L2_PIXEL_ENC_BAYER,
-               .mipi_dt        = RKISP1_CIF_CSI2_DT_RAW12,
-               .bayer_pat      = RKISP1_RAW_GBRG,
-               .bus_width      = 12,
-               .direction      = RKISP1_ISP_SD_SINK | RKISP1_ISP_SD_SRC,
-       }, {
-               .mbus_code      = MEDIA_BUS_FMT_SGRBG12_1X12,
-               .pixel_enc      = V4L2_PIXEL_ENC_BAYER,
-               .mipi_dt        = RKISP1_CIF_CSI2_DT_RAW12,
-               .bayer_pat      = RKISP1_RAW_GRBG,
-               .bus_width      = 12,
-               .direction      = RKISP1_ISP_SD_SINK | RKISP1_ISP_SD_SRC,
-       }, {
-               .mbus_code      = MEDIA_BUS_FMT_SRGGB8_1X8,
-               .pixel_enc      = V4L2_PIXEL_ENC_BAYER,
-               .mipi_dt        = RKISP1_CIF_CSI2_DT_RAW8,
-               .bayer_pat      = RKISP1_RAW_RGGB,
-               .bus_width      = 8,
-               .direction      = RKISP1_ISP_SD_SINK | RKISP1_ISP_SD_SRC,
-       }, {
-               .mbus_code      = MEDIA_BUS_FMT_SBGGR8_1X8,
-               .pixel_enc      = V4L2_PIXEL_ENC_BAYER,
-               .mipi_dt        = RKISP1_CIF_CSI2_DT_RAW8,
-               .bayer_pat      = RKISP1_RAW_BGGR,
-               .bus_width      = 8,
-               .direction      = RKISP1_ISP_SD_SINK | RKISP1_ISP_SD_SRC,
-       }, {
-               .mbus_code      = MEDIA_BUS_FMT_SGBRG8_1X8,
-               .pixel_enc      = V4L2_PIXEL_ENC_BAYER,
-               .mipi_dt        = RKISP1_CIF_CSI2_DT_RAW8,
-               .bayer_pat      = RKISP1_RAW_GBRG,
-               .bus_width      = 8,
-               .direction      = RKISP1_ISP_SD_SINK | RKISP1_ISP_SD_SRC,
-       }, {
-               .mbus_code      = MEDIA_BUS_FMT_SGRBG8_1X8,
-               .pixel_enc      = V4L2_PIXEL_ENC_BAYER,
-               .mipi_dt        = RKISP1_CIF_CSI2_DT_RAW8,
-               .bayer_pat      = RKISP1_RAW_GRBG,
-               .bus_width      = 8,
-               .direction      = RKISP1_ISP_SD_SINK | RKISP1_ISP_SD_SRC,
-       }, {
-               .mbus_code      = MEDIA_BUS_FMT_YUYV8_1X16,
-               .pixel_enc      = V4L2_PIXEL_ENC_YUV,
-               .mipi_dt        = RKISP1_CIF_CSI2_DT_YUV422_8b,
-               .yuv_seq        = RKISP1_CIF_ISP_ACQ_PROP_YCBYCR,
-               .bus_width      = 16,
-               .direction      = RKISP1_ISP_SD_SINK,
-       }, {
-               .mbus_code      = MEDIA_BUS_FMT_YVYU8_1X16,
-               .pixel_enc      = V4L2_PIXEL_ENC_YUV,
-               .mipi_dt        = RKISP1_CIF_CSI2_DT_YUV422_8b,
-               .yuv_seq        = RKISP1_CIF_ISP_ACQ_PROP_YCRYCB,
-               .bus_width      = 16,
-               .direction      = RKISP1_ISP_SD_SINK,
-       }, {
-               .mbus_code      = MEDIA_BUS_FMT_UYVY8_1X16,
-               .pixel_enc      = V4L2_PIXEL_ENC_YUV,
-               .mipi_dt        = RKISP1_CIF_CSI2_DT_YUV422_8b,
-               .yuv_seq        = RKISP1_CIF_ISP_ACQ_PROP_CBYCRY,
-               .bus_width      = 16,
-               .direction      = RKISP1_ISP_SD_SINK,
-       }, {
-               .mbus_code      = MEDIA_BUS_FMT_VYUY8_1X16,
-               .pixel_enc      = V4L2_PIXEL_ENC_YUV,
-               .mipi_dt        = RKISP1_CIF_CSI2_DT_YUV422_8b,
-               .yuv_seq        = RKISP1_CIF_ISP_ACQ_PROP_CRYCBY,
-               .bus_width      = 16,
-               .direction      = RKISP1_ISP_SD_SINK,
-       },
-};
-
-/* ----------------------------------------------------------------------------
- * Helpers
- */
-
-const struct rkisp1_isp_mbus_info *rkisp1_isp_mbus_info_get(u32 mbus_code)
-{
-       unsigned int i;
-
-       for (i = 0; i < ARRAY_SIZE(rkisp1_isp_formats); i++) {
-               const struct rkisp1_isp_mbus_info *fmt = &rkisp1_isp_formats[i];
-
-               if (fmt->mbus_code == mbus_code)
-                       return fmt;
-       }
-
-       return NULL;
-}
-
-static struct v4l2_subdev *rkisp1_get_remote_sensor(struct v4l2_subdev *sd)
-{
-       struct media_pad *local, *remote;
-       struct media_entity *sensor_me;
-
-       local = &sd->entity.pads[RKISP1_ISP_PAD_SINK_VIDEO];
-       remote = media_entity_remote_pad(local);
-       if (!remote)
-               return NULL;
-
-       sensor_me = remote->entity;
-       return media_entity_to_v4l2_subdev(sensor_me);
-}
-
-static struct v4l2_mbus_framefmt *
-rkisp1_isp_get_pad_fmt(struct rkisp1_isp *isp,
-                      struct v4l2_subdev_pad_config *cfg,
-                      unsigned int pad, u32 which)
-{
-       if (which == V4L2_SUBDEV_FORMAT_TRY)
-               return v4l2_subdev_get_try_format(&isp->sd, cfg, pad);
-       else
-               return v4l2_subdev_get_try_format(&isp->sd, isp->pad_cfg, pad);
-}
-
-static struct v4l2_rect *
-rkisp1_isp_get_pad_crop(struct rkisp1_isp *isp,
-                       struct v4l2_subdev_pad_config *cfg,
-                       unsigned int pad, u32 which)
-{
-       if (which == V4L2_SUBDEV_FORMAT_TRY)
-               return v4l2_subdev_get_try_crop(&isp->sd, cfg, pad);
-       else
-               return v4l2_subdev_get_try_crop(&isp->sd, isp->pad_cfg, pad);
-}
-
-/* ----------------------------------------------------------------------------
- * Camera Interface registers configurations
- */
-
-/*
- * Image Stabilization.
- * This should only be called when configuring CIF
- * or at the frame end interrupt
- */
-static void rkisp1_config_ism(struct rkisp1_device *rkisp1)
-{
-       struct v4l2_rect *src_crop =
-               rkisp1_isp_get_pad_crop(&rkisp1->isp, NULL,
-                                       RKISP1_ISP_PAD_SOURCE_VIDEO,
-                                       V4L2_SUBDEV_FORMAT_ACTIVE);
-       u32 val;
-
-       rkisp1_write(rkisp1, 0, RKISP1_CIF_ISP_IS_RECENTER);
-       rkisp1_write(rkisp1, 0, RKISP1_CIF_ISP_IS_MAX_DX);
-       rkisp1_write(rkisp1, 0, RKISP1_CIF_ISP_IS_MAX_DY);
-       rkisp1_write(rkisp1, 0, RKISP1_CIF_ISP_IS_DISPLACE);
-       rkisp1_write(rkisp1, src_crop->left, RKISP1_CIF_ISP_IS_H_OFFS);
-       rkisp1_write(rkisp1, src_crop->top, RKISP1_CIF_ISP_IS_V_OFFS);
-       rkisp1_write(rkisp1, src_crop->width, RKISP1_CIF_ISP_IS_H_SIZE);
-       rkisp1_write(rkisp1, src_crop->height, RKISP1_CIF_ISP_IS_V_SIZE);
-
-       /* IS(Image Stabilization) is always on, working as output crop */
-       rkisp1_write(rkisp1, 1, RKISP1_CIF_ISP_IS_CTRL);
-       val = rkisp1_read(rkisp1, RKISP1_CIF_ISP_CTRL);
-       val |= RKISP1_CIF_ISP_CTRL_ISP_CFG_UPD;
-       rkisp1_write(rkisp1, val, RKISP1_CIF_ISP_CTRL);
-}
-
-/*
- * configure ISP blocks with input format, size......
- */
-static int rkisp1_config_isp(struct rkisp1_device *rkisp1)
-{
-       u32 isp_ctrl = 0, irq_mask = 0, acq_mult = 0, signal = 0;
-       const struct rkisp1_isp_mbus_info *src_fmt, *sink_fmt;
-       struct rkisp1_sensor_async *sensor;
-       struct v4l2_mbus_framefmt *sink_frm;
-       struct v4l2_rect *sink_crop;
-
-       sensor = rkisp1->active_sensor;
-       sink_fmt = rkisp1->isp.sink_fmt;
-       src_fmt = rkisp1->isp.src_fmt;
-       sink_frm = rkisp1_isp_get_pad_fmt(&rkisp1->isp, NULL,
-                                         RKISP1_ISP_PAD_SINK_VIDEO,
-                                         V4L2_SUBDEV_FORMAT_ACTIVE);
-       sink_crop = rkisp1_isp_get_pad_crop(&rkisp1->isp, NULL,
-                                           RKISP1_ISP_PAD_SINK_VIDEO,
-                                           V4L2_SUBDEV_FORMAT_ACTIVE);
-
-       if (sink_fmt->pixel_enc == V4L2_PIXEL_ENC_BAYER) {
-               acq_mult = 1;
-               if (src_fmt->pixel_enc == V4L2_PIXEL_ENC_BAYER) {
-                       if (sensor->mbus_type == V4L2_MBUS_BT656)
-                               isp_ctrl = RKISP1_CIF_ISP_CTRL_ISP_MODE_RAW_PICT_ITU656;
-                       else
-                               isp_ctrl = RKISP1_CIF_ISP_CTRL_ISP_MODE_RAW_PICT;
-               } else {
-                       rkisp1_write(rkisp1, RKISP1_CIF_ISP_DEMOSAIC_TH(0xc),
-                                    RKISP1_CIF_ISP_DEMOSAIC);
-
-                       if (sensor->mbus_type == V4L2_MBUS_BT656)
-                               isp_ctrl = RKISP1_CIF_ISP_CTRL_ISP_MODE_BAYER_ITU656;
-                       else
-                               isp_ctrl = RKISP1_CIF_ISP_CTRL_ISP_MODE_BAYER_ITU601;
-               }
-       } else if (sink_fmt->pixel_enc == V4L2_PIXEL_ENC_YUV) {
-               acq_mult = 2;
-               if (sensor->mbus_type == V4L2_MBUS_CSI2_DPHY) {
-                       isp_ctrl = RKISP1_CIF_ISP_CTRL_ISP_MODE_ITU601;
-               } else {
-                       if (sensor->mbus_type == V4L2_MBUS_BT656)
-                               isp_ctrl = RKISP1_CIF_ISP_CTRL_ISP_MODE_ITU656;
-                       else
-                               isp_ctrl = RKISP1_CIF_ISP_CTRL_ISP_MODE_ITU601;
-               }
-
-               irq_mask |= RKISP1_CIF_ISP_DATA_LOSS;
-       }
-
-       /* Set up input acquisition properties */
-       if (sensor->mbus_type == V4L2_MBUS_BT656 ||
-           sensor->mbus_type == V4L2_MBUS_PARALLEL) {
-               if (sensor->mbus_flags & V4L2_MBUS_PCLK_SAMPLE_RISING)
-                       signal = RKISP1_CIF_ISP_ACQ_PROP_POS_EDGE;
-       }
-
-       if (sensor->mbus_type == V4L2_MBUS_PARALLEL) {
-               if (sensor->mbus_flags & V4L2_MBUS_VSYNC_ACTIVE_LOW)
-                       signal |= RKISP1_CIF_ISP_ACQ_PROP_VSYNC_LOW;
-
-               if (sensor->mbus_flags & V4L2_MBUS_HSYNC_ACTIVE_LOW)
-                       signal |= RKISP1_CIF_ISP_ACQ_PROP_HSYNC_LOW;
-       }
-
-       rkisp1_write(rkisp1, isp_ctrl, RKISP1_CIF_ISP_CTRL);
-       rkisp1_write(rkisp1, signal | sink_fmt->yuv_seq |
-                    RKISP1_CIF_ISP_ACQ_PROP_BAYER_PAT(sink_fmt->bayer_pat) |
-                    RKISP1_CIF_ISP_ACQ_PROP_FIELD_SEL_ALL,
-                    RKISP1_CIF_ISP_ACQ_PROP);
-       rkisp1_write(rkisp1, 0, RKISP1_CIF_ISP_ACQ_NR_FRAMES);
-
-       /* Acquisition Size */
-       rkisp1_write(rkisp1, 0, RKISP1_CIF_ISP_ACQ_H_OFFS);
-       rkisp1_write(rkisp1, 0, RKISP1_CIF_ISP_ACQ_V_OFFS);
-       rkisp1_write(rkisp1,
-                    acq_mult * sink_frm->width, RKISP1_CIF_ISP_ACQ_H_SIZE);
-       rkisp1_write(rkisp1, sink_frm->height, RKISP1_CIF_ISP_ACQ_V_SIZE);
-
-       /* ISP Out Area */
-       rkisp1_write(rkisp1, sink_crop->left, RKISP1_CIF_ISP_OUT_H_OFFS);
-       rkisp1_write(rkisp1, sink_crop->top, RKISP1_CIF_ISP_OUT_V_OFFS);
-       rkisp1_write(rkisp1, sink_crop->width, RKISP1_CIF_ISP_OUT_H_SIZE);
-       rkisp1_write(rkisp1, sink_crop->height, RKISP1_CIF_ISP_OUT_V_SIZE);
-
-       irq_mask |= RKISP1_CIF_ISP_FRAME | RKISP1_CIF_ISP_V_START |
-                   RKISP1_CIF_ISP_PIC_SIZE_ERROR;
-       rkisp1_write(rkisp1, irq_mask, RKISP1_CIF_ISP_IMSC);
-
-       if (src_fmt->pixel_enc == V4L2_PIXEL_ENC_BAYER) {
-               rkisp1_params_disable(&rkisp1->params);
-       } else {
-               struct v4l2_mbus_framefmt *src_frm;
-
-               src_frm = rkisp1_isp_get_pad_fmt(&rkisp1->isp, NULL,
-                                                RKISP1_ISP_PAD_SINK_VIDEO,
-                                                V4L2_SUBDEV_FORMAT_ACTIVE);
-               rkisp1_params_configure(&rkisp1->params, sink_fmt->bayer_pat,
-                                       src_frm->quantization);
-       }
-
-       return 0;
-}
-
-static int rkisp1_config_dvp(struct rkisp1_device *rkisp1)
-{
-       const struct rkisp1_isp_mbus_info *sink_fmt = rkisp1->isp.sink_fmt;
-       u32 val, input_sel;
-
-       switch (sink_fmt->bus_width) {
-       case 8:
-               input_sel = RKISP1_CIF_ISP_ACQ_PROP_IN_SEL_8B_ZERO;
-               break;
-       case 10:
-               input_sel = RKISP1_CIF_ISP_ACQ_PROP_IN_SEL_10B_ZERO;
-               break;
-       case 12:
-               input_sel = RKISP1_CIF_ISP_ACQ_PROP_IN_SEL_12B;
-               break;
-       default:
-               dev_err(rkisp1->dev, "Invalid bus width\n");
-               return -EINVAL;
-       }
-
-       val = rkisp1_read(rkisp1, RKISP1_CIF_ISP_ACQ_PROP);
-       rkisp1_write(rkisp1, val | input_sel, RKISP1_CIF_ISP_ACQ_PROP);
-
-       return 0;
-}
-
-static int rkisp1_config_mipi(struct rkisp1_device *rkisp1)
-{
-       const struct rkisp1_isp_mbus_info *sink_fmt = rkisp1->isp.sink_fmt;
-       unsigned int lanes = rkisp1->active_sensor->lanes;
-       u32 mipi_ctrl;
-
-       if (lanes < 1 || lanes > 4)
-               return -EINVAL;
-
-       mipi_ctrl = RKISP1_CIF_MIPI_CTRL_NUM_LANES(lanes - 1) |
-                   RKISP1_CIF_MIPI_CTRL_SHUTDOWNLANES(0xf) |
-                   RKISP1_CIF_MIPI_CTRL_ERR_SOT_SYNC_HS_SKIP |
-                   RKISP1_CIF_MIPI_CTRL_CLOCKLANE_ENA;
-
-       rkisp1_write(rkisp1, mipi_ctrl, RKISP1_CIF_MIPI_CTRL);
-
-       /* Configure Data Type and Virtual Channel */
-       rkisp1_write(rkisp1,
-                    RKISP1_CIF_MIPI_DATA_SEL_DT(sink_fmt->mipi_dt) |
-                    RKISP1_CIF_MIPI_DATA_SEL_VC(0),
-                    RKISP1_CIF_MIPI_IMG_DATA_SEL);
-
-       /* Clear MIPI interrupts */
-       rkisp1_write(rkisp1, ~0, RKISP1_CIF_MIPI_ICR);
-       /*
-        * Disable RKISP1_CIF_MIPI_ERR_DPHY interrupt here temporary for
-        * isp bus may be dead when switch isp.
-        */
-       rkisp1_write(rkisp1,
-                    RKISP1_CIF_MIPI_FRAME_END | RKISP1_CIF_MIPI_ERR_CSI |
-                    RKISP1_CIF_MIPI_ERR_DPHY |
-                    RKISP1_CIF_MIPI_SYNC_FIFO_OVFLW(0x03) |
-                    RKISP1_CIF_MIPI_ADD_DATA_OVFLW,
-                    RKISP1_CIF_MIPI_IMSC);
-
-       dev_dbg(rkisp1->dev, "\n  MIPI_CTRL 0x%08x\n"
-               "  MIPI_IMG_DATA_SEL 0x%08x\n"
-               "  MIPI_STATUS 0x%08x\n"
-               "  MIPI_IMSC 0x%08x\n",
-               rkisp1_read(rkisp1, RKISP1_CIF_MIPI_CTRL),
-               rkisp1_read(rkisp1, RKISP1_CIF_MIPI_IMG_DATA_SEL),
-               rkisp1_read(rkisp1, RKISP1_CIF_MIPI_STATUS),
-               rkisp1_read(rkisp1, RKISP1_CIF_MIPI_IMSC));
-
-       return 0;
-}
-
-/* Configure MUX */
-static int rkisp1_config_path(struct rkisp1_device *rkisp1)
-{
-       struct rkisp1_sensor_async *sensor = rkisp1->active_sensor;
-       u32 dpcl = rkisp1_read(rkisp1, RKISP1_CIF_VI_DPCL);
-       int ret = 0;
-
-       if (sensor->mbus_type == V4L2_MBUS_BT656 ||
-           sensor->mbus_type == V4L2_MBUS_PARALLEL) {
-               ret = rkisp1_config_dvp(rkisp1);
-               dpcl |= RKISP1_CIF_VI_DPCL_IF_SEL_PARALLEL;
-       } else if (sensor->mbus_type == V4L2_MBUS_CSI2_DPHY) {
-               ret = rkisp1_config_mipi(rkisp1);
-               dpcl |= RKISP1_CIF_VI_DPCL_IF_SEL_MIPI;
-       }
-
-       rkisp1_write(rkisp1, dpcl, RKISP1_CIF_VI_DPCL);
-
-       return ret;
-}
-
-/* Hardware configure Entry */
-static int rkisp1_config_cif(struct rkisp1_device *rkisp1)
-{
-       u32 cif_id;
-       int ret;
-
-       cif_id = rkisp1_read(rkisp1, RKISP1_CIF_VI_ID);
-       dev_dbg(rkisp1->dev, "CIF_ID 0x%08x\n", cif_id);
-
-       ret = rkisp1_config_isp(rkisp1);
-       if (ret)
-               return ret;
-       ret = rkisp1_config_path(rkisp1);
-       if (ret)
-               return ret;
-       rkisp1_config_ism(rkisp1);
-
-       return 0;
-}
-
-static void rkisp1_isp_stop(struct rkisp1_device *rkisp1)
-{
-       u32 val;
-
-       /*
-        * ISP(mi) stop in mi frame end -> Stop ISP(mipi) ->
-        * Stop ISP(isp) ->wait for ISP isp off
-        */
-       /* stop and clear MI, MIPI, and ISP interrupts */
-       rkisp1_write(rkisp1, 0, RKISP1_CIF_MIPI_IMSC);
-       rkisp1_write(rkisp1, ~0, RKISP1_CIF_MIPI_ICR);
-
-       rkisp1_write(rkisp1, 0, RKISP1_CIF_ISP_IMSC);
-       rkisp1_write(rkisp1, ~0, RKISP1_CIF_ISP_ICR);
-
-       rkisp1_write(rkisp1, 0, RKISP1_CIF_MI_IMSC);
-       rkisp1_write(rkisp1, ~0, RKISP1_CIF_MI_ICR);
-       val = rkisp1_read(rkisp1, RKISP1_CIF_MIPI_CTRL);
-       rkisp1_write(rkisp1, val & (~RKISP1_CIF_MIPI_CTRL_OUTPUT_ENA),
-                    RKISP1_CIF_MIPI_CTRL);
-       /* stop ISP */
-       val = rkisp1_read(rkisp1, RKISP1_CIF_ISP_CTRL);
-       val &= ~(RKISP1_CIF_ISP_CTRL_ISP_INFORM_ENABLE |
-                RKISP1_CIF_ISP_CTRL_ISP_ENABLE);
-       rkisp1_write(rkisp1, val, RKISP1_CIF_ISP_CTRL);
-
-       val = rkisp1_read(rkisp1,       RKISP1_CIF_ISP_CTRL);
-       rkisp1_write(rkisp1, val | RKISP1_CIF_ISP_CTRL_ISP_CFG_UPD,
-                    RKISP1_CIF_ISP_CTRL);
-
-       readx_poll_timeout(readl, rkisp1->base_addr + RKISP1_CIF_ISP_RIS,
-                          val, val & RKISP1_CIF_ISP_OFF, 20, 100);
-       rkisp1_write(rkisp1,
-                    RKISP1_CIF_IRCL_MIPI_SW_RST | RKISP1_CIF_IRCL_ISP_SW_RST,
-                    RKISP1_CIF_IRCL);
-       rkisp1_write(rkisp1, 0x0, RKISP1_CIF_IRCL);
-}
-
-static void rkisp1_config_clk(struct rkisp1_device *rkisp1)
-{
-       u32 val = RKISP1_CIF_ICCL_ISP_CLK | RKISP1_CIF_ICCL_CP_CLK |
-                 RKISP1_CIF_ICCL_MRSZ_CLK | RKISP1_CIF_ICCL_SRSZ_CLK |
-                 RKISP1_CIF_ICCL_JPEG_CLK | RKISP1_CIF_ICCL_MI_CLK |
-                 RKISP1_CIF_ICCL_IE_CLK | RKISP1_CIF_ICCL_MIPI_CLK |
-                 RKISP1_CIF_ICCL_DCROP_CLK;
-
-       rkisp1_write(rkisp1, val, RKISP1_CIF_ICCL);
-}
-
-static void rkisp1_isp_start(struct rkisp1_device *rkisp1)
-{
-       struct rkisp1_sensor_async *sensor = rkisp1->active_sensor;
-       u32 val;
-
-       rkisp1_config_clk(rkisp1);
-
-       /* Activate MIPI */
-       if (sensor->mbus_type == V4L2_MBUS_CSI2_DPHY) {
-               val = rkisp1_read(rkisp1, RKISP1_CIF_MIPI_CTRL);
-               rkisp1_write(rkisp1, val | RKISP1_CIF_MIPI_CTRL_OUTPUT_ENA,
-                            RKISP1_CIF_MIPI_CTRL);
-       }
-       /* Activate ISP */
-       val = rkisp1_read(rkisp1, RKISP1_CIF_ISP_CTRL);
-       val |= RKISP1_CIF_ISP_CTRL_ISP_CFG_UPD |
-              RKISP1_CIF_ISP_CTRL_ISP_ENABLE |
-              RKISP1_CIF_ISP_CTRL_ISP_INFORM_ENABLE;
-       rkisp1_write(rkisp1, val, RKISP1_CIF_ISP_CTRL);
-
-       /*
-        * CIF spec says to wait for sufficient time after enabling
-        * the MIPI interface and before starting the sensor output.
-        */
-       usleep_range(1000, 1200);
-}
-
-/* ----------------------------------------------------------------------------
- * Subdev pad operations
- */
-
-static int rkisp1_isp_enum_mbus_code(struct v4l2_subdev *sd,
-                                    struct v4l2_subdev_pad_config *cfg,
-                                    struct v4l2_subdev_mbus_code_enum *code)
-{
-       unsigned int i, dir;
-       int pos = 0;
-
-       if (code->pad == RKISP1_ISP_PAD_SINK_VIDEO) {
-               dir = RKISP1_ISP_SD_SINK;
-       } else if (code->pad == RKISP1_ISP_PAD_SOURCE_VIDEO) {
-               dir = RKISP1_ISP_SD_SRC;
-       } else {
-               if (code->index > 0)
-                       return -EINVAL;
-               code->code = MEDIA_BUS_FMT_FIXED;
-               return 0;
-       }
-
-       if (code->index >= ARRAY_SIZE(rkisp1_isp_formats))
-               return -EINVAL;
-
-       for (i = 0; i < ARRAY_SIZE(rkisp1_isp_formats); i++) {
-               const struct rkisp1_isp_mbus_info *fmt = &rkisp1_isp_formats[i];
-
-               if (fmt->direction & dir)
-                       pos++;
-
-               if (code->index == pos - 1) {
-                       code->code = fmt->mbus_code;
-                       if (fmt->pixel_enc == V4L2_PIXEL_ENC_YUV &&
-                           dir == RKISP1_ISP_SD_SRC)
-                               code->flags =
-                                       V4L2_SUBDEV_MBUS_CODE_CSC_QUANTIZATION;
-                       return 0;
-               }
-       }
-
-       return -EINVAL;
-}
-
-static int rkisp1_isp_init_config(struct v4l2_subdev *sd,
-                                 struct v4l2_subdev_pad_config *cfg)
-{
-       struct v4l2_mbus_framefmt *sink_fmt, *src_fmt;
-       struct v4l2_rect *sink_crop, *src_crop;
-
-       sink_fmt = v4l2_subdev_get_try_format(sd, cfg,
-                                             RKISP1_ISP_PAD_SINK_VIDEO);
-       sink_fmt->width = RKISP1_DEFAULT_WIDTH;
-       sink_fmt->height = RKISP1_DEFAULT_HEIGHT;
-       sink_fmt->field = V4L2_FIELD_NONE;
-       sink_fmt->code = RKISP1_DEF_SINK_PAD_FMT;
-
-       sink_crop = v4l2_subdev_get_try_crop(sd, cfg,
-                                            RKISP1_ISP_PAD_SINK_VIDEO);
-       sink_crop->width = RKISP1_DEFAULT_WIDTH;
-       sink_crop->height = RKISP1_DEFAULT_HEIGHT;
-       sink_crop->left = 0;
-       sink_crop->top = 0;
-
-       src_fmt = v4l2_subdev_get_try_format(sd, cfg,
-                                            RKISP1_ISP_PAD_SOURCE_VIDEO);
-       *src_fmt = *sink_fmt;
-       src_fmt->code = RKISP1_DEF_SRC_PAD_FMT;
-
-       src_crop = v4l2_subdev_get_try_crop(sd, cfg,
-                                           RKISP1_ISP_PAD_SOURCE_VIDEO);
-       *src_crop = *sink_crop;
-
-       sink_fmt = v4l2_subdev_get_try_format(sd, cfg,
-                                             RKISP1_ISP_PAD_SINK_PARAMS);
-       src_fmt = v4l2_subdev_get_try_format(sd, cfg,
-                                            RKISP1_ISP_PAD_SOURCE_STATS);
-       sink_fmt->width = RKISP1_DEFAULT_WIDTH;
-       sink_fmt->height = RKISP1_DEFAULT_HEIGHT;
-       sink_fmt->field = V4L2_FIELD_NONE;
-       sink_fmt->code = MEDIA_BUS_FMT_FIXED;
-       *src_fmt = *sink_fmt;
-
-       return 0;
-}
-
-static void rkisp1_isp_set_src_fmt(struct rkisp1_isp *isp,
-                                  struct v4l2_subdev_pad_config *cfg,
-                                  struct v4l2_mbus_framefmt *format,
-                                  unsigned int which)
-{
-       const struct rkisp1_isp_mbus_info *mbus_info;
-       struct v4l2_mbus_framefmt *src_fmt;
-       const struct v4l2_rect *src_crop;
-
-       src_fmt = rkisp1_isp_get_pad_fmt(isp, cfg,
-                                        RKISP1_ISP_PAD_SOURCE_VIDEO, which);
-       src_crop = rkisp1_isp_get_pad_crop(isp, cfg,
-                                          RKISP1_ISP_PAD_SOURCE_VIDEO, which);
-
-       src_fmt->code = format->code;
-       mbus_info = rkisp1_isp_mbus_info_get(src_fmt->code);
-       if (!mbus_info || !(mbus_info->direction & RKISP1_ISP_SD_SRC)) {
-               src_fmt->code = RKISP1_DEF_SRC_PAD_FMT;
-               mbus_info = rkisp1_isp_mbus_info_get(src_fmt->code);
-       }
-       if (which == V4L2_SUBDEV_FORMAT_ACTIVE)
-               isp->src_fmt = mbus_info;
-       src_fmt->width  = src_crop->width;
-       src_fmt->height = src_crop->height;
-
-       /*
-        * The CSC API is used to allow userspace to force full
-        * quantization on YUV formats.
-        */
-       if (format->flags & V4L2_MBUS_FRAMEFMT_SET_CSC &&
-           format->quantization == V4L2_QUANTIZATION_FULL_RANGE &&
-           mbus_info->pixel_enc == V4L2_PIXEL_ENC_YUV)
-               src_fmt->quantization = V4L2_QUANTIZATION_FULL_RANGE;
-       else if (mbus_info->pixel_enc == V4L2_PIXEL_ENC_YUV)
-               src_fmt->quantization = V4L2_QUANTIZATION_LIM_RANGE;
-       else
-               src_fmt->quantization = V4L2_QUANTIZATION_FULL_RANGE;
-
-       *format = *src_fmt;
-}
-
-static void rkisp1_isp_set_src_crop(struct rkisp1_isp *isp,
-                                   struct v4l2_subdev_pad_config *cfg,
-                                   struct v4l2_rect *r, unsigned int which)
-{
-       struct v4l2_mbus_framefmt *src_fmt;
-       const struct v4l2_rect *sink_crop;
-       struct v4l2_rect *src_crop;
-
-       src_crop = rkisp1_isp_get_pad_crop(isp, cfg,
-                                          RKISP1_ISP_PAD_SOURCE_VIDEO,
-                                          which);
-       sink_crop = rkisp1_isp_get_pad_crop(isp, cfg,
-                                           RKISP1_ISP_PAD_SINK_VIDEO,
-                                           which);
-
-       src_crop->left = ALIGN(r->left, 2);
-       src_crop->width = ALIGN(r->width, 2);
-       src_crop->top = r->top;
-       src_crop->height = r->height;
-       rkisp1_sd_adjust_crop_rect(src_crop, sink_crop);
-
-       *r = *src_crop;
-
-       /* Propagate to out format */
-       src_fmt = rkisp1_isp_get_pad_fmt(isp, cfg,
-                                        RKISP1_ISP_PAD_SOURCE_VIDEO, which);
-       rkisp1_isp_set_src_fmt(isp, cfg, src_fmt, which);
-}
-
-static void rkisp1_isp_set_sink_crop(struct rkisp1_isp *isp,
-                                    struct v4l2_subdev_pad_config *cfg,
-                                    struct v4l2_rect *r, unsigned int which)
-{
-       struct v4l2_rect *sink_crop, *src_crop;
-       struct v4l2_mbus_framefmt *sink_fmt;
-
-       sink_crop = rkisp1_isp_get_pad_crop(isp, cfg, RKISP1_ISP_PAD_SINK_VIDEO,
-                                           which);
-       sink_fmt = rkisp1_isp_get_pad_fmt(isp, cfg, RKISP1_ISP_PAD_SINK_VIDEO,
-                                         which);
-
-       sink_crop->left = ALIGN(r->left, 2);
-       sink_crop->width = ALIGN(r->width, 2);
-       sink_crop->top = r->top;
-       sink_crop->height = r->height;
-       rkisp1_sd_adjust_crop(sink_crop, sink_fmt);
-
-       *r = *sink_crop;
-
-       /* Propagate to out crop */
-       src_crop = rkisp1_isp_get_pad_crop(isp, cfg,
-                                          RKISP1_ISP_PAD_SOURCE_VIDEO, which);
-       rkisp1_isp_set_src_crop(isp, cfg, src_crop, which);
-}
-
-static void rkisp1_isp_set_sink_fmt(struct rkisp1_isp *isp,
-                                   struct v4l2_subdev_pad_config *cfg,
-                                   struct v4l2_mbus_framefmt *format,
-                                   unsigned int which)
-{
-       const struct rkisp1_isp_mbus_info *mbus_info;
-       struct v4l2_mbus_framefmt *sink_fmt;
-       struct v4l2_rect *sink_crop;
-
-       sink_fmt = rkisp1_isp_get_pad_fmt(isp, cfg, RKISP1_ISP_PAD_SINK_VIDEO,
-                                         which);
-       sink_fmt->code = format->code;
-       mbus_info = rkisp1_isp_mbus_info_get(sink_fmt->code);
-       if (!mbus_info || !(mbus_info->direction & RKISP1_ISP_SD_SINK)) {
-               sink_fmt->code = RKISP1_DEF_SINK_PAD_FMT;
-               mbus_info = rkisp1_isp_mbus_info_get(sink_fmt->code);
-       }
-       if (which == V4L2_SUBDEV_FORMAT_ACTIVE)
-               isp->sink_fmt = mbus_info;
-
-       sink_fmt->width = clamp_t(u32, format->width,
-                                 RKISP1_ISP_MIN_WIDTH,
-                                 RKISP1_ISP_MAX_WIDTH);
-       sink_fmt->height = clamp_t(u32, format->height,
-                                  RKISP1_ISP_MIN_HEIGHT,
-                                  RKISP1_ISP_MAX_HEIGHT);
-
-       *format = *sink_fmt;
-
-       /* Propagate to in crop */
-       sink_crop = rkisp1_isp_get_pad_crop(isp, cfg, RKISP1_ISP_PAD_SINK_VIDEO,
-                                           which);
-       rkisp1_isp_set_sink_crop(isp, cfg, sink_crop, which);
-}
-
-static int rkisp1_isp_get_fmt(struct v4l2_subdev *sd,
-                             struct v4l2_subdev_pad_config *cfg,
-                             struct v4l2_subdev_format *fmt)
-{
-       struct rkisp1_isp *isp = container_of(sd, struct rkisp1_isp, sd);
-
-       mutex_lock(&isp->ops_lock);
-       fmt->format = *rkisp1_isp_get_pad_fmt(isp, cfg, fmt->pad, fmt->which);
-       mutex_unlock(&isp->ops_lock);
-       return 0;
-}
-
-static int rkisp1_isp_set_fmt(struct v4l2_subdev *sd,
-                             struct v4l2_subdev_pad_config *cfg,
-                             struct v4l2_subdev_format *fmt)
-{
-       struct rkisp1_isp *isp = container_of(sd, struct rkisp1_isp, sd);
-
-       mutex_lock(&isp->ops_lock);
-       if (fmt->pad == RKISP1_ISP_PAD_SINK_VIDEO)
-               rkisp1_isp_set_sink_fmt(isp, cfg, &fmt->format, fmt->which);
-       else if (fmt->pad == RKISP1_ISP_PAD_SOURCE_VIDEO)
-               rkisp1_isp_set_src_fmt(isp, cfg, &fmt->format, fmt->which);
-       else
-               fmt->format = *rkisp1_isp_get_pad_fmt(isp, cfg, fmt->pad,
-                                                     fmt->which);
-
-       mutex_unlock(&isp->ops_lock);
-       return 0;
-}
-
-static int rkisp1_isp_get_selection(struct v4l2_subdev *sd,
-                                   struct v4l2_subdev_pad_config *cfg,
-                                   struct v4l2_subdev_selection *sel)
-{
-       struct rkisp1_isp *isp = container_of(sd, struct rkisp1_isp, sd);
-       int ret = 0;
-
-       if (sel->pad != RKISP1_ISP_PAD_SOURCE_VIDEO &&
-           sel->pad != RKISP1_ISP_PAD_SINK_VIDEO)
-               return -EINVAL;
-
-       mutex_lock(&isp->ops_lock);
-       switch (sel->target) {
-       case V4L2_SEL_TGT_CROP_BOUNDS:
-               if (sel->pad == RKISP1_ISP_PAD_SINK_VIDEO) {
-                       struct v4l2_mbus_framefmt *fmt;
-
-                       fmt = rkisp1_isp_get_pad_fmt(isp, cfg, sel->pad,
-                                                    sel->which);
-                       sel->r.height = fmt->height;
-                       sel->r.width = fmt->width;
-                       sel->r.left = 0;
-                       sel->r.top = 0;
-               } else {
-                       sel->r = *rkisp1_isp_get_pad_crop(isp, cfg,
-                                               RKISP1_ISP_PAD_SINK_VIDEO,
-                                               sel->which);
-               }
-               break;
-       case V4L2_SEL_TGT_CROP:
-               sel->r = *rkisp1_isp_get_pad_crop(isp, cfg, sel->pad,
-                                                 sel->which);
-               break;
-       default:
-               ret = -EINVAL;
-       }
-       mutex_unlock(&isp->ops_lock);
-       return ret;
-}
-
-static int rkisp1_isp_set_selection(struct v4l2_subdev *sd,
-                                   struct v4l2_subdev_pad_config *cfg,
-                                   struct v4l2_subdev_selection *sel)
-{
-       struct rkisp1_device *rkisp1 =
-               container_of(sd->v4l2_dev, struct rkisp1_device, v4l2_dev);
-       struct rkisp1_isp *isp = container_of(sd, struct rkisp1_isp, sd);
-       int ret = 0;
-
-       if (sel->target != V4L2_SEL_TGT_CROP)
-               return -EINVAL;
-
-       dev_dbg(rkisp1->dev, "%s: pad: %d sel(%d,%d)/%dx%d\n", __func__,
-               sel->pad, sel->r.left, sel->r.top, sel->r.width, sel->r.height);
-       mutex_lock(&isp->ops_lock);
-       if (sel->pad == RKISP1_ISP_PAD_SINK_VIDEO)
-               rkisp1_isp_set_sink_crop(isp, cfg, &sel->r, sel->which);
-       else if (sel->pad == RKISP1_ISP_PAD_SOURCE_VIDEO)
-               rkisp1_isp_set_src_crop(isp, cfg, &sel->r, sel->which);
-       else
-               ret = -EINVAL;
-
-       mutex_unlock(&isp->ops_lock);
-       return ret;
-}
-
-static int rkisp1_subdev_link_validate(struct media_link *link)
-{
-       if (link->sink->index == RKISP1_ISP_PAD_SINK_PARAMS)
-               return 0;
-
-       return v4l2_subdev_link_validate(link);
-}
-
-static const struct v4l2_subdev_pad_ops rkisp1_isp_pad_ops = {
-       .enum_mbus_code = rkisp1_isp_enum_mbus_code,
-       .get_selection = rkisp1_isp_get_selection,
-       .set_selection = rkisp1_isp_set_selection,
-       .init_cfg = rkisp1_isp_init_config,
-       .get_fmt = rkisp1_isp_get_fmt,
-       .set_fmt = rkisp1_isp_set_fmt,
-       .link_validate = v4l2_subdev_link_validate_default,
-};
-
-/* ----------------------------------------------------------------------------
- * Stream operations
- */
-
-static int rkisp1_mipi_csi2_start(struct rkisp1_isp *isp,
-                                 struct rkisp1_sensor_async *sensor)
-{
-       struct rkisp1_device *rkisp1 =
-               container_of(isp->sd.v4l2_dev, struct rkisp1_device, v4l2_dev);
-       union phy_configure_opts opts;
-       struct phy_configure_opts_mipi_dphy *cfg = &opts.mipi_dphy;
-       s64 pixel_clock;
-
-       if (!sensor->pixel_rate_ctrl) {
-               dev_warn(rkisp1->dev, "No pixel rate control in sensor subdev\n");
-               return -EPIPE;
-       }
-
-       pixel_clock = v4l2_ctrl_g_ctrl_int64(sensor->pixel_rate_ctrl);
-       if (!pixel_clock) {
-               dev_err(rkisp1->dev, "Invalid pixel rate value\n");
-               return -EINVAL;
-       }
-
-       phy_mipi_dphy_get_default_config(pixel_clock, isp->sink_fmt->bus_width,
-                                        sensor->lanes, cfg);
-       phy_set_mode(sensor->dphy, PHY_MODE_MIPI_DPHY);
-       phy_configure(sensor->dphy, &opts);
-       phy_power_on(sensor->dphy);
-
-       return 0;
-}
-
-static void rkisp1_mipi_csi2_stop(struct rkisp1_sensor_async *sensor)
-{
-       phy_power_off(sensor->dphy);
-}
-
-static int rkisp1_isp_s_stream(struct v4l2_subdev *sd, int enable)
-{
-       struct rkisp1_device *rkisp1 =
-               container_of(sd->v4l2_dev, struct rkisp1_device, v4l2_dev);
-       struct rkisp1_isp *isp = &rkisp1->isp;
-       struct v4l2_subdev *sensor_sd;
-       int ret = 0;
-
-       if (!enable) {
-               rkisp1_isp_stop(rkisp1);
-               rkisp1_mipi_csi2_stop(rkisp1->active_sensor);
-               return 0;
-       }
-
-       sensor_sd = rkisp1_get_remote_sensor(sd);
-       if (!sensor_sd) {
-               dev_warn(rkisp1->dev, "No link between isp and sensor\n");
-               return -ENODEV;
-       }
-
-       rkisp1->active_sensor = container_of(sensor_sd->asd,
-                                            struct rkisp1_sensor_async, asd);
-
-       if (rkisp1->active_sensor->mbus_type != V4L2_MBUS_CSI2_DPHY)
-               return -EINVAL;
-
-       rkisp1->isp.frame_sequence = -1;
-       mutex_lock(&isp->ops_lock);
-       ret = rkisp1_config_cif(rkisp1);
-       if (ret)
-               goto mutex_unlock;
-
-       ret = rkisp1_mipi_csi2_start(&rkisp1->isp, rkisp1->active_sensor);
-       if (ret)
-               goto mutex_unlock;
-
-       rkisp1_isp_start(rkisp1);
-
-mutex_unlock:
-       mutex_unlock(&isp->ops_lock);
-       return ret;
-}
-
-static int rkisp1_isp_subs_evt(struct v4l2_subdev *sd, struct v4l2_fh *fh,
-                              struct v4l2_event_subscription *sub)
-{
-       if (sub->type != V4L2_EVENT_FRAME_SYNC)
-               return -EINVAL;
-
-       /* V4L2_EVENT_FRAME_SYNC doesn't require an id, so zero should be set */
-       if (sub->id != 0)
-               return -EINVAL;
-
-       return v4l2_event_subscribe(fh, sub, 0, NULL);
-}
-
-static const struct media_entity_operations rkisp1_isp_media_ops = {
-       .link_validate = rkisp1_subdev_link_validate,
-};
-
-static const struct v4l2_subdev_video_ops rkisp1_isp_video_ops = {
-       .s_stream = rkisp1_isp_s_stream,
-};
-
-static const struct v4l2_subdev_core_ops rkisp1_isp_core_ops = {
-       .subscribe_event = rkisp1_isp_subs_evt,
-       .unsubscribe_event = v4l2_event_subdev_unsubscribe,
-};
-
-static const struct v4l2_subdev_ops rkisp1_isp_ops = {
-       .core = &rkisp1_isp_core_ops,
-       .video = &rkisp1_isp_video_ops,
-       .pad = &rkisp1_isp_pad_ops,
-};
-
-int rkisp1_isp_register(struct rkisp1_device *rkisp1)
-{
-       struct rkisp1_isp *isp = &rkisp1->isp;
-       struct media_pad *pads = isp->pads;
-       struct v4l2_subdev *sd = &isp->sd;
-       int ret;
-
-       v4l2_subdev_init(sd, &rkisp1_isp_ops);
-       sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE | V4L2_SUBDEV_FL_HAS_EVENTS;
-       sd->entity.ops = &rkisp1_isp_media_ops;
-       sd->entity.function = MEDIA_ENT_F_PROC_VIDEO_PIXEL_FORMATTER;
-       sd->owner = THIS_MODULE;
-       strscpy(sd->name, RKISP1_ISP_DEV_NAME, sizeof(sd->name));
-
-       pads[RKISP1_ISP_PAD_SINK_VIDEO].flags = MEDIA_PAD_FL_SINK |
-                                               MEDIA_PAD_FL_MUST_CONNECT;
-       pads[RKISP1_ISP_PAD_SINK_PARAMS].flags = MEDIA_PAD_FL_SINK;
-       pads[RKISP1_ISP_PAD_SOURCE_VIDEO].flags = MEDIA_PAD_FL_SOURCE;
-       pads[RKISP1_ISP_PAD_SOURCE_STATS].flags = MEDIA_PAD_FL_SOURCE;
-
-       isp->sink_fmt = rkisp1_isp_mbus_info_get(RKISP1_DEF_SINK_PAD_FMT);
-       isp->src_fmt = rkisp1_isp_mbus_info_get(RKISP1_DEF_SRC_PAD_FMT);
-
-       mutex_init(&isp->ops_lock);
-       ret = media_entity_pads_init(&sd->entity, RKISP1_ISP_PAD_MAX, pads);
-       if (ret)
-               return ret;
-
-       ret = v4l2_device_register_subdev(&rkisp1->v4l2_dev, sd);
-       if (ret) {
-               dev_err(rkisp1->dev, "Failed to register isp subdev\n");
-               goto err_cleanup_media_entity;
-       }
-
-       rkisp1_isp_init_config(sd, rkisp1->isp.pad_cfg);
-       return 0;
-
-err_cleanup_media_entity:
-       media_entity_cleanup(&sd->entity);
-
-       return ret;
-}
-
-void rkisp1_isp_unregister(struct rkisp1_device *rkisp1)
-{
-       struct v4l2_subdev *sd = &rkisp1->isp.sd;
-
-       v4l2_device_unregister_subdev(sd);
-       media_entity_cleanup(&sd->entity);
-}
-
-/* ----------------------------------------------------------------------------
- * Interrupt handlers
- */
-
-void rkisp1_mipi_isr(struct rkisp1_device *rkisp1)
-{
-       u32 val, status;
-
-       status = rkisp1_read(rkisp1, RKISP1_CIF_MIPI_MIS);
-       if (!status)
-               return;
-
-       rkisp1_write(rkisp1, status, RKISP1_CIF_MIPI_ICR);
-
-       /*
-        * Disable DPHY errctrl interrupt, because this dphy
-        * erctrl signal is asserted until the next changes
-        * of line state. This time is may be too long and cpu
-        * is hold in this interrupt.
-        */
-       if (status & RKISP1_CIF_MIPI_ERR_CTRL(0x0f)) {
-               val = rkisp1_read(rkisp1, RKISP1_CIF_MIPI_IMSC);
-               rkisp1_write(rkisp1, val & ~RKISP1_CIF_MIPI_ERR_CTRL(0x0f),
-                            RKISP1_CIF_MIPI_IMSC);
-               rkisp1->isp.is_dphy_errctrl_disabled = true;
-       }
-
-       /*
-        * Enable DPHY errctrl interrupt again, if mipi have receive
-        * the whole frame without any error.
-        */
-       if (status == RKISP1_CIF_MIPI_FRAME_END) {
-               /*
-                * Enable DPHY errctrl interrupt again, if mipi have receive
-                * the whole frame without any error.
-                */
-               if (rkisp1->isp.is_dphy_errctrl_disabled) {
-                       val = rkisp1_read(rkisp1, RKISP1_CIF_MIPI_IMSC);
-                       val |= RKISP1_CIF_MIPI_ERR_CTRL(0x0f);
-                       rkisp1_write(rkisp1, val, RKISP1_CIF_MIPI_IMSC);
-                       rkisp1->isp.is_dphy_errctrl_disabled = false;
-               }
-       } else {
-               rkisp1->debug.mipi_error++;
-       }
-}
-
-static void rkisp1_isp_queue_event_sof(struct rkisp1_isp *isp)
-{
-       struct v4l2_event event = {
-               .type = V4L2_EVENT_FRAME_SYNC,
-       };
-       event.u.frame_sync.frame_sequence = isp->frame_sequence;
-
-       v4l2_event_queue(isp->sd.devnode, &event);
-}
-
-void rkisp1_isp_isr(struct rkisp1_device *rkisp1)
-{
-       u32 status, isp_err;
-
-       status = rkisp1_read(rkisp1, RKISP1_CIF_ISP_MIS);
-       if (!status)
-               return;
-
-       rkisp1_write(rkisp1, status, RKISP1_CIF_ISP_ICR);
-
-       /* Vertical sync signal, starting generating new frame */
-       if (status & RKISP1_CIF_ISP_V_START) {
-               rkisp1->isp.frame_sequence++;
-               rkisp1_isp_queue_event_sof(&rkisp1->isp);
-               if (status & RKISP1_CIF_ISP_FRAME) {
-                       WARN_ONCE(1, "irq delay is too long, buffers might not be in sync\n");
-                       rkisp1->debug.irq_delay++;
-               }
-       }
-       if (status & RKISP1_CIF_ISP_PIC_SIZE_ERROR) {
-               /* Clear pic_size_error */
-               isp_err = rkisp1_read(rkisp1, RKISP1_CIF_ISP_ERR);
-               if (isp_err & RKISP1_CIF_ISP_ERR_INFORM_SIZE)
-                       rkisp1->debug.inform_size_error++;
-               if (isp_err & RKISP1_CIF_ISP_ERR_IS_SIZE)
-                       rkisp1->debug.img_stabilization_size_error++;
-               if (isp_err & RKISP1_CIF_ISP_ERR_OUTFORM_SIZE)
-                       rkisp1->debug.outform_size_error++;
-               rkisp1_write(rkisp1, isp_err, RKISP1_CIF_ISP_ERR_CLR);
-       } else if (status & RKISP1_CIF_ISP_DATA_LOSS) {
-               /* keep track of data_loss in debugfs */
-               rkisp1->debug.data_loss++;
-       }
-
-       if (status & RKISP1_CIF_ISP_FRAME) {
-               u32 isp_ris;
-
-               /* New frame from the sensor received */
-               isp_ris = rkisp1_read(rkisp1, RKISP1_CIF_ISP_RIS);
-               if (isp_ris & RKISP1_STATS_MEAS_MASK)
-                       rkisp1_stats_isr(&rkisp1->stats, isp_ris);
-               /*
-                * Then update changed configs. Some of them involve
-                * lot of register writes. Do those only one per frame.
-                * Do the updates in the order of the processing flow.
-                */
-               rkisp1_params_isr(rkisp1);
-       }
-
-}
diff --git a/drivers/staging/media/rkisp1/rkisp1-params.c b/drivers/staging/media/rkisp1/rkisp1-params.c
deleted file mode 100644 (file)
index 986d293..0000000
+++ /dev/null
@@ -1,1595 +0,0 @@
-// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
-/*
- * Rockchip ISP1 Driver - Params subdevice
- *
- * Copyright (C) 2017 Rockchip Electronics Co., Ltd.
- */
-
-#include <media/v4l2-common.h>
-#include <media/v4l2-event.h>
-#include <media/v4l2-ioctl.h>
-#include <media/videobuf2-core.h>
-#include <media/videobuf2-vmalloc.h>   /* for ISP params */
-
-#include "rkisp1-common.h"
-
-#define RKISP1_PARAMS_DEV_NAME RKISP1_DRIVER_NAME "_params"
-
-#define RKISP1_ISP_PARAMS_REQ_BUFS_MIN 2
-#define RKISP1_ISP_PARAMS_REQ_BUFS_MAX 8
-
-#define RKISP1_ISP_DPCC_LINE_THRESH(n) \
-                       (RKISP1_CIF_ISP_DPCC_LINE_THRESH_1 + 0x14 * (n))
-#define RKISP1_ISP_DPCC_LINE_MAD_FAC(n) \
-                       (RKISP1_CIF_ISP_DPCC_LINE_MAD_FAC_1 + 0x14 * (n))
-#define RKISP1_ISP_DPCC_PG_FAC(n) \
-                       (RKISP1_CIF_ISP_DPCC_PG_FAC_1 + 0x14 * (n))
-#define RKISP1_ISP_DPCC_RND_THRESH(n) \
-                       (RKISP1_CIF_ISP_DPCC_RND_THRESH_1 + 0x14 * (n))
-#define RKISP1_ISP_DPCC_RG_FAC(n) \
-                       (RKISP1_CIF_ISP_DPCC_RG_FAC_1 + 0x14 * (n))
-#define RKISP1_ISP_CC_COEFF(n) \
-                       (RKISP1_CIF_ISP_CC_COEFF_0 + (n) * 4)
-
-static inline void
-rkisp1_param_set_bits(struct rkisp1_params *params, u32 reg, u32 bit_mask)
-{
-       u32 val;
-
-       val = rkisp1_read(params->rkisp1, reg);
-       rkisp1_write(params->rkisp1, val | bit_mask, reg);
-}
-
-static inline void
-rkisp1_param_clear_bits(struct rkisp1_params *params, u32 reg, u32 bit_mask)
-{
-       u32 val;
-
-       val = rkisp1_read(params->rkisp1, reg);
-       rkisp1_write(params->rkisp1, val & ~bit_mask, reg);
-}
-
-/* ISP BP interface function */
-static void rkisp1_dpcc_config(struct rkisp1_params *params,
-                              const struct rkisp1_cif_isp_dpcc_config *arg)
-{
-       unsigned int i;
-       u32 mode;
-
-       /* avoid to override the old enable value */
-       mode = rkisp1_read(params->rkisp1, RKISP1_CIF_ISP_DPCC_MODE);
-       mode &= RKISP1_CIF_ISP_DPCC_ENA;
-       mode |= arg->mode & ~RKISP1_CIF_ISP_DPCC_ENA;
-       rkisp1_write(params->rkisp1, mode, RKISP1_CIF_ISP_DPCC_MODE);
-       rkisp1_write(params->rkisp1, arg->output_mode,
-                    RKISP1_CIF_ISP_DPCC_OUTPUT_MODE);
-       rkisp1_write(params->rkisp1, arg->set_use,
-                    RKISP1_CIF_ISP_DPCC_SET_USE);
-
-       rkisp1_write(params->rkisp1, arg->methods[0].method,
-                    RKISP1_CIF_ISP_DPCC_METHODS_SET_1);
-       rkisp1_write(params->rkisp1, arg->methods[1].method,
-                    RKISP1_CIF_ISP_DPCC_METHODS_SET_2);
-       rkisp1_write(params->rkisp1, arg->methods[2].method,
-                    RKISP1_CIF_ISP_DPCC_METHODS_SET_3);
-       for (i = 0; i < RKISP1_CIF_ISP_DPCC_METHODS_MAX; i++) {
-               rkisp1_write(params->rkisp1, arg->methods[i].line_thresh,
-                            RKISP1_ISP_DPCC_LINE_THRESH(i));
-               rkisp1_write(params->rkisp1, arg->methods[i].line_mad_fac,
-                            RKISP1_ISP_DPCC_LINE_MAD_FAC(i));
-               rkisp1_write(params->rkisp1, arg->methods[i].pg_fac,
-                            RKISP1_ISP_DPCC_PG_FAC(i));
-               rkisp1_write(params->rkisp1, arg->methods[i].rnd_thresh,
-                            RKISP1_ISP_DPCC_RND_THRESH(i));
-               rkisp1_write(params->rkisp1, arg->methods[i].rg_fac,
-                            RKISP1_ISP_DPCC_RG_FAC(i));
-       }
-
-       rkisp1_write(params->rkisp1, arg->rnd_offs,
-                    RKISP1_CIF_ISP_DPCC_RND_OFFS);
-       rkisp1_write(params->rkisp1, arg->ro_limits,
-                    RKISP1_CIF_ISP_DPCC_RO_LIMITS);
-}
-
-/* ISP black level subtraction interface function */
-static void rkisp1_bls_config(struct rkisp1_params *params,
-                             const struct rkisp1_cif_isp_bls_config *arg)
-{
-       /* avoid to override the old enable value */
-       u32 new_control;
-
-       new_control = rkisp1_read(params->rkisp1, RKISP1_CIF_ISP_BLS_CTRL);
-       new_control &= RKISP1_CIF_ISP_BLS_ENA;
-       /* fixed subtraction values */
-       if (!arg->enable_auto) {
-               const struct rkisp1_cif_isp_bls_fixed_val *pval =
-                                                               &arg->fixed_val;
-
-               switch (params->raw_type) {
-               case RKISP1_RAW_BGGR:
-                       rkisp1_write(params->rkisp1,
-                                    pval->r, RKISP1_CIF_ISP_BLS_D_FIXED);
-                       rkisp1_write(params->rkisp1,
-                                    pval->gr, RKISP1_CIF_ISP_BLS_C_FIXED);
-                       rkisp1_write(params->rkisp1,
-                                    pval->gb, RKISP1_CIF_ISP_BLS_B_FIXED);
-                       rkisp1_write(params->rkisp1,
-                                    pval->b, RKISP1_CIF_ISP_BLS_A_FIXED);
-                       break;
-               case RKISP1_RAW_GBRG:
-                       rkisp1_write(params->rkisp1,
-                                    pval->r, RKISP1_CIF_ISP_BLS_C_FIXED);
-                       rkisp1_write(params->rkisp1,
-                                    pval->gr, RKISP1_CIF_ISP_BLS_D_FIXED);
-                       rkisp1_write(params->rkisp1,
-                                    pval->gb, RKISP1_CIF_ISP_BLS_A_FIXED);
-                       rkisp1_write(params->rkisp1,
-                                    pval->b, RKISP1_CIF_ISP_BLS_B_FIXED);
-                       break;
-               case RKISP1_RAW_GRBG:
-                       rkisp1_write(params->rkisp1,
-                                    pval->r, RKISP1_CIF_ISP_BLS_B_FIXED);
-                       rkisp1_write(params->rkisp1,
-                                    pval->gr, RKISP1_CIF_ISP_BLS_A_FIXED);
-                       rkisp1_write(params->rkisp1,
-                                    pval->gb, RKISP1_CIF_ISP_BLS_D_FIXED);
-                       rkisp1_write(params->rkisp1,
-                                    pval->b, RKISP1_CIF_ISP_BLS_C_FIXED);
-                       break;
-               case RKISP1_RAW_RGGB:
-                       rkisp1_write(params->rkisp1,
-                                    pval->r, RKISP1_CIF_ISP_BLS_A_FIXED);
-                       rkisp1_write(params->rkisp1,
-                                    pval->gr, RKISP1_CIF_ISP_BLS_B_FIXED);
-                       rkisp1_write(params->rkisp1,
-                                    pval->gb, RKISP1_CIF_ISP_BLS_C_FIXED);
-                       rkisp1_write(params->rkisp1,
-                                    pval->b, RKISP1_CIF_ISP_BLS_D_FIXED);
-                       break;
-               default:
-                       break;
-               }
-
-       } else {
-               if (arg->en_windows & BIT(1)) {
-                       rkisp1_write(params->rkisp1, arg->bls_window2.h_offs,
-                                    RKISP1_CIF_ISP_BLS_H2_START);
-                       rkisp1_write(params->rkisp1, arg->bls_window2.h_size,
-                                    RKISP1_CIF_ISP_BLS_H2_STOP);
-                       rkisp1_write(params->rkisp1, arg->bls_window2.v_offs,
-                                    RKISP1_CIF_ISP_BLS_V2_START);
-                       rkisp1_write(params->rkisp1, arg->bls_window2.v_size,
-                                    RKISP1_CIF_ISP_BLS_V2_STOP);
-                       new_control |= RKISP1_CIF_ISP_BLS_WINDOW_2;
-               }
-
-               if (arg->en_windows & BIT(0)) {
-                       rkisp1_write(params->rkisp1, arg->bls_window1.h_offs,
-                                    RKISP1_CIF_ISP_BLS_H1_START);
-                       rkisp1_write(params->rkisp1, arg->bls_window1.h_size,
-                                    RKISP1_CIF_ISP_BLS_H1_STOP);
-                       rkisp1_write(params->rkisp1, arg->bls_window1.v_offs,
-                                    RKISP1_CIF_ISP_BLS_V1_START);
-                       rkisp1_write(params->rkisp1, arg->bls_window1.v_size,
-                                    RKISP1_CIF_ISP_BLS_V1_STOP);
-                       new_control |= RKISP1_CIF_ISP_BLS_WINDOW_1;
-               }
-
-               rkisp1_write(params->rkisp1, arg->bls_samples,
-                            RKISP1_CIF_ISP_BLS_SAMPLES);
-
-               new_control |= RKISP1_CIF_ISP_BLS_MODE_MEASURED;
-       }
-       rkisp1_write(params->rkisp1, new_control, RKISP1_CIF_ISP_BLS_CTRL);
-}
-
-/* ISP LS correction interface function */
-static void
-rkisp1_lsc_correct_matrix_config(struct rkisp1_params *params,
-                               const struct rkisp1_cif_isp_lsc_config *pconfig)
-{
-       unsigned int isp_lsc_status, sram_addr, isp_lsc_table_sel, i, j, data;
-
-       isp_lsc_status = rkisp1_read(params->rkisp1, RKISP1_CIF_ISP_LSC_STATUS);
-
-       /* RKISP1_CIF_ISP_LSC_TABLE_ADDRESS_153 = ( 17 * 18 ) >> 1 */
-       sram_addr = (isp_lsc_status & RKISP1_CIF_ISP_LSC_ACTIVE_TABLE) ?
-                   RKISP1_CIF_ISP_LSC_TABLE_ADDRESS_0 :
-                   RKISP1_CIF_ISP_LSC_TABLE_ADDRESS_153;
-       rkisp1_write(params->rkisp1, sram_addr,
-                    RKISP1_CIF_ISP_LSC_R_TABLE_ADDR);
-       rkisp1_write(params->rkisp1, sram_addr,
-                    RKISP1_CIF_ISP_LSC_GR_TABLE_ADDR);
-       rkisp1_write(params->rkisp1, sram_addr,
-                    RKISP1_CIF_ISP_LSC_GB_TABLE_ADDR);
-       rkisp1_write(params->rkisp1, sram_addr,
-                    RKISP1_CIF_ISP_LSC_B_TABLE_ADDR);
-
-       /* program data tables (table size is 9 * 17 = 153) */
-       for (i = 0; i < RKISP1_CIF_ISP_LSC_SAMPLES_MAX; i++) {
-               /*
-                * 17 sectors with 2 values in one DWORD = 9
-                * DWORDs (2nd value of last DWORD unused)
-                */
-               for (j = 0; j < RKISP1_CIF_ISP_LSC_SAMPLES_MAX - 1; j += 2) {
-                       data = RKISP1_CIF_ISP_LSC_TABLE_DATA(pconfig->r_data_tbl[i][j],
-                                                            pconfig->r_data_tbl[i][j + 1]);
-                       rkisp1_write(params->rkisp1, data,
-                                    RKISP1_CIF_ISP_LSC_R_TABLE_DATA);
-
-                       data = RKISP1_CIF_ISP_LSC_TABLE_DATA(pconfig->gr_data_tbl[i][j],
-                                                            pconfig->gr_data_tbl[i][j + 1]);
-                       rkisp1_write(params->rkisp1, data,
-                                    RKISP1_CIF_ISP_LSC_GR_TABLE_DATA);
-
-                       data = RKISP1_CIF_ISP_LSC_TABLE_DATA(pconfig->gb_data_tbl[i][j],
-                                                            pconfig->gb_data_tbl[i][j + 1]);
-                       rkisp1_write(params->rkisp1, data,
-                                    RKISP1_CIF_ISP_LSC_GB_TABLE_DATA);
-
-                       data = RKISP1_CIF_ISP_LSC_TABLE_DATA(pconfig->b_data_tbl[i][j],
-                                                            pconfig->b_data_tbl[i][j + 1]);
-                       rkisp1_write(params->rkisp1, data,
-                                    RKISP1_CIF_ISP_LSC_B_TABLE_DATA);
-               }
-               data = RKISP1_CIF_ISP_LSC_TABLE_DATA(pconfig->r_data_tbl[i][j], 0);
-               rkisp1_write(params->rkisp1, data,
-                            RKISP1_CIF_ISP_LSC_R_TABLE_DATA);
-
-               data = RKISP1_CIF_ISP_LSC_TABLE_DATA(pconfig->gr_data_tbl[i][j], 0);
-               rkisp1_write(params->rkisp1, data,
-                            RKISP1_CIF_ISP_LSC_GR_TABLE_DATA);
-
-               data = RKISP1_CIF_ISP_LSC_TABLE_DATA(pconfig->gb_data_tbl[i][j], 0);
-               rkisp1_write(params->rkisp1, data,
-                            RKISP1_CIF_ISP_LSC_GB_TABLE_DATA);
-
-               data = RKISP1_CIF_ISP_LSC_TABLE_DATA(pconfig->b_data_tbl[i][j], 0);
-               rkisp1_write(params->rkisp1, data,
-                            RKISP1_CIF_ISP_LSC_B_TABLE_DATA);
-       }
-       isp_lsc_table_sel = (isp_lsc_status & RKISP1_CIF_ISP_LSC_ACTIVE_TABLE) ?
-                           RKISP1_CIF_ISP_LSC_TABLE_0 :
-                           RKISP1_CIF_ISP_LSC_TABLE_1;
-       rkisp1_write(params->rkisp1, isp_lsc_table_sel,
-                    RKISP1_CIF_ISP_LSC_TABLE_SEL);
-}
-
-static void rkisp1_lsc_config(struct rkisp1_params *params,
-                             const struct rkisp1_cif_isp_lsc_config *arg)
-{
-       unsigned int i, data;
-       u32 lsc_ctrl;
-
-       /* To config must be off , store the current status firstly */
-       lsc_ctrl = rkisp1_read(params->rkisp1, RKISP1_CIF_ISP_LSC_CTRL);
-       rkisp1_param_clear_bits(params, RKISP1_CIF_ISP_LSC_CTRL,
-                               RKISP1_CIF_ISP_LSC_CTRL_ENA);
-       rkisp1_lsc_correct_matrix_config(params, arg);
-
-       for (i = 0; i < RKISP1_CIF_ISP_LSC_SECTORS_TBL_SIZE / 2; i++) {
-               /* program x size tables */
-               data = RKISP1_CIF_ISP_LSC_SECT_SIZE(arg->x_size_tbl[i * 2],
-                                                   arg->x_size_tbl[i * 2 + 1]);
-               rkisp1_write(params->rkisp1, data,
-                            RKISP1_CIF_ISP_LSC_XSIZE_01 + i * 4);
-
-               /* program x grad tables */
-               data = RKISP1_CIF_ISP_LSC_SECT_SIZE(arg->x_grad_tbl[i * 2],
-                                                   arg->x_grad_tbl[i * 2 + 1]);
-               rkisp1_write(params->rkisp1, data,
-                            RKISP1_CIF_ISP_LSC_XGRAD_01 + i * 4);
-
-               /* program y size tables */
-               data = RKISP1_CIF_ISP_LSC_SECT_SIZE(arg->y_size_tbl[i * 2],
-                                                   arg->y_size_tbl[i * 2 + 1]);
-               rkisp1_write(params->rkisp1, data,
-                            RKISP1_CIF_ISP_LSC_YSIZE_01 + i * 4);
-
-               /* program y grad tables */
-               data = RKISP1_CIF_ISP_LSC_SECT_SIZE(arg->y_grad_tbl[i * 2],
-                                                   arg->y_grad_tbl[i * 2 + 1]);
-               rkisp1_write(params->rkisp1, data,
-                            RKISP1_CIF_ISP_LSC_YGRAD_01 + i * 4);
-       }
-
-       /* restore the lsc ctrl status */
-       if (lsc_ctrl & RKISP1_CIF_ISP_LSC_CTRL_ENA) {
-               rkisp1_param_set_bits(params,
-                                     RKISP1_CIF_ISP_LSC_CTRL,
-                                     RKISP1_CIF_ISP_LSC_CTRL_ENA);
-       } else {
-               rkisp1_param_clear_bits(params,
-                                       RKISP1_CIF_ISP_LSC_CTRL,
-                                       RKISP1_CIF_ISP_LSC_CTRL_ENA);
-       }
-}
-
-/* ISP Filtering function */
-static void rkisp1_flt_config(struct rkisp1_params *params,
-                             const struct rkisp1_cif_isp_flt_config *arg)
-{
-       u32 filt_mode;
-
-       rkisp1_write(params->rkisp1,
-                    arg->thresh_bl0, RKISP1_CIF_ISP_FILT_THRESH_BL0);
-       rkisp1_write(params->rkisp1,
-                    arg->thresh_bl1, RKISP1_CIF_ISP_FILT_THRESH_BL1);
-       rkisp1_write(params->rkisp1,
-                    arg->thresh_sh0, RKISP1_CIF_ISP_FILT_THRESH_SH0);
-       rkisp1_write(params->rkisp1,
-                    arg->thresh_sh1, RKISP1_CIF_ISP_FILT_THRESH_SH1);
-       rkisp1_write(params->rkisp1, arg->fac_bl0, RKISP1_CIF_ISP_FILT_FAC_BL0);
-       rkisp1_write(params->rkisp1, arg->fac_bl1, RKISP1_CIF_ISP_FILT_FAC_BL1);
-       rkisp1_write(params->rkisp1, arg->fac_mid, RKISP1_CIF_ISP_FILT_FAC_MID);
-       rkisp1_write(params->rkisp1, arg->fac_sh0, RKISP1_CIF_ISP_FILT_FAC_SH0);
-       rkisp1_write(params->rkisp1, arg->fac_sh1, RKISP1_CIF_ISP_FILT_FAC_SH1);
-       rkisp1_write(params->rkisp1,
-                    arg->lum_weight, RKISP1_CIF_ISP_FILT_LUM_WEIGHT);
-
-       rkisp1_write(params->rkisp1,
-                    (arg->mode ? RKISP1_CIF_ISP_FLT_MODE_DNR : 0) |
-                    RKISP1_CIF_ISP_FLT_CHROMA_V_MODE(arg->chr_v_mode) |
-                    RKISP1_CIF_ISP_FLT_CHROMA_H_MODE(arg->chr_h_mode) |
-                    RKISP1_CIF_ISP_FLT_GREEN_STAGE1(arg->grn_stage1),
-                    RKISP1_CIF_ISP_FILT_MODE);
-
-       /* avoid to override the old enable value */
-       filt_mode = rkisp1_read(params->rkisp1, RKISP1_CIF_ISP_FILT_MODE);
-       filt_mode &= RKISP1_CIF_ISP_FLT_ENA;
-       if (arg->mode)
-               filt_mode |= RKISP1_CIF_ISP_FLT_MODE_DNR;
-       filt_mode |= RKISP1_CIF_ISP_FLT_CHROMA_V_MODE(arg->chr_v_mode) |
-                    RKISP1_CIF_ISP_FLT_CHROMA_H_MODE(arg->chr_h_mode) |
-                    RKISP1_CIF_ISP_FLT_GREEN_STAGE1(arg->grn_stage1);
-       rkisp1_write(params->rkisp1, filt_mode, RKISP1_CIF_ISP_FILT_MODE);
-}
-
-/* ISP demosaic interface function */
-static int rkisp1_bdm_config(struct rkisp1_params *params,
-                            const struct rkisp1_cif_isp_bdm_config *arg)
-{
-       u32 bdm_th;
-
-       /* avoid to override the old enable value */
-       bdm_th = rkisp1_read(params->rkisp1, RKISP1_CIF_ISP_DEMOSAIC);
-       bdm_th &= RKISP1_CIF_ISP_DEMOSAIC_BYPASS;
-       bdm_th |= arg->demosaic_th & ~RKISP1_CIF_ISP_DEMOSAIC_BYPASS;
-       /* set demosaic threshold */
-       rkisp1_write(params->rkisp1, bdm_th, RKISP1_CIF_ISP_DEMOSAIC);
-       return 0;
-}
-
-/* ISP GAMMA correction interface function */
-static void rkisp1_sdg_config(struct rkisp1_params *params,
-                             const struct rkisp1_cif_isp_sdg_config *arg)
-{
-       unsigned int i;
-
-       rkisp1_write(params->rkisp1,
-                    arg->xa_pnts.gamma_dx0, RKISP1_CIF_ISP_GAMMA_DX_LO);
-       rkisp1_write(params->rkisp1,
-                    arg->xa_pnts.gamma_dx1, RKISP1_CIF_ISP_GAMMA_DX_HI);
-
-       for (i = 0; i < RKISP1_CIF_ISP_DEGAMMA_CURVE_SIZE; i++) {
-               rkisp1_write(params->rkisp1, arg->curve_r.gamma_y[i],
-                            RKISP1_CIF_ISP_GAMMA_R_Y0 + i * 4);
-               rkisp1_write(params->rkisp1, arg->curve_g.gamma_y[i],
-                            RKISP1_CIF_ISP_GAMMA_G_Y0 + i * 4);
-               rkisp1_write(params->rkisp1, arg->curve_b.gamma_y[i],
-                            RKISP1_CIF_ISP_GAMMA_B_Y0 + i * 4);
-       }
-}
-
-/* ISP GAMMA correction interface function */
-static void rkisp1_goc_config(struct rkisp1_params *params,
-                             const struct rkisp1_cif_isp_goc_config *arg)
-{
-       unsigned int i;
-
-       rkisp1_param_clear_bits(params, RKISP1_CIF_ISP_CTRL,
-                               RKISP1_CIF_ISP_CTRL_ISP_GAMMA_OUT_ENA);
-       rkisp1_write(params->rkisp1, arg->mode, RKISP1_CIF_ISP_GAMMA_OUT_MODE);
-
-       for (i = 0; i < RKISP1_CIF_ISP_GAMMA_OUT_MAX_SAMPLES; i++)
-               rkisp1_write(params->rkisp1, arg->gamma_y[i],
-                            RKISP1_CIF_ISP_GAMMA_OUT_Y_0 + i * 4);
-}
-
-/* ISP Cross Talk */
-static void rkisp1_ctk_config(struct rkisp1_params *params,
-                             const struct rkisp1_cif_isp_ctk_config *arg)
-{
-       unsigned int i, j, k = 0;
-
-       for (i = 0; i < 3; i++)
-               for (j = 0; j < 3; j++)
-                       rkisp1_write(params->rkisp1, arg->coeff[i][j],
-                                    RKISP1_CIF_ISP_CT_COEFF_0 + 4 * k++);
-       for (i = 0; i < 3; i++)
-               rkisp1_write(params->rkisp1, arg->ct_offset[i],
-                            RKISP1_CIF_ISP_CT_OFFSET_R + i * 4);
-}
-
-static void rkisp1_ctk_enable(struct rkisp1_params *params, bool en)
-{
-       if (en)
-               return;
-
-       /* Write back the default values. */
-       rkisp1_write(params->rkisp1, 0x80, RKISP1_CIF_ISP_CT_COEFF_0);
-       rkisp1_write(params->rkisp1, 0, RKISP1_CIF_ISP_CT_COEFF_1);
-       rkisp1_write(params->rkisp1, 0, RKISP1_CIF_ISP_CT_COEFF_2);
-       rkisp1_write(params->rkisp1, 0, RKISP1_CIF_ISP_CT_COEFF_3);
-       rkisp1_write(params->rkisp1, 0x80, RKISP1_CIF_ISP_CT_COEFF_4);
-       rkisp1_write(params->rkisp1, 0, RKISP1_CIF_ISP_CT_COEFF_5);
-       rkisp1_write(params->rkisp1, 0, RKISP1_CIF_ISP_CT_COEFF_6);
-       rkisp1_write(params->rkisp1, 0, RKISP1_CIF_ISP_CT_COEFF_7);
-       rkisp1_write(params->rkisp1, 0x80, RKISP1_CIF_ISP_CT_COEFF_8);
-
-       rkisp1_write(params->rkisp1, 0, RKISP1_CIF_ISP_CT_OFFSET_R);
-       rkisp1_write(params->rkisp1, 0, RKISP1_CIF_ISP_CT_OFFSET_G);
-       rkisp1_write(params->rkisp1, 0, RKISP1_CIF_ISP_CT_OFFSET_B);
-}
-
-/* ISP White Balance Mode */
-static void rkisp1_awb_meas_config(struct rkisp1_params *params,
-                       const struct rkisp1_cif_isp_awb_meas_config *arg)
-{
-       u32 reg_val = 0;
-       /* based on the mode,configure the awb module */
-       if (arg->awb_mode == RKISP1_CIF_ISP_AWB_MODE_YCBCR) {
-               /* Reference Cb and Cr */
-               rkisp1_write(params->rkisp1,
-                            RKISP1_CIF_ISP_AWB_REF_CR_SET(arg->awb_ref_cr) |
-                            arg->awb_ref_cb, RKISP1_CIF_ISP_AWB_REF);
-               /* Yc Threshold */
-               rkisp1_write(params->rkisp1,
-                            RKISP1_CIF_ISP_AWB_MAX_Y_SET(arg->max_y) |
-                            RKISP1_CIF_ISP_AWB_MIN_Y_SET(arg->min_y) |
-                            RKISP1_CIF_ISP_AWB_MAX_CS_SET(arg->max_csum) |
-                            arg->min_c, RKISP1_CIF_ISP_AWB_THRESH);
-       }
-
-       reg_val = rkisp1_read(params->rkisp1, RKISP1_CIF_ISP_AWB_PROP);
-       if (arg->enable_ymax_cmp)
-               reg_val |= RKISP1_CIF_ISP_AWB_YMAX_CMP_EN;
-       else
-               reg_val &= ~RKISP1_CIF_ISP_AWB_YMAX_CMP_EN;
-       rkisp1_write(params->rkisp1, reg_val, RKISP1_CIF_ISP_AWB_PROP);
-
-       /* window offset */
-       rkisp1_write(params->rkisp1,
-                    arg->awb_wnd.v_offs, RKISP1_CIF_ISP_AWB_WND_V_OFFS);
-       rkisp1_write(params->rkisp1,
-                    arg->awb_wnd.h_offs, RKISP1_CIF_ISP_AWB_WND_H_OFFS);
-       /* AWB window size */
-       rkisp1_write(params->rkisp1,
-                    arg->awb_wnd.v_size, RKISP1_CIF_ISP_AWB_WND_V_SIZE);
-       rkisp1_write(params->rkisp1,
-                    arg->awb_wnd.h_size, RKISP1_CIF_ISP_AWB_WND_H_SIZE);
-       /* Number of frames */
-       rkisp1_write(params->rkisp1,
-                    arg->frames, RKISP1_CIF_ISP_AWB_FRAMES);
-}
-
-static void
-rkisp1_awb_meas_enable(struct rkisp1_params *params,
-                      const struct rkisp1_cif_isp_awb_meas_config *arg,
-                      bool en)
-{
-       u32 reg_val = rkisp1_read(params->rkisp1, RKISP1_CIF_ISP_AWB_PROP);
-
-       /* switch off */
-       reg_val &= RKISP1_CIF_ISP_AWB_MODE_MASK_NONE;
-
-       if (en) {
-               if (arg->awb_mode == RKISP1_CIF_ISP_AWB_MODE_RGB)
-                       reg_val |= RKISP1_CIF_ISP_AWB_MODE_RGB_EN;
-               else
-                       reg_val |= RKISP1_CIF_ISP_AWB_MODE_YCBCR_EN;
-
-               rkisp1_write(params->rkisp1, reg_val, RKISP1_CIF_ISP_AWB_PROP);
-
-               /* Measurements require AWB block be active. */
-               rkisp1_param_set_bits(params, RKISP1_CIF_ISP_CTRL,
-                                     RKISP1_CIF_ISP_CTRL_ISP_AWB_ENA);
-       } else {
-               rkisp1_write(params->rkisp1,
-                            reg_val, RKISP1_CIF_ISP_AWB_PROP);
-               rkisp1_param_clear_bits(params, RKISP1_CIF_ISP_CTRL,
-                                       RKISP1_CIF_ISP_CTRL_ISP_AWB_ENA);
-       }
-}
-
-static void
-rkisp1_awb_gain_config(struct rkisp1_params *params,
-                      const struct rkisp1_cif_isp_awb_gain_config *arg)
-{
-       rkisp1_write(params->rkisp1,
-                    RKISP1_CIF_ISP_AWB_GAIN_R_SET(arg->gain_green_r) |
-                    arg->gain_green_b, RKISP1_CIF_ISP_AWB_GAIN_G);
-
-       rkisp1_write(params->rkisp1,
-                    RKISP1_CIF_ISP_AWB_GAIN_R_SET(arg->gain_red) |
-                    arg->gain_blue, RKISP1_CIF_ISP_AWB_GAIN_RB);
-}
-
-static void rkisp1_aec_config(struct rkisp1_params *params,
-                             const struct rkisp1_cif_isp_aec_config *arg)
-{
-       unsigned int block_hsize, block_vsize;
-       u32 exp_ctrl;
-
-       /* avoid to override the old enable value */
-       exp_ctrl = rkisp1_read(params->rkisp1, RKISP1_CIF_ISP_EXP_CTRL);
-       exp_ctrl &= RKISP1_CIF_ISP_EXP_ENA;
-       if (arg->autostop)
-               exp_ctrl |= RKISP1_CIF_ISP_EXP_CTRL_AUTOSTOP;
-       if (arg->mode == RKISP1_CIF_ISP_EXP_MEASURING_MODE_1)
-               exp_ctrl |= RKISP1_CIF_ISP_EXP_CTRL_MEASMODE_1;
-       rkisp1_write(params->rkisp1, exp_ctrl, RKISP1_CIF_ISP_EXP_CTRL);
-
-       rkisp1_write(params->rkisp1,
-                    arg->meas_window.h_offs, RKISP1_CIF_ISP_EXP_H_OFFSET);
-       rkisp1_write(params->rkisp1,
-                    arg->meas_window.v_offs, RKISP1_CIF_ISP_EXP_V_OFFSET);
-
-       block_hsize = arg->meas_window.h_size /
-                     RKISP1_CIF_ISP_EXP_COLUMN_NUM - 1;
-       block_vsize = arg->meas_window.v_size /
-                     RKISP1_CIF_ISP_EXP_ROW_NUM - 1;
-
-       rkisp1_write(params->rkisp1,
-                    RKISP1_CIF_ISP_EXP_H_SIZE_SET(block_hsize),
-                    RKISP1_CIF_ISP_EXP_H_SIZE);
-       rkisp1_write(params->rkisp1,
-                    RKISP1_CIF_ISP_EXP_V_SIZE_SET(block_vsize),
-                    RKISP1_CIF_ISP_EXP_V_SIZE);
-}
-
-static void rkisp1_cproc_config(struct rkisp1_params *params,
-                               const struct rkisp1_cif_isp_cproc_config *arg)
-{
-       struct rkisp1_cif_isp_isp_other_cfg *cur_other_cfg =
-               container_of(arg, struct rkisp1_cif_isp_isp_other_cfg, cproc_config);
-       struct rkisp1_cif_isp_ie_config *cur_ie_config =
-                                               &cur_other_cfg->ie_config;
-       u32 effect = cur_ie_config->effect;
-       u32 quantization = params->quantization;
-
-       rkisp1_write(params->rkisp1, arg->contrast, RKISP1_CIF_C_PROC_CONTRAST);
-       rkisp1_write(params->rkisp1, arg->hue, RKISP1_CIF_C_PROC_HUE);
-       rkisp1_write(params->rkisp1, arg->sat, RKISP1_CIF_C_PROC_SATURATION);
-       rkisp1_write(params->rkisp1, arg->brightness,
-                    RKISP1_CIF_C_PROC_BRIGHTNESS);
-
-       if (quantization != V4L2_QUANTIZATION_FULL_RANGE ||
-           effect != V4L2_COLORFX_NONE) {
-               rkisp1_param_clear_bits(params, RKISP1_CIF_C_PROC_CTRL,
-                                       RKISP1_CIF_C_PROC_YOUT_FULL |
-                                       RKISP1_CIF_C_PROC_YIN_FULL |
-                                       RKISP1_CIF_C_PROC_COUT_FULL);
-       } else {
-               rkisp1_param_set_bits(params, RKISP1_CIF_C_PROC_CTRL,
-                                     RKISP1_CIF_C_PROC_YOUT_FULL |
-                                     RKISP1_CIF_C_PROC_YIN_FULL |
-                                     RKISP1_CIF_C_PROC_COUT_FULL);
-       }
-}
-
-static void rkisp1_hst_config(struct rkisp1_params *params,
-                             const struct rkisp1_cif_isp_hst_config *arg)
-{
-       unsigned int block_hsize, block_vsize;
-       static const u32 hist_weight_regs[] = {
-               RKISP1_CIF_ISP_HIST_WEIGHT_00TO30,
-               RKISP1_CIF_ISP_HIST_WEIGHT_40TO21,
-               RKISP1_CIF_ISP_HIST_WEIGHT_31TO12,
-               RKISP1_CIF_ISP_HIST_WEIGHT_22TO03,
-               RKISP1_CIF_ISP_HIST_WEIGHT_13TO43,
-               RKISP1_CIF_ISP_HIST_WEIGHT_04TO34,
-               RKISP1_CIF_ISP_HIST_WEIGHT_44,
-       };
-       const u8 *weight;
-       unsigned int i;
-       u32 hist_prop;
-
-       /* avoid to override the old enable value */
-       hist_prop = rkisp1_read(params->rkisp1, RKISP1_CIF_ISP_HIST_PROP);
-       hist_prop &= RKISP1_CIF_ISP_HIST_PROP_MODE_MASK;
-       hist_prop |= RKISP1_CIF_ISP_HIST_PREDIV_SET(arg->histogram_predivider);
-       rkisp1_write(params->rkisp1, hist_prop, RKISP1_CIF_ISP_HIST_PROP);
-       rkisp1_write(params->rkisp1,
-                    arg->meas_window.h_offs,
-                    RKISP1_CIF_ISP_HIST_H_OFFS);
-       rkisp1_write(params->rkisp1,
-                    arg->meas_window.v_offs,
-                    RKISP1_CIF_ISP_HIST_V_OFFS);
-
-       block_hsize = arg->meas_window.h_size /
-                     RKISP1_CIF_ISP_HIST_COLUMN_NUM - 1;
-       block_vsize = arg->meas_window.v_size / RKISP1_CIF_ISP_HIST_ROW_NUM - 1;
-
-       rkisp1_write(params->rkisp1, block_hsize, RKISP1_CIF_ISP_HIST_H_SIZE);
-       rkisp1_write(params->rkisp1, block_vsize, RKISP1_CIF_ISP_HIST_V_SIZE);
-
-       weight = arg->hist_weight;
-       for (i = 0; i < ARRAY_SIZE(hist_weight_regs); ++i, weight += 4)
-               rkisp1_write(params->rkisp1,
-                            RKISP1_CIF_ISP_HIST_WEIGHT_SET(weight[0],
-                                                           weight[1],
-                                                           weight[2],
-                                                           weight[3]),
-                                hist_weight_regs[i]);
-}
-
-static void
-rkisp1_hst_enable(struct rkisp1_params *params,
-                 const struct rkisp1_cif_isp_hst_config *arg, bool en)
-{
-       if (en) {
-               u32 hist_prop = rkisp1_read(params->rkisp1,
-                                           RKISP1_CIF_ISP_HIST_PROP);
-
-               hist_prop &= ~RKISP1_CIF_ISP_HIST_PROP_MODE_MASK;
-               hist_prop |= arg->mode;
-               rkisp1_param_set_bits(params, RKISP1_CIF_ISP_HIST_PROP,
-                                     hist_prop);
-       } else {
-               rkisp1_param_clear_bits(params, RKISP1_CIF_ISP_HIST_PROP,
-                                       RKISP1_CIF_ISP_HIST_PROP_MODE_MASK);
-       }
-}
-
-static void rkisp1_afm_config(struct rkisp1_params *params,
-                             const struct rkisp1_cif_isp_afc_config *arg)
-{
-       size_t num_of_win = min_t(size_t, ARRAY_SIZE(arg->afm_win),
-                                 arg->num_afm_win);
-       u32 afm_ctrl = rkisp1_read(params->rkisp1, RKISP1_CIF_ISP_AFM_CTRL);
-       unsigned int i;
-
-       /* Switch off to configure. */
-       rkisp1_param_clear_bits(params, RKISP1_CIF_ISP_AFM_CTRL,
-                               RKISP1_CIF_ISP_AFM_ENA);
-
-       for (i = 0; i < num_of_win; i++) {
-               rkisp1_write(params->rkisp1,
-                            RKISP1_CIF_ISP_AFM_WINDOW_X(arg->afm_win[i].h_offs) |
-                            RKISP1_CIF_ISP_AFM_WINDOW_Y(arg->afm_win[i].v_offs),
-                            RKISP1_CIF_ISP_AFM_LT_A + i * 8);
-               rkisp1_write(params->rkisp1,
-                            RKISP1_CIF_ISP_AFM_WINDOW_X(arg->afm_win[i].h_size +
-                                                        arg->afm_win[i].h_offs) |
-                            RKISP1_CIF_ISP_AFM_WINDOW_Y(arg->afm_win[i].v_size +
-                                                        arg->afm_win[i].v_offs),
-                            RKISP1_CIF_ISP_AFM_RB_A + i * 8);
-       }
-       rkisp1_write(params->rkisp1, arg->thres, RKISP1_CIF_ISP_AFM_THRES);
-       rkisp1_write(params->rkisp1, arg->var_shift,
-                    RKISP1_CIF_ISP_AFM_VAR_SHIFT);
-       /* restore afm status */
-       rkisp1_write(params->rkisp1, afm_ctrl, RKISP1_CIF_ISP_AFM_CTRL);
-}
-
-static void rkisp1_ie_config(struct rkisp1_params *params,
-                            const struct rkisp1_cif_isp_ie_config *arg)
-{
-       u32 eff_ctrl;
-
-       eff_ctrl = rkisp1_read(params->rkisp1, RKISP1_CIF_IMG_EFF_CTRL);
-       eff_ctrl &= ~RKISP1_CIF_IMG_EFF_CTRL_MODE_MASK;
-
-       if (params->quantization == V4L2_QUANTIZATION_FULL_RANGE)
-               eff_ctrl |= RKISP1_CIF_IMG_EFF_CTRL_YCBCR_FULL;
-
-       switch (arg->effect) {
-       case V4L2_COLORFX_SEPIA:
-               eff_ctrl |= RKISP1_CIF_IMG_EFF_CTRL_MODE_SEPIA;
-               break;
-       case V4L2_COLORFX_SET_CBCR:
-               rkisp1_write(params->rkisp1, arg->eff_tint,
-                            RKISP1_CIF_IMG_EFF_TINT);
-               eff_ctrl |= RKISP1_CIF_IMG_EFF_CTRL_MODE_SEPIA;
-               break;
-               /*
-                * Color selection is similar to water color(AQUA):
-                * grayscale + selected color w threshold
-                */
-       case V4L2_COLORFX_AQUA:
-               eff_ctrl |= RKISP1_CIF_IMG_EFF_CTRL_MODE_COLOR_SEL;
-               rkisp1_write(params->rkisp1, arg->color_sel,
-                            RKISP1_CIF_IMG_EFF_COLOR_SEL);
-               break;
-       case V4L2_COLORFX_EMBOSS:
-               eff_ctrl |= RKISP1_CIF_IMG_EFF_CTRL_MODE_EMBOSS;
-               rkisp1_write(params->rkisp1, arg->eff_mat_1,
-                            RKISP1_CIF_IMG_EFF_MAT_1);
-               rkisp1_write(params->rkisp1, arg->eff_mat_2,
-                            RKISP1_CIF_IMG_EFF_MAT_2);
-               rkisp1_write(params->rkisp1, arg->eff_mat_3,
-                            RKISP1_CIF_IMG_EFF_MAT_3);
-               break;
-       case V4L2_COLORFX_SKETCH:
-               eff_ctrl |= RKISP1_CIF_IMG_EFF_CTRL_MODE_SKETCH;
-               rkisp1_write(params->rkisp1, arg->eff_mat_3,
-                            RKISP1_CIF_IMG_EFF_MAT_3);
-               rkisp1_write(params->rkisp1, arg->eff_mat_4,
-                            RKISP1_CIF_IMG_EFF_MAT_4);
-               rkisp1_write(params->rkisp1, arg->eff_mat_5,
-                            RKISP1_CIF_IMG_EFF_MAT_5);
-               break;
-       case V4L2_COLORFX_BW:
-               eff_ctrl |= RKISP1_CIF_IMG_EFF_CTRL_MODE_BLACKWHITE;
-               break;
-       case V4L2_COLORFX_NEGATIVE:
-               eff_ctrl |= RKISP1_CIF_IMG_EFF_CTRL_MODE_NEGATIVE;
-               break;
-       default:
-               break;
-       }
-
-       rkisp1_write(params->rkisp1, eff_ctrl, RKISP1_CIF_IMG_EFF_CTRL);
-}
-
-static void rkisp1_ie_enable(struct rkisp1_params *params, bool en)
-{
-       if (en) {
-               rkisp1_param_set_bits(params, RKISP1_CIF_ICCL,
-                                     RKISP1_CIF_ICCL_IE_CLK);
-               rkisp1_write(params->rkisp1, RKISP1_CIF_IMG_EFF_CTRL_ENABLE,
-                            RKISP1_CIF_IMG_EFF_CTRL);
-               rkisp1_param_set_bits(params, RKISP1_CIF_IMG_EFF_CTRL,
-                                     RKISP1_CIF_IMG_EFF_CTRL_CFG_UPD);
-       } else {
-               rkisp1_param_clear_bits(params, RKISP1_CIF_IMG_EFF_CTRL,
-                                       RKISP1_CIF_IMG_EFF_CTRL_ENABLE);
-               rkisp1_param_clear_bits(params, RKISP1_CIF_ICCL,
-                                       RKISP1_CIF_ICCL_IE_CLK);
-       }
-}
-
-static void rkisp1_csm_config(struct rkisp1_params *params, bool full_range)
-{
-       static const u16 full_range_coeff[] = {
-               0x0026, 0x004b, 0x000f,
-               0x01ea, 0x01d6, 0x0040,
-               0x0040, 0x01ca, 0x01f6
-       };
-       static const u16 limited_range_coeff[] = {
-               0x0021, 0x0040, 0x000d,
-               0x01ed, 0x01db, 0x0038,
-               0x0038, 0x01d1, 0x01f7,
-       };
-       unsigned int i;
-
-       if (full_range) {
-               for (i = 0; i < ARRAY_SIZE(full_range_coeff); i++)
-                       rkisp1_write(params->rkisp1, full_range_coeff[i],
-                                    RKISP1_CIF_ISP_CC_COEFF_0 + i * 4);
-
-               rkisp1_param_set_bits(params, RKISP1_CIF_ISP_CTRL,
-                                     RKISP1_CIF_ISP_CTRL_ISP_CSM_Y_FULL_ENA |
-                                     RKISP1_CIF_ISP_CTRL_ISP_CSM_C_FULL_ENA);
-       } else {
-               for (i = 0; i < ARRAY_SIZE(limited_range_coeff); i++)
-                       rkisp1_write(params->rkisp1, limited_range_coeff[i],
-                                    RKISP1_CIF_ISP_CC_COEFF_0 + i * 4);
-
-               rkisp1_param_clear_bits(params, RKISP1_CIF_ISP_CTRL,
-                                       RKISP1_CIF_ISP_CTRL_ISP_CSM_Y_FULL_ENA |
-                                       RKISP1_CIF_ISP_CTRL_ISP_CSM_C_FULL_ENA);
-       }
-}
-
-/* ISP De-noise Pre-Filter(DPF) function */
-static void rkisp1_dpf_config(struct rkisp1_params *params,
-                             const struct rkisp1_cif_isp_dpf_config *arg)
-{
-       unsigned int isp_dpf_mode, spatial_coeff, i;
-
-       switch (arg->gain.mode) {
-       case RKISP1_CIF_ISP_DPF_GAIN_USAGE_NF_GAINS:
-               isp_dpf_mode = RKISP1_CIF_ISP_DPF_MODE_USE_NF_GAIN |
-                              RKISP1_CIF_ISP_DPF_MODE_AWB_GAIN_COMP;
-               break;
-       case RKISP1_CIF_ISP_DPF_GAIN_USAGE_LSC_GAINS:
-               isp_dpf_mode = RKISP1_CIF_ISP_DPF_MODE_LSC_GAIN_COMP;
-               break;
-       case RKISP1_CIF_ISP_DPF_GAIN_USAGE_NF_LSC_GAINS:
-               isp_dpf_mode = RKISP1_CIF_ISP_DPF_MODE_USE_NF_GAIN |
-                              RKISP1_CIF_ISP_DPF_MODE_AWB_GAIN_COMP |
-                              RKISP1_CIF_ISP_DPF_MODE_LSC_GAIN_COMP;
-               break;
-       case RKISP1_CIF_ISP_DPF_GAIN_USAGE_AWB_GAINS:
-               isp_dpf_mode = RKISP1_CIF_ISP_DPF_MODE_AWB_GAIN_COMP;
-               break;
-       case RKISP1_CIF_ISP_DPF_GAIN_USAGE_AWB_LSC_GAINS:
-               isp_dpf_mode = RKISP1_CIF_ISP_DPF_MODE_LSC_GAIN_COMP |
-                              RKISP1_CIF_ISP_DPF_MODE_AWB_GAIN_COMP;
-               break;
-       case RKISP1_CIF_ISP_DPF_GAIN_USAGE_DISABLED:
-       default:
-               isp_dpf_mode = 0;
-               break;
-       }
-
-       if (arg->nll.scale_mode == RKISP1_CIF_ISP_NLL_SCALE_LOGARITHMIC)
-               isp_dpf_mode |= RKISP1_CIF_ISP_DPF_MODE_NLL_SEGMENTATION;
-       if (arg->rb_flt.fltsize == RKISP1_CIF_ISP_DPF_RB_FILTERSIZE_9x9)
-               isp_dpf_mode |= RKISP1_CIF_ISP_DPF_MODE_RB_FLTSIZE_9x9;
-       if (!arg->rb_flt.r_enable)
-               isp_dpf_mode |= RKISP1_CIF_ISP_DPF_MODE_R_FLT_DIS;
-       if (!arg->rb_flt.b_enable)
-               isp_dpf_mode |= RKISP1_CIF_ISP_DPF_MODE_B_FLT_DIS;
-       if (!arg->g_flt.gb_enable)
-               isp_dpf_mode |= RKISP1_CIF_ISP_DPF_MODE_GB_FLT_DIS;
-       if (!arg->g_flt.gr_enable)
-               isp_dpf_mode |= RKISP1_CIF_ISP_DPF_MODE_GR_FLT_DIS;
-
-       rkisp1_param_set_bits(params, RKISP1_CIF_ISP_DPF_MODE,
-                             isp_dpf_mode);
-       rkisp1_write(params->rkisp1, arg->gain.nf_b_gain,
-                    RKISP1_CIF_ISP_DPF_NF_GAIN_B);
-       rkisp1_write(params->rkisp1, arg->gain.nf_r_gain,
-                    RKISP1_CIF_ISP_DPF_NF_GAIN_R);
-       rkisp1_write(params->rkisp1, arg->gain.nf_gb_gain,
-                    RKISP1_CIF_ISP_DPF_NF_GAIN_GB);
-       rkisp1_write(params->rkisp1, arg->gain.nf_gr_gain,
-                    RKISP1_CIF_ISP_DPF_NF_GAIN_GR);
-
-       for (i = 0; i < RKISP1_CIF_ISP_DPF_MAX_NLF_COEFFS; i++) {
-               rkisp1_write(params->rkisp1, arg->nll.coeff[i],
-                            RKISP1_CIF_ISP_DPF_NULL_COEFF_0 + i * 4);
-       }
-
-       spatial_coeff = arg->g_flt.spatial_coeff[0] |
-                       (arg->g_flt.spatial_coeff[1] << 8) |
-                       (arg->g_flt.spatial_coeff[2] << 16) |
-                       (arg->g_flt.spatial_coeff[3] << 24);
-       rkisp1_write(params->rkisp1, spatial_coeff,
-                    RKISP1_CIF_ISP_DPF_S_WEIGHT_G_1_4);
-
-       spatial_coeff = arg->g_flt.spatial_coeff[4] |
-                       (arg->g_flt.spatial_coeff[5] << 8);
-       rkisp1_write(params->rkisp1, spatial_coeff,
-                    RKISP1_CIF_ISP_DPF_S_WEIGHT_G_5_6);
-
-       spatial_coeff = arg->rb_flt.spatial_coeff[0] |
-                       (arg->rb_flt.spatial_coeff[1] << 8) |
-                       (arg->rb_flt.spatial_coeff[2] << 16) |
-                       (arg->rb_flt.spatial_coeff[3] << 24);
-       rkisp1_write(params->rkisp1, spatial_coeff,
-                    RKISP1_CIF_ISP_DPF_S_WEIGHT_RB_1_4);
-
-       spatial_coeff = arg->rb_flt.spatial_coeff[4] |
-                       (arg->rb_flt.spatial_coeff[5] << 8);
-       rkisp1_write(params->rkisp1, spatial_coeff,
-                    RKISP1_CIF_ISP_DPF_S_WEIGHT_RB_5_6);
-}
-
-static void
-rkisp1_dpf_strength_config(struct rkisp1_params *params,
-                          const struct rkisp1_cif_isp_dpf_strength_config *arg)
-{
-       rkisp1_write(params->rkisp1, arg->b, RKISP1_CIF_ISP_DPF_STRENGTH_B);
-       rkisp1_write(params->rkisp1, arg->g, RKISP1_CIF_ISP_DPF_STRENGTH_G);
-       rkisp1_write(params->rkisp1, arg->r, RKISP1_CIF_ISP_DPF_STRENGTH_R);
-}
-
-static void
-rkisp1_isp_isr_other_config(struct rkisp1_params *params,
-                           const struct rkisp1_params_cfg *new_params)
-{
-       unsigned int module_en_update, module_cfg_update, module_ens;
-
-       module_en_update = new_params->module_en_update;
-       module_cfg_update = new_params->module_cfg_update;
-       module_ens = new_params->module_ens;
-
-       if ((module_en_update & RKISP1_CIF_ISP_MODULE_DPCC) ||
-           (module_cfg_update & RKISP1_CIF_ISP_MODULE_DPCC)) {
-               /*update dpc config */
-               if ((module_cfg_update & RKISP1_CIF_ISP_MODULE_DPCC))
-                       rkisp1_dpcc_config(params,
-                                          &new_params->others.dpcc_config);
-
-               if (module_en_update & RKISP1_CIF_ISP_MODULE_DPCC) {
-                       if (!!(module_ens & RKISP1_CIF_ISP_MODULE_DPCC))
-                               rkisp1_param_set_bits(params,
-                                                     RKISP1_CIF_ISP_DPCC_MODE,
-                                                     RKISP1_CIF_ISP_DPCC_ENA);
-                       else
-                               rkisp1_param_clear_bits(params,
-                                               RKISP1_CIF_ISP_DPCC_MODE,
-                                               RKISP1_CIF_ISP_DPCC_ENA);
-               }
-       }
-
-       if ((module_en_update & RKISP1_CIF_ISP_MODULE_BLS) ||
-           (module_cfg_update & RKISP1_CIF_ISP_MODULE_BLS)) {
-               /* update bls config */
-               if ((module_cfg_update & RKISP1_CIF_ISP_MODULE_BLS))
-                       rkisp1_bls_config(params,
-                                         &new_params->others.bls_config);
-
-               if (module_en_update & RKISP1_CIF_ISP_MODULE_BLS) {
-                       if (!!(module_ens & RKISP1_CIF_ISP_MODULE_BLS))
-                               rkisp1_param_set_bits(params,
-                                                     RKISP1_CIF_ISP_BLS_CTRL,
-                                                     RKISP1_CIF_ISP_BLS_ENA);
-                       else
-                               rkisp1_param_clear_bits(params,
-                                                       RKISP1_CIF_ISP_BLS_CTRL,
-                                                       RKISP1_CIF_ISP_BLS_ENA);
-               }
-       }
-
-       if ((module_en_update & RKISP1_CIF_ISP_MODULE_SDG) ||
-           (module_cfg_update & RKISP1_CIF_ISP_MODULE_SDG)) {
-               /* update sdg config */
-               if ((module_cfg_update & RKISP1_CIF_ISP_MODULE_SDG))
-                       rkisp1_sdg_config(params,
-                                         &new_params->others.sdg_config);
-
-               if (module_en_update & RKISP1_CIF_ISP_MODULE_SDG) {
-                       if (!!(module_ens & RKISP1_CIF_ISP_MODULE_SDG))
-                               rkisp1_param_set_bits(params,
-                                       RKISP1_CIF_ISP_CTRL,
-                                       RKISP1_CIF_ISP_CTRL_ISP_GAMMA_IN_ENA);
-                       else
-                               rkisp1_param_clear_bits(params,
-                                       RKISP1_CIF_ISP_CTRL,
-                                       RKISP1_CIF_ISP_CTRL_ISP_GAMMA_IN_ENA);
-               }
-       }
-
-       if ((module_en_update & RKISP1_CIF_ISP_MODULE_LSC) ||
-           (module_cfg_update & RKISP1_CIF_ISP_MODULE_LSC)) {
-               /* update lsc config */
-               if ((module_cfg_update & RKISP1_CIF_ISP_MODULE_LSC))
-                       rkisp1_lsc_config(params,
-                                         &new_params->others.lsc_config);
-
-               if (module_en_update & RKISP1_CIF_ISP_MODULE_LSC) {
-                       if (!!(module_ens & RKISP1_CIF_ISP_MODULE_LSC))
-                               rkisp1_param_set_bits(params,
-                                               RKISP1_CIF_ISP_LSC_CTRL,
-                                               RKISP1_CIF_ISP_LSC_CTRL_ENA);
-                       else
-                               rkisp1_param_clear_bits(params,
-                                               RKISP1_CIF_ISP_LSC_CTRL,
-                                               RKISP1_CIF_ISP_LSC_CTRL_ENA);
-               }
-       }
-
-       if ((module_en_update & RKISP1_CIF_ISP_MODULE_AWB_GAIN) ||
-           (module_cfg_update & RKISP1_CIF_ISP_MODULE_AWB_GAIN)) {
-               /* update awb gains */
-               if ((module_cfg_update & RKISP1_CIF_ISP_MODULE_AWB_GAIN))
-                       rkisp1_awb_gain_config(params,
-                                       &new_params->others.awb_gain_config);
-
-               if (module_en_update & RKISP1_CIF_ISP_MODULE_AWB_GAIN) {
-                       if (!!(module_ens & RKISP1_CIF_ISP_MODULE_AWB_GAIN))
-                               rkisp1_param_set_bits(params,
-                                       RKISP1_CIF_ISP_CTRL,
-                                       RKISP1_CIF_ISP_CTRL_ISP_AWB_ENA);
-                       else
-                               rkisp1_param_clear_bits(params,
-                                       RKISP1_CIF_ISP_CTRL,
-                                       RKISP1_CIF_ISP_CTRL_ISP_AWB_ENA);
-               }
-       }
-
-       if ((module_en_update & RKISP1_CIF_ISP_MODULE_BDM) ||
-           (module_cfg_update & RKISP1_CIF_ISP_MODULE_BDM)) {
-               /* update bdm config */
-               if ((module_cfg_update & RKISP1_CIF_ISP_MODULE_BDM))
-                       rkisp1_bdm_config(params,
-                                         &new_params->others.bdm_config);
-
-               if (module_en_update & RKISP1_CIF_ISP_MODULE_BDM) {
-                       if (!!(module_ens & RKISP1_CIF_ISP_MODULE_BDM))
-                               rkisp1_param_set_bits(params,
-                                               RKISP1_CIF_ISP_DEMOSAIC,
-                                               RKISP1_CIF_ISP_DEMOSAIC_BYPASS);
-                       else
-                               rkisp1_param_clear_bits(params,
-                                               RKISP1_CIF_ISP_DEMOSAIC,
-                                               RKISP1_CIF_ISP_DEMOSAIC_BYPASS);
-               }
-       }
-
-       if ((module_en_update & RKISP1_CIF_ISP_MODULE_FLT) ||
-           (module_cfg_update & RKISP1_CIF_ISP_MODULE_FLT)) {
-               /* update filter config */
-               if ((module_cfg_update & RKISP1_CIF_ISP_MODULE_FLT))
-                       rkisp1_flt_config(params,
-                                         &new_params->others.flt_config);
-
-               if (module_en_update & RKISP1_CIF_ISP_MODULE_FLT) {
-                       if (!!(module_ens & RKISP1_CIF_ISP_MODULE_FLT))
-                               rkisp1_param_set_bits(params,
-                                                     RKISP1_CIF_ISP_FILT_MODE,
-                                                     RKISP1_CIF_ISP_FLT_ENA);
-                       else
-                               rkisp1_param_clear_bits(params,
-                                               RKISP1_CIF_ISP_FILT_MODE,
-                                               RKISP1_CIF_ISP_FLT_ENA);
-               }
-       }
-
-       if ((module_en_update & RKISP1_CIF_ISP_MODULE_CTK) ||
-           (module_cfg_update & RKISP1_CIF_ISP_MODULE_CTK)) {
-               /* update ctk config */
-               if ((module_cfg_update & RKISP1_CIF_ISP_MODULE_CTK))
-                       rkisp1_ctk_config(params,
-                                         &new_params->others.ctk_config);
-
-               if (module_en_update & RKISP1_CIF_ISP_MODULE_CTK)
-                       rkisp1_ctk_enable(params,
-                               !!(module_ens & RKISP1_CIF_ISP_MODULE_CTK));
-       }
-
-       if ((module_en_update & RKISP1_CIF_ISP_MODULE_GOC) ||
-           (module_cfg_update & RKISP1_CIF_ISP_MODULE_GOC)) {
-               /* update goc config */
-               if ((module_cfg_update & RKISP1_CIF_ISP_MODULE_GOC))
-                       rkisp1_goc_config(params,
-                                         &new_params->others.goc_config);
-
-               if (module_en_update & RKISP1_CIF_ISP_MODULE_GOC) {
-                       if (!!(module_ens & RKISP1_CIF_ISP_MODULE_GOC))
-                               rkisp1_param_set_bits(params,
-                                       RKISP1_CIF_ISP_CTRL,
-                                       RKISP1_CIF_ISP_CTRL_ISP_GAMMA_OUT_ENA);
-                       else
-                               rkisp1_param_clear_bits(params,
-                                       RKISP1_CIF_ISP_CTRL,
-                                       RKISP1_CIF_ISP_CTRL_ISP_GAMMA_OUT_ENA);
-               }
-       }
-
-       if ((module_en_update & RKISP1_CIF_ISP_MODULE_CPROC) ||
-           (module_cfg_update & RKISP1_CIF_ISP_MODULE_CPROC)) {
-               /* update cproc config */
-               if ((module_cfg_update & RKISP1_CIF_ISP_MODULE_CPROC)) {
-                       rkisp1_cproc_config(params,
-                                           &new_params->others.cproc_config);
-               }
-
-               if (module_en_update & RKISP1_CIF_ISP_MODULE_CPROC) {
-                       if (!!(module_ens & RKISP1_CIF_ISP_MODULE_CPROC))
-                               rkisp1_param_set_bits(params,
-                                               RKISP1_CIF_C_PROC_CTRL,
-                                               RKISP1_CIF_C_PROC_CTR_ENABLE);
-                       else
-                               rkisp1_param_clear_bits(params,
-                                               RKISP1_CIF_C_PROC_CTRL,
-                                               RKISP1_CIF_C_PROC_CTR_ENABLE);
-               }
-       }
-
-       if ((module_en_update & RKISP1_CIF_ISP_MODULE_IE) ||
-           (module_cfg_update & RKISP1_CIF_ISP_MODULE_IE)) {
-               /* update ie config */
-               if ((module_cfg_update & RKISP1_CIF_ISP_MODULE_IE))
-                       rkisp1_ie_config(params,
-                                        &new_params->others.ie_config);
-
-               if (module_en_update & RKISP1_CIF_ISP_MODULE_IE)
-                       rkisp1_ie_enable(params,
-                               !!(module_ens & RKISP1_CIF_ISP_MODULE_IE));
-       }
-
-       if ((module_en_update & RKISP1_CIF_ISP_MODULE_DPF) ||
-           (module_cfg_update & RKISP1_CIF_ISP_MODULE_DPF)) {
-               /* update dpf  config */
-               if ((module_cfg_update & RKISP1_CIF_ISP_MODULE_DPF))
-                       rkisp1_dpf_config(params,
-                                         &new_params->others.dpf_config);
-
-               if (module_en_update & RKISP1_CIF_ISP_MODULE_DPF) {
-                       if (!!(module_ens & RKISP1_CIF_ISP_MODULE_DPF))
-                               rkisp1_param_set_bits(params,
-                                                  RKISP1_CIF_ISP_DPF_MODE,
-                                                  RKISP1_CIF_ISP_DPF_MODE_EN);
-                       else
-                               rkisp1_param_clear_bits(params,
-                                               RKISP1_CIF_ISP_DPF_MODE,
-                                               RKISP1_CIF_ISP_DPF_MODE_EN);
-               }
-       }
-
-       if ((module_en_update & RKISP1_CIF_ISP_MODULE_DPF_STRENGTH) ||
-           (module_cfg_update & RKISP1_CIF_ISP_MODULE_DPF_STRENGTH)) {
-               /* update dpf strength config */
-               rkisp1_dpf_strength_config(params,
-                               &new_params->others.dpf_strength_config);
-       }
-}
-
-static void rkisp1_isp_isr_meas_config(struct rkisp1_params *params,
-                                      struct  rkisp1_params_cfg *new_params)
-{
-       unsigned int module_en_update, module_cfg_update, module_ens;
-
-       module_en_update = new_params->module_en_update;
-       module_cfg_update = new_params->module_cfg_update;
-       module_ens = new_params->module_ens;
-
-       if ((module_en_update & RKISP1_CIF_ISP_MODULE_AWB) ||
-           (module_cfg_update & RKISP1_CIF_ISP_MODULE_AWB)) {
-               /* update awb config */
-               if ((module_cfg_update & RKISP1_CIF_ISP_MODULE_AWB))
-                       rkisp1_awb_meas_config(params,
-                                       &new_params->meas.awb_meas_config);
-
-               if (module_en_update & RKISP1_CIF_ISP_MODULE_AWB)
-                       rkisp1_awb_meas_enable(params,
-                               &new_params->meas.awb_meas_config,
-                               !!(module_ens & RKISP1_CIF_ISP_MODULE_AWB));
-       }
-
-       if ((module_en_update & RKISP1_CIF_ISP_MODULE_AFC) ||
-           (module_cfg_update & RKISP1_CIF_ISP_MODULE_AFC)) {
-               /* update afc config */
-               if ((module_cfg_update & RKISP1_CIF_ISP_MODULE_AFC))
-                       rkisp1_afm_config(params,
-                                         &new_params->meas.afc_config);
-
-               if (module_en_update & RKISP1_CIF_ISP_MODULE_AFC) {
-                       if (!!(module_ens & RKISP1_CIF_ISP_MODULE_AFC))
-                               rkisp1_param_set_bits(params,
-                                                     RKISP1_CIF_ISP_AFM_CTRL,
-                                                     RKISP1_CIF_ISP_AFM_ENA);
-                       else
-                               rkisp1_param_clear_bits(params,
-                                                       RKISP1_CIF_ISP_AFM_CTRL,
-                                                       RKISP1_CIF_ISP_AFM_ENA);
-               }
-       }
-
-       if ((module_en_update & RKISP1_CIF_ISP_MODULE_HST) ||
-           (module_cfg_update & RKISP1_CIF_ISP_MODULE_HST)) {
-               /* update hst config */
-               if ((module_cfg_update & RKISP1_CIF_ISP_MODULE_HST))
-                       rkisp1_hst_config(params,
-                                         &new_params->meas.hst_config);
-
-               if (module_en_update & RKISP1_CIF_ISP_MODULE_HST)
-                       rkisp1_hst_enable(params,
-                               &new_params->meas.hst_config,
-                               !!(module_ens & RKISP1_CIF_ISP_MODULE_HST));
-       }
-
-       if ((module_en_update & RKISP1_CIF_ISP_MODULE_AEC) ||
-           (module_cfg_update & RKISP1_CIF_ISP_MODULE_AEC)) {
-               /* update aec config */
-               if ((module_cfg_update & RKISP1_CIF_ISP_MODULE_AEC))
-                       rkisp1_aec_config(params,
-                                         &new_params->meas.aec_config);
-
-               if (module_en_update & RKISP1_CIF_ISP_MODULE_AEC) {
-                       if (!!(module_ens & RKISP1_CIF_ISP_MODULE_AEC))
-                               rkisp1_param_set_bits(params,
-                                                     RKISP1_CIF_ISP_EXP_CTRL,
-                                                     RKISP1_CIF_ISP_EXP_ENA);
-                       else
-                               rkisp1_param_clear_bits(params,
-                                                       RKISP1_CIF_ISP_EXP_CTRL,
-                                                       RKISP1_CIF_ISP_EXP_ENA);
-               }
-       }
-}
-
-static void rkisp1_params_apply_params_cfg(struct rkisp1_params *params,
-                                          unsigned int frame_sequence)
-{
-       struct rkisp1_params_cfg *new_params;
-       struct rkisp1_buffer *cur_buf = NULL;
-
-       if (list_empty(&params->params))
-               return;
-
-       cur_buf = list_first_entry(&params->params,
-                                  struct rkisp1_buffer, queue);
-
-       new_params = (struct rkisp1_params_cfg *)(cur_buf->vaddr);
-
-       rkisp1_isp_isr_other_config(params, new_params);
-       rkisp1_isp_isr_meas_config(params, new_params);
-
-       /* update shadow register immediately */
-       rkisp1_param_set_bits(params, RKISP1_CIF_ISP_CTRL, RKISP1_CIF_ISP_CTRL_ISP_CFG_UPD);
-
-       list_del(&cur_buf->queue);
-
-       cur_buf->vb.sequence = frame_sequence;
-       vb2_buffer_done(&cur_buf->vb.vb2_buf, VB2_BUF_STATE_DONE);
-}
-
-void rkisp1_params_isr(struct rkisp1_device *rkisp1)
-{
-       /*
-        * This isr is called when the ISR finishes processing a frame (RKISP1_CIF_ISP_FRAME).
-        * Configurations performed here will be applied on the next frame.
-        * Since frame_sequence is updated on the vertical sync signal, we should use
-        * frame_sequence + 1 here to indicate to userspace on which frame these parameters
-        * are being applied.
-        */
-       unsigned int frame_sequence = rkisp1->isp.frame_sequence + 1;
-       struct rkisp1_params *params = &rkisp1->params;
-
-       spin_lock(&params->config_lock);
-       if (!params->is_streaming) {
-               spin_unlock(&params->config_lock);
-               return;
-       }
-       rkisp1_params_apply_params_cfg(params, frame_sequence);
-
-       spin_unlock(&params->config_lock);
-}
-
-static const struct rkisp1_cif_isp_awb_meas_config rkisp1_awb_params_default_config = {
-       {
-               0, 0, RKISP1_DEFAULT_WIDTH, RKISP1_DEFAULT_HEIGHT
-       },
-       RKISP1_CIF_ISP_AWB_MODE_YCBCR, 200, 30, 20, 20, 0, 128, 128
-};
-
-static const struct rkisp1_cif_isp_aec_config rkisp1_aec_params_default_config = {
-       RKISP1_CIF_ISP_EXP_MEASURING_MODE_0,
-       RKISP1_CIF_ISP_EXP_CTRL_AUTOSTOP_0,
-       {
-               RKISP1_DEFAULT_WIDTH >> 2, RKISP1_DEFAULT_HEIGHT >> 2,
-               RKISP1_DEFAULT_WIDTH >> 1, RKISP1_DEFAULT_HEIGHT >> 1
-       }
-};
-
-static const struct rkisp1_cif_isp_hst_config rkisp1_hst_params_default_config = {
-       RKISP1_CIF_ISP_HISTOGRAM_MODE_RGB_COMBINED,
-       3,
-       {
-               RKISP1_DEFAULT_WIDTH >> 2, RKISP1_DEFAULT_HEIGHT >> 2,
-               RKISP1_DEFAULT_WIDTH >> 1, RKISP1_DEFAULT_HEIGHT >> 1
-       },
-       {
-               0, /* To be filled in with 0x01 at runtime. */
-       }
-};
-
-static const struct rkisp1_cif_isp_afc_config rkisp1_afc_params_default_config = {
-       1,
-       {
-               {
-                       300, 225, 200, 150
-               }
-       },
-       4,
-       14
-};
-
-static void rkisp1_params_config_parameter(struct rkisp1_params *params)
-{
-       struct rkisp1_cif_isp_hst_config hst = rkisp1_hst_params_default_config;
-
-       rkisp1_awb_meas_config(params, &rkisp1_awb_params_default_config);
-       rkisp1_awb_meas_enable(params, &rkisp1_awb_params_default_config,
-                              true);
-
-       rkisp1_aec_config(params, &rkisp1_aec_params_default_config);
-       rkisp1_param_set_bits(params, RKISP1_CIF_ISP_EXP_CTRL,
-                             RKISP1_CIF_ISP_EXP_ENA);
-
-       rkisp1_afm_config(params, &rkisp1_afc_params_default_config);
-       rkisp1_param_set_bits(params, RKISP1_CIF_ISP_AFM_CTRL,
-                             RKISP1_CIF_ISP_AFM_ENA);
-
-       memset(hst.hist_weight, 0x01, sizeof(hst.hist_weight));
-       rkisp1_hst_config(params, &hst);
-       rkisp1_param_set_bits(params, RKISP1_CIF_ISP_HIST_PROP,
-                             ~RKISP1_CIF_ISP_HIST_PROP_MODE_MASK |
-                             rkisp1_hst_params_default_config.mode);
-
-       /* set the  range */
-       if (params->quantization == V4L2_QUANTIZATION_FULL_RANGE)
-               rkisp1_csm_config(params, true);
-       else
-               rkisp1_csm_config(params, false);
-
-       spin_lock_irq(&params->config_lock);
-
-       /* apply the first buffer if there is one already */
-       if (params->is_streaming)
-               rkisp1_params_apply_params_cfg(params, 0);
-
-       spin_unlock_irq(&params->config_lock);
-}
-
-void rkisp1_params_configure(struct rkisp1_params *params,
-                            enum rkisp1_fmt_raw_pat_type bayer_pat,
-                            enum v4l2_quantization quantization)
-{
-       params->quantization = quantization;
-       params->raw_type = bayer_pat;
-       rkisp1_params_config_parameter(params);
-}
-
-/* Not called when the camera active, thus not isr protection. */
-void rkisp1_params_disable(struct rkisp1_params *params)
-{
-       rkisp1_param_clear_bits(params, RKISP1_CIF_ISP_DPCC_MODE,
-                               RKISP1_CIF_ISP_DPCC_ENA);
-       rkisp1_param_clear_bits(params, RKISP1_CIF_ISP_LSC_CTRL,
-                               RKISP1_CIF_ISP_LSC_CTRL_ENA);
-       rkisp1_param_clear_bits(params, RKISP1_CIF_ISP_BLS_CTRL,
-                               RKISP1_CIF_ISP_BLS_ENA);
-       rkisp1_param_clear_bits(params, RKISP1_CIF_ISP_CTRL,
-                               RKISP1_CIF_ISP_CTRL_ISP_GAMMA_IN_ENA);
-       rkisp1_param_clear_bits(params, RKISP1_CIF_ISP_CTRL,
-                               RKISP1_CIF_ISP_CTRL_ISP_GAMMA_OUT_ENA);
-       rkisp1_param_clear_bits(params, RKISP1_CIF_ISP_DEMOSAIC,
-                               RKISP1_CIF_ISP_DEMOSAIC_BYPASS);
-       rkisp1_param_clear_bits(params, RKISP1_CIF_ISP_FILT_MODE,
-                               RKISP1_CIF_ISP_FLT_ENA);
-       rkisp1_awb_meas_enable(params, NULL, false);
-       rkisp1_param_clear_bits(params, RKISP1_CIF_ISP_CTRL,
-                               RKISP1_CIF_ISP_CTRL_ISP_AWB_ENA);
-       rkisp1_param_clear_bits(params, RKISP1_CIF_ISP_EXP_CTRL,
-                               RKISP1_CIF_ISP_EXP_ENA);
-       rkisp1_ctk_enable(params, false);
-       rkisp1_param_clear_bits(params, RKISP1_CIF_C_PROC_CTRL,
-                               RKISP1_CIF_C_PROC_CTR_ENABLE);
-       rkisp1_hst_enable(params, NULL, false);
-       rkisp1_param_clear_bits(params, RKISP1_CIF_ISP_AFM_CTRL,
-                               RKISP1_CIF_ISP_AFM_ENA);
-       rkisp1_ie_enable(params, false);
-       rkisp1_param_clear_bits(params, RKISP1_CIF_ISP_DPF_MODE,
-                               RKISP1_CIF_ISP_DPF_MODE_EN);
-}
-
-static int rkisp1_params_enum_fmt_meta_out(struct file *file, void *priv,
-                                          struct v4l2_fmtdesc *f)
-{
-       struct video_device *video = video_devdata(file);
-       struct rkisp1_params *params = video_get_drvdata(video);
-
-       if (f->index > 0 || f->type != video->queue->type)
-               return -EINVAL;
-
-       f->pixelformat = params->vdev_fmt.fmt.meta.dataformat;
-
-       return 0;
-}
-
-static int rkisp1_params_g_fmt_meta_out(struct file *file, void *fh,
-                                       struct v4l2_format *f)
-{
-       struct video_device *video = video_devdata(file);
-       struct rkisp1_params *params = video_get_drvdata(video);
-       struct v4l2_meta_format *meta = &f->fmt.meta;
-
-       if (f->type != video->queue->type)
-               return -EINVAL;
-
-       memset(meta, 0, sizeof(*meta));
-       meta->dataformat = params->vdev_fmt.fmt.meta.dataformat;
-       meta->buffersize = params->vdev_fmt.fmt.meta.buffersize;
-
-       return 0;
-}
-
-static int rkisp1_params_querycap(struct file *file,
-                                 void *priv, struct v4l2_capability *cap)
-{
-       struct video_device *vdev = video_devdata(file);
-
-       strscpy(cap->driver, RKISP1_DRIVER_NAME, sizeof(cap->driver));
-       strscpy(cap->card, vdev->name, sizeof(cap->card));
-       strscpy(cap->bus_info, RKISP1_BUS_INFO, sizeof(cap->bus_info));
-
-       return 0;
-}
-
-/* ISP params video device IOCTLs */
-static const struct v4l2_ioctl_ops rkisp1_params_ioctl = {
-       .vidioc_reqbufs = vb2_ioctl_reqbufs,
-       .vidioc_querybuf = vb2_ioctl_querybuf,
-       .vidioc_create_bufs = vb2_ioctl_create_bufs,
-       .vidioc_qbuf = vb2_ioctl_qbuf,
-       .vidioc_dqbuf = vb2_ioctl_dqbuf,
-       .vidioc_prepare_buf = vb2_ioctl_prepare_buf,
-       .vidioc_expbuf = vb2_ioctl_expbuf,
-       .vidioc_streamon = vb2_ioctl_streamon,
-       .vidioc_streamoff = vb2_ioctl_streamoff,
-       .vidioc_enum_fmt_meta_out = rkisp1_params_enum_fmt_meta_out,
-       .vidioc_g_fmt_meta_out = rkisp1_params_g_fmt_meta_out,
-       .vidioc_s_fmt_meta_out = rkisp1_params_g_fmt_meta_out,
-       .vidioc_try_fmt_meta_out = rkisp1_params_g_fmt_meta_out,
-       .vidioc_querycap = rkisp1_params_querycap,
-       .vidioc_subscribe_event = v4l2_ctrl_subscribe_event,
-       .vidioc_unsubscribe_event = v4l2_event_unsubscribe,
-};
-
-static int rkisp1_params_vb2_queue_setup(struct vb2_queue *vq,
-                                        unsigned int *num_buffers,
-                                        unsigned int *num_planes,
-                                        unsigned int sizes[],
-                                        struct device *alloc_devs[])
-{
-       struct rkisp1_params *params = vq->drv_priv;
-
-       *num_buffers = clamp_t(u32, *num_buffers,
-                              RKISP1_ISP_PARAMS_REQ_BUFS_MIN,
-                              RKISP1_ISP_PARAMS_REQ_BUFS_MAX);
-
-       *num_planes = 1;
-
-       sizes[0] = sizeof(struct rkisp1_params_cfg);
-
-       INIT_LIST_HEAD(&params->params);
-       return 0;
-}
-
-static void rkisp1_params_vb2_buf_queue(struct vb2_buffer *vb)
-{
-       struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
-       struct rkisp1_buffer *params_buf =
-               container_of(vbuf, struct rkisp1_buffer, vb);
-       struct vb2_queue *vq = vb->vb2_queue;
-       struct rkisp1_params *params = vq->drv_priv;
-
-       params_buf->vaddr = vb2_plane_vaddr(vb, 0);
-       spin_lock_irq(&params->config_lock);
-       list_add_tail(&params_buf->queue, &params->params);
-       spin_unlock_irq(&params->config_lock);
-}
-
-static int rkisp1_params_vb2_buf_prepare(struct vb2_buffer *vb)
-{
-       if (vb2_plane_size(vb, 0) < sizeof(struct rkisp1_params_cfg))
-               return -EINVAL;
-
-       vb2_set_plane_payload(vb, 0, sizeof(struct rkisp1_params_cfg));
-
-       return 0;
-}
-
-static void rkisp1_params_vb2_stop_streaming(struct vb2_queue *vq)
-{
-       struct rkisp1_params *params = vq->drv_priv;
-       struct rkisp1_buffer *buf;
-       struct list_head tmp_list;
-
-       INIT_LIST_HEAD(&tmp_list);
-
-       /*
-        * we first move the buffers into a local list 'tmp_list'
-        * and then we can iterate it and call vb2_buffer_done
-        * without holding the lock
-        */
-       spin_lock_irq(&params->config_lock);
-       params->is_streaming = false;
-       list_cut_position(&tmp_list, &params->params, params->params.prev);
-       spin_unlock_irq(&params->config_lock);
-
-       list_for_each_entry(buf, &tmp_list, queue)
-               vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_ERROR);
-}
-
-static int
-rkisp1_params_vb2_start_streaming(struct vb2_queue *queue, unsigned int count)
-{
-       struct rkisp1_params *params = queue->drv_priv;
-
-       spin_lock_irq(&params->config_lock);
-       params->is_streaming = true;
-       spin_unlock_irq(&params->config_lock);
-
-       return 0;
-}
-
-static struct vb2_ops rkisp1_params_vb2_ops = {
-       .queue_setup = rkisp1_params_vb2_queue_setup,
-       .wait_prepare = vb2_ops_wait_prepare,
-       .wait_finish = vb2_ops_wait_finish,
-       .buf_queue = rkisp1_params_vb2_buf_queue,
-       .buf_prepare = rkisp1_params_vb2_buf_prepare,
-       .start_streaming = rkisp1_params_vb2_start_streaming,
-       .stop_streaming = rkisp1_params_vb2_stop_streaming,
-
-};
-
-static struct v4l2_file_operations rkisp1_params_fops = {
-       .mmap = vb2_fop_mmap,
-       .unlocked_ioctl = video_ioctl2,
-       .poll = vb2_fop_poll,
-       .open = v4l2_fh_open,
-       .release = vb2_fop_release
-};
-
-static int rkisp1_params_init_vb2_queue(struct vb2_queue *q,
-                                       struct rkisp1_params *params)
-{
-       struct rkisp1_vdev_node *node;
-
-       node = container_of(q, struct rkisp1_vdev_node, buf_queue);
-
-       q->type = V4L2_BUF_TYPE_META_OUTPUT;
-       q->io_modes = VB2_MMAP | VB2_USERPTR | VB2_DMABUF;
-       q->drv_priv = params;
-       q->ops = &rkisp1_params_vb2_ops;
-       q->mem_ops = &vb2_vmalloc_memops;
-       q->buf_struct_size = sizeof(struct rkisp1_buffer);
-       q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
-       q->lock = &node->vlock;
-
-       return vb2_queue_init(q);
-}
-
-static void rkisp1_init_params(struct rkisp1_params *params)
-{
-       params->vdev_fmt.fmt.meta.dataformat =
-               V4L2_META_FMT_RK_ISP1_PARAMS;
-       params->vdev_fmt.fmt.meta.buffersize =
-               sizeof(struct rkisp1_params_cfg);
-}
-
-int rkisp1_params_register(struct rkisp1_device *rkisp1)
-{
-       struct rkisp1_params *params = &rkisp1->params;
-       struct rkisp1_vdev_node *node = &params->vnode;
-       struct video_device *vdev = &node->vdev;
-       int ret;
-
-       params->rkisp1 = rkisp1;
-       mutex_init(&node->vlock);
-       spin_lock_init(&params->config_lock);
-
-       strscpy(vdev->name, RKISP1_PARAMS_DEV_NAME, sizeof(vdev->name));
-
-       video_set_drvdata(vdev, params);
-       vdev->ioctl_ops = &rkisp1_params_ioctl;
-       vdev->fops = &rkisp1_params_fops;
-       vdev->release = video_device_release_empty;
-       /*
-        * Provide a mutex to v4l2 core. It will be used
-        * to protect all fops and v4l2 ioctls.
-        */
-       vdev->lock = &node->vlock;
-       vdev->v4l2_dev = &rkisp1->v4l2_dev;
-       vdev->queue = &node->buf_queue;
-       vdev->device_caps = V4L2_CAP_STREAMING | V4L2_CAP_META_OUTPUT;
-       vdev->vfl_dir = VFL_DIR_TX;
-       rkisp1_params_init_vb2_queue(vdev->queue, params);
-       rkisp1_init_params(params);
-       video_set_drvdata(vdev, params);
-
-       node->pad.flags = MEDIA_PAD_FL_SOURCE;
-       ret = media_entity_pads_init(&vdev->entity, 1, &node->pad);
-       if (ret)
-               return ret;
-       ret = video_register_device(vdev, VFL_TYPE_VIDEO, -1);
-       if (ret) {
-               dev_err(rkisp1->dev,
-                       "failed to register %s, ret=%d\n", vdev->name, ret);
-               goto err_cleanup_media_entity;
-       }
-       return 0;
-err_cleanup_media_entity:
-       media_entity_cleanup(&vdev->entity);
-       return ret;
-}
-
-void rkisp1_params_unregister(struct rkisp1_device *rkisp1)
-{
-       struct rkisp1_params *params = &rkisp1->params;
-       struct rkisp1_vdev_node *node = &params->vnode;
-       struct video_device *vdev = &node->vdev;
-
-       vb2_video_unregister_device(vdev);
-       media_entity_cleanup(&vdev->entity);
-}
diff --git a/drivers/staging/media/rkisp1/rkisp1-regs.h b/drivers/staging/media/rkisp1/rkisp1-regs.h
deleted file mode 100644 (file)
index 049f6c3..0000000
+++ /dev/null
@@ -1,1262 +0,0 @@
-/* SPDX-License-Identifier: (GPL-2.0+ OR MIT) */
-/*
- * Rockchip ISP1 Driver - Registers header
- *
- * Copyright (C) 2017 Rockchip Electronics Co., Ltd.
- */
-
-#ifndef _RKISP1_REGS_H
-#define _RKISP1_REGS_H
-
-/* ISP_CTRL */
-#define RKISP1_CIF_ISP_CTRL_ISP_ENABLE                 BIT(0)
-#define RKISP1_CIF_ISP_CTRL_ISP_MODE_RAW_PICT          (0 << 1)
-#define RKISP1_CIF_ISP_CTRL_ISP_MODE_ITU656            BIT(1)
-#define RKISP1_CIF_ISP_CTRL_ISP_MODE_ITU601            (2 << 1)
-#define RKISP1_CIF_ISP_CTRL_ISP_MODE_BAYER_ITU601      (3 << 1)
-#define RKISP1_CIF_ISP_CTRL_ISP_MODE_DATA_MODE         (4 << 1)
-#define RKISP1_CIF_ISP_CTRL_ISP_MODE_BAYER_ITU656      (5 << 1)
-#define RKISP1_CIF_ISP_CTRL_ISP_MODE_RAW_PICT_ITU656   (6 << 1)
-#define RKISP1_CIF_ISP_CTRL_ISP_INFORM_ENABLE          BIT(4)
-#define RKISP1_CIF_ISP_CTRL_ISP_GAMMA_IN_ENA           BIT(6)
-#define RKISP1_CIF_ISP_CTRL_ISP_AWB_ENA                        BIT(7)
-#define RKISP1_CIF_ISP_CTRL_ISP_CFG_UPD_PERMANENT      BIT(8)
-#define RKISP1_CIF_ISP_CTRL_ISP_CFG_UPD                        BIT(9)
-#define RKISP1_CIF_ISP_CTRL_ISP_GEN_CFG_UPD            BIT(10)
-#define RKISP1_CIF_ISP_CTRL_ISP_GAMMA_OUT_ENA          BIT(11)
-#define RKISP1_CIF_ISP_CTRL_ISP_FLASH_MODE_ENA         BIT(12)
-#define RKISP1_CIF_ISP_CTRL_ISP_CSM_Y_FULL_ENA         BIT(13)
-#define RKISP1_CIF_ISP_CTRL_ISP_CSM_C_FULL_ENA         BIT(14)
-
-/* ISP_ACQ_PROP */
-#define RKISP1_CIF_ISP_ACQ_PROP_POS_EDGE               BIT(0)
-#define RKISP1_CIF_ISP_ACQ_PROP_HSYNC_LOW              BIT(1)
-#define RKISP1_CIF_ISP_ACQ_PROP_VSYNC_LOW              BIT(2)
-#define RKISP1_CIF_ISP_ACQ_PROP_BAYER_PAT_RGGB         (0 << 3)
-#define RKISP1_CIF_ISP_ACQ_PROP_BAYER_PAT_GRBG         BIT(3)
-#define RKISP1_CIF_ISP_ACQ_PROP_BAYER_PAT_GBRG         (2 << 3)
-#define RKISP1_CIF_ISP_ACQ_PROP_BAYER_PAT_BGGR         (3 << 3)
-#define RKISP1_CIF_ISP_ACQ_PROP_BAYER_PAT(pat)         ((pat) << 3)
-#define RKISP1_CIF_ISP_ACQ_PROP_YCBYCR                 (0 << 7)
-#define RKISP1_CIF_ISP_ACQ_PROP_YCRYCB                 BIT(7)
-#define RKISP1_CIF_ISP_ACQ_PROP_CBYCRY                 (2 << 7)
-#define RKISP1_CIF_ISP_ACQ_PROP_CRYCBY                 (3 << 7)
-#define RKISP1_CIF_ISP_ACQ_PROP_FIELD_SEL_ALL          (0 << 9)
-#define RKISP1_CIF_ISP_ACQ_PROP_FIELD_SEL_EVEN         BIT(9)
-#define RKISP1_CIF_ISP_ACQ_PROP_FIELD_SEL_ODD          (2 << 9)
-#define RKISP1_CIF_ISP_ACQ_PROP_IN_SEL_12B             (0 << 12)
-#define RKISP1_CIF_ISP_ACQ_PROP_IN_SEL_10B_ZERO                BIT(12)
-#define RKISP1_CIF_ISP_ACQ_PROP_IN_SEL_10B_MSB         (2 << 12)
-#define RKISP1_CIF_ISP_ACQ_PROP_IN_SEL_8B_ZERO         (3 << 12)
-#define RKISP1_CIF_ISP_ACQ_PROP_IN_SEL_8B_MSB          (4 << 12)
-
-/* VI_DPCL */
-#define RKISP1_CIF_VI_DPCL_DMA_JPEG                    (0 << 0)
-#define RKISP1_CIF_VI_DPCL_MP_MUX_MRSZ_MI              BIT(0)
-#define RKISP1_CIF_VI_DPCL_MP_MUX_MRSZ_JPEG            (2 << 0)
-#define RKISP1_CIF_VI_DPCL_CHAN_MODE_MP                        BIT(2)
-#define RKISP1_CIF_VI_DPCL_CHAN_MODE_SP                        (2 << 2)
-#define RKISP1_CIF_VI_DPCL_CHAN_MODE_MPSP              (3 << 2)
-#define RKISP1_CIF_VI_DPCL_DMA_SW_SPMUX                        (0 << 4)
-#define RKISP1_CIF_VI_DPCL_DMA_SW_SI                   BIT(4)
-#define RKISP1_CIF_VI_DPCL_DMA_SW_IE                   (2 << 4)
-#define RKISP1_CIF_VI_DPCL_DMA_SW_JPEG                 (3 << 4)
-#define RKISP1_CIF_VI_DPCL_DMA_SW_ISP                  (4 << 4)
-#define RKISP1_CIF_VI_DPCL_IF_SEL_PARALLEL             (0 << 8)
-#define RKISP1_CIF_VI_DPCL_IF_SEL_SMIA                 BIT(8)
-#define RKISP1_CIF_VI_DPCL_IF_SEL_MIPI                 (2 << 8)
-#define RKISP1_CIF_VI_DPCL_DMA_IE_MUX_DMA              BIT(10)
-#define RKISP1_CIF_VI_DPCL_DMA_SP_MUX_DMA              BIT(11)
-
-/* ISP_IMSC - ISP_MIS - ISP_RIS - ISP_ICR - ISP_ISR */
-#define RKISP1_CIF_ISP_OFF                             BIT(0)
-#define RKISP1_CIF_ISP_FRAME                           BIT(1)
-#define RKISP1_CIF_ISP_DATA_LOSS                       BIT(2)
-#define RKISP1_CIF_ISP_PIC_SIZE_ERROR                  BIT(3)
-#define RKISP1_CIF_ISP_AWB_DONE                                BIT(4)
-#define RKISP1_CIF_ISP_FRAME_IN                                BIT(5)
-#define RKISP1_CIF_ISP_V_START                         BIT(6)
-#define RKISP1_CIF_ISP_H_START                         BIT(7)
-#define RKISP1_CIF_ISP_FLASH_ON                                BIT(8)
-#define RKISP1_CIF_ISP_FLASH_OFF                       BIT(9)
-#define RKISP1_CIF_ISP_SHUTTER_ON                      BIT(10)
-#define RKISP1_CIF_ISP_SHUTTER_OFF                     BIT(11)
-#define RKISP1_CIF_ISP_AFM_SUM_OF                      BIT(12)
-#define RKISP1_CIF_ISP_AFM_LUM_OF                      BIT(13)
-#define RKISP1_CIF_ISP_AFM_FIN                         BIT(14)
-#define RKISP1_CIF_ISP_HIST_MEASURE_RDY                        BIT(15)
-#define RKISP1_CIF_ISP_FLASH_CAP                       BIT(17)
-#define RKISP1_CIF_ISP_EXP_END                         BIT(18)
-#define RKISP1_CIF_ISP_VSM_END                         BIT(19)
-
-/* ISP_ERR */
-#define RKISP1_CIF_ISP_ERR_INFORM_SIZE                 BIT(0)
-#define RKISP1_CIF_ISP_ERR_IS_SIZE                     BIT(1)
-#define RKISP1_CIF_ISP_ERR_OUTFORM_SIZE                        BIT(2)
-
-/* MI_CTRL */
-#define RKISP1_CIF_MI_CTRL_MP_ENABLE                   BIT(0)
-#define RKISP1_CIF_MI_CTRL_SP_ENABLE                   (2 << 0)
-#define RKISP1_CIF_MI_CTRL_JPEG_ENABLE                 (4 << 0)
-#define RKISP1_CIF_MI_CTRL_RAW_ENABLE                  (8 << 0)
-#define RKISP1_CIF_MI_CTRL_HFLIP                       BIT(4)
-#define RKISP1_CIF_MI_CTRL_VFLIP                       BIT(5)
-#define RKISP1_CIF_MI_CTRL_ROT                         BIT(6)
-#define RKISP1_CIF_MI_BYTE_SWAP                                BIT(7)
-#define RKISP1_CIF_MI_SP_Y_FULL_YUV2RGB                        BIT(8)
-#define RKISP1_CIF_MI_SP_CBCR_FULL_YUV2RGB             BIT(9)
-#define RKISP1_CIF_MI_SP_422NONCOSITEED                        BIT(10)
-#define RKISP1_CIF_MI_MP_PINGPONG_ENABEL               BIT(11)
-#define RKISP1_CIF_MI_SP_PINGPONG_ENABEL               BIT(12)
-#define RKISP1_CIF_MI_MP_AUTOUPDATE_ENABLE             BIT(13)
-#define RKISP1_CIF_MI_SP_AUTOUPDATE_ENABLE             BIT(14)
-#define RKISP1_CIF_MI_LAST_PIXEL_SIG_ENABLE            BIT(15)
-#define RKISP1_CIF_MI_CTRL_BURST_LEN_LUM_16            (0 << 16)
-#define RKISP1_CIF_MI_CTRL_BURST_LEN_LUM_32            BIT(16)
-#define RKISP1_CIF_MI_CTRL_BURST_LEN_LUM_64            (2 << 16)
-#define RKISP1_CIF_MI_CTRL_BURST_LEN_CHROM_16          (0 << 18)
-#define RKISP1_CIF_MI_CTRL_BURST_LEN_CHROM_32          BIT(18)
-#define RKISP1_CIF_MI_CTRL_BURST_LEN_CHROM_64          (2 << 18)
-#define RKISP1_CIF_MI_CTRL_INIT_BASE_EN                        BIT(20)
-#define RKISP1_CIF_MI_CTRL_INIT_OFFSET_EN              BIT(21)
-#define RKISP1_MI_CTRL_MP_WRITE_YUV_PLA_OR_RAW8                (0 << 22)
-#define RKISP1_MI_CTRL_MP_WRITE_YUV_SPLA               BIT(22)
-#define RKISP1_MI_CTRL_MP_WRITE_YUVINT                 (2 << 22)
-#define RKISP1_MI_CTRL_MP_WRITE_RAW12                  (2 << 22)
-#define RKISP1_MI_CTRL_SP_WRITE_PLA                    (0 << 24)
-#define RKISP1_MI_CTRL_SP_WRITE_SPLA                   BIT(24)
-#define RKISP1_MI_CTRL_SP_WRITE_INT                    (2 << 24)
-#define RKISP1_MI_CTRL_SP_INPUT_YUV400                 (0 << 26)
-#define RKISP1_MI_CTRL_SP_INPUT_YUV420                 BIT(26)
-#define RKISP1_MI_CTRL_SP_INPUT_YUV422                 (2 << 26)
-#define RKISP1_MI_CTRL_SP_INPUT_YUV444                 (3 << 26)
-#define RKISP1_MI_CTRL_SP_OUTPUT_YUV400                        (0 << 28)
-#define RKISP1_MI_CTRL_SP_OUTPUT_YUV420                        BIT(28)
-#define RKISP1_MI_CTRL_SP_OUTPUT_YUV422                        (2 << 28)
-#define RKISP1_MI_CTRL_SP_OUTPUT_YUV444                        (3 << 28)
-#define RKISP1_MI_CTRL_SP_OUTPUT_RGB565                        (4 << 28)
-#define RKISP1_MI_CTRL_SP_OUTPUT_RGB666                        (5 << 28)
-#define RKISP1_MI_CTRL_SP_OUTPUT_RGB888                        (6 << 28)
-
-#define RKISP1_MI_CTRL_MP_FMT_MASK                     GENMASK(23, 22)
-#define RKISP1_MI_CTRL_SP_FMT_MASK                     GENMASK(30, 24)
-
-/* MI_INIT */
-#define RKISP1_CIF_MI_INIT_SKIP                                BIT(2)
-#define RKISP1_CIF_MI_INIT_SOFT_UPD                    BIT(4)
-
-/* MI_CTRL_SHD */
-#define RKISP1_CIF_MI_CTRL_SHD_MP_IN_ENABLED           BIT(0)
-#define RKISP1_CIF_MI_CTRL_SHD_SP_IN_ENABLED           BIT(1)
-#define RKISP1_CIF_MI_CTRL_SHD_JPEG_IN_ENABLED         BIT(2)
-#define RKISP1_CIF_MI_CTRL_SHD_RAW_IN_ENABLED          BIT(3)
-#define RKISP1_CIF_MI_CTRL_SHD_MP_OUT_ENABLED          BIT(16)
-#define RKISP1_CIF_MI_CTRL_SHD_SP_OUT_ENABLED          BIT(17)
-#define RKISP1_CIF_MI_CTRL_SHD_JPEG_OUT_ENABLED                BIT(18)
-#define RKISP1_CIF_MI_CTRL_SHD_RAW_OUT_ENABLED         BIT(19)
-
-/* RSZ_CTRL */
-#define RKISP1_CIF_RSZ_CTRL_SCALE_HY_ENABLE            BIT(0)
-#define RKISP1_CIF_RSZ_CTRL_SCALE_HC_ENABLE            BIT(1)
-#define RKISP1_CIF_RSZ_CTRL_SCALE_VY_ENABLE            BIT(2)
-#define RKISP1_CIF_RSZ_CTRL_SCALE_VC_ENABLE            BIT(3)
-#define RKISP1_CIF_RSZ_CTRL_SCALE_HY_UP                        BIT(4)
-#define RKISP1_CIF_RSZ_CTRL_SCALE_HC_UP                        BIT(5)
-#define RKISP1_CIF_RSZ_CTRL_SCALE_VY_UP                        BIT(6)
-#define RKISP1_CIF_RSZ_CTRL_SCALE_VC_UP                        BIT(7)
-#define RKISP1_CIF_RSZ_CTRL_CFG_UPD                    BIT(8)
-#define RKISP1_CIF_RSZ_CTRL_CFG_UPD_AUTO               BIT(9)
-#define RKISP1_CIF_RSZ_SCALER_FACTOR                   BIT(16)
-
-/* MI_IMSC - MI_MIS - MI_RIS - MI_ICR - MI_ISR */
-#define RKISP1_CIF_MI_FRAME(stream)                    BIT((stream)->id)
-#define RKISP1_CIF_MI_MBLK_LINE                                BIT(2)
-#define RKISP1_CIF_MI_FILL_MP_Y                                BIT(3)
-#define RKISP1_CIF_MI_WRAP_MP_Y                                BIT(4)
-#define RKISP1_CIF_MI_WRAP_MP_CB                       BIT(5)
-#define RKISP1_CIF_MI_WRAP_MP_CR                       BIT(6)
-#define RKISP1_CIF_MI_WRAP_SP_Y                                BIT(7)
-#define RKISP1_CIF_MI_WRAP_SP_CB                       BIT(8)
-#define RKISP1_CIF_MI_WRAP_SP_CR                       BIT(9)
-#define RKISP1_CIF_MI_DMA_READY                                BIT(11)
-
-/* MI_STATUS */
-#define RKISP1_CIF_MI_STATUS_MP_Y_FIFO_FULL            BIT(0)
-#define RKISP1_CIF_MI_STATUS_SP_Y_FIFO_FULL            BIT(4)
-
-/* MI_DMA_CTRL */
-#define RKISP1_CIF_MI_DMA_CTRL_BURST_LEN_LUM_16                (0 << 0)
-#define RKISP1_CIF_MI_DMA_CTRL_BURST_LEN_LUM_32                BIT(0)
-#define RKISP1_CIF_MI_DMA_CTRL_BURST_LEN_LUM_64                (2 << 0)
-#define RKISP1_CIF_MI_DMA_CTRL_BURST_LEN_CHROM_16      (0 << 2)
-#define RKISP1_CIF_MI_DMA_CTRL_BURST_LEN_CHROM_32      BIT(2)
-#define RKISP1_CIF_MI_DMA_CTRL_BURST_LEN_CHROM_64      (2 << 2)
-#define RKISP1_CIF_MI_DMA_CTRL_READ_FMT_PLANAR         (0 << 4)
-#define RKISP1_CIF_MI_DMA_CTRL_READ_FMT_SPLANAR                BIT(4)
-#define RKISP1_CIF_MI_DMA_CTRL_FMT_YUV400              (0 << 6)
-#define RKISP1_CIF_MI_DMA_CTRL_FMT_YUV420              BIT(6)
-#define RKISP1_CIF_MI_DMA_CTRL_READ_FMT_PACKED         (2 << 4)
-#define RKISP1_CIF_MI_DMA_CTRL_FMT_YUV422              (2 << 6)
-#define RKISP1_CIF_MI_DMA_CTRL_FMT_YUV444              (3 << 6)
-#define RKISP1_CIF_MI_DMA_CTRL_BYTE_SWAP               BIT(8)
-#define RKISP1_CIF_MI_DMA_CTRL_CONTINUOUS_ENA          BIT(9)
-#define RKISP1_CIF_MI_DMA_CTRL_RGB_BAYER_NO            (0 << 12)
-#define RKISP1_CIF_MI_DMA_CTRL_RGB_BAYER_8BIT          BIT(12)
-#define RKISP1_CIF_MI_DMA_CTRL_RGB_BAYER_16BIT         (2 << 12)
-/* MI_DMA_START */
-#define RKISP1_CIF_MI_DMA_START_ENABLE                 BIT(0)
-/* MI_XTD_FORMAT_CTRL  */
-#define RKISP1_CIF_MI_XTD_FMT_CTRL_MP_CB_CR_SWAP       BIT(0)
-#define RKISP1_CIF_MI_XTD_FMT_CTRL_SP_CB_CR_SWAP       BIT(1)
-#define RKISP1_CIF_MI_XTD_FMT_CTRL_DMA_CB_CR_SWAP      BIT(2)
-
-/* CCL */
-#define RKISP1_CIF_CCL_CIF_CLK_DIS                     BIT(2)
-/* ICCL */
-#define RKISP1_CIF_ICCL_ISP_CLK                                BIT(0)
-#define RKISP1_CIF_ICCL_CP_CLK                         BIT(1)
-#define RKISP1_CIF_ICCL_RES_2                          BIT(2)
-#define RKISP1_CIF_ICCL_MRSZ_CLK                       BIT(3)
-#define RKISP1_CIF_ICCL_SRSZ_CLK                       BIT(4)
-#define RKISP1_CIF_ICCL_JPEG_CLK                       BIT(5)
-#define RKISP1_CIF_ICCL_MI_CLK                         BIT(6)
-#define RKISP1_CIF_ICCL_RES_7                          BIT(7)
-#define RKISP1_CIF_ICCL_IE_CLK                         BIT(8)
-#define RKISP1_CIF_ICCL_SIMP_CLK                       BIT(9)
-#define RKISP1_CIF_ICCL_SMIA_CLK                       BIT(10)
-#define RKISP1_CIF_ICCL_MIPI_CLK                       BIT(11)
-#define RKISP1_CIF_ICCL_DCROP_CLK                      BIT(12)
-/* IRCL */
-#define RKISP1_CIF_IRCL_ISP_SW_RST                     BIT(0)
-#define RKISP1_CIF_IRCL_CP_SW_RST                      BIT(1)
-#define RKISP1_CIF_IRCL_YCS_SW_RST                     BIT(2)
-#define RKISP1_CIF_IRCL_MRSZ_SW_RST                    BIT(3)
-#define RKISP1_CIF_IRCL_SRSZ_SW_RST                    BIT(4)
-#define RKISP1_CIF_IRCL_JPEG_SW_RST                    BIT(5)
-#define RKISP1_CIF_IRCL_MI_SW_RST                      BIT(6)
-#define RKISP1_CIF_IRCL_CIF_SW_RST                     BIT(7)
-#define RKISP1_CIF_IRCL_IE_SW_RST                      BIT(8)
-#define RKISP1_CIF_IRCL_SI_SW_RST                      BIT(9)
-#define RKISP1_CIF_IRCL_MIPI_SW_RST                    BIT(11)
-
-/* C_PROC_CTR */
-#define RKISP1_CIF_C_PROC_CTR_ENABLE                   BIT(0)
-#define RKISP1_CIF_C_PROC_YOUT_FULL                    BIT(1)
-#define RKISP1_CIF_C_PROC_YIN_FULL                     BIT(2)
-#define RKISP1_CIF_C_PROC_COUT_FULL                    BIT(3)
-#define RKISP1_CIF_C_PROC_CTRL_RESERVED                        0xFFFFFFFE
-#define RKISP1_CIF_C_PROC_CONTRAST_RESERVED            0xFFFFFF00
-#define RKISP1_CIF_C_PROC_BRIGHTNESS_RESERVED          0xFFFFFF00
-#define RKISP1_CIF_C_PROC_HUE_RESERVED                 0xFFFFFF00
-#define RKISP1_CIF_C_PROC_SATURATION_RESERVED          0xFFFFFF00
-#define RKISP1_CIF_C_PROC_MACC_RESERVED                        0xE000E000
-#define RKISP1_CIF_C_PROC_TONE_RESERVED                        0xF000
-/* DUAL_CROP_CTRL */
-#define RKISP1_CIF_DUAL_CROP_MP_MODE_BYPASS            (0 << 0)
-#define RKISP1_CIF_DUAL_CROP_MP_MODE_YUV               BIT(0)
-#define RKISP1_CIF_DUAL_CROP_MP_MODE_RAW               (2 << 0)
-#define RKISP1_CIF_DUAL_CROP_SP_MODE_BYPASS            (0 << 2)
-#define RKISP1_CIF_DUAL_CROP_SP_MODE_YUV               BIT(2)
-#define RKISP1_CIF_DUAL_CROP_SP_MODE_RAW               (2 << 2)
-#define RKISP1_CIF_DUAL_CROP_CFG_UPD_PERMANENT         BIT(4)
-#define RKISP1_CIF_DUAL_CROP_CFG_UPD                   BIT(5)
-#define RKISP1_CIF_DUAL_CROP_GEN_CFG_UPD               BIT(6)
-
-/* IMG_EFF_CTRL */
-#define RKISP1_CIF_IMG_EFF_CTRL_ENABLE                 BIT(0)
-#define RKISP1_CIF_IMG_EFF_CTRL_MODE_BLACKWHITE                (0 << 1)
-#define RKISP1_CIF_IMG_EFF_CTRL_MODE_NEGATIVE          BIT(1)
-#define RKISP1_CIF_IMG_EFF_CTRL_MODE_SEPIA             (2 << 1)
-#define RKISP1_CIF_IMG_EFF_CTRL_MODE_COLOR_SEL         (3 << 1)
-#define RKISP1_CIF_IMG_EFF_CTRL_MODE_EMBOSS            (4 << 1)
-#define RKISP1_CIF_IMG_EFF_CTRL_MODE_SKETCH            (5 << 1)
-#define RKISP1_CIF_IMG_EFF_CTRL_MODE_SHARPEN           (6 << 1)
-#define RKISP1_CIF_IMG_EFF_CTRL_CFG_UPD                        BIT(4)
-#define RKISP1_CIF_IMG_EFF_CTRL_YCBCR_FULL             BIT(5)
-
-#define RKISP1_CIF_IMG_EFF_CTRL_MODE_BLACKWHITE_SHIFT  0
-#define RKISP1_CIF_IMG_EFF_CTRL_MODE_NEGATIVE_SHIFT    1
-#define RKISP1_CIF_IMG_EFF_CTRL_MODE_SEPIA_SHIFT       2
-#define RKISP1_CIF_IMG_EFF_CTRL_MODE_COLOR_SEL_SHIFT   3
-#define RKISP1_CIF_IMG_EFF_CTRL_MODE_EMBOSS_SHIFT      4
-#define RKISP1_CIF_IMG_EFF_CTRL_MODE_SKETCH_SHIFT      5
-#define RKISP1_CIF_IMG_EFF_CTRL_MODE_SHARPEN_SHIFT     6
-#define RKISP1_CIF_IMG_EFF_CTRL_MODE_MASK              0xE
-
-/* IMG_EFF_COLOR_SEL */
-#define RKISP1_CIF_IMG_EFF_COLOR_RGB                   0
-#define RKISP1_CIF_IMG_EFF_COLOR_B                     BIT(0)
-#define RKISP1_CIF_IMG_EFF_COLOR_G                     (2 << 0)
-#define RKISP1_CIF_IMG_EFF_COLOR_GB                    (3 << 0)
-#define RKISP1_CIF_IMG_EFF_COLOR_R                     (4 << 0)
-#define RKISP1_CIF_IMG_EFF_COLOR_RB                    (5 << 0)
-#define RKISP1_CIF_IMG_EFF_COLOR_RG                    (6 << 0)
-#define RKISP1_CIF_IMG_EFF_COLOR_RGB2                  (7 << 0)
-
-/* MIPI_CTRL */
-#define RKISP1_CIF_MIPI_CTRL_OUTPUT_ENA                        BIT(0)
-#define RKISP1_CIF_MIPI_CTRL_SHUTDOWNLANES(a)          (((a) & 0xF) << 8)
-#define RKISP1_CIF_MIPI_CTRL_NUM_LANES(a)              (((a) & 0x3) << 12)
-#define RKISP1_CIF_MIPI_CTRL_ERR_SOT_HS_SKIP           BIT(16)
-#define RKISP1_CIF_MIPI_CTRL_ERR_SOT_SYNC_HS_SKIP      BIT(17)
-#define RKISP1_CIF_MIPI_CTRL_CLOCKLANE_ENA             BIT(18)
-
-/* MIPI_DATA_SEL */
-#define RKISP1_CIF_MIPI_DATA_SEL_VC(a)                 (((a) & 0x3) << 6)
-#define RKISP1_CIF_MIPI_DATA_SEL_DT(a)                 (((a) & 0x3F) << 0)
-/* MIPI DATA_TYPE */
-#define RKISP1_CIF_CSI2_DT_YUV420_8b                   0x18
-#define RKISP1_CIF_CSI2_DT_YUV420_10b                  0x19
-#define RKISP1_CIF_CSI2_DT_YUV422_8b                   0x1E
-#define RKISP1_CIF_CSI2_DT_YUV422_10b                  0x1F
-#define RKISP1_CIF_CSI2_DT_RGB565                      0x22
-#define RKISP1_CIF_CSI2_DT_RGB666                      0x23
-#define RKISP1_CIF_CSI2_DT_RGB888                      0x24
-#define RKISP1_CIF_CSI2_DT_RAW8                                0x2A
-#define RKISP1_CIF_CSI2_DT_RAW10                       0x2B
-#define RKISP1_CIF_CSI2_DT_RAW12                       0x2C
-
-/* MIPI_IMSC, MIPI_RIS, MIPI_MIS, MIPI_ICR, MIPI_ISR */
-#define RKISP1_CIF_MIPI_SYNC_FIFO_OVFLW(a)             (((a) & 0xF) << 0)
-#define RKISP1_CIF_MIPI_ERR_SOT(a)                     (((a) & 0xF) << 4)
-#define RKISP1_CIF_MIPI_ERR_SOT_SYNC(a)                        (((a) & 0xF) << 8)
-#define RKISP1_CIF_MIPI_ERR_EOT_SYNC(a)                        (((a) & 0xF) << 12)
-#define RKISP1_CIF_MIPI_ERR_CTRL(a)                    (((a) & 0xF) << 16)
-#define RKISP1_CIF_MIPI_ERR_PROTOCOL                   BIT(20)
-#define RKISP1_CIF_MIPI_ERR_ECC1                       BIT(21)
-#define RKISP1_CIF_MIPI_ERR_ECC2                       BIT(22)
-#define RKISP1_CIF_MIPI_ERR_CS                         BIT(23)
-#define RKISP1_CIF_MIPI_FRAME_END                      BIT(24)
-#define RKISP1_CIF_MIPI_ADD_DATA_OVFLW                 BIT(25)
-#define RKISP1_CIF_MIPI_ADD_DATA_WATER_MARK            BIT(26)
-
-#define RKISP1_CIF_MIPI_ERR_CSI  (RKISP1_CIF_MIPI_ERR_PROTOCOL | \
-       RKISP1_CIF_MIPI_ERR_ECC1 | \
-       RKISP1_CIF_MIPI_ERR_ECC2 | \
-       RKISP1_CIF_MIPI_ERR_CS)
-
-#define RKISP1_CIF_MIPI_ERR_DPHY  (RKISP1_CIF_MIPI_ERR_SOT(3) | \
-       RKISP1_CIF_MIPI_ERR_SOT_SYNC(3) | \
-       RKISP1_CIF_MIPI_ERR_EOT_SYNC(3) | \
-       RKISP1_CIF_MIPI_ERR_CTRL(3))
-
-/* SUPER_IMPOSE */
-#define RKISP1_CIF_SUPER_IMP_CTRL_NORMAL_MODE          BIT(0)
-#define RKISP1_CIF_SUPER_IMP_CTRL_REF_IMG_MEM          BIT(1)
-#define RKISP1_CIF_SUPER_IMP_CTRL_TRANSP_DIS           BIT(2)
-
-/* ISP HISTOGRAM CALCULATION : ISP_HIST_PROP */
-#define RKISP1_CIF_ISP_HIST_PROP_MODE_DIS              (0 << 0)
-#define RKISP1_CIF_ISP_HIST_PROP_MODE_RGB              BIT(0)
-#define RKISP1_CIF_ISP_HIST_PROP_MODE_RED              (2 << 0)
-#define RKISP1_CIF_ISP_HIST_PROP_MODE_GREEN            (3 << 0)
-#define RKISP1_CIF_ISP_HIST_PROP_MODE_BLUE             (4 << 0)
-#define RKISP1_CIF_ISP_HIST_PROP_MODE_LUM              (5 << 0)
-#define RKISP1_CIF_ISP_HIST_PROP_MODE_MASK             0x7
-#define RKISP1_CIF_ISP_HIST_PREDIV_SET(x)              (((x) & 0x7F) << 3)
-#define RKISP1_CIF_ISP_HIST_WEIGHT_SET(v0, v1, v2, v3) \
-                                    (((v0) & 0x1F) | (((v1) & 0x1F) << 8)  |\
-                                    (((v2) & 0x1F) << 16) | \
-                                    (((v3) & 0x1F) << 24))
-
-#define RKISP1_CIF_ISP_HIST_WINDOW_OFFSET_RESERVED     0xFFFFF000
-#define RKISP1_CIF_ISP_HIST_WINDOW_SIZE_RESERVED       0xFFFFF800
-#define RKISP1_CIF_ISP_HIST_WEIGHT_RESERVED            0xE0E0E0E0
-#define RKISP1_CIF_ISP_MAX_HIST_PREDIVIDER             0x0000007F
-#define RKISP1_CIF_ISP_HIST_ROW_NUM                    5
-#define RKISP1_CIF_ISP_HIST_COLUMN_NUM                 5
-
-/* AUTO FOCUS MEASUREMENT:  ISP_AFM_CTRL */
-#define RKISP1_ISP_AFM_CTRL_ENABLE                     BIT(0)
-
-/* SHUTTER CONTROL */
-#define RKISP1_CIF_ISP_SH_CTRL_SH_ENA                  BIT(0)
-#define RKISP1_CIF_ISP_SH_CTRL_REP_EN                  BIT(1)
-#define RKISP1_CIF_ISP_SH_CTRL_SRC_SH_TRIG             BIT(2)
-#define RKISP1_CIF_ISP_SH_CTRL_EDGE_POS                        BIT(3)
-#define RKISP1_CIF_ISP_SH_CTRL_POL_LOW                 BIT(4)
-
-/* FLASH MODULE */
-/* ISP_FLASH_CMD */
-#define RKISP1_CIFFLASH_CMD_PRELIGHT_ON                        BIT(0)
-#define RKISP1_CIFFLASH_CMD_FLASH_ON                   BIT(1)
-#define RKISP1_CIFFLASH_CMD_PRE_FLASH_ON               BIT(2)
-/* ISP_FLASH_CONFIG */
-#define RKISP1_CIFFLASH_CONFIG_PRELIGHT_END            BIT(0)
-#define RKISP1_CIFFLASH_CONFIG_VSYNC_POS               BIT(1)
-#define RKISP1_CIFFLASH_CONFIG_PRELIGHT_LOW            BIT(2)
-#define RKISP1_CIFFLASH_CONFIG_SRC_FL_TRIG             BIT(3)
-#define RKISP1_CIFFLASH_CONFIG_DELAY(a)                        (((a) & 0xF) << 4)
-
-/* Demosaic:  ISP_DEMOSAIC */
-#define RKISP1_CIF_ISP_DEMOSAIC_BYPASS                 BIT(10)
-#define RKISP1_CIF_ISP_DEMOSAIC_TH(x)                  ((x) & 0xFF)
-
-/* AWB */
-/* ISP_AWB_PROP */
-#define RKISP1_CIF_ISP_AWB_YMAX_CMP_EN                 BIT(2)
-#define RKISP1_CIF_ISP_AWB_YMAX_READ(x)                        (((x) >> 2) & 1)
-#define RKISP1_CIF_ISP_AWB_MODE_RGB_EN                 ((1 << 31) | (0x2 << 0))
-#define RKISP1_CIF_ISP_AWB_MODE_YCBCR_EN               ((0 << 31) | (0x2 << 0))
-#define RKISP1_CIF_ISP_AWB_MODE_MASK_NONE              0xFFFFFFFC
-#define RKISP1_CIF_ISP_AWB_MODE_READ(x)                        ((x) & 3)
-/* ISP_AWB_GAIN_RB, ISP_AWB_GAIN_G  */
-#define RKISP1_CIF_ISP_AWB_GAIN_R_SET(x)               (((x) & 0x3FF) << 16)
-#define RKISP1_CIF_ISP_AWB_GAIN_R_READ(x)              (((x) >> 16) & 0x3FF)
-#define RKISP1_CIF_ISP_AWB_GAIN_B_SET(x)               ((x) & 0x3FFF)
-#define RKISP1_CIF_ISP_AWB_GAIN_B_READ(x)              ((x) & 0x3FFF)
-/* ISP_AWB_REF */
-#define RKISP1_CIF_ISP_AWB_REF_CR_SET(x)               (((x) & 0xFF) << 8)
-#define RKISP1_CIF_ISP_AWB_REF_CR_READ(x)              (((x) >> 8) & 0xFF)
-#define RKISP1_CIF_ISP_AWB_REF_CB_READ(x)              ((x) & 0xFF)
-/* ISP_AWB_THRESH */
-#define RKISP1_CIF_ISP_AWB_MAX_CS_SET(x)               (((x) & 0xFF) << 8)
-#define RKISP1_CIF_ISP_AWB_MAX_CS_READ(x)              (((x) >> 8) & 0xFF)
-#define RKISP1_CIF_ISP_AWB_MIN_C_READ(x)               ((x) & 0xFF)
-#define RKISP1_CIF_ISP_AWB_MIN_Y_SET(x)                        (((x) & 0xFF) << 16)
-#define RKISP1_CIF_ISP_AWB_MIN_Y_READ(x)               (((x) >> 16) & 0xFF)
-#define RKISP1_CIF_ISP_AWB_MAX_Y_SET(x)                        (((x) & 0xFF) << 24)
-#define RKISP1_CIF_ISP_AWB_MAX_Y_READ(x)                       (((x) >> 24) & 0xFF)
-/* ISP_AWB_MEAN */
-#define RKISP1_CIF_ISP_AWB_GET_MEAN_CR_R(x)            ((x) & 0xFF)
-#define RKISP1_CIF_ISP_AWB_GET_MEAN_CB_B(x)            (((x) >> 8) & 0xFF)
-#define RKISP1_CIF_ISP_AWB_GET_MEAN_Y_G(x)             (((x) >> 16) & 0xFF)
-/* ISP_AWB_WHITE_CNT */
-#define RKISP1_CIF_ISP_AWB_GET_PIXEL_CNT(x)            ((x) & 0x3FFFFFF)
-
-#define RKISP1_CIF_ISP_AWB_GAINS_MAX_VAL               0x000003FF
-#define RKISP1_CIF_ISP_AWB_WINDOW_OFFSET_MAX           0x00000FFF
-#define RKISP1_CIF_ISP_AWB_WINDOW_MAX_SIZE             0x00001FFF
-#define RKISP1_CIF_ISP_AWB_CBCR_MAX_REF                        0x000000FF
-#define RKISP1_CIF_ISP_AWB_THRES_MAX_YC                        0x000000FF
-
-/* AE */
-/* ISP_EXP_CTRL */
-#define RKISP1_CIF_ISP_EXP_ENA                         BIT(0)
-#define RKISP1_CIF_ISP_EXP_CTRL_AUTOSTOP               BIT(1)
-/*
- *'1' luminance calculation according to  Y=(R+G+B) x 0.332 (85/256)
- *'0' luminance calculation according to Y=16+0.25R+0.5G+0.1094B
- */
-#define RKISP1_CIF_ISP_EXP_CTRL_MEASMODE_1             BIT(31)
-
-/* ISP_EXP_H_SIZE */
-#define RKISP1_CIF_ISP_EXP_H_SIZE_SET(x)               ((x) & 0x7FF)
-#define RKISP1_CIF_ISP_EXP_HEIGHT_MASK                 0x000007FF
-/* ISP_EXP_V_SIZE : vertical size must be a multiple of 2). */
-#define RKISP1_CIF_ISP_EXP_V_SIZE_SET(x)               ((x) & 0x7FE)
-
-/* ISP_EXP_H_OFFSET */
-#define RKISP1_CIF_ISP_EXP_H_OFFSET_SET(x)             ((x) & 0x1FFF)
-#define RKISP1_CIF_ISP_EXP_MAX_HOFFS                   2424
-/* ISP_EXP_V_OFFSET */
-#define RKISP1_CIF_ISP_EXP_V_OFFSET_SET(x)             ((x) & 0x1FFF)
-#define RKISP1_CIF_ISP_EXP_MAX_VOFFS                   1806
-
-#define RKISP1_CIF_ISP_EXP_ROW_NUM                     5
-#define RKISP1_CIF_ISP_EXP_COLUMN_NUM                  5
-#define RKISP1_CIF_ISP_EXP_NUM_LUMA_REGS \
-       (RKISP1_CIF_ISP_EXP_ROW_NUM * RKISP1_CIF_ISP_EXP_COLUMN_NUM)
-#define RKISP1_CIF_ISP_EXP_BLOCK_MAX_HSIZE             516
-#define RKISP1_CIF_ISP_EXP_BLOCK_MIN_HSIZE             35
-#define RKISP1_CIF_ISP_EXP_BLOCK_MAX_VSIZE             390
-#define RKISP1_CIF_ISP_EXP_BLOCK_MIN_VSIZE             28
-#define RKISP1_CIF_ISP_EXP_MAX_HSIZE   \
-       (RKISP1_CIF_ISP_EXP_BLOCK_MAX_HSIZE * RKISP1_CIF_ISP_EXP_COLUMN_NUM + 1)
-#define RKISP1_CIF_ISP_EXP_MIN_HSIZE   \
-       (RKISP1_CIF_ISP_EXP_BLOCK_MIN_HSIZE * RKISP1_CIF_ISP_EXP_COLUMN_NUM + 1)
-#define RKISP1_CIF_ISP_EXP_MAX_VSIZE   \
-       (RKISP1_CIF_ISP_EXP_BLOCK_MAX_VSIZE * RKISP1_CIF_ISP_EXP_ROW_NUM + 1)
-#define RKISP1_CIF_ISP_EXP_MIN_VSIZE   \
-       (RKISP1_CIF_ISP_EXP_BLOCK_MIN_VSIZE * RKISP1_CIF_ISP_EXP_ROW_NUM + 1)
-
-/* LSC: ISP_LSC_CTRL */
-#define RKISP1_CIF_ISP_LSC_CTRL_ENA                    BIT(0)
-#define RKISP1_CIF_ISP_LSC_SECT_SIZE_RESERVED          0xFC00FC00
-#define RKISP1_CIF_ISP_LSC_GRAD_RESERVED               0xF000F000
-#define RKISP1_CIF_ISP_LSC_SAMPLE_RESERVED             0xF000F000
-#define RKISP1_CIF_ISP_LSC_TABLE_DATA(v0, v1)     \
-       (((v0) & 0xFFF) | (((v1) & 0xFFF) << 12))
-#define RKISP1_CIF_ISP_LSC_SECT_SIZE(v0, v1)      \
-       (((v0) & 0xFFF) | (((v1) & 0xFFF) << 16))
-#define RKISP1_CIF_ISP_LSC_GRAD_SIZE(v0, v1)      \
-       (((v0) & 0xFFF) | (((v1) & 0xFFF) << 16))
-
-/* LSC: ISP_LSC_TABLE_SEL */
-#define RKISP1_CIF_ISP_LSC_TABLE_0                     0
-#define RKISP1_CIF_ISP_LSC_TABLE_1                     1
-
-/* LSC: ISP_LSC_STATUS */
-#define RKISP1_CIF_ISP_LSC_ACTIVE_TABLE                        BIT(1)
-#define RKISP1_CIF_ISP_LSC_TABLE_ADDRESS_0             0
-#define RKISP1_CIF_ISP_LSC_TABLE_ADDRESS_153           153
-
-/* FLT */
-/* ISP_FILT_MODE */
-#define RKISP1_CIF_ISP_FLT_ENA                         BIT(0)
-
-/*
- * 0: green filter static mode (active filter factor = FILT_FAC_MID)
- * 1: dynamic noise reduction/sharpen Default
- */
-#define RKISP1_CIF_ISP_FLT_MODE_DNR                    BIT(1)
-#define RKISP1_CIF_ISP_FLT_MODE_MAX                    1
-#define RKISP1_CIF_ISP_FLT_CHROMA_V_MODE(x)            (((x) & 0x3) << 4)
-#define RKISP1_CIF_ISP_FLT_CHROMA_H_MODE(x)            (((x) & 0x3) << 6)
-#define RKISP1_CIF_ISP_FLT_CHROMA_MODE_MAX             3
-#define RKISP1_CIF_ISP_FLT_GREEN_STAGE1(x)             (((x) & 0xF) << 8)
-#define RKISP1_CIF_ISP_FLT_GREEN_STAGE1_MAX            8
-#define RKISP1_CIF_ISP_FLT_THREAD_RESERVED             0xFFFFFC00
-#define RKISP1_CIF_ISP_FLT_FAC_RESERVED                        0xFFFFFFC0
-#define RKISP1_CIF_ISP_FLT_LUM_WEIGHT_RESERVED         0xFFF80000
-
-#define RKISP1_CIF_ISP_CTK_COEFF_RESERVED              0xFFFFF800
-#define RKISP1_CIF_ISP_XTALK_OFFSET_RESERVED           0xFFFFF000
-
-/* GOC */
-#define RKISP1_CIF_ISP_GAMMA_OUT_MODE_EQU              BIT(0)
-#define RKISP1_CIF_ISP_GOC_MODE_MAX                    1
-#define RKISP1_CIF_ISP_GOC_RESERVED                    0xFFFFF800
-/* ISP_CTRL BIT 11*/
-#define RKISP1_CIF_ISP_CTRL_ISP_GAMMA_OUT_ENA_READ(x)  (((x) >> 11) & 1)
-
-/* DPCC */
-/* ISP_DPCC_MODE */
-#define RKISP1_CIF_ISP_DPCC_ENA                                BIT(0)
-#define RKISP1_CIF_ISP_DPCC_MODE_MAX                   0x07
-#define RKISP1_CIF_ISP_DPCC_OUTPUTMODE_MAX             0x0F
-#define RKISP1_CIF_ISP_DPCC_SETUSE_MAX                 0x0F
-#define RKISP1_CIF_ISP_DPCC_METHODS_SET_RESERVED       0xFFFFE000
-#define RKISP1_CIF_ISP_DPCC_LINE_THRESH_RESERVED       0xFFFF0000
-#define RKISP1_CIF_ISP_DPCC_LINE_MAD_FAC_RESERVED      0xFFFFC0C0
-#define RKISP1_CIF_ISP_DPCC_PG_FAC_RESERVED            0xFFFFC0C0
-#define RKISP1_CIF_ISP_DPCC_RND_THRESH_RESERVED                0xFFFF0000
-#define RKISP1_CIF_ISP_DPCC_RG_FAC_RESERVED            0xFFFFC0C0
-#define RKISP1_CIF_ISP_DPCC_RO_LIMIT_RESERVED          0xFFFFF000
-#define RKISP1_CIF_ISP_DPCC_RND_OFFS_RESERVED          0xFFFFF000
-
-/* BLS */
-/* ISP_BLS_CTRL */
-#define RKISP1_CIF_ISP_BLS_ENA                         BIT(0)
-#define RKISP1_CIF_ISP_BLS_MODE_MEASURED               BIT(1)
-#define RKISP1_CIF_ISP_BLS_MODE_FIXED                  0
-#define RKISP1_CIF_ISP_BLS_WINDOW_1                    BIT(2)
-#define RKISP1_CIF_ISP_BLS_WINDOW_2                    (2 << 2)
-
-/* GAMMA-IN */
-#define RKISP1_CIFISP_DEGAMMA_X_RESERVED       \
-       ((1 << 31) | (1 << 27) | (1 << 23) | (1 << 19) |\
-       (1 << 15) | (1 << 11) | (1 << 7) | (1 << 3))
-#define RKISP1_CIFISP_DEGAMMA_Y_RESERVED               0xFFFFF000
-
-/* AFM */
-#define RKISP1_CIF_ISP_AFM_ENA                         BIT(0)
-#define RKISP1_CIF_ISP_AFM_THRES_RESERVED              0xFFFF0000
-#define RKISP1_CIF_ISP_AFM_VAR_SHIFT_RESERVED          0xFFF8FFF8
-#define RKISP1_CIF_ISP_AFM_WINDOW_X_RESERVED           0xE000
-#define RKISP1_CIF_ISP_AFM_WINDOW_Y_RESERVED           0xF000
-#define RKISP1_CIF_ISP_AFM_WINDOW_X_MIN                        0x5
-#define RKISP1_CIF_ISP_AFM_WINDOW_Y_MIN                        0x2
-#define RKISP1_CIF_ISP_AFM_WINDOW_X(x)                 (((x) & 0x1FFF) << 16)
-#define RKISP1_CIF_ISP_AFM_WINDOW_Y(x)                 ((x) & 0x1FFF)
-
-/* DPF */
-#define RKISP1_CIF_ISP_DPF_MODE_EN                     BIT(0)
-#define RKISP1_CIF_ISP_DPF_MODE_B_FLT_DIS              BIT(1)
-#define RKISP1_CIF_ISP_DPF_MODE_GB_FLT_DIS             BIT(2)
-#define RKISP1_CIF_ISP_DPF_MODE_GR_FLT_DIS             BIT(3)
-#define RKISP1_CIF_ISP_DPF_MODE_R_FLT_DIS              BIT(4)
-#define RKISP1_CIF_ISP_DPF_MODE_RB_FLTSIZE_9x9         BIT(5)
-#define RKISP1_CIF_ISP_DPF_MODE_NLL_SEGMENTATION       BIT(6)
-#define RKISP1_CIF_ISP_DPF_MODE_AWB_GAIN_COMP          BIT(7)
-#define RKISP1_CIF_ISP_DPF_MODE_LSC_GAIN_COMP          BIT(8)
-#define RKISP1_CIF_ISP_DPF_MODE_USE_NF_GAIN            BIT(9)
-#define RKISP1_CIF_ISP_DPF_NF_GAIN_RESERVED            0xFFFFF000
-#define RKISP1_CIF_ISP_DPF_SPATIAL_COEFF_MAX           0x1F
-#define RKISP1_CIF_ISP_DPF_NLL_COEFF_N_MAX             0x3FF
-
-/* =================================================================== */
-/*                            CIF Registers                            */
-/* =================================================================== */
-#define RKISP1_CIF_CTRL_BASE                   0x00000000
-#define RKISP1_CIF_CCL                         (RKISP1_CIF_CTRL_BASE + 0x00000000)
-#define RKISP1_CIF_VI_ID                       (RKISP1_CIF_CTRL_BASE + 0x00000008)
-#define RKISP1_CIF_ICCL                                (RKISP1_CIF_CTRL_BASE + 0x00000010)
-#define RKISP1_CIF_IRCL                                (RKISP1_CIF_CTRL_BASE + 0x00000014)
-#define RKISP1_CIF_VI_DPCL                     (RKISP1_CIF_CTRL_BASE + 0x00000018)
-
-#define RKISP1_CIF_IMG_EFF_BASE                        0x00000200
-#define RKISP1_CIF_IMG_EFF_CTRL                        (RKISP1_CIF_IMG_EFF_BASE + 0x00000000)
-#define RKISP1_CIF_IMG_EFF_COLOR_SEL           (RKISP1_CIF_IMG_EFF_BASE + 0x00000004)
-#define RKISP1_CIF_IMG_EFF_MAT_1               (RKISP1_CIF_IMG_EFF_BASE + 0x00000008)
-#define RKISP1_CIF_IMG_EFF_MAT_2               (RKISP1_CIF_IMG_EFF_BASE + 0x0000000C)
-#define RKISP1_CIF_IMG_EFF_MAT_3               (RKISP1_CIF_IMG_EFF_BASE + 0x00000010)
-#define RKISP1_CIF_IMG_EFF_MAT_4               (RKISP1_CIF_IMG_EFF_BASE + 0x00000014)
-#define RKISP1_CIF_IMG_EFF_MAT_5               (RKISP1_CIF_IMG_EFF_BASE + 0x00000018)
-#define RKISP1_CIF_IMG_EFF_TINT                        (RKISP1_CIF_IMG_EFF_BASE + 0x0000001C)
-#define RKISP1_CIF_IMG_EFF_CTRL_SHD            (RKISP1_CIF_IMG_EFF_BASE + 0x00000020)
-#define RKISP1_CIF_IMG_EFF_SHARPEN             (RKISP1_CIF_IMG_EFF_BASE + 0x00000024)
-
-#define RKISP1_CIF_SUPER_IMP_BASE              0x00000300
-#define RKISP1_CIF_SUPER_IMP_CTRL              (RKISP1_CIF_SUPER_IMP_BASE + 0x00000000)
-#define RKISP1_CIF_SUPER_IMP_OFFSET_X          (RKISP1_CIF_SUPER_IMP_BASE + 0x00000004)
-#define RKISP1_CIF_SUPER_IMP_OFFSET_Y          (RKISP1_CIF_SUPER_IMP_BASE + 0x00000008)
-#define RKISP1_CIF_SUPER_IMP_COLOR_Y           (RKISP1_CIF_SUPER_IMP_BASE + 0x0000000C)
-#define RKISP1_CIF_SUPER_IMP_COLOR_CB          (RKISP1_CIF_SUPER_IMP_BASE + 0x00000010)
-#define RKISP1_CIF_SUPER_IMP_COLOR_CR          (RKISP1_CIF_SUPER_IMP_BASE + 0x00000014)
-
-#define RKISP1_CIF_ISP_BASE                    0x00000400
-#define RKISP1_CIF_ISP_CTRL                    (RKISP1_CIF_ISP_BASE + 0x00000000)
-#define RKISP1_CIF_ISP_ACQ_PROP                        (RKISP1_CIF_ISP_BASE + 0x00000004)
-#define RKISP1_CIF_ISP_ACQ_H_OFFS              (RKISP1_CIF_ISP_BASE + 0x00000008)
-#define RKISP1_CIF_ISP_ACQ_V_OFFS              (RKISP1_CIF_ISP_BASE + 0x0000000C)
-#define RKISP1_CIF_ISP_ACQ_H_SIZE              (RKISP1_CIF_ISP_BASE + 0x00000010)
-#define RKISP1_CIF_ISP_ACQ_V_SIZE              (RKISP1_CIF_ISP_BASE + 0x00000014)
-#define RKISP1_CIF_ISP_ACQ_NR_FRAMES           (RKISP1_CIF_ISP_BASE + 0x00000018)
-#define RKISP1_CIF_ISP_GAMMA_DX_LO             (RKISP1_CIF_ISP_BASE + 0x0000001C)
-#define RKISP1_CIF_ISP_GAMMA_DX_HI             (RKISP1_CIF_ISP_BASE + 0x00000020)
-#define RKISP1_CIF_ISP_GAMMA_R_Y0              (RKISP1_CIF_ISP_BASE + 0x00000024)
-#define RKISP1_CIF_ISP_GAMMA_R_Y1              (RKISP1_CIF_ISP_BASE + 0x00000028)
-#define RKISP1_CIF_ISP_GAMMA_R_Y2              (RKISP1_CIF_ISP_BASE + 0x0000002C)
-#define RKISP1_CIF_ISP_GAMMA_R_Y3              (RKISP1_CIF_ISP_BASE + 0x00000030)
-#define RKISP1_CIF_ISP_GAMMA_R_Y4              (RKISP1_CIF_ISP_BASE + 0x00000034)
-#define RKISP1_CIF_ISP_GAMMA_R_Y5              (RKISP1_CIF_ISP_BASE + 0x00000038)
-#define RKISP1_CIF_ISP_GAMMA_R_Y6              (RKISP1_CIF_ISP_BASE + 0x0000003C)
-#define RKISP1_CIF_ISP_GAMMA_R_Y7              (RKISP1_CIF_ISP_BASE + 0x00000040)
-#define RKISP1_CIF_ISP_GAMMA_R_Y8              (RKISP1_CIF_ISP_BASE + 0x00000044)
-#define RKISP1_CIF_ISP_GAMMA_R_Y9              (RKISP1_CIF_ISP_BASE + 0x00000048)
-#define RKISP1_CIF_ISP_GAMMA_R_Y10             (RKISP1_CIF_ISP_BASE + 0x0000004C)
-#define RKISP1_CIF_ISP_GAMMA_R_Y11             (RKISP1_CIF_ISP_BASE + 0x00000050)
-#define RKISP1_CIF_ISP_GAMMA_R_Y12             (RKISP1_CIF_ISP_BASE + 0x00000054)
-#define RKISP1_CIF_ISP_GAMMA_R_Y13             (RKISP1_CIF_ISP_BASE + 0x00000058)
-#define RKISP1_CIF_ISP_GAMMA_R_Y14             (RKISP1_CIF_ISP_BASE + 0x0000005C)
-#define RKISP1_CIF_ISP_GAMMA_R_Y15             (RKISP1_CIF_ISP_BASE + 0x00000060)
-#define RKISP1_CIF_ISP_GAMMA_R_Y16             (RKISP1_CIF_ISP_BASE + 0x00000064)
-#define RKISP1_CIF_ISP_GAMMA_G_Y0              (RKISP1_CIF_ISP_BASE + 0x00000068)
-#define RKISP1_CIF_ISP_GAMMA_G_Y1              (RKISP1_CIF_ISP_BASE + 0x0000006C)
-#define RKISP1_CIF_ISP_GAMMA_G_Y2              (RKISP1_CIF_ISP_BASE + 0x00000070)
-#define RKISP1_CIF_ISP_GAMMA_G_Y3              (RKISP1_CIF_ISP_BASE + 0x00000074)
-#define RKISP1_CIF_ISP_GAMMA_G_Y4              (RKISP1_CIF_ISP_BASE + 0x00000078)
-#define RKISP1_CIF_ISP_GAMMA_G_Y5              (RKISP1_CIF_ISP_BASE + 0x0000007C)
-#define RKISP1_CIF_ISP_GAMMA_G_Y6              (RKISP1_CIF_ISP_BASE + 0x00000080)
-#define RKISP1_CIF_ISP_GAMMA_G_Y7              (RKISP1_CIF_ISP_BASE + 0x00000084)
-#define RKISP1_CIF_ISP_GAMMA_G_Y8              (RKISP1_CIF_ISP_BASE + 0x00000088)
-#define RKISP1_CIF_ISP_GAMMA_G_Y9              (RKISP1_CIF_ISP_BASE + 0x0000008C)
-#define RKISP1_CIF_ISP_GAMMA_G_Y10             (RKISP1_CIF_ISP_BASE + 0x00000090)
-#define RKISP1_CIF_ISP_GAMMA_G_Y11             (RKISP1_CIF_ISP_BASE + 0x00000094)
-#define RKISP1_CIF_ISP_GAMMA_G_Y12             (RKISP1_CIF_ISP_BASE + 0x00000098)
-#define RKISP1_CIF_ISP_GAMMA_G_Y13             (RKISP1_CIF_ISP_BASE + 0x0000009C)
-#define RKISP1_CIF_ISP_GAMMA_G_Y14             (RKISP1_CIF_ISP_BASE + 0x000000A0)
-#define RKISP1_CIF_ISP_GAMMA_G_Y15             (RKISP1_CIF_ISP_BASE + 0x000000A4)
-#define RKISP1_CIF_ISP_GAMMA_G_Y16             (RKISP1_CIF_ISP_BASE + 0x000000A8)
-#define RKISP1_CIF_ISP_GAMMA_B_Y0              (RKISP1_CIF_ISP_BASE + 0x000000AC)
-#define RKISP1_CIF_ISP_GAMMA_B_Y1              (RKISP1_CIF_ISP_BASE + 0x000000B0)
-#define RKISP1_CIF_ISP_GAMMA_B_Y2              (RKISP1_CIF_ISP_BASE + 0x000000B4)
-#define RKISP1_CIF_ISP_GAMMA_B_Y3              (RKISP1_CIF_ISP_BASE + 0x000000B8)
-#define RKISP1_CIF_ISP_GAMMA_B_Y4              (RKISP1_CIF_ISP_BASE + 0x000000BC)
-#define RKISP1_CIF_ISP_GAMMA_B_Y5              (RKISP1_CIF_ISP_BASE + 0x000000C0)
-#define RKISP1_CIF_ISP_GAMMA_B_Y6              (RKISP1_CIF_ISP_BASE + 0x000000C4)
-#define RKISP1_CIF_ISP_GAMMA_B_Y7              (RKISP1_CIF_ISP_BASE + 0x000000C8)
-#define RKISP1_CIF_ISP_GAMMA_B_Y8              (RKISP1_CIF_ISP_BASE + 0x000000CC)
-#define RKISP1_CIF_ISP_GAMMA_B_Y9              (RKISP1_CIF_ISP_BASE + 0x000000D0)
-#define RKISP1_CIF_ISP_GAMMA_B_Y10             (RKISP1_CIF_ISP_BASE + 0x000000D4)
-#define RKISP1_CIF_ISP_GAMMA_B_Y11             (RKISP1_CIF_ISP_BASE + 0x000000D8)
-#define RKISP1_CIF_ISP_GAMMA_B_Y12             (RKISP1_CIF_ISP_BASE + 0x000000DC)
-#define RKISP1_CIF_ISP_GAMMA_B_Y13             (RKISP1_CIF_ISP_BASE + 0x000000E0)
-#define RKISP1_CIF_ISP_GAMMA_B_Y14             (RKISP1_CIF_ISP_BASE + 0x000000E4)
-#define RKISP1_CIF_ISP_GAMMA_B_Y15             (RKISP1_CIF_ISP_BASE + 0x000000E8)
-#define RKISP1_CIF_ISP_GAMMA_B_Y16             (RKISP1_CIF_ISP_BASE + 0x000000EC)
-#define RKISP1_CIF_ISP_AWB_PROP                        (RKISP1_CIF_ISP_BASE + 0x00000110)
-#define RKISP1_CIF_ISP_AWB_WND_H_OFFS          (RKISP1_CIF_ISP_BASE + 0x00000114)
-#define RKISP1_CIF_ISP_AWB_WND_V_OFFS          (RKISP1_CIF_ISP_BASE + 0x00000118)
-#define RKISP1_CIF_ISP_AWB_WND_H_SIZE          (RKISP1_CIF_ISP_BASE + 0x0000011C)
-#define RKISP1_CIF_ISP_AWB_WND_V_SIZE          (RKISP1_CIF_ISP_BASE + 0x00000120)
-#define RKISP1_CIF_ISP_AWB_FRAMES              (RKISP1_CIF_ISP_BASE + 0x00000124)
-#define RKISP1_CIF_ISP_AWB_REF                 (RKISP1_CIF_ISP_BASE + 0x00000128)
-#define RKISP1_CIF_ISP_AWB_THRESH              (RKISP1_CIF_ISP_BASE + 0x0000012C)
-#define RKISP1_CIF_ISP_AWB_GAIN_G              (RKISP1_CIF_ISP_BASE + 0x00000138)
-#define RKISP1_CIF_ISP_AWB_GAIN_RB             (RKISP1_CIF_ISP_BASE + 0x0000013C)
-#define RKISP1_CIF_ISP_AWB_WHITE_CNT           (RKISP1_CIF_ISP_BASE + 0x00000140)
-#define RKISP1_CIF_ISP_AWB_MEAN                        (RKISP1_CIF_ISP_BASE + 0x00000144)
-#define RKISP1_CIF_ISP_CC_COEFF_0              (RKISP1_CIF_ISP_BASE + 0x00000170)
-#define RKISP1_CIF_ISP_CC_COEFF_1              (RKISP1_CIF_ISP_BASE + 0x00000174)
-#define RKISP1_CIF_ISP_CC_COEFF_2              (RKISP1_CIF_ISP_BASE + 0x00000178)
-#define RKISP1_CIF_ISP_CC_COEFF_3              (RKISP1_CIF_ISP_BASE + 0x0000017C)
-#define RKISP1_CIF_ISP_CC_COEFF_4              (RKISP1_CIF_ISP_BASE + 0x00000180)
-#define RKISP1_CIF_ISP_CC_COEFF_5              (RKISP1_CIF_ISP_BASE + 0x00000184)
-#define RKISP1_CIF_ISP_CC_COEFF_6              (RKISP1_CIF_ISP_BASE + 0x00000188)
-#define RKISP1_CIF_ISP_CC_COEFF_7              (RKISP1_CIF_ISP_BASE + 0x0000018C)
-#define RKISP1_CIF_ISP_CC_COEFF_8              (RKISP1_CIF_ISP_BASE + 0x00000190)
-#define RKISP1_CIF_ISP_OUT_H_OFFS              (RKISP1_CIF_ISP_BASE + 0x00000194)
-#define RKISP1_CIF_ISP_OUT_V_OFFS              (RKISP1_CIF_ISP_BASE + 0x00000198)
-#define RKISP1_CIF_ISP_OUT_H_SIZE              (RKISP1_CIF_ISP_BASE + 0x0000019C)
-#define RKISP1_CIF_ISP_OUT_V_SIZE              (RKISP1_CIF_ISP_BASE + 0x000001A0)
-#define RKISP1_CIF_ISP_DEMOSAIC                        (RKISP1_CIF_ISP_BASE + 0x000001A4)
-#define RKISP1_CIF_ISP_FLAGS_SHD               (RKISP1_CIF_ISP_BASE + 0x000001A8)
-#define RKISP1_CIF_ISP_OUT_H_OFFS_SHD          (RKISP1_CIF_ISP_BASE + 0x000001AC)
-#define RKISP1_CIF_ISP_OUT_V_OFFS_SHD          (RKISP1_CIF_ISP_BASE + 0x000001B0)
-#define RKISP1_CIF_ISP_OUT_H_SIZE_SHD          (RKISP1_CIF_ISP_BASE + 0x000001B4)
-#define RKISP1_CIF_ISP_OUT_V_SIZE_SHD          (RKISP1_CIF_ISP_BASE + 0x000001B8)
-#define RKISP1_CIF_ISP_IMSC                    (RKISP1_CIF_ISP_BASE + 0x000001BC)
-#define RKISP1_CIF_ISP_RIS                     (RKISP1_CIF_ISP_BASE + 0x000001C0)
-#define RKISP1_CIF_ISP_MIS                     (RKISP1_CIF_ISP_BASE + 0x000001C4)
-#define RKISP1_CIF_ISP_ICR                     (RKISP1_CIF_ISP_BASE + 0x000001C8)
-#define RKISP1_CIF_ISP_ISR                     (RKISP1_CIF_ISP_BASE + 0x000001CC)
-#define RKISP1_CIF_ISP_CT_COEFF_0              (RKISP1_CIF_ISP_BASE + 0x000001D0)
-#define RKISP1_CIF_ISP_CT_COEFF_1              (RKISP1_CIF_ISP_BASE + 0x000001D4)
-#define RKISP1_CIF_ISP_CT_COEFF_2              (RKISP1_CIF_ISP_BASE + 0x000001D8)
-#define RKISP1_CIF_ISP_CT_COEFF_3              (RKISP1_CIF_ISP_BASE + 0x000001DC)
-#define RKISP1_CIF_ISP_CT_COEFF_4              (RKISP1_CIF_ISP_BASE + 0x000001E0)
-#define RKISP1_CIF_ISP_CT_COEFF_5              (RKISP1_CIF_ISP_BASE + 0x000001E4)
-#define RKISP1_CIF_ISP_CT_COEFF_6              (RKISP1_CIF_ISP_BASE + 0x000001E8)
-#define RKISP1_CIF_ISP_CT_COEFF_7              (RKISP1_CIF_ISP_BASE + 0x000001EC)
-#define RKISP1_CIF_ISP_CT_COEFF_8              (RKISP1_CIF_ISP_BASE + 0x000001F0)
-#define RKISP1_CIF_ISP_GAMMA_OUT_MODE          (RKISP1_CIF_ISP_BASE + 0x000001F4)
-#define RKISP1_CIF_ISP_GAMMA_OUT_Y_0           (RKISP1_CIF_ISP_BASE + 0x000001F8)
-#define RKISP1_CIF_ISP_GAMMA_OUT_Y_1           (RKISP1_CIF_ISP_BASE + 0x000001FC)
-#define RKISP1_CIF_ISP_GAMMA_OUT_Y_2           (RKISP1_CIF_ISP_BASE + 0x00000200)
-#define RKISP1_CIF_ISP_GAMMA_OUT_Y_3           (RKISP1_CIF_ISP_BASE + 0x00000204)
-#define RKISP1_CIF_ISP_GAMMA_OUT_Y_4           (RKISP1_CIF_ISP_BASE + 0x00000208)
-#define RKISP1_CIF_ISP_GAMMA_OUT_Y_5           (RKISP1_CIF_ISP_BASE + 0x0000020C)
-#define RKISP1_CIF_ISP_GAMMA_OUT_Y_6           (RKISP1_CIF_ISP_BASE + 0x00000210)
-#define RKISP1_CIF_ISP_GAMMA_OUT_Y_7           (RKISP1_CIF_ISP_BASE + 0x00000214)
-#define RKISP1_CIF_ISP_GAMMA_OUT_Y_8           (RKISP1_CIF_ISP_BASE + 0x00000218)
-#define RKISP1_CIF_ISP_GAMMA_OUT_Y_9           (RKISP1_CIF_ISP_BASE + 0x0000021C)
-#define RKISP1_CIF_ISP_GAMMA_OUT_Y_10          (RKISP1_CIF_ISP_BASE + 0x00000220)
-#define RKISP1_CIF_ISP_GAMMA_OUT_Y_11          (RKISP1_CIF_ISP_BASE + 0x00000224)
-#define RKISP1_CIF_ISP_GAMMA_OUT_Y_12          (RKISP1_CIF_ISP_BASE + 0x00000228)
-#define RKISP1_CIF_ISP_GAMMA_OUT_Y_13          (RKISP1_CIF_ISP_BASE + 0x0000022C)
-#define RKISP1_CIF_ISP_GAMMA_OUT_Y_14          (RKISP1_CIF_ISP_BASE + 0x00000230)
-#define RKISP1_CIF_ISP_GAMMA_OUT_Y_15          (RKISP1_CIF_ISP_BASE + 0x00000234)
-#define RKISP1_CIF_ISP_GAMMA_OUT_Y_16          (RKISP1_CIF_ISP_BASE + 0x00000238)
-#define RKISP1_CIF_ISP_ERR                     (RKISP1_CIF_ISP_BASE + 0x0000023C)
-#define RKISP1_CIF_ISP_ERR_CLR                 (RKISP1_CIF_ISP_BASE + 0x00000240)
-#define RKISP1_CIF_ISP_FRAME_COUNT             (RKISP1_CIF_ISP_BASE + 0x00000244)
-#define RKISP1_CIF_ISP_CT_OFFSET_R             (RKISP1_CIF_ISP_BASE + 0x00000248)
-#define RKISP1_CIF_ISP_CT_OFFSET_G             (RKISP1_CIF_ISP_BASE + 0x0000024C)
-#define RKISP1_CIF_ISP_CT_OFFSET_B             (RKISP1_CIF_ISP_BASE + 0x00000250)
-
-#define RKISP1_CIF_ISP_FLASH_BASE              0x00000660
-#define RKISP1_CIF_ISP_FLASH_CMD               (RKISP1_CIF_ISP_FLASH_BASE + 0x00000000)
-#define RKISP1_CIF_ISP_FLASH_CONFIG            (RKISP1_CIF_ISP_FLASH_BASE + 0x00000004)
-#define RKISP1_CIF_ISP_FLASH_PREDIV            (RKISP1_CIF_ISP_FLASH_BASE + 0x00000008)
-#define RKISP1_CIF_ISP_FLASH_DELAY             (RKISP1_CIF_ISP_FLASH_BASE + 0x0000000C)
-#define RKISP1_CIF_ISP_FLASH_TIME              (RKISP1_CIF_ISP_FLASH_BASE + 0x00000010)
-#define RKISP1_CIF_ISP_FLASH_MAXP              (RKISP1_CIF_ISP_FLASH_BASE + 0x00000014)
-
-#define RKISP1_CIF_ISP_SH_BASE                 0x00000680
-#define RKISP1_CIF_ISP_SH_CTRL                 (RKISP1_CIF_ISP_SH_BASE + 0x00000000)
-#define RKISP1_CIF_ISP_SH_PREDIV               (RKISP1_CIF_ISP_SH_BASE + 0x00000004)
-#define RKISP1_CIF_ISP_SH_DELAY                        (RKISP1_CIF_ISP_SH_BASE + 0x00000008)
-#define RKISP1_CIF_ISP_SH_TIME                 (RKISP1_CIF_ISP_SH_BASE + 0x0000000C)
-
-#define RKISP1_CIF_C_PROC_BASE                 0x00000800
-#define RKISP1_CIF_C_PROC_CTRL                 (RKISP1_CIF_C_PROC_BASE + 0x00000000)
-#define RKISP1_CIF_C_PROC_CONTRAST             (RKISP1_CIF_C_PROC_BASE + 0x00000004)
-#define RKISP1_CIF_C_PROC_BRIGHTNESS           (RKISP1_CIF_C_PROC_BASE + 0x00000008)
-#define RKISP1_CIF_C_PROC_SATURATION           (RKISP1_CIF_C_PROC_BASE + 0x0000000C)
-#define RKISP1_CIF_C_PROC_HUE                  (RKISP1_CIF_C_PROC_BASE + 0x00000010)
-
-#define RKISP1_CIF_DUAL_CROP_BASE              0x00000880
-#define RKISP1_CIF_DUAL_CROP_CTRL              (RKISP1_CIF_DUAL_CROP_BASE + 0x00000000)
-#define RKISP1_CIF_DUAL_CROP_M_H_OFFS          (RKISP1_CIF_DUAL_CROP_BASE + 0x00000004)
-#define RKISP1_CIF_DUAL_CROP_M_V_OFFS          (RKISP1_CIF_DUAL_CROP_BASE + 0x00000008)
-#define RKISP1_CIF_DUAL_CROP_M_H_SIZE          (RKISP1_CIF_DUAL_CROP_BASE + 0x0000000C)
-#define RKISP1_CIF_DUAL_CROP_M_V_SIZE          (RKISP1_CIF_DUAL_CROP_BASE + 0x00000010)
-#define RKISP1_CIF_DUAL_CROP_S_H_OFFS          (RKISP1_CIF_DUAL_CROP_BASE + 0x00000014)
-#define RKISP1_CIF_DUAL_CROP_S_V_OFFS          (RKISP1_CIF_DUAL_CROP_BASE + 0x00000018)
-#define RKISP1_CIF_DUAL_CROP_S_H_SIZE          (RKISP1_CIF_DUAL_CROP_BASE + 0x0000001C)
-#define RKISP1_CIF_DUAL_CROP_S_V_SIZE          (RKISP1_CIF_DUAL_CROP_BASE + 0x00000020)
-#define RKISP1_CIF_DUAL_CROP_M_H_OFFS_SHD      (RKISP1_CIF_DUAL_CROP_BASE + 0x00000024)
-#define RKISP1_CIF_DUAL_CROP_M_V_OFFS_SHD      (RKISP1_CIF_DUAL_CROP_BASE + 0x00000028)
-#define RKISP1_CIF_DUAL_CROP_M_H_SIZE_SHD      (RKISP1_CIF_DUAL_CROP_BASE + 0x0000002C)
-#define RKISP1_CIF_DUAL_CROP_M_V_SIZE_SHD      (RKISP1_CIF_DUAL_CROP_BASE + 0x00000030)
-#define RKISP1_CIF_DUAL_CROP_S_H_OFFS_SHD      (RKISP1_CIF_DUAL_CROP_BASE + 0x00000034)
-#define RKISP1_CIF_DUAL_CROP_S_V_OFFS_SHD      (RKISP1_CIF_DUAL_CROP_BASE + 0x00000038)
-#define RKISP1_CIF_DUAL_CROP_S_H_SIZE_SHD      (RKISP1_CIF_DUAL_CROP_BASE + 0x0000003C)
-#define RKISP1_CIF_DUAL_CROP_S_V_SIZE_SHD      (RKISP1_CIF_DUAL_CROP_BASE + 0x00000040)
-
-#define RKISP1_CIF_MRSZ_BASE                   0x00000C00
-#define RKISP1_CIF_MRSZ_CTRL                   (RKISP1_CIF_MRSZ_BASE + 0x00000000)
-#define RKISP1_CIF_MRSZ_SCALE_HY               (RKISP1_CIF_MRSZ_BASE + 0x00000004)
-#define RKISP1_CIF_MRSZ_SCALE_HCB              (RKISP1_CIF_MRSZ_BASE + 0x00000008)
-#define RKISP1_CIF_MRSZ_SCALE_HCR              (RKISP1_CIF_MRSZ_BASE + 0x0000000C)
-#define RKISP1_CIF_MRSZ_SCALE_VY               (RKISP1_CIF_MRSZ_BASE + 0x00000010)
-#define RKISP1_CIF_MRSZ_SCALE_VC               (RKISP1_CIF_MRSZ_BASE + 0x00000014)
-#define RKISP1_CIF_MRSZ_PHASE_HY               (RKISP1_CIF_MRSZ_BASE + 0x00000018)
-#define RKISP1_CIF_MRSZ_PHASE_HC               (RKISP1_CIF_MRSZ_BASE + 0x0000001C)
-#define RKISP1_CIF_MRSZ_PHASE_VY               (RKISP1_CIF_MRSZ_BASE + 0x00000020)
-#define RKISP1_CIF_MRSZ_PHASE_VC               (RKISP1_CIF_MRSZ_BASE + 0x00000024)
-#define RKISP1_CIF_MRSZ_SCALE_LUT_ADDR         (RKISP1_CIF_MRSZ_BASE + 0x00000028)
-#define RKISP1_CIF_MRSZ_SCALE_LUT              (RKISP1_CIF_MRSZ_BASE + 0x0000002C)
-#define RKISP1_CIF_MRSZ_CTRL_SHD               (RKISP1_CIF_MRSZ_BASE + 0x00000030)
-#define RKISP1_CIF_MRSZ_SCALE_HY_SHD           (RKISP1_CIF_MRSZ_BASE + 0x00000034)
-#define RKISP1_CIF_MRSZ_SCALE_HCB_SHD          (RKISP1_CIF_MRSZ_BASE + 0x00000038)
-#define RKISP1_CIF_MRSZ_SCALE_HCR_SHD          (RKISP1_CIF_MRSZ_BASE + 0x0000003C)
-#define RKISP1_CIF_MRSZ_SCALE_VY_SHD           (RKISP1_CIF_MRSZ_BASE + 0x00000040)
-#define RKISP1_CIF_MRSZ_SCALE_VC_SHD           (RKISP1_CIF_MRSZ_BASE + 0x00000044)
-#define RKISP1_CIF_MRSZ_PHASE_HY_SHD           (RKISP1_CIF_MRSZ_BASE + 0x00000048)
-#define RKISP1_CIF_MRSZ_PHASE_HC_SHD           (RKISP1_CIF_MRSZ_BASE + 0x0000004C)
-#define RKISP1_CIF_MRSZ_PHASE_VY_SHD           (RKISP1_CIF_MRSZ_BASE + 0x00000050)
-#define RKISP1_CIF_MRSZ_PHASE_VC_SHD           (RKISP1_CIF_MRSZ_BASE + 0x00000054)
-
-#define RKISP1_CIF_SRSZ_BASE                   0x00001000
-#define RKISP1_CIF_SRSZ_CTRL                   (RKISP1_CIF_SRSZ_BASE + 0x00000000)
-#define RKISP1_CIF_SRSZ_SCALE_HY               (RKISP1_CIF_SRSZ_BASE + 0x00000004)
-#define RKISP1_CIF_SRSZ_SCALE_HCB              (RKISP1_CIF_SRSZ_BASE + 0x00000008)
-#define RKISP1_CIF_SRSZ_SCALE_HCR              (RKISP1_CIF_SRSZ_BASE + 0x0000000C)
-#define RKISP1_CIF_SRSZ_SCALE_VY               (RKISP1_CIF_SRSZ_BASE + 0x00000010)
-#define RKISP1_CIF_SRSZ_SCALE_VC               (RKISP1_CIF_SRSZ_BASE + 0x00000014)
-#define RKISP1_CIF_SRSZ_PHASE_HY               (RKISP1_CIF_SRSZ_BASE + 0x00000018)
-#define RKISP1_CIF_SRSZ_PHASE_HC               (RKISP1_CIF_SRSZ_BASE + 0x0000001C)
-#define RKISP1_CIF_SRSZ_PHASE_VY               (RKISP1_CIF_SRSZ_BASE + 0x00000020)
-#define RKISP1_CIF_SRSZ_PHASE_VC               (RKISP1_CIF_SRSZ_BASE + 0x00000024)
-#define RKISP1_CIF_SRSZ_SCALE_LUT_ADDR         (RKISP1_CIF_SRSZ_BASE + 0x00000028)
-#define RKISP1_CIF_SRSZ_SCALE_LUT              (RKISP1_CIF_SRSZ_BASE + 0x0000002C)
-#define RKISP1_CIF_SRSZ_CTRL_SHD               (RKISP1_CIF_SRSZ_BASE + 0x00000030)
-#define RKISP1_CIF_SRSZ_SCALE_HY_SHD           (RKISP1_CIF_SRSZ_BASE + 0x00000034)
-#define RKISP1_CIF_SRSZ_SCALE_HCB_SHD          (RKISP1_CIF_SRSZ_BASE + 0x00000038)
-#define RKISP1_CIF_SRSZ_SCALE_HCR_SHD          (RKISP1_CIF_SRSZ_BASE + 0x0000003C)
-#define RKISP1_CIF_SRSZ_SCALE_VY_SHD           (RKISP1_CIF_SRSZ_BASE + 0x00000040)
-#define RKISP1_CIF_SRSZ_SCALE_VC_SHD           (RKISP1_CIF_SRSZ_BASE + 0x00000044)
-#define RKISP1_CIF_SRSZ_PHASE_HY_SHD           (RKISP1_CIF_SRSZ_BASE + 0x00000048)
-#define RKISP1_CIF_SRSZ_PHASE_HC_SHD           (RKISP1_CIF_SRSZ_BASE + 0x0000004C)
-#define RKISP1_CIF_SRSZ_PHASE_VY_SHD           (RKISP1_CIF_SRSZ_BASE + 0x00000050)
-#define RKISP1_CIF_SRSZ_PHASE_VC_SHD           (RKISP1_CIF_SRSZ_BASE + 0x00000054)
-
-#define RKISP1_CIF_MI_BASE                     0x00001400
-#define RKISP1_CIF_MI_CTRL                     (RKISP1_CIF_MI_BASE + 0x00000000)
-#define RKISP1_CIF_MI_INIT                     (RKISP1_CIF_MI_BASE + 0x00000004)
-#define RKISP1_CIF_MI_MP_Y_BASE_AD_INIT                (RKISP1_CIF_MI_BASE + 0x00000008)
-#define RKISP1_CIF_MI_MP_Y_SIZE_INIT           (RKISP1_CIF_MI_BASE + 0x0000000C)
-#define RKISP1_CIF_MI_MP_Y_OFFS_CNT_INIT       (RKISP1_CIF_MI_BASE + 0x00000010)
-#define RKISP1_CIF_MI_MP_Y_OFFS_CNT_START      (RKISP1_CIF_MI_BASE + 0x00000014)
-#define RKISP1_CIF_MI_MP_Y_IRQ_OFFS_INIT       (RKISP1_CIF_MI_BASE + 0x00000018)
-#define RKISP1_CIF_MI_MP_CB_BASE_AD_INIT       (RKISP1_CIF_MI_BASE + 0x0000001C)
-#define RKISP1_CIF_MI_MP_CB_SIZE_INIT          (RKISP1_CIF_MI_BASE + 0x00000020)
-#define RKISP1_CIF_MI_MP_CB_OFFS_CNT_INIT      (RKISP1_CIF_MI_BASE + 0x00000024)
-#define RKISP1_CIF_MI_MP_CB_OFFS_CNT_START     (RKISP1_CIF_MI_BASE + 0x00000028)
-#define RKISP1_CIF_MI_MP_CR_BASE_AD_INIT       (RKISP1_CIF_MI_BASE + 0x0000002C)
-#define RKISP1_CIF_MI_MP_CR_SIZE_INIT          (RKISP1_CIF_MI_BASE + 0x00000030)
-#define RKISP1_CIF_MI_MP_CR_OFFS_CNT_INIT      (RKISP1_CIF_MI_BASE + 0x00000034)
-#define RKISP1_CIF_MI_MP_CR_OFFS_CNT_START     (RKISP1_CIF_MI_BASE + 0x00000038)
-#define RKISP1_CIF_MI_SP_Y_BASE_AD_INIT                (RKISP1_CIF_MI_BASE + 0x0000003C)
-#define RKISP1_CIF_MI_SP_Y_SIZE_INIT           (RKISP1_CIF_MI_BASE + 0x00000040)
-#define RKISP1_CIF_MI_SP_Y_OFFS_CNT_INIT       (RKISP1_CIF_MI_BASE + 0x00000044)
-#define RKISP1_CIF_MI_SP_Y_OFFS_CNT_START      (RKISP1_CIF_MI_BASE + 0x00000048)
-#define RKISP1_CIF_MI_SP_Y_LLENGTH             (RKISP1_CIF_MI_BASE + 0x0000004C)
-#define RKISP1_CIF_MI_SP_CB_BASE_AD_INIT       (RKISP1_CIF_MI_BASE + 0x00000050)
-#define RKISP1_CIF_MI_SP_CB_SIZE_INIT          (RKISP1_CIF_MI_BASE + 0x00000054)
-#define RKISP1_CIF_MI_SP_CB_OFFS_CNT_INIT      (RKISP1_CIF_MI_BASE + 0x00000058)
-#define RKISP1_CIF_MI_SP_CB_OFFS_CNT_START     (RKISP1_CIF_MI_BASE + 0x0000005C)
-#define RKISP1_CIF_MI_SP_CR_BASE_AD_INIT       (RKISP1_CIF_MI_BASE + 0x00000060)
-#define RKISP1_CIF_MI_SP_CR_SIZE_INIT          (RKISP1_CIF_MI_BASE + 0x00000064)
-#define RKISP1_CIF_MI_SP_CR_OFFS_CNT_INIT      (RKISP1_CIF_MI_BASE + 0x00000068)
-#define RKISP1_CIF_MI_SP_CR_OFFS_CNT_START     (RKISP1_CIF_MI_BASE + 0x0000006C)
-#define RKISP1_CIF_MI_BYTE_CNT                 (RKISP1_CIF_MI_BASE + 0x00000070)
-#define RKISP1_CIF_MI_CTRL_SHD                 (RKISP1_CIF_MI_BASE + 0x00000074)
-#define RKISP1_CIF_MI_MP_Y_BASE_AD_SHD         (RKISP1_CIF_MI_BASE + 0x00000078)
-#define RKISP1_CIF_MI_MP_Y_SIZE_SHD            (RKISP1_CIF_MI_BASE + 0x0000007C)
-#define RKISP1_CIF_MI_MP_Y_OFFS_CNT_SHD                (RKISP1_CIF_MI_BASE + 0x00000080)
-#define RKISP1_CIF_MI_MP_Y_IRQ_OFFS_SHD                (RKISP1_CIF_MI_BASE + 0x00000084)
-#define RKISP1_CIF_MI_MP_CB_BASE_AD_SHD                (RKISP1_CIF_MI_BASE + 0x00000088)
-#define RKISP1_CIF_MI_MP_CB_SIZE_SHD           (RKISP1_CIF_MI_BASE + 0x0000008C)
-#define RKISP1_CIF_MI_MP_CB_OFFS_CNT_SHD       (RKISP1_CIF_MI_BASE + 0x00000090)
-#define RKISP1_CIF_MI_MP_CR_BASE_AD_SHD                (RKISP1_CIF_MI_BASE + 0x00000094)
-#define RKISP1_CIF_MI_MP_CR_SIZE_SHD           (RKISP1_CIF_MI_BASE + 0x00000098)
-#define RKISP1_CIF_MI_MP_CR_OFFS_CNT_SHD       (RKISP1_CIF_MI_BASE + 0x0000009C)
-#define RKISP1_CIF_MI_SP_Y_BASE_AD_SHD         (RKISP1_CIF_MI_BASE + 0x000000A0)
-#define RKISP1_CIF_MI_SP_Y_SIZE_SHD            (RKISP1_CIF_MI_BASE + 0x000000A4)
-#define RKISP1_CIF_MI_SP_Y_OFFS_CNT_SHD                (RKISP1_CIF_MI_BASE + 0x000000A8)
-#define RKISP1_CIF_MI_SP_CB_BASE_AD_SHD                (RKISP1_CIF_MI_BASE + 0x000000B0)
-#define RKISP1_CIF_MI_SP_CB_SIZE_SHD           (RKISP1_CIF_MI_BASE + 0x000000B4)
-#define RKISP1_CIF_MI_SP_CB_OFFS_CNT_SHD       (RKISP1_CIF_MI_BASE + 0x000000B8)
-#define RKISP1_CIF_MI_SP_CR_BASE_AD_SHD                (RKISP1_CIF_MI_BASE + 0x000000BC)
-#define RKISP1_CIF_MI_SP_CR_SIZE_SHD           (RKISP1_CIF_MI_BASE + 0x000000C0)
-#define RKISP1_CIF_MI_SP_CR_OFFS_CNT_SHD       (RKISP1_CIF_MI_BASE + 0x000000C4)
-#define RKISP1_CIF_MI_DMA_Y_PIC_START_AD       (RKISP1_CIF_MI_BASE + 0x000000C8)
-#define RKISP1_CIF_MI_DMA_Y_PIC_WIDTH          (RKISP1_CIF_MI_BASE + 0x000000CC)
-#define RKISP1_CIF_MI_DMA_Y_LLENGTH            (RKISP1_CIF_MI_BASE + 0x000000D0)
-#define RKISP1_CIF_MI_DMA_Y_PIC_SIZE           (RKISP1_CIF_MI_BASE + 0x000000D4)
-#define RKISP1_CIF_MI_DMA_CB_PIC_START_AD      (RKISP1_CIF_MI_BASE + 0x000000D8)
-#define RKISP1_CIF_MI_DMA_CR_PIC_START_AD      (RKISP1_CIF_MI_BASE + 0x000000E8)
-#define RKISP1_CIF_MI_IMSC                     (RKISP1_CIF_MI_BASE + 0x000000F8)
-#define RKISP1_CIF_MI_RIS                      (RKISP1_CIF_MI_BASE + 0x000000FC)
-#define RKISP1_CIF_MI_MIS                      (RKISP1_CIF_MI_BASE + 0x00000100)
-#define RKISP1_CIF_MI_ICR                      (RKISP1_CIF_MI_BASE + 0x00000104)
-#define RKISP1_CIF_MI_ISR                      (RKISP1_CIF_MI_BASE + 0x00000108)
-#define RKISP1_CIF_MI_STATUS                   (RKISP1_CIF_MI_BASE + 0x0000010C)
-#define RKISP1_CIF_MI_STATUS_CLR               (RKISP1_CIF_MI_BASE + 0x00000110)
-#define RKISP1_CIF_MI_SP_Y_PIC_WIDTH           (RKISP1_CIF_MI_BASE + 0x00000114)
-#define RKISP1_CIF_MI_SP_Y_PIC_HEIGHT          (RKISP1_CIF_MI_BASE + 0x00000118)
-#define RKISP1_CIF_MI_SP_Y_PIC_SIZE            (RKISP1_CIF_MI_BASE + 0x0000011C)
-#define RKISP1_CIF_MI_DMA_CTRL                 (RKISP1_CIF_MI_BASE + 0x00000120)
-#define RKISP1_CIF_MI_DMA_START                        (RKISP1_CIF_MI_BASE + 0x00000124)
-#define RKISP1_CIF_MI_DMA_STATUS               (RKISP1_CIF_MI_BASE + 0x00000128)
-#define RKISP1_CIF_MI_PIXEL_COUNT              (RKISP1_CIF_MI_BASE + 0x0000012C)
-#define RKISP1_CIF_MI_MP_Y_BASE_AD_INIT2       (RKISP1_CIF_MI_BASE + 0x00000130)
-#define RKISP1_CIF_MI_MP_CB_BASE_AD_INIT2      (RKISP1_CIF_MI_BASE + 0x00000134)
-#define RKISP1_CIF_MI_MP_CR_BASE_AD_INIT2      (RKISP1_CIF_MI_BASE + 0x00000138)
-#define RKISP1_CIF_MI_SP_Y_BASE_AD_INIT2       (RKISP1_CIF_MI_BASE + 0x0000013C)
-#define RKISP1_CIF_MI_SP_CB_BASE_AD_INIT2      (RKISP1_CIF_MI_BASE + 0x00000140)
-#define RKISP1_CIF_MI_SP_CR_BASE_AD_INIT2      (RKISP1_CIF_MI_BASE + 0x00000144)
-#define RKISP1_CIF_MI_XTD_FORMAT_CTRL          (RKISP1_CIF_MI_BASE + 0x00000148)
-
-#define RKISP1_CIF_SMIA_BASE                   0x00001A00
-#define RKISP1_CIF_SMIA_CTRL                   (RKISP1_CIF_SMIA_BASE + 0x00000000)
-#define RKISP1_CIF_SMIA_STATUS                 (RKISP1_CIF_SMIA_BASE + 0x00000004)
-#define RKISP1_CIF_SMIA_IMSC                   (RKISP1_CIF_SMIA_BASE + 0x00000008)
-#define RKISP1_CIF_SMIA_RIS                    (RKISP1_CIF_SMIA_BASE + 0x0000000C)
-#define RKISP1_CIF_SMIA_MIS                    (RKISP1_CIF_SMIA_BASE + 0x00000010)
-#define RKISP1_CIF_SMIA_ICR                    (RKISP1_CIF_SMIA_BASE + 0x00000014)
-#define RKISP1_CIF_SMIA_ISR                    (RKISP1_CIF_SMIA_BASE + 0x00000018)
-#define RKISP1_CIF_SMIA_DATA_FORMAT_SEL                (RKISP1_CIF_SMIA_BASE + 0x0000001C)
-#define RKISP1_CIF_SMIA_SOF_EMB_DATA_LINES     (RKISP1_CIF_SMIA_BASE + 0x00000020)
-#define RKISP1_CIF_SMIA_EMB_HSTART             (RKISP1_CIF_SMIA_BASE + 0x00000024)
-#define RKISP1_CIF_SMIA_EMB_HSIZE              (RKISP1_CIF_SMIA_BASE + 0x00000028)
-#define RKISP1_CIF_SMIA_EMB_VSTART             (RKISP1_CIF_SMIA_BASE + 0x0000002c)
-#define RKISP1_CIF_SMIA_NUM_LINES              (RKISP1_CIF_SMIA_BASE + 0x00000030)
-#define RKISP1_CIF_SMIA_EMB_DATA_FIFO          (RKISP1_CIF_SMIA_BASE + 0x00000034)
-#define RKISP1_CIF_SMIA_EMB_DATA_WATERMARK     (RKISP1_CIF_SMIA_BASE + 0x00000038)
-
-#define RKISP1_CIF_MIPI_BASE                   0x00001C00
-#define RKISP1_CIF_MIPI_CTRL                   (RKISP1_CIF_MIPI_BASE + 0x00000000)
-#define RKISP1_CIF_MIPI_STATUS                 (RKISP1_CIF_MIPI_BASE + 0x00000004)
-#define RKISP1_CIF_MIPI_IMSC                   (RKISP1_CIF_MIPI_BASE + 0x00000008)
-#define RKISP1_CIF_MIPI_RIS                    (RKISP1_CIF_MIPI_BASE + 0x0000000C)
-#define RKISP1_CIF_MIPI_MIS                    (RKISP1_CIF_MIPI_BASE + 0x00000010)
-#define RKISP1_CIF_MIPI_ICR                    (RKISP1_CIF_MIPI_BASE + 0x00000014)
-#define RKISP1_CIF_MIPI_ISR                    (RKISP1_CIF_MIPI_BASE + 0x00000018)
-#define RKISP1_CIF_MIPI_CUR_DATA_ID            (RKISP1_CIF_MIPI_BASE + 0x0000001C)
-#define RKISP1_CIF_MIPI_IMG_DATA_SEL           (RKISP1_CIF_MIPI_BASE + 0x00000020)
-#define RKISP1_CIF_MIPI_ADD_DATA_SEL_1         (RKISP1_CIF_MIPI_BASE + 0x00000024)
-#define RKISP1_CIF_MIPI_ADD_DATA_SEL_2         (RKISP1_CIF_MIPI_BASE + 0x00000028)
-#define RKISP1_CIF_MIPI_ADD_DATA_SEL_3         (RKISP1_CIF_MIPI_BASE + 0x0000002C)
-#define RKISP1_CIF_MIPI_ADD_DATA_SEL_4         (RKISP1_CIF_MIPI_BASE + 0x00000030)
-#define RKISP1_CIF_MIPI_ADD_DATA_FIFO          (RKISP1_CIF_MIPI_BASE + 0x00000034)
-#define RKISP1_CIF_MIPI_FIFO_FILL_LEVEL                (RKISP1_CIF_MIPI_BASE + 0x00000038)
-#define RKISP1_CIF_MIPI_COMPRESSED_MODE                (RKISP1_CIF_MIPI_BASE + 0x0000003C)
-#define RKISP1_CIF_MIPI_FRAME                  (RKISP1_CIF_MIPI_BASE + 0x00000040)
-#define RKISP1_CIF_MIPI_GEN_SHORT_DT           (RKISP1_CIF_MIPI_BASE + 0x00000044)
-#define RKISP1_CIF_MIPI_GEN_SHORT_8_9          (RKISP1_CIF_MIPI_BASE + 0x00000048)
-#define RKISP1_CIF_MIPI_GEN_SHORT_A_B          (RKISP1_CIF_MIPI_BASE + 0x0000004C)
-#define RKISP1_CIF_MIPI_GEN_SHORT_C_D          (RKISP1_CIF_MIPI_BASE + 0x00000050)
-#define RKISP1_CIF_MIPI_GEN_SHORT_E_F          (RKISP1_CIF_MIPI_BASE + 0x00000054)
-
-#define RKISP1_CIF_ISP_AFM_BASE                        0x00002000
-#define RKISP1_CIF_ISP_AFM_CTRL                        (RKISP1_CIF_ISP_AFM_BASE + 0x00000000)
-#define RKISP1_CIF_ISP_AFM_LT_A                        (RKISP1_CIF_ISP_AFM_BASE + 0x00000004)
-#define RKISP1_CIF_ISP_AFM_RB_A                        (RKISP1_CIF_ISP_AFM_BASE + 0x00000008)
-#define RKISP1_CIF_ISP_AFM_LT_B                        (RKISP1_CIF_ISP_AFM_BASE + 0x0000000C)
-#define RKISP1_CIF_ISP_AFM_RB_B                        (RKISP1_CIF_ISP_AFM_BASE + 0x00000010)
-#define RKISP1_CIF_ISP_AFM_LT_C                        (RKISP1_CIF_ISP_AFM_BASE + 0x00000014)
-#define RKISP1_CIF_ISP_AFM_RB_C                        (RKISP1_CIF_ISP_AFM_BASE + 0x00000018)
-#define RKISP1_CIF_ISP_AFM_THRES               (RKISP1_CIF_ISP_AFM_BASE + 0x0000001C)
-#define RKISP1_CIF_ISP_AFM_VAR_SHIFT           (RKISP1_CIF_ISP_AFM_BASE + 0x00000020)
-#define RKISP1_CIF_ISP_AFM_SUM_A               (RKISP1_CIF_ISP_AFM_BASE + 0x00000024)
-#define RKISP1_CIF_ISP_AFM_SUM_B               (RKISP1_CIF_ISP_AFM_BASE + 0x00000028)
-#define RKISP1_CIF_ISP_AFM_SUM_C               (RKISP1_CIF_ISP_AFM_BASE + 0x0000002C)
-#define RKISP1_CIF_ISP_AFM_LUM_A               (RKISP1_CIF_ISP_AFM_BASE + 0x00000030)
-#define RKISP1_CIF_ISP_AFM_LUM_B               (RKISP1_CIF_ISP_AFM_BASE + 0x00000034)
-#define RKISP1_CIF_ISP_AFM_LUM_C               (RKISP1_CIF_ISP_AFM_BASE + 0x00000038)
-
-#define RKISP1_CIF_ISP_LSC_BASE                        0x00002200
-#define RKISP1_CIF_ISP_LSC_CTRL                        (RKISP1_CIF_ISP_LSC_BASE + 0x00000000)
-#define RKISP1_CIF_ISP_LSC_R_TABLE_ADDR                (RKISP1_CIF_ISP_LSC_BASE + 0x00000004)
-#define RKISP1_CIF_ISP_LSC_GR_TABLE_ADDR       (RKISP1_CIF_ISP_LSC_BASE + 0x00000008)
-#define RKISP1_CIF_ISP_LSC_B_TABLE_ADDR                (RKISP1_CIF_ISP_LSC_BASE + 0x0000000C)
-#define RKISP1_CIF_ISP_LSC_GB_TABLE_ADDR       (RKISP1_CIF_ISP_LSC_BASE + 0x00000010)
-#define RKISP1_CIF_ISP_LSC_R_TABLE_DATA                (RKISP1_CIF_ISP_LSC_BASE + 0x00000014)
-#define RKISP1_CIF_ISP_LSC_GR_TABLE_DATA       (RKISP1_CIF_ISP_LSC_BASE + 0x00000018)
-#define RKISP1_CIF_ISP_LSC_B_TABLE_DATA                (RKISP1_CIF_ISP_LSC_BASE + 0x0000001C)
-#define RKISP1_CIF_ISP_LSC_GB_TABLE_DATA       (RKISP1_CIF_ISP_LSC_BASE + 0x00000020)
-#define RKISP1_CIF_ISP_LSC_XGRAD_01            (RKISP1_CIF_ISP_LSC_BASE + 0x00000024)
-#define RKISP1_CIF_ISP_LSC_XGRAD_23            (RKISP1_CIF_ISP_LSC_BASE + 0x00000028)
-#define RKISP1_CIF_ISP_LSC_XGRAD_45            (RKISP1_CIF_ISP_LSC_BASE + 0x0000002C)
-#define RKISP1_CIF_ISP_LSC_XGRAD_67            (RKISP1_CIF_ISP_LSC_BASE + 0x00000030)
-#define RKISP1_CIF_ISP_LSC_YGRAD_01            (RKISP1_CIF_ISP_LSC_BASE + 0x00000034)
-#define RKISP1_CIF_ISP_LSC_YGRAD_23            (RKISP1_CIF_ISP_LSC_BASE + 0x00000038)
-#define RKISP1_CIF_ISP_LSC_YGRAD_45            (RKISP1_CIF_ISP_LSC_BASE + 0x0000003C)
-#define RKISP1_CIF_ISP_LSC_YGRAD_67            (RKISP1_CIF_ISP_LSC_BASE + 0x00000040)
-#define RKISP1_CIF_ISP_LSC_XSIZE_01            (RKISP1_CIF_ISP_LSC_BASE + 0x00000044)
-#define RKISP1_CIF_ISP_LSC_XSIZE_23            (RKISP1_CIF_ISP_LSC_BASE + 0x00000048)
-#define RKISP1_CIF_ISP_LSC_XSIZE_45            (RKISP1_CIF_ISP_LSC_BASE + 0x0000004C)
-#define RKISP1_CIF_ISP_LSC_XSIZE_67            (RKISP1_CIF_ISP_LSC_BASE + 0x00000050)
-#define RKISP1_CIF_ISP_LSC_YSIZE_01            (RKISP1_CIF_ISP_LSC_BASE + 0x00000054)
-#define RKISP1_CIF_ISP_LSC_YSIZE_23            (RKISP1_CIF_ISP_LSC_BASE + 0x00000058)
-#define RKISP1_CIF_ISP_LSC_YSIZE_45            (RKISP1_CIF_ISP_LSC_BASE + 0x0000005C)
-#define RKISP1_CIF_ISP_LSC_YSIZE_67            (RKISP1_CIF_ISP_LSC_BASE + 0x00000060)
-#define RKISP1_CIF_ISP_LSC_TABLE_SEL           (RKISP1_CIF_ISP_LSC_BASE + 0x00000064)
-#define RKISP1_CIF_ISP_LSC_STATUS              (RKISP1_CIF_ISP_LSC_BASE + 0x00000068)
-
-#define RKISP1_CIF_ISP_IS_BASE                 0x00002300
-#define RKISP1_CIF_ISP_IS_CTRL                 (RKISP1_CIF_ISP_IS_BASE + 0x00000000)
-#define RKISP1_CIF_ISP_IS_RECENTER             (RKISP1_CIF_ISP_IS_BASE + 0x00000004)
-#define RKISP1_CIF_ISP_IS_H_OFFS               (RKISP1_CIF_ISP_IS_BASE + 0x00000008)
-#define RKISP1_CIF_ISP_IS_V_OFFS               (RKISP1_CIF_ISP_IS_BASE + 0x0000000C)
-#define RKISP1_CIF_ISP_IS_H_SIZE               (RKISP1_CIF_ISP_IS_BASE + 0x00000010)
-#define RKISP1_CIF_ISP_IS_V_SIZE               (RKISP1_CIF_ISP_IS_BASE + 0x00000014)
-#define RKISP1_CIF_ISP_IS_MAX_DX               (RKISP1_CIF_ISP_IS_BASE + 0x00000018)
-#define RKISP1_CIF_ISP_IS_MAX_DY               (RKISP1_CIF_ISP_IS_BASE + 0x0000001C)
-#define RKISP1_CIF_ISP_IS_DISPLACE             (RKISP1_CIF_ISP_IS_BASE + 0x00000020)
-#define RKISP1_CIF_ISP_IS_H_OFFS_SHD           (RKISP1_CIF_ISP_IS_BASE + 0x00000024)
-#define RKISP1_CIF_ISP_IS_V_OFFS_SHD           (RKISP1_CIF_ISP_IS_BASE + 0x00000028)
-#define RKISP1_CIF_ISP_IS_H_SIZE_SHD           (RKISP1_CIF_ISP_IS_BASE + 0x0000002C)
-#define RKISP1_CIF_ISP_IS_V_SIZE_SHD           (RKISP1_CIF_ISP_IS_BASE + 0x00000030)
-
-#define RKISP1_CIF_ISP_HIST_BASE               0x00002400
-
-#define RKISP1_CIF_ISP_HIST_PROP               (RKISP1_CIF_ISP_HIST_BASE + 0x00000000)
-#define RKISP1_CIF_ISP_HIST_H_OFFS             (RKISP1_CIF_ISP_HIST_BASE + 0x00000004)
-#define RKISP1_CIF_ISP_HIST_V_OFFS             (RKISP1_CIF_ISP_HIST_BASE + 0x00000008)
-#define RKISP1_CIF_ISP_HIST_H_SIZE             (RKISP1_CIF_ISP_HIST_BASE + 0x0000000C)
-#define RKISP1_CIF_ISP_HIST_V_SIZE             (RKISP1_CIF_ISP_HIST_BASE + 0x00000010)
-#define RKISP1_CIF_ISP_HIST_BIN_0              (RKISP1_CIF_ISP_HIST_BASE + 0x00000014)
-#define RKISP1_CIF_ISP_HIST_BIN_1              (RKISP1_CIF_ISP_HIST_BASE + 0x00000018)
-#define RKISP1_CIF_ISP_HIST_BIN_2              (RKISP1_CIF_ISP_HIST_BASE + 0x0000001C)
-#define RKISP1_CIF_ISP_HIST_BIN_3              (RKISP1_CIF_ISP_HIST_BASE + 0x00000020)
-#define RKISP1_CIF_ISP_HIST_BIN_4              (RKISP1_CIF_ISP_HIST_BASE + 0x00000024)
-#define RKISP1_CIF_ISP_HIST_BIN_5              (RKISP1_CIF_ISP_HIST_BASE + 0x00000028)
-#define RKISP1_CIF_ISP_HIST_BIN_6              (RKISP1_CIF_ISP_HIST_BASE + 0x0000002C)
-#define RKISP1_CIF_ISP_HIST_BIN_7              (RKISP1_CIF_ISP_HIST_BASE + 0x00000030)
-#define RKISP1_CIF_ISP_HIST_BIN_8              (RKISP1_CIF_ISP_HIST_BASE + 0x00000034)
-#define RKISP1_CIF_ISP_HIST_BIN_9              (RKISP1_CIF_ISP_HIST_BASE + 0x00000038)
-#define RKISP1_CIF_ISP_HIST_BIN_10             (RKISP1_CIF_ISP_HIST_BASE + 0x0000003C)
-#define RKISP1_CIF_ISP_HIST_BIN_11             (RKISP1_CIF_ISP_HIST_BASE + 0x00000040)
-#define RKISP1_CIF_ISP_HIST_BIN_12             (RKISP1_CIF_ISP_HIST_BASE + 0x00000044)
-#define RKISP1_CIF_ISP_HIST_BIN_13             (RKISP1_CIF_ISP_HIST_BASE + 0x00000048)
-#define RKISP1_CIF_ISP_HIST_BIN_14             (RKISP1_CIF_ISP_HIST_BASE + 0x0000004C)
-#define RKISP1_CIF_ISP_HIST_BIN_15             (RKISP1_CIF_ISP_HIST_BASE + 0x00000050)
-#define RKISP1_CIF_ISP_HIST_WEIGHT_00TO30      (RKISP1_CIF_ISP_HIST_BASE + 0x00000054)
-#define RKISP1_CIF_ISP_HIST_WEIGHT_40TO21      (RKISP1_CIF_ISP_HIST_BASE + 0x00000058)
-#define RKISP1_CIF_ISP_HIST_WEIGHT_31TO12      (RKISP1_CIF_ISP_HIST_BASE + 0x0000005C)
-#define RKISP1_CIF_ISP_HIST_WEIGHT_22TO03      (RKISP1_CIF_ISP_HIST_BASE + 0x00000060)
-#define RKISP1_CIF_ISP_HIST_WEIGHT_13TO43      (RKISP1_CIF_ISP_HIST_BASE + 0x00000064)
-#define RKISP1_CIF_ISP_HIST_WEIGHT_04TO34      (RKISP1_CIF_ISP_HIST_BASE + 0x00000068)
-#define RKISP1_CIF_ISP_HIST_WEIGHT_44          (RKISP1_CIF_ISP_HIST_BASE + 0x0000006C)
-
-#define RKISP1_CIF_ISP_FILT_BASE               0x00002500
-#define RKISP1_CIF_ISP_FILT_MODE               (RKISP1_CIF_ISP_FILT_BASE + 0x00000000)
-#define RKISP1_CIF_ISP_FILT_THRESH_BL0         (RKISP1_CIF_ISP_FILT_BASE + 0x00000028)
-#define RKISP1_CIF_ISP_FILT_THRESH_BL1         (RKISP1_CIF_ISP_FILT_BASE + 0x0000002c)
-#define RKISP1_CIF_ISP_FILT_THRESH_SH0         (RKISP1_CIF_ISP_FILT_BASE + 0x00000030)
-#define RKISP1_CIF_ISP_FILT_THRESH_SH1         (RKISP1_CIF_ISP_FILT_BASE + 0x00000034)
-#define RKISP1_CIF_ISP_FILT_LUM_WEIGHT         (RKISP1_CIF_ISP_FILT_BASE + 0x00000038)
-#define RKISP1_CIF_ISP_FILT_FAC_SH1            (RKISP1_CIF_ISP_FILT_BASE + 0x0000003c)
-#define RKISP1_CIF_ISP_FILT_FAC_SH0            (RKISP1_CIF_ISP_FILT_BASE + 0x00000040)
-#define RKISP1_CIF_ISP_FILT_FAC_MID            (RKISP1_CIF_ISP_FILT_BASE + 0x00000044)
-#define RKISP1_CIF_ISP_FILT_FAC_BL0            (RKISP1_CIF_ISP_FILT_BASE + 0x00000048)
-#define RKISP1_CIF_ISP_FILT_FAC_BL1            (RKISP1_CIF_ISP_FILT_BASE + 0x0000004C)
-
-#define RKISP1_CIF_ISP_CAC_BASE                        0x00002580
-#define RKISP1_CIF_ISP_CAC_CTRL                        (RKISP1_CIF_ISP_CAC_BASE + 0x00000000)
-#define RKISP1_CIF_ISP_CAC_COUNT_START         (RKISP1_CIF_ISP_CAC_BASE + 0x00000004)
-#define RKISP1_CIF_ISP_CAC_A                   (RKISP1_CIF_ISP_CAC_BASE + 0x00000008)
-#define RKISP1_CIF_ISP_CAC_B                   (RKISP1_CIF_ISP_CAC_BASE + 0x0000000C)
-#define RKISP1_CIF_ISP_CAC_C                   (RKISP1_CIF_ISP_CAC_BASE + 0x00000010)
-#define RKISP1_CIF_ISP_X_NORM                  (RKISP1_CIF_ISP_CAC_BASE + 0x00000014)
-#define RKISP1_CIF_ISP_Y_NORM                  (RKISP1_CIF_ISP_CAC_BASE + 0x00000018)
-
-#define RKISP1_CIF_ISP_EXP_BASE                        0x00002600
-#define RKISP1_CIF_ISP_EXP_CTRL                        (RKISP1_CIF_ISP_EXP_BASE + 0x00000000)
-#define RKISP1_CIF_ISP_EXP_H_OFFSET            (RKISP1_CIF_ISP_EXP_BASE + 0x00000004)
-#define RKISP1_CIF_ISP_EXP_V_OFFSET            (RKISP1_CIF_ISP_EXP_BASE + 0x00000008)
-#define RKISP1_CIF_ISP_EXP_H_SIZE              (RKISP1_CIF_ISP_EXP_BASE + 0x0000000C)
-#define RKISP1_CIF_ISP_EXP_V_SIZE              (RKISP1_CIF_ISP_EXP_BASE + 0x00000010)
-#define RKISP1_CIF_ISP_EXP_MEAN_00             (RKISP1_CIF_ISP_EXP_BASE + 0x00000014)
-#define RKISP1_CIF_ISP_EXP_MEAN_10             (RKISP1_CIF_ISP_EXP_BASE + 0x00000018)
-#define RKISP1_CIF_ISP_EXP_MEAN_20             (RKISP1_CIF_ISP_EXP_BASE + 0x0000001c)
-#define RKISP1_CIF_ISP_EXP_MEAN_30             (RKISP1_CIF_ISP_EXP_BASE + 0x00000020)
-#define RKISP1_CIF_ISP_EXP_MEAN_40             (RKISP1_CIF_ISP_EXP_BASE + 0x00000024)
-#define RKISP1_CIF_ISP_EXP_MEAN_01             (RKISP1_CIF_ISP_EXP_BASE + 0x00000028)
-#define RKISP1_CIF_ISP_EXP_MEAN_11             (RKISP1_CIF_ISP_EXP_BASE + 0x0000002c)
-#define RKISP1_CIF_ISP_EXP_MEAN_21             (RKISP1_CIF_ISP_EXP_BASE + 0x00000030)
-#define RKISP1_CIF_ISP_EXP_MEAN_31             (RKISP1_CIF_ISP_EXP_BASE + 0x00000034)
-#define RKISP1_CIF_ISP_EXP_MEAN_41             (RKISP1_CIF_ISP_EXP_BASE + 0x00000038)
-#define RKISP1_CIF_ISP_EXP_MEAN_02             (RKISP1_CIF_ISP_EXP_BASE + 0x0000003c)
-#define RKISP1_CIF_ISP_EXP_MEAN_12             (RKISP1_CIF_ISP_EXP_BASE + 0x00000040)
-#define RKISP1_CIF_ISP_EXP_MEAN_22             (RKISP1_CIF_ISP_EXP_BASE + 0x00000044)
-#define RKISP1_CIF_ISP_EXP_MEAN_32             (RKISP1_CIF_ISP_EXP_BASE + 0x00000048)
-#define RKISP1_CIF_ISP_EXP_MEAN_42             (RKISP1_CIF_ISP_EXP_BASE + 0x0000004c)
-#define RKISP1_CIF_ISP_EXP_MEAN_03             (RKISP1_CIF_ISP_EXP_BASE + 0x00000050)
-#define RKISP1_CIF_ISP_EXP_MEAN_13             (RKISP1_CIF_ISP_EXP_BASE + 0x00000054)
-#define RKISP1_CIF_ISP_EXP_MEAN_23             (RKISP1_CIF_ISP_EXP_BASE + 0x00000058)
-#define RKISP1_CIF_ISP_EXP_MEAN_33             (RKISP1_CIF_ISP_EXP_BASE + 0x0000005c)
-#define RKISP1_CIF_ISP_EXP_MEAN_43             (RKISP1_CIF_ISP_EXP_BASE + 0x00000060)
-#define RKISP1_CIF_ISP_EXP_MEAN_04             (RKISP1_CIF_ISP_EXP_BASE + 0x00000064)
-#define RKISP1_CIF_ISP_EXP_MEAN_14             (RKISP1_CIF_ISP_EXP_BASE + 0x00000068)
-#define RKISP1_CIF_ISP_EXP_MEAN_24             (RKISP1_CIF_ISP_EXP_BASE + 0x0000006c)
-#define RKISP1_CIF_ISP_EXP_MEAN_34             (RKISP1_CIF_ISP_EXP_BASE + 0x00000070)
-#define RKISP1_CIF_ISP_EXP_MEAN_44             (RKISP1_CIF_ISP_EXP_BASE + 0x00000074)
-
-#define RKISP1_CIF_ISP_BLS_BASE                        0x00002700
-#define RKISP1_CIF_ISP_BLS_CTRL                        (RKISP1_CIF_ISP_BLS_BASE + 0x00000000)
-#define RKISP1_CIF_ISP_BLS_SAMPLES             (RKISP1_CIF_ISP_BLS_BASE + 0x00000004)
-#define RKISP1_CIF_ISP_BLS_H1_START            (RKISP1_CIF_ISP_BLS_BASE + 0x00000008)
-#define RKISP1_CIF_ISP_BLS_H1_STOP             (RKISP1_CIF_ISP_BLS_BASE + 0x0000000c)
-#define RKISP1_CIF_ISP_BLS_V1_START            (RKISP1_CIF_ISP_BLS_BASE + 0x00000010)
-#define RKISP1_CIF_ISP_BLS_V1_STOP             (RKISP1_CIF_ISP_BLS_BASE + 0x00000014)
-#define RKISP1_CIF_ISP_BLS_H2_START            (RKISP1_CIF_ISP_BLS_BASE + 0x00000018)
-#define RKISP1_CIF_ISP_BLS_H2_STOP             (RKISP1_CIF_ISP_BLS_BASE + 0x0000001c)
-#define RKISP1_CIF_ISP_BLS_V2_START            (RKISP1_CIF_ISP_BLS_BASE + 0x00000020)
-#define RKISP1_CIF_ISP_BLS_V2_STOP             (RKISP1_CIF_ISP_BLS_BASE + 0x00000024)
-#define RKISP1_CIF_ISP_BLS_A_FIXED             (RKISP1_CIF_ISP_BLS_BASE + 0x00000028)
-#define RKISP1_CIF_ISP_BLS_B_FIXED             (RKISP1_CIF_ISP_BLS_BASE + 0x0000002c)
-#define RKISP1_CIF_ISP_BLS_C_FIXED             (RKISP1_CIF_ISP_BLS_BASE + 0x00000030)
-#define RKISP1_CIF_ISP_BLS_D_FIXED             (RKISP1_CIF_ISP_BLS_BASE + 0x00000034)
-#define RKISP1_CIF_ISP_BLS_A_MEASURED          (RKISP1_CIF_ISP_BLS_BASE + 0x00000038)
-#define RKISP1_CIF_ISP_BLS_B_MEASURED          (RKISP1_CIF_ISP_BLS_BASE + 0x0000003c)
-#define RKISP1_CIF_ISP_BLS_C_MEASURED          (RKISP1_CIF_ISP_BLS_BASE + 0x00000040)
-#define RKISP1_CIF_ISP_BLS_D_MEASURED          (RKISP1_CIF_ISP_BLS_BASE + 0x00000044)
-
-#define RKISP1_CIF_ISP_DPF_BASE                        0x00002800
-#define RKISP1_CIF_ISP_DPF_MODE                        (RKISP1_CIF_ISP_DPF_BASE + 0x00000000)
-#define RKISP1_CIF_ISP_DPF_STRENGTH_R          (RKISP1_CIF_ISP_DPF_BASE + 0x00000004)
-#define RKISP1_CIF_ISP_DPF_STRENGTH_G          (RKISP1_CIF_ISP_DPF_BASE + 0x00000008)
-#define RKISP1_CIF_ISP_DPF_STRENGTH_B          (RKISP1_CIF_ISP_DPF_BASE + 0x0000000C)
-#define RKISP1_CIF_ISP_DPF_S_WEIGHT_G_1_4      (RKISP1_CIF_ISP_DPF_BASE + 0x00000010)
-#define RKISP1_CIF_ISP_DPF_S_WEIGHT_G_5_6      (RKISP1_CIF_ISP_DPF_BASE + 0x00000014)
-#define RKISP1_CIF_ISP_DPF_S_WEIGHT_RB_1_4     (RKISP1_CIF_ISP_DPF_BASE + 0x00000018)
-#define RKISP1_CIF_ISP_DPF_S_WEIGHT_RB_5_6     (RKISP1_CIF_ISP_DPF_BASE + 0x0000001C)
-#define RKISP1_CIF_ISP_DPF_NULL_COEFF_0                (RKISP1_CIF_ISP_DPF_BASE + 0x00000020)
-#define RKISP1_CIF_ISP_DPF_NULL_COEFF_1                (RKISP1_CIF_ISP_DPF_BASE + 0x00000024)
-#define RKISP1_CIF_ISP_DPF_NULL_COEFF_2                (RKISP1_CIF_ISP_DPF_BASE + 0x00000028)
-#define RKISP1_CIF_ISP_DPF_NULL_COEFF_3                (RKISP1_CIF_ISP_DPF_BASE + 0x0000002C)
-#define RKISP1_CIF_ISP_DPF_NULL_COEFF_4                (RKISP1_CIF_ISP_DPF_BASE + 0x00000030)
-#define RKISP1_CIF_ISP_DPF_NULL_COEFF_5                (RKISP1_CIF_ISP_DPF_BASE + 0x00000034)
-#define RKISP1_CIF_ISP_DPF_NULL_COEFF_6                (RKISP1_CIF_ISP_DPF_BASE + 0x00000038)
-#define RKISP1_CIF_ISP_DPF_NULL_COEFF_7                (RKISP1_CIF_ISP_DPF_BASE + 0x0000003C)
-#define RKISP1_CIF_ISP_DPF_NULL_COEFF_8                (RKISP1_CIF_ISP_DPF_BASE + 0x00000040)
-#define RKISP1_CIF_ISP_DPF_NULL_COEFF_9                (RKISP1_CIF_ISP_DPF_BASE + 0x00000044)
-#define RKISP1_CIF_ISP_DPF_NULL_COEFF_10       (RKISP1_CIF_ISP_DPF_BASE + 0x00000048)
-#define RKISP1_CIF_ISP_DPF_NULL_COEFF_11       (RKISP1_CIF_ISP_DPF_BASE + 0x0000004C)
-#define RKISP1_CIF_ISP_DPF_NULL_COEFF_12       (RKISP1_CIF_ISP_DPF_BASE + 0x00000050)
-#define RKISP1_CIF_ISP_DPF_NULL_COEFF_13       (RKISP1_CIF_ISP_DPF_BASE + 0x00000054)
-#define RKISP1_CIF_ISP_DPF_NULL_COEFF_14       (RKISP1_CIF_ISP_DPF_BASE + 0x00000058)
-#define RKISP1_CIF_ISP_DPF_NULL_COEFF_15       (RKISP1_CIF_ISP_DPF_BASE + 0x0000005C)
-#define RKISP1_CIF_ISP_DPF_NULL_COEFF_16       (RKISP1_CIF_ISP_DPF_BASE + 0x00000060)
-#define RKISP1_CIF_ISP_DPF_NF_GAIN_R           (RKISP1_CIF_ISP_DPF_BASE + 0x00000064)
-#define RKISP1_CIF_ISP_DPF_NF_GAIN_GR          (RKISP1_CIF_ISP_DPF_BASE + 0x00000068)
-#define RKISP1_CIF_ISP_DPF_NF_GAIN_GB          (RKISP1_CIF_ISP_DPF_BASE + 0x0000006C)
-#define RKISP1_CIF_ISP_DPF_NF_GAIN_B           (RKISP1_CIF_ISP_DPF_BASE + 0x00000070)
-
-#define RKISP1_CIF_ISP_DPCC_BASE               0x00002900
-#define RKISP1_CIF_ISP_DPCC_MODE               (RKISP1_CIF_ISP_DPCC_BASE + 0x00000000)
-#define RKISP1_CIF_ISP_DPCC_OUTPUT_MODE                (RKISP1_CIF_ISP_DPCC_BASE + 0x00000004)
-#define RKISP1_CIF_ISP_DPCC_SET_USE            (RKISP1_CIF_ISP_DPCC_BASE + 0x00000008)
-#define RKISP1_CIF_ISP_DPCC_METHODS_SET_1      (RKISP1_CIF_ISP_DPCC_BASE + 0x0000000C)
-#define RKISP1_CIF_ISP_DPCC_METHODS_SET_2      (RKISP1_CIF_ISP_DPCC_BASE + 0x00000010)
-#define RKISP1_CIF_ISP_DPCC_METHODS_SET_3      (RKISP1_CIF_ISP_DPCC_BASE + 0x00000014)
-#define RKISP1_CIF_ISP_DPCC_LINE_THRESH_1      (RKISP1_CIF_ISP_DPCC_BASE + 0x00000018)
-#define RKISP1_CIF_ISP_DPCC_LINE_MAD_FAC_1     (RKISP1_CIF_ISP_DPCC_BASE + 0x0000001C)
-#define RKISP1_CIF_ISP_DPCC_PG_FAC_1           (RKISP1_CIF_ISP_DPCC_BASE + 0x00000020)
-#define RKISP1_CIF_ISP_DPCC_RND_THRESH_1       (RKISP1_CIF_ISP_DPCC_BASE + 0x00000024)
-#define RKISP1_CIF_ISP_DPCC_RG_FAC_1           (RKISP1_CIF_ISP_DPCC_BASE + 0x00000028)
-#define RKISP1_CIF_ISP_DPCC_LINE_THRESH_2      (RKISP1_CIF_ISP_DPCC_BASE + 0x0000002C)
-#define RKISP1_CIF_ISP_DPCC_LINE_MAD_FAC_2     (RKISP1_CIF_ISP_DPCC_BASE + 0x00000030)
-#define RKISP1_CIF_ISP_DPCC_PG_FAC_2           (RKISP1_CIF_ISP_DPCC_BASE + 0x00000034)
-#define RKISP1_CIF_ISP_DPCC_RND_THRESH_2       (RKISP1_CIF_ISP_DPCC_BASE + 0x00000038)
-#define RKISP1_CIF_ISP_DPCC_RG_FAC_2           (RKISP1_CIF_ISP_DPCC_BASE + 0x0000003C)
-#define RKISP1_CIF_ISP_DPCC_LINE_THRESH_3      (RKISP1_CIF_ISP_DPCC_BASE + 0x00000040)
-#define RKISP1_CIF_ISP_DPCC_LINE_MAD_FAC_3     (RKISP1_CIF_ISP_DPCC_BASE + 0x00000044)
-#define RKISP1_CIF_ISP_DPCC_PG_FAC_3           (RKISP1_CIF_ISP_DPCC_BASE + 0x00000048)
-#define RKISP1_CIF_ISP_DPCC_RND_THRESH_3       (RKISP1_CIF_ISP_DPCC_BASE + 0x0000004C)
-#define RKISP1_CIF_ISP_DPCC_RG_FAC_3           (RKISP1_CIF_ISP_DPCC_BASE + 0x00000050)
-#define RKISP1_CIF_ISP_DPCC_RO_LIMITS          (RKISP1_CIF_ISP_DPCC_BASE + 0x00000054)
-#define RKISP1_CIF_ISP_DPCC_RND_OFFS           (RKISP1_CIF_ISP_DPCC_BASE + 0x00000058)
-#define RKISP1_CIF_ISP_DPCC_BPT_CTRL           (RKISP1_CIF_ISP_DPCC_BASE + 0x0000005C)
-#define RKISP1_CIF_ISP_DPCC_BPT_NUMBER         (RKISP1_CIF_ISP_DPCC_BASE + 0x00000060)
-#define RKISP1_CIF_ISP_DPCC_BPT_ADDR           (RKISP1_CIF_ISP_DPCC_BASE + 0x00000064)
-#define RKISP1_CIF_ISP_DPCC_BPT_DATA           (RKISP1_CIF_ISP_DPCC_BASE + 0x00000068)
-
-#define RKISP1_CIF_ISP_WDR_BASE                        0x00002A00
-#define RKISP1_CIF_ISP_WDR_CTRL                        (RKISP1_CIF_ISP_WDR_BASE + 0x00000000)
-#define RKISP1_CIF_ISP_WDR_TONECURVE_1         (RKISP1_CIF_ISP_WDR_BASE + 0x00000004)
-#define RKISP1_CIF_ISP_WDR_TONECURVE_2         (RKISP1_CIF_ISP_WDR_BASE + 0x00000008)
-#define RKISP1_CIF_ISP_WDR_TONECURVE_3         (RKISP1_CIF_ISP_WDR_BASE + 0x0000000C)
-#define RKISP1_CIF_ISP_WDR_TONECURVE_4         (RKISP1_CIF_ISP_WDR_BASE + 0x00000010)
-#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_0      (RKISP1_CIF_ISP_WDR_BASE + 0x00000014)
-#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_1      (RKISP1_CIF_ISP_WDR_BASE + 0x00000018)
-#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_2      (RKISP1_CIF_ISP_WDR_BASE + 0x0000001C)
-#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_3      (RKISP1_CIF_ISP_WDR_BASE + 0x00000020)
-#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_4      (RKISP1_CIF_ISP_WDR_BASE + 0x00000024)
-#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_5      (RKISP1_CIF_ISP_WDR_BASE + 0x00000028)
-#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_6      (RKISP1_CIF_ISP_WDR_BASE + 0x0000002C)
-#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_7      (RKISP1_CIF_ISP_WDR_BASE + 0x00000030)
-#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_8      (RKISP1_CIF_ISP_WDR_BASE + 0x00000034)
-#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_9      (RKISP1_CIF_ISP_WDR_BASE + 0x00000038)
-#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_10     (RKISP1_CIF_ISP_WDR_BASE + 0x0000003C)
-#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_11     (RKISP1_CIF_ISP_WDR_BASE + 0x00000040)
-#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_12     (RKISP1_CIF_ISP_WDR_BASE + 0x00000044)
-#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_13     (RKISP1_CIF_ISP_WDR_BASE + 0x00000048)
-#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_14     (RKISP1_CIF_ISP_WDR_BASE + 0x0000004C)
-#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_15     (RKISP1_CIF_ISP_WDR_BASE + 0x00000050)
-#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_16     (RKISP1_CIF_ISP_WDR_BASE + 0x00000054)
-#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_17     (RKISP1_CIF_ISP_WDR_BASE + 0x00000058)
-#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_18     (RKISP1_CIF_ISP_WDR_BASE + 0x0000005C)
-#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_19     (RKISP1_CIF_ISP_WDR_BASE + 0x00000060)
-#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_20     (RKISP1_CIF_ISP_WDR_BASE + 0x00000064)
-#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_21     (RKISP1_CIF_ISP_WDR_BASE + 0x00000068)
-#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_22     (RKISP1_CIF_ISP_WDR_BASE + 0x0000006C)
-#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_23     (RKISP1_CIF_ISP_WDR_BASE + 0x00000070)
-#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_24     (RKISP1_CIF_ISP_WDR_BASE + 0x00000074)
-#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_25     (RKISP1_CIF_ISP_WDR_BASE + 0x00000078)
-#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_26     (RKISP1_CIF_ISP_WDR_BASE + 0x0000007C)
-#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_27     (RKISP1_CIF_ISP_WDR_BASE + 0x00000080)
-#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_28     (RKISP1_CIF_ISP_WDR_BASE + 0x00000084)
-#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_29     (RKISP1_CIF_ISP_WDR_BASE + 0x00000088)
-#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_30     (RKISP1_CIF_ISP_WDR_BASE + 0x0000008C)
-#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_31     (RKISP1_CIF_ISP_WDR_BASE + 0x00000090)
-#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_32     (RKISP1_CIF_ISP_WDR_BASE + 0x00000094)
-#define RKISP1_CIF_ISP_WDR_OFFSET              (RKISP1_CIF_ISP_WDR_BASE + 0x00000098)
-#define RKISP1_CIF_ISP_WDR_DELTAMIN            (RKISP1_CIF_ISP_WDR_BASE + 0x0000009C)
-#define RKISP1_CIF_ISP_WDR_TONECURVE_1_SHD     (RKISP1_CIF_ISP_WDR_BASE + 0x000000A0)
-#define RKISP1_CIF_ISP_WDR_TONECURVE_2_SHD     (RKISP1_CIF_ISP_WDR_BASE + 0x000000A4)
-#define RKISP1_CIF_ISP_WDR_TONECURVE_3_SHD     (RKISP1_CIF_ISP_WDR_BASE + 0x000000A8)
-#define RKISP1_CIF_ISP_WDR_TONECURVE_4_SHD     (RKISP1_CIF_ISP_WDR_BASE + 0x000000AC)
-#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_0_SHD  (RKISP1_CIF_ISP_WDR_BASE + 0x000000B0)
-#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_1_SHD  (RKISP1_CIF_ISP_WDR_BASE + 0x000000B4)
-#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_2_SHD  (RKISP1_CIF_ISP_WDR_BASE + 0x000000B8)
-#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_3_SHD  (RKISP1_CIF_ISP_WDR_BASE + 0x000000BC)
-#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_4_SHD  (RKISP1_CIF_ISP_WDR_BASE + 0x000000C0)
-#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_5_SHD  (RKISP1_CIF_ISP_WDR_BASE + 0x000000C4)
-#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_6_SHD  (RKISP1_CIF_ISP_WDR_BASE + 0x000000C8)
-#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_7_SHD  (RKISP1_CIF_ISP_WDR_BASE + 0x000000CC)
-#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_8_SHD  (RKISP1_CIF_ISP_WDR_BASE + 0x000000D0)
-#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_9_SHD  (RKISP1_CIF_ISP_WDR_BASE + 0x000000D4)
-#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_10_SHD (RKISP1_CIF_ISP_WDR_BASE + 0x000000D8)
-#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_11_SHD (RKISP1_CIF_ISP_WDR_BASE + 0x000000DC)
-#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_12_SHD (RKISP1_CIF_ISP_WDR_BASE + 0x000000E0)
-#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_13_SHD (RKISP1_CIF_ISP_WDR_BASE + 0x000000E4)
-#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_14_SHD (RKISP1_CIF_ISP_WDR_BASE + 0x000000E8)
-#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_15_SHD (RKISP1_CIF_ISP_WDR_BASE + 0x000000EC)
-#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_16_SHD (RKISP1_CIF_ISP_WDR_BASE + 0x000000F0)
-#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_17_SHD (RKISP1_CIF_ISP_WDR_BASE + 0x000000F4)
-#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_18_SHD (RKISP1_CIF_ISP_WDR_BASE + 0x000000F8)
-#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_19_SHD (RKISP1_CIF_ISP_WDR_BASE + 0x000000FC)
-#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_20_SHD (RKISP1_CIF_ISP_WDR_BASE + 0x00000100)
-#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_21_SHD (RKISP1_CIF_ISP_WDR_BASE + 0x00000104)
-#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_22_SHD (RKISP1_CIF_ISP_WDR_BASE + 0x00000108)
-#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_23_SHD (RKISP1_CIF_ISP_WDR_BASE + 0x0000010C)
-#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_24_SHD (RKISP1_CIF_ISP_WDR_BASE + 0x00000110)
-#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_25_SHD (RKISP1_CIF_ISP_WDR_BASE + 0x00000114)
-#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_26_SHD (RKISP1_CIF_ISP_WDR_BASE + 0x00000118)
-#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_27_SHD (RKISP1_CIF_ISP_WDR_BASE + 0x0000011C)
-#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_28_SHD (RKISP1_CIF_ISP_WDR_BASE + 0x00000120)
-#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_29_SHD (RKISP1_CIF_ISP_WDR_BASE + 0x00000124)
-#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_30_SHD (RKISP1_CIF_ISP_WDR_BASE + 0x00000128)
-#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_31_SHD (RKISP1_CIF_ISP_WDR_BASE + 0x0000012C)
-#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_32_SHD (RKISP1_CIF_ISP_WDR_BASE + 0x00000130)
-
-#define RKISP1_CIF_ISP_VSM_BASE                        0x00002F00
-#define RKISP1_CIF_ISP_VSM_MODE                        (RKISP1_CIF_ISP_VSM_BASE + 0x00000000)
-#define RKISP1_CIF_ISP_VSM_H_OFFS              (RKISP1_CIF_ISP_VSM_BASE + 0x00000004)
-#define RKISP1_CIF_ISP_VSM_V_OFFS              (RKISP1_CIF_ISP_VSM_BASE + 0x00000008)
-#define RKISP1_CIF_ISP_VSM_H_SIZE              (RKISP1_CIF_ISP_VSM_BASE + 0x0000000C)
-#define RKISP1_CIF_ISP_VSM_V_SIZE              (RKISP1_CIF_ISP_VSM_BASE + 0x00000010)
-#define RKISP1_CIF_ISP_VSM_H_SEGMENTS          (RKISP1_CIF_ISP_VSM_BASE + 0x00000014)
-#define RKISP1_CIF_ISP_VSM_V_SEGMENTS          (RKISP1_CIF_ISP_VSM_BASE + 0x00000018)
-#define RKISP1_CIF_ISP_VSM_DELTA_H             (RKISP1_CIF_ISP_VSM_BASE + 0x0000001C)
-#define RKISP1_CIF_ISP_VSM_DELTA_V             (RKISP1_CIF_ISP_VSM_BASE + 0x00000020)
-
-#endif /* _RKISP1_REGS_H */
diff --git a/drivers/staging/media/rkisp1/rkisp1-resizer.c b/drivers/staging/media/rkisp1/rkisp1-resizer.c
deleted file mode 100644 (file)
index 1687d82..0000000
+++ /dev/null
@@ -1,844 +0,0 @@
-// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
-/*
- * Rockchip ISP1 Driver - V4l resizer device
- *
- * Copyright (C) 2019 Collabora, Ltd.
- *
- * Based on Rockchip ISP1 driver by Rockchip Electronics Co., Ltd.
- * Copyright (C) 2017 Rockchip Electronics Co., Ltd.
- */
-
-#include "rkisp1-common.h"
-
-#define RKISP1_RSZ_SP_DEV_NAME RKISP1_DRIVER_NAME "_resizer_selfpath"
-#define RKISP1_RSZ_MP_DEV_NAME RKISP1_DRIVER_NAME "_resizer_mainpath"
-
-#define RKISP1_DEF_FMT MEDIA_BUS_FMT_YUYV8_2X8
-#define RKISP1_DEF_PIXEL_ENC V4L2_PIXEL_ENC_YUV
-
-struct rkisp1_rsz_yuv_mbus_info {
-       u32 mbus_code;
-       u32 hdiv;
-       u32 vdiv;
-};
-
-static const struct rkisp1_rsz_yuv_mbus_info rkisp1_rsz_yuv_src_formats[] = {
-       {
-               .mbus_code      = MEDIA_BUS_FMT_YUYV8_2X8, /* YUV422 */
-               .hdiv           = 2,
-               .vdiv           = 1,
-       },
-       {
-               .mbus_code      = MEDIA_BUS_FMT_YUYV8_1_5X8, /* YUV420 */
-               .hdiv           = 2,
-               .vdiv           = 2,
-       },
-};
-
-static const struct rkisp1_rsz_yuv_mbus_info *rkisp1_rsz_get_yuv_mbus_info(u32 mbus_code)
-{
-       unsigned int i;
-
-       for (i = 0; i < ARRAY_SIZE(rkisp1_rsz_yuv_src_formats); i++) {
-               if (rkisp1_rsz_yuv_src_formats[i].mbus_code == mbus_code)
-                       return &rkisp1_rsz_yuv_src_formats[i];
-       }
-
-       return NULL;
-}
-
-enum rkisp1_shadow_regs_when {
-       RKISP1_SHADOW_REGS_SYNC,
-       RKISP1_SHADOW_REGS_ASYNC,
-};
-
-struct rkisp1_rsz_config {
-       /* constrains */
-       const int max_rsz_width;
-       const int max_rsz_height;
-       const int min_rsz_width;
-       const int min_rsz_height;
-       /* registers */
-       struct {
-               u32 ctrl;
-               u32 ctrl_shd;
-               u32 scale_hy;
-               u32 scale_hcr;
-               u32 scale_hcb;
-               u32 scale_vy;
-               u32 scale_vc;
-               u32 scale_lut;
-               u32 scale_lut_addr;
-               u32 scale_hy_shd;
-               u32 scale_hcr_shd;
-               u32 scale_hcb_shd;
-               u32 scale_vy_shd;
-               u32 scale_vc_shd;
-               u32 phase_hy;
-               u32 phase_hc;
-               u32 phase_vy;
-               u32 phase_vc;
-               u32 phase_hy_shd;
-               u32 phase_hc_shd;
-               u32 phase_vy_shd;
-               u32 phase_vc_shd;
-       } rsz;
-       struct {
-               u32 ctrl;
-               u32 yuvmode_mask;
-               u32 rawmode_mask;
-               u32 h_offset;
-               u32 v_offset;
-               u32 h_size;
-               u32 v_size;
-       } dual_crop;
-};
-
-static const struct rkisp1_rsz_config rkisp1_rsz_config_mp = {
-       /* constraints */
-       .max_rsz_width = RKISP1_RSZ_MP_SRC_MAX_WIDTH,
-       .max_rsz_height = RKISP1_RSZ_MP_SRC_MAX_HEIGHT,
-       .min_rsz_width = RKISP1_RSZ_SRC_MIN_WIDTH,
-       .min_rsz_height = RKISP1_RSZ_SRC_MIN_HEIGHT,
-       /* registers */
-       .rsz = {
-               .ctrl =                 RKISP1_CIF_MRSZ_CTRL,
-               .scale_hy =             RKISP1_CIF_MRSZ_SCALE_HY,
-               .scale_hcr =            RKISP1_CIF_MRSZ_SCALE_HCR,
-               .scale_hcb =            RKISP1_CIF_MRSZ_SCALE_HCB,
-               .scale_vy =             RKISP1_CIF_MRSZ_SCALE_VY,
-               .scale_vc =             RKISP1_CIF_MRSZ_SCALE_VC,
-               .scale_lut =            RKISP1_CIF_MRSZ_SCALE_LUT,
-               .scale_lut_addr =       RKISP1_CIF_MRSZ_SCALE_LUT_ADDR,
-               .scale_hy_shd =         RKISP1_CIF_MRSZ_SCALE_HY_SHD,
-               .scale_hcr_shd =        RKISP1_CIF_MRSZ_SCALE_HCR_SHD,
-               .scale_hcb_shd =        RKISP1_CIF_MRSZ_SCALE_HCB_SHD,
-               .scale_vy_shd =         RKISP1_CIF_MRSZ_SCALE_VY_SHD,
-               .scale_vc_shd =         RKISP1_CIF_MRSZ_SCALE_VC_SHD,
-               .phase_hy =             RKISP1_CIF_MRSZ_PHASE_HY,
-               .phase_hc =             RKISP1_CIF_MRSZ_PHASE_HC,
-               .phase_vy =             RKISP1_CIF_MRSZ_PHASE_VY,
-               .phase_vc =             RKISP1_CIF_MRSZ_PHASE_VC,
-               .ctrl_shd =             RKISP1_CIF_MRSZ_CTRL_SHD,
-               .phase_hy_shd =         RKISP1_CIF_MRSZ_PHASE_HY_SHD,
-               .phase_hc_shd =         RKISP1_CIF_MRSZ_PHASE_HC_SHD,
-               .phase_vy_shd =         RKISP1_CIF_MRSZ_PHASE_VY_SHD,
-               .phase_vc_shd =         RKISP1_CIF_MRSZ_PHASE_VC_SHD,
-       },
-       .dual_crop = {
-               .ctrl =                 RKISP1_CIF_DUAL_CROP_CTRL,
-               .yuvmode_mask =         RKISP1_CIF_DUAL_CROP_MP_MODE_YUV,
-               .rawmode_mask =         RKISP1_CIF_DUAL_CROP_MP_MODE_RAW,
-               .h_offset =             RKISP1_CIF_DUAL_CROP_M_H_OFFS,
-               .v_offset =             RKISP1_CIF_DUAL_CROP_M_V_OFFS,
-               .h_size =               RKISP1_CIF_DUAL_CROP_M_H_SIZE,
-               .v_size =               RKISP1_CIF_DUAL_CROP_M_V_SIZE,
-       },
-};
-
-static const struct rkisp1_rsz_config rkisp1_rsz_config_sp = {
-       /* constraints */
-       .max_rsz_width = RKISP1_RSZ_SP_SRC_MAX_WIDTH,
-       .max_rsz_height = RKISP1_RSZ_SP_SRC_MAX_HEIGHT,
-       .min_rsz_width = RKISP1_RSZ_SRC_MIN_WIDTH,
-       .min_rsz_height = RKISP1_RSZ_SRC_MIN_HEIGHT,
-       /* registers */
-       .rsz = {
-               .ctrl =                 RKISP1_CIF_SRSZ_CTRL,
-               .scale_hy =             RKISP1_CIF_SRSZ_SCALE_HY,
-               .scale_hcr =            RKISP1_CIF_SRSZ_SCALE_HCR,
-               .scale_hcb =            RKISP1_CIF_SRSZ_SCALE_HCB,
-               .scale_vy =             RKISP1_CIF_SRSZ_SCALE_VY,
-               .scale_vc =             RKISP1_CIF_SRSZ_SCALE_VC,
-               .scale_lut =            RKISP1_CIF_SRSZ_SCALE_LUT,
-               .scale_lut_addr =       RKISP1_CIF_SRSZ_SCALE_LUT_ADDR,
-               .scale_hy_shd =         RKISP1_CIF_SRSZ_SCALE_HY_SHD,
-               .scale_hcr_shd =        RKISP1_CIF_SRSZ_SCALE_HCR_SHD,
-               .scale_hcb_shd =        RKISP1_CIF_SRSZ_SCALE_HCB_SHD,
-               .scale_vy_shd =         RKISP1_CIF_SRSZ_SCALE_VY_SHD,
-               .scale_vc_shd =         RKISP1_CIF_SRSZ_SCALE_VC_SHD,
-               .phase_hy =             RKISP1_CIF_SRSZ_PHASE_HY,
-               .phase_hc =             RKISP1_CIF_SRSZ_PHASE_HC,
-               .phase_vy =             RKISP1_CIF_SRSZ_PHASE_VY,
-               .phase_vc =             RKISP1_CIF_SRSZ_PHASE_VC,
-               .ctrl_shd =             RKISP1_CIF_SRSZ_CTRL_SHD,
-               .phase_hy_shd =         RKISP1_CIF_SRSZ_PHASE_HY_SHD,
-               .phase_hc_shd =         RKISP1_CIF_SRSZ_PHASE_HC_SHD,
-               .phase_vy_shd =         RKISP1_CIF_SRSZ_PHASE_VY_SHD,
-               .phase_vc_shd =         RKISP1_CIF_SRSZ_PHASE_VC_SHD,
-       },
-       .dual_crop = {
-               .ctrl =                 RKISP1_CIF_DUAL_CROP_CTRL,
-               .yuvmode_mask =         RKISP1_CIF_DUAL_CROP_SP_MODE_YUV,
-               .rawmode_mask =         RKISP1_CIF_DUAL_CROP_SP_MODE_RAW,
-               .h_offset =             RKISP1_CIF_DUAL_CROP_S_H_OFFS,
-               .v_offset =             RKISP1_CIF_DUAL_CROP_S_V_OFFS,
-               .h_size =               RKISP1_CIF_DUAL_CROP_S_H_SIZE,
-               .v_size =               RKISP1_CIF_DUAL_CROP_S_V_SIZE,
-       },
-};
-
-static struct v4l2_mbus_framefmt *
-rkisp1_rsz_get_pad_fmt(struct rkisp1_resizer *rsz,
-                      struct v4l2_subdev_pad_config *cfg,
-                      unsigned int pad, u32 which)
-{
-       if (which == V4L2_SUBDEV_FORMAT_TRY)
-               return v4l2_subdev_get_try_format(&rsz->sd, cfg, pad);
-       else
-               return v4l2_subdev_get_try_format(&rsz->sd, rsz->pad_cfg, pad);
-}
-
-static struct v4l2_rect *
-rkisp1_rsz_get_pad_crop(struct rkisp1_resizer *rsz,
-                       struct v4l2_subdev_pad_config *cfg,
-                       unsigned int pad, u32 which)
-{
-       if (which == V4L2_SUBDEV_FORMAT_TRY)
-               return v4l2_subdev_get_try_crop(&rsz->sd, cfg, pad);
-       else
-               return v4l2_subdev_get_try_crop(&rsz->sd, rsz->pad_cfg, pad);
-}
-
-/* ----------------------------------------------------------------------------
- * Dual crop hw configs
- */
-
-static void rkisp1_dcrop_disable(struct rkisp1_resizer *rsz,
-                                enum rkisp1_shadow_regs_when when)
-{
-       u32 dc_ctrl = rkisp1_read(rsz->rkisp1, rsz->config->dual_crop.ctrl);
-       u32 mask = ~(rsz->config->dual_crop.yuvmode_mask |
-                    rsz->config->dual_crop.rawmode_mask);
-
-       dc_ctrl &= mask;
-       if (when == RKISP1_SHADOW_REGS_ASYNC)
-               dc_ctrl |= RKISP1_CIF_DUAL_CROP_GEN_CFG_UPD;
-       else
-               dc_ctrl |= RKISP1_CIF_DUAL_CROP_CFG_UPD;
-       rkisp1_write(rsz->rkisp1, dc_ctrl, rsz->config->dual_crop.ctrl);
-}
-
-/* configure dual-crop unit */
-static void rkisp1_dcrop_config(struct rkisp1_resizer *rsz)
-{
-       struct rkisp1_device *rkisp1 = rsz->rkisp1;
-       struct v4l2_mbus_framefmt *sink_fmt;
-       struct v4l2_rect *sink_crop;
-       u32 dc_ctrl;
-
-       sink_crop = rkisp1_rsz_get_pad_crop(rsz, NULL, RKISP1_RSZ_PAD_SINK,
-                                           V4L2_SUBDEV_FORMAT_ACTIVE);
-       sink_fmt = rkisp1_rsz_get_pad_fmt(rsz, NULL, RKISP1_RSZ_PAD_SINK,
-                                         V4L2_SUBDEV_FORMAT_ACTIVE);
-
-       if (sink_crop->width == sink_fmt->width &&
-           sink_crop->height == sink_fmt->height &&
-           sink_crop->left == 0 && sink_crop->top == 0) {
-               rkisp1_dcrop_disable(rsz, RKISP1_SHADOW_REGS_SYNC);
-               dev_dbg(rkisp1->dev, "capture %d crop disabled\n", rsz->id);
-               return;
-       }
-
-       dc_ctrl = rkisp1_read(rkisp1, rsz->config->dual_crop.ctrl);
-       rkisp1_write(rkisp1, sink_crop->left, rsz->config->dual_crop.h_offset);
-       rkisp1_write(rkisp1, sink_crop->top, rsz->config->dual_crop.v_offset);
-       rkisp1_write(rkisp1, sink_crop->width, rsz->config->dual_crop.h_size);
-       rkisp1_write(rkisp1, sink_crop->height, rsz->config->dual_crop.v_size);
-       dc_ctrl |= rsz->config->dual_crop.yuvmode_mask;
-       dc_ctrl |= RKISP1_CIF_DUAL_CROP_CFG_UPD;
-       rkisp1_write(rkisp1, dc_ctrl, rsz->config->dual_crop.ctrl);
-
-       dev_dbg(rkisp1->dev, "stream %d crop: %dx%d -> %dx%d\n", rsz->id,
-               sink_fmt->width, sink_fmt->height,
-               sink_crop->width, sink_crop->height);
-}
-
-/* ----------------------------------------------------------------------------
- * Resizer hw configs
- */
-
-static void rkisp1_rsz_dump_regs(struct rkisp1_resizer *rsz)
-{
-       dev_dbg(rsz->rkisp1->dev,
-               "RSZ_CTRL 0x%08x/0x%08x\n"
-               "RSZ_SCALE_HY %d/%d\n"
-               "RSZ_SCALE_HCB %d/%d\n"
-               "RSZ_SCALE_HCR %d/%d\n"
-               "RSZ_SCALE_VY %d/%d\n"
-               "RSZ_SCALE_VC %d/%d\n"
-               "RSZ_PHASE_HY %d/%d\n"
-               "RSZ_PHASE_HC %d/%d\n"
-               "RSZ_PHASE_VY %d/%d\n"
-               "RSZ_PHASE_VC %d/%d\n",
-               rkisp1_read(rsz->rkisp1, rsz->config->rsz.ctrl),
-               rkisp1_read(rsz->rkisp1, rsz->config->rsz.ctrl_shd),
-               rkisp1_read(rsz->rkisp1, rsz->config->rsz.scale_hy),
-               rkisp1_read(rsz->rkisp1, rsz->config->rsz.scale_hy_shd),
-               rkisp1_read(rsz->rkisp1, rsz->config->rsz.scale_hcb),
-               rkisp1_read(rsz->rkisp1, rsz->config->rsz.scale_hcb_shd),
-               rkisp1_read(rsz->rkisp1, rsz->config->rsz.scale_hcr),
-               rkisp1_read(rsz->rkisp1, rsz->config->rsz.scale_hcr_shd),
-               rkisp1_read(rsz->rkisp1, rsz->config->rsz.scale_vy),
-               rkisp1_read(rsz->rkisp1, rsz->config->rsz.scale_vy_shd),
-               rkisp1_read(rsz->rkisp1, rsz->config->rsz.scale_vc),
-               rkisp1_read(rsz->rkisp1, rsz->config->rsz.scale_vc_shd),
-               rkisp1_read(rsz->rkisp1, rsz->config->rsz.phase_hy),
-               rkisp1_read(rsz->rkisp1, rsz->config->rsz.phase_hy_shd),
-               rkisp1_read(rsz->rkisp1, rsz->config->rsz.phase_hc),
-               rkisp1_read(rsz->rkisp1, rsz->config->rsz.phase_hc_shd),
-               rkisp1_read(rsz->rkisp1, rsz->config->rsz.phase_vy),
-               rkisp1_read(rsz->rkisp1, rsz->config->rsz.phase_vy_shd),
-               rkisp1_read(rsz->rkisp1, rsz->config->rsz.phase_vc),
-               rkisp1_read(rsz->rkisp1, rsz->config->rsz.phase_vc_shd));
-}
-
-static void rkisp1_rsz_update_shadow(struct rkisp1_resizer *rsz,
-                                    enum rkisp1_shadow_regs_when when)
-{
-       u32 ctrl_cfg = rkisp1_read(rsz->rkisp1, rsz->config->rsz.ctrl);
-
-       if (when == RKISP1_SHADOW_REGS_ASYNC)
-               ctrl_cfg |= RKISP1_CIF_RSZ_CTRL_CFG_UPD_AUTO;
-       else
-               ctrl_cfg |= RKISP1_CIF_RSZ_CTRL_CFG_UPD;
-
-       rkisp1_write(rsz->rkisp1, ctrl_cfg, rsz->config->rsz.ctrl);
-}
-
-static u32 rkisp1_rsz_calc_ratio(u32 len_sink, u32 len_src)
-{
-       if (len_sink < len_src)
-               return ((len_sink - 1) * RKISP1_CIF_RSZ_SCALER_FACTOR) /
-                      (len_src - 1);
-
-       return ((len_src - 1) * RKISP1_CIF_RSZ_SCALER_FACTOR) /
-              (len_sink - 1) + 1;
-}
-
-static void rkisp1_rsz_disable(struct rkisp1_resizer *rsz,
-                              enum rkisp1_shadow_regs_when when)
-{
-       rkisp1_write(rsz->rkisp1, 0, rsz->config->rsz.ctrl);
-
-       if (when == RKISP1_SHADOW_REGS_SYNC)
-               rkisp1_rsz_update_shadow(rsz, when);
-}
-
-static void rkisp1_rsz_config_regs(struct rkisp1_resizer *rsz,
-                                  struct v4l2_rect *sink_y,
-                                  struct v4l2_rect *sink_c,
-                                  struct v4l2_rect *src_y,
-                                  struct v4l2_rect *src_c,
-                                  enum rkisp1_shadow_regs_when when)
-{
-       struct rkisp1_device *rkisp1 = rsz->rkisp1;
-       u32 ratio, rsz_ctrl = 0;
-       unsigned int i;
-
-       /* No phase offset */
-       rkisp1_write(rkisp1, 0, rsz->config->rsz.phase_hy);
-       rkisp1_write(rkisp1, 0, rsz->config->rsz.phase_hc);
-       rkisp1_write(rkisp1, 0, rsz->config->rsz.phase_vy);
-       rkisp1_write(rkisp1, 0, rsz->config->rsz.phase_vc);
-
-       /* Linear interpolation */
-       for (i = 0; i < 64; i++) {
-               rkisp1_write(rkisp1, i, rsz->config->rsz.scale_lut_addr);
-               rkisp1_write(rkisp1, i, rsz->config->rsz.scale_lut);
-       }
-
-       if (sink_y->width != src_y->width) {
-               rsz_ctrl |= RKISP1_CIF_RSZ_CTRL_SCALE_HY_ENABLE;
-               if (sink_y->width < src_y->width)
-                       rsz_ctrl |= RKISP1_CIF_RSZ_CTRL_SCALE_HY_UP;
-               ratio = rkisp1_rsz_calc_ratio(sink_y->width, src_y->width);
-               rkisp1_write(rkisp1, ratio, rsz->config->rsz.scale_hy);
-       }
-
-       if (sink_c->width != src_c->width) {
-               rsz_ctrl |= RKISP1_CIF_RSZ_CTRL_SCALE_HC_ENABLE;
-               if (sink_c->width < src_c->width)
-                       rsz_ctrl |= RKISP1_CIF_RSZ_CTRL_SCALE_HC_UP;
-               ratio = rkisp1_rsz_calc_ratio(sink_c->width, src_c->width);
-               rkisp1_write(rkisp1, ratio, rsz->config->rsz.scale_hcb);
-               rkisp1_write(rkisp1, ratio, rsz->config->rsz.scale_hcr);
-       }
-
-       if (sink_y->height != src_y->height) {
-               rsz_ctrl |= RKISP1_CIF_RSZ_CTRL_SCALE_VY_ENABLE;
-               if (sink_y->height < src_y->height)
-                       rsz_ctrl |= RKISP1_CIF_RSZ_CTRL_SCALE_VY_UP;
-               ratio = rkisp1_rsz_calc_ratio(sink_y->height, src_y->height);
-               rkisp1_write(rkisp1, ratio, rsz->config->rsz.scale_vy);
-       }
-
-       if (sink_c->height != src_c->height) {
-               rsz_ctrl |= RKISP1_CIF_RSZ_CTRL_SCALE_VC_ENABLE;
-               if (sink_c->height < src_c->height)
-                       rsz_ctrl |= RKISP1_CIF_RSZ_CTRL_SCALE_VC_UP;
-               ratio = rkisp1_rsz_calc_ratio(sink_c->height, src_c->height);
-               rkisp1_write(rkisp1, ratio, rsz->config->rsz.scale_vc);
-       }
-
-       rkisp1_write(rkisp1, rsz_ctrl, rsz->config->rsz.ctrl);
-
-       rkisp1_rsz_update_shadow(rsz, when);
-}
-
-static void rkisp1_rsz_config(struct rkisp1_resizer *rsz,
-                             enum rkisp1_shadow_regs_when when)
-{
-       const struct rkisp1_rsz_yuv_mbus_info *sink_yuv_info, *src_yuv_info;
-       struct v4l2_rect sink_y, sink_c, src_y, src_c;
-       struct v4l2_mbus_framefmt *src_fmt, *sink_fmt;
-       struct v4l2_rect *sink_crop;
-
-       sink_crop = rkisp1_rsz_get_pad_crop(rsz, NULL, RKISP1_RSZ_PAD_SINK,
-                                           V4L2_SUBDEV_FORMAT_ACTIVE);
-       src_fmt = rkisp1_rsz_get_pad_fmt(rsz, NULL, RKISP1_RSZ_PAD_SRC,
-                                        V4L2_SUBDEV_FORMAT_ACTIVE);
-       src_yuv_info = rkisp1_rsz_get_yuv_mbus_info(src_fmt->code);
-       sink_fmt = rkisp1_rsz_get_pad_fmt(rsz, NULL, RKISP1_RSZ_PAD_SINK,
-                                         V4L2_SUBDEV_FORMAT_ACTIVE);
-       sink_yuv_info = rkisp1_rsz_get_yuv_mbus_info(sink_fmt->code);
-
-       /*
-        * The resizer only works on yuv formats,
-        * so return if it is bayer format.
-        */
-       if (rsz->pixel_enc == V4L2_PIXEL_ENC_BAYER) {
-               rkisp1_rsz_disable(rsz, when);
-               return;
-       }
-
-       sink_y.width = sink_crop->width;
-       sink_y.height = sink_crop->height;
-       src_y.width = src_fmt->width;
-       src_y.height = src_fmt->height;
-
-       sink_c.width = sink_y.width / sink_yuv_info->hdiv;
-       sink_c.height = sink_y.height / sink_yuv_info->vdiv;
-
-       /*
-        * The resizer is used not only to change the dimensions of the frame
-        * but also to change the scale for YUV formats,
-        * (4:2:2 -> 4:2:0 for example). So the width/height of the CbCr
-        * streams should be set according to the media bus format in the src pad.
-        */
-       src_c.width = src_y.width / src_yuv_info->hdiv;
-       src_c.height = src_y.height / src_yuv_info->vdiv;
-
-       if (sink_c.width == src_c.width && sink_c.height == src_c.height) {
-               rkisp1_rsz_disable(rsz, when);
-               return;
-       }
-
-       dev_dbg(rsz->rkisp1->dev, "stream %d rsz/scale: %dx%d -> %dx%d\n",
-               rsz->id, sink_crop->width, sink_crop->height,
-               src_fmt->width, src_fmt->height);
-       dev_dbg(rsz->rkisp1->dev, "chroma scaling %dx%d -> %dx%d\n",
-               sink_c.width, sink_c.height, src_c.width, src_c.height);
-
-       /* set values in the hw */
-       rkisp1_rsz_config_regs(rsz, &sink_y, &sink_c, &src_y, &src_c, when);
-
-       rkisp1_rsz_dump_regs(rsz);
-}
-
-/* ----------------------------------------------------------------------------
- * Subdev pad operations
- */
-
-static int rkisp1_rsz_enum_mbus_code(struct v4l2_subdev *sd,
-                                    struct v4l2_subdev_pad_config *cfg,
-                                    struct v4l2_subdev_mbus_code_enum *code)
-{
-       struct rkisp1_resizer *rsz =
-               container_of(sd, struct rkisp1_resizer, sd);
-       struct v4l2_subdev_pad_config dummy_cfg;
-       u32 pad = code->pad;
-       int ret;
-
-       if (code->pad == RKISP1_RSZ_PAD_SRC) {
-               /* supported mbus codes on the src are the same as in the capture */
-               struct rkisp1_capture *cap = &rsz->rkisp1->capture_devs[rsz->id];
-
-               return rkisp1_cap_enum_mbus_codes(cap, code);
-       }
-
-       /*
-        * The selfpath capture doesn't support bayer formats. Therefore the selfpath resizer
-        * should support only YUV422 on the sink pad
-        */
-       if (rsz->id == RKISP1_SELFPATH) {
-               if (code->index > 0)
-                       return -EINVAL;
-               code->code = MEDIA_BUS_FMT_YUYV8_2X8;
-               return 0;
-       }
-
-       /* supported mbus codes on the sink pad are the same as isp src pad */
-       code->pad = RKISP1_ISP_PAD_SOURCE_VIDEO;
-       ret = v4l2_subdev_call(&rsz->rkisp1->isp.sd, pad, enum_mbus_code,
-                              &dummy_cfg, code);
-
-       /* restore pad */
-       code->pad = pad;
-       code->flags = 0;
-       return ret;
-}
-
-static int rkisp1_rsz_init_config(struct v4l2_subdev *sd,
-                                 struct v4l2_subdev_pad_config *cfg)
-{
-       struct v4l2_mbus_framefmt *sink_fmt, *src_fmt;
-       struct v4l2_rect *sink_crop;
-
-       sink_fmt = v4l2_subdev_get_try_format(sd, cfg, RKISP1_RSZ_PAD_SRC);
-       sink_fmt->width = RKISP1_DEFAULT_WIDTH;
-       sink_fmt->height = RKISP1_DEFAULT_HEIGHT;
-       sink_fmt->field = V4L2_FIELD_NONE;
-       sink_fmt->code = RKISP1_DEF_FMT;
-
-       sink_crop = v4l2_subdev_get_try_crop(sd, cfg, RKISP1_RSZ_PAD_SINK);
-       sink_crop->width = RKISP1_DEFAULT_WIDTH;
-       sink_crop->height = RKISP1_DEFAULT_HEIGHT;
-       sink_crop->left = 0;
-       sink_crop->top = 0;
-
-       src_fmt = v4l2_subdev_get_try_format(sd, cfg, RKISP1_RSZ_PAD_SINK);
-       *src_fmt = *sink_fmt;
-
-       /* NOTE: there is no crop in the source pad, only in the sink */
-
-       return 0;
-}
-
-static void rkisp1_rsz_set_src_fmt(struct rkisp1_resizer *rsz,
-                                  struct v4l2_subdev_pad_config *cfg,
-                                  struct v4l2_mbus_framefmt *format,
-                                  unsigned int which)
-{
-       const struct rkisp1_isp_mbus_info *mbus_info;
-       struct v4l2_mbus_framefmt *src_fmt;
-
-       src_fmt = rkisp1_rsz_get_pad_fmt(rsz, cfg, RKISP1_RSZ_PAD_SRC, which);
-       mbus_info = rkisp1_isp_mbus_info_get(src_fmt->code);
-
-       /* for YUV formats, userspace can change the mbus code on the src pad if it is supported */
-       if (mbus_info->pixel_enc == V4L2_PIXEL_ENC_YUV &&
-           rkisp1_rsz_get_yuv_mbus_info(format->code))
-               src_fmt->code = format->code;
-
-       src_fmt->width = clamp_t(u32, format->width,
-                                rsz->config->min_rsz_width,
-                                rsz->config->max_rsz_width);
-       src_fmt->height = clamp_t(u32, format->height,
-                                 rsz->config->min_rsz_height,
-                                 rsz->config->max_rsz_height);
-
-       *format = *src_fmt;
-}
-
-static void rkisp1_rsz_set_sink_crop(struct rkisp1_resizer *rsz,
-                                    struct v4l2_subdev_pad_config *cfg,
-                                    struct v4l2_rect *r,
-                                    unsigned int which)
-{
-       const struct rkisp1_isp_mbus_info *mbus_info;
-       struct v4l2_mbus_framefmt *sink_fmt;
-       struct v4l2_rect *sink_crop;
-
-       sink_fmt = rkisp1_rsz_get_pad_fmt(rsz, cfg, RKISP1_RSZ_PAD_SINK, which);
-       sink_crop = rkisp1_rsz_get_pad_crop(rsz, cfg, RKISP1_RSZ_PAD_SINK,
-                                           which);
-
-       /* Not crop for MP bayer raw data */
-       mbus_info = rkisp1_isp_mbus_info_get(sink_fmt->code);
-
-       if (rsz->id == RKISP1_MAINPATH &&
-           mbus_info->pixel_enc == V4L2_PIXEL_ENC_BAYER) {
-               sink_crop->left = 0;
-               sink_crop->top = 0;
-               sink_crop->width = sink_fmt->width;
-               sink_crop->height = sink_fmt->height;
-
-               *r = *sink_crop;
-               return;
-       }
-
-       sink_crop->left = ALIGN(r->left, 2);
-       sink_crop->width = ALIGN(r->width, 2);
-       sink_crop->top = r->top;
-       sink_crop->height = r->height;
-       rkisp1_sd_adjust_crop(sink_crop, sink_fmt);
-
-       *r = *sink_crop;
-}
-
-static void rkisp1_rsz_set_sink_fmt(struct rkisp1_resizer *rsz,
-                                   struct v4l2_subdev_pad_config *cfg,
-                                   struct v4l2_mbus_framefmt *format,
-                                   unsigned int which)
-{
-       const struct rkisp1_isp_mbus_info *mbus_info;
-       struct v4l2_mbus_framefmt *sink_fmt, *src_fmt;
-       struct v4l2_rect *sink_crop;
-
-       sink_fmt = rkisp1_rsz_get_pad_fmt(rsz, cfg, RKISP1_RSZ_PAD_SINK, which);
-       src_fmt = rkisp1_rsz_get_pad_fmt(rsz, cfg, RKISP1_RSZ_PAD_SRC, which);
-       sink_crop = rkisp1_rsz_get_pad_crop(rsz, cfg, RKISP1_RSZ_PAD_SINK,
-                                           which);
-       if (rsz->id == RKISP1_SELFPATH)
-               sink_fmt->code = MEDIA_BUS_FMT_YUYV8_2X8;
-       else
-               sink_fmt->code = format->code;
-
-       mbus_info = rkisp1_isp_mbus_info_get(sink_fmt->code);
-       if (!mbus_info || !(mbus_info->direction & RKISP1_ISP_SD_SRC)) {
-               sink_fmt->code = RKISP1_DEF_FMT;
-               mbus_info = rkisp1_isp_mbus_info_get(sink_fmt->code);
-       }
-       if (which == V4L2_SUBDEV_FORMAT_ACTIVE)
-               rsz->pixel_enc = mbus_info->pixel_enc;
-
-       /* Propagete to source pad */
-       src_fmt->code = sink_fmt->code;
-
-       sink_fmt->width = clamp_t(u32, format->width,
-                                 RKISP1_ISP_MIN_WIDTH,
-                                 RKISP1_ISP_MAX_WIDTH);
-       sink_fmt->height = clamp_t(u32, format->height,
-                                 RKISP1_ISP_MIN_HEIGHT,
-                                 RKISP1_ISP_MAX_HEIGHT);
-
-       *format = *sink_fmt;
-
-       /* Update sink crop */
-       rkisp1_rsz_set_sink_crop(rsz, cfg, sink_crop, which);
-}
-
-static int rkisp1_rsz_get_fmt(struct v4l2_subdev *sd,
-                             struct v4l2_subdev_pad_config *cfg,
-                             struct v4l2_subdev_format *fmt)
-{
-       struct rkisp1_resizer *rsz =
-               container_of(sd, struct rkisp1_resizer, sd);
-
-       mutex_lock(&rsz->ops_lock);
-       fmt->format = *rkisp1_rsz_get_pad_fmt(rsz, cfg, fmt->pad, fmt->which);
-       mutex_unlock(&rsz->ops_lock);
-       return 0;
-}
-
-static int rkisp1_rsz_set_fmt(struct v4l2_subdev *sd,
-                             struct v4l2_subdev_pad_config *cfg,
-                             struct v4l2_subdev_format *fmt)
-{
-       struct rkisp1_resizer *rsz =
-               container_of(sd, struct rkisp1_resizer, sd);
-
-       mutex_lock(&rsz->ops_lock);
-       if (fmt->pad == RKISP1_RSZ_PAD_SINK)
-               rkisp1_rsz_set_sink_fmt(rsz, cfg, &fmt->format, fmt->which);
-       else
-               rkisp1_rsz_set_src_fmt(rsz, cfg, &fmt->format, fmt->which);
-
-       mutex_unlock(&rsz->ops_lock);
-       return 0;
-}
-
-static int rkisp1_rsz_get_selection(struct v4l2_subdev *sd,
-                                   struct v4l2_subdev_pad_config *cfg,
-                                   struct v4l2_subdev_selection *sel)
-{
-       struct rkisp1_resizer *rsz =
-               container_of(sd, struct rkisp1_resizer, sd);
-       struct v4l2_mbus_framefmt *mf_sink;
-       int ret = 0;
-
-       if (sel->pad == RKISP1_RSZ_PAD_SRC)
-               return -EINVAL;
-
-       mutex_lock(&rsz->ops_lock);
-       switch (sel->target) {
-       case V4L2_SEL_TGT_CROP_BOUNDS:
-               mf_sink = rkisp1_rsz_get_pad_fmt(rsz, cfg, RKISP1_RSZ_PAD_SINK,
-                                                sel->which);
-               sel->r.height = mf_sink->height;
-               sel->r.width = mf_sink->width;
-               sel->r.left = 0;
-               sel->r.top = 0;
-               break;
-       case V4L2_SEL_TGT_CROP:
-               sel->r = *rkisp1_rsz_get_pad_crop(rsz, cfg, RKISP1_RSZ_PAD_SINK,
-                                                 sel->which);
-               break;
-       default:
-               ret = -EINVAL;
-       }
-
-       mutex_unlock(&rsz->ops_lock);
-       return ret;
-}
-
-static int rkisp1_rsz_set_selection(struct v4l2_subdev *sd,
-                                   struct v4l2_subdev_pad_config *cfg,
-                                   struct v4l2_subdev_selection *sel)
-{
-       struct rkisp1_resizer *rsz =
-               container_of(sd, struct rkisp1_resizer, sd);
-
-       if (sel->target != V4L2_SEL_TGT_CROP || sel->pad == RKISP1_RSZ_PAD_SRC)
-               return -EINVAL;
-
-       dev_dbg(rsz->rkisp1->dev, "%s: pad: %d sel(%d,%d)/%dx%d\n", __func__,
-               sel->pad, sel->r.left, sel->r.top, sel->r.width, sel->r.height);
-
-       mutex_lock(&rsz->ops_lock);
-       rkisp1_rsz_set_sink_crop(rsz, cfg, &sel->r, sel->which);
-       mutex_unlock(&rsz->ops_lock);
-
-       return 0;
-}
-
-static const struct media_entity_operations rkisp1_rsz_media_ops = {
-       .link_validate = v4l2_subdev_link_validate,
-};
-
-static const struct v4l2_subdev_pad_ops rkisp1_rsz_pad_ops = {
-       .enum_mbus_code = rkisp1_rsz_enum_mbus_code,
-       .get_selection = rkisp1_rsz_get_selection,
-       .set_selection = rkisp1_rsz_set_selection,
-       .init_cfg = rkisp1_rsz_init_config,
-       .get_fmt = rkisp1_rsz_get_fmt,
-       .set_fmt = rkisp1_rsz_set_fmt,
-       .link_validate = v4l2_subdev_link_validate_default,
-};
-
-/* ----------------------------------------------------------------------------
- * Stream operations
- */
-
-static int rkisp1_rsz_s_stream(struct v4l2_subdev *sd, int enable)
-{
-       struct rkisp1_resizer *rsz =
-               container_of(sd, struct rkisp1_resizer, sd);
-       struct rkisp1_device *rkisp1 = rsz->rkisp1;
-       struct rkisp1_capture *other = &rkisp1->capture_devs[rsz->id ^ 1];
-       enum rkisp1_shadow_regs_when when = RKISP1_SHADOW_REGS_SYNC;
-
-       if (!enable) {
-               rkisp1_dcrop_disable(rsz, RKISP1_SHADOW_REGS_ASYNC);
-               rkisp1_rsz_disable(rsz, RKISP1_SHADOW_REGS_ASYNC);
-               return 0;
-       }
-
-       if (other->is_streaming)
-               when = RKISP1_SHADOW_REGS_ASYNC;
-
-       mutex_lock(&rsz->ops_lock);
-       rkisp1_rsz_config(rsz, when);
-       rkisp1_dcrop_config(rsz);
-
-       mutex_unlock(&rsz->ops_lock);
-       return 0;
-}
-
-static const struct v4l2_subdev_video_ops rkisp1_rsz_video_ops = {
-       .s_stream = rkisp1_rsz_s_stream,
-};
-
-static const struct v4l2_subdev_ops rkisp1_rsz_ops = {
-       .video = &rkisp1_rsz_video_ops,
-       .pad = &rkisp1_rsz_pad_ops,
-};
-
-static void rkisp1_rsz_unregister(struct rkisp1_resizer *rsz)
-{
-       v4l2_device_unregister_subdev(&rsz->sd);
-       media_entity_cleanup(&rsz->sd.entity);
-}
-
-static int rkisp1_rsz_register(struct rkisp1_resizer *rsz)
-{
-       const char * const dev_names[] = {RKISP1_RSZ_MP_DEV_NAME,
-                                         RKISP1_RSZ_SP_DEV_NAME};
-       struct media_pad *pads = rsz->pads;
-       struct v4l2_subdev *sd = &rsz->sd;
-       int ret;
-
-       if (rsz->id == RKISP1_SELFPATH)
-               rsz->config = &rkisp1_rsz_config_sp;
-       else
-               rsz->config = &rkisp1_rsz_config_mp;
-
-       v4l2_subdev_init(sd, &rkisp1_rsz_ops);
-       sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
-       sd->entity.ops = &rkisp1_rsz_media_ops;
-       sd->entity.function = MEDIA_ENT_F_PROC_VIDEO_SCALER;
-       sd->owner = THIS_MODULE;
-       strscpy(sd->name, dev_names[rsz->id], sizeof(sd->name));
-
-       pads[RKISP1_RSZ_PAD_SINK].flags = MEDIA_PAD_FL_SINK |
-                                         MEDIA_PAD_FL_MUST_CONNECT;
-       pads[RKISP1_RSZ_PAD_SRC].flags = MEDIA_PAD_FL_SOURCE |
-                                        MEDIA_PAD_FL_MUST_CONNECT;
-
-       rsz->pixel_enc = RKISP1_DEF_PIXEL_ENC;
-
-       mutex_init(&rsz->ops_lock);
-       ret = media_entity_pads_init(&sd->entity, RKISP1_RSZ_PAD_MAX, pads);
-       if (ret)
-               return ret;
-
-       ret = v4l2_device_register_subdev(&rsz->rkisp1->v4l2_dev, sd);
-       if (ret) {
-               dev_err(sd->dev, "Failed to register resizer subdev\n");
-               goto err_cleanup_media_entity;
-       }
-
-       rkisp1_rsz_init_config(sd, rsz->pad_cfg);
-       return 0;
-
-err_cleanup_media_entity:
-       media_entity_cleanup(&sd->entity);
-
-       return ret;
-}
-
-int rkisp1_resizer_devs_register(struct rkisp1_device *rkisp1)
-{
-       struct rkisp1_resizer *rsz;
-       unsigned int i, j;
-       int ret;
-
-       for (i = 0; i < ARRAY_SIZE(rkisp1->resizer_devs); i++) {
-               rsz = &rkisp1->resizer_devs[i];
-               rsz->rkisp1 = rkisp1;
-               rsz->id = i;
-               ret = rkisp1_rsz_register(rsz);
-               if (ret)
-                       goto err_unreg_resizer_devs;
-       }
-
-       return 0;
-
-err_unreg_resizer_devs:
-       for (j = 0; j < i; j++) {
-               rsz = &rkisp1->resizer_devs[j];
-               rkisp1_rsz_unregister(rsz);
-       }
-
-       return ret;
-}
-
-void rkisp1_resizer_devs_unregister(struct rkisp1_device *rkisp1)
-{
-       struct rkisp1_resizer *mp = &rkisp1->resizer_devs[RKISP1_MAINPATH];
-       struct rkisp1_resizer *sp = &rkisp1->resizer_devs[RKISP1_SELFPATH];
-
-       rkisp1_rsz_unregister(mp);
-       rkisp1_rsz_unregister(sp);
-}
diff --git a/drivers/staging/media/rkisp1/rkisp1-stats.c b/drivers/staging/media/rkisp1/rkisp1-stats.c
deleted file mode 100644 (file)
index 51c64f7..0000000
+++ /dev/null
@@ -1,436 +0,0 @@
-// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
-/*
- * Rockchip ISP1 Driver - Stats subdevice
- *
- * Copyright (C) 2017 Rockchip Electronics Co., Ltd.
- */
-
-#include <media/v4l2-common.h>
-#include <media/v4l2-event.h>
-#include <media/v4l2-ioctl.h>
-#include <media/videobuf2-core.h>
-#include <media/videobuf2-vmalloc.h>   /* for ISP statistics */
-
-#include "rkisp1-common.h"
-
-#define RKISP1_STATS_DEV_NAME  RKISP1_DRIVER_NAME "_stats"
-
-#define RKISP1_ISP_STATS_REQ_BUFS_MIN 2
-#define RKISP1_ISP_STATS_REQ_BUFS_MAX 8
-
-static int rkisp1_stats_enum_fmt_meta_cap(struct file *file, void *priv,
-                                         struct v4l2_fmtdesc *f)
-{
-       struct video_device *video = video_devdata(file);
-       struct rkisp1_stats *stats = video_get_drvdata(video);
-
-       if (f->index > 0 || f->type != video->queue->type)
-               return -EINVAL;
-
-       f->pixelformat = stats->vdev_fmt.fmt.meta.dataformat;
-       return 0;
-}
-
-static int rkisp1_stats_g_fmt_meta_cap(struct file *file, void *priv,
-                                      struct v4l2_format *f)
-{
-       struct video_device *video = video_devdata(file);
-       struct rkisp1_stats *stats = video_get_drvdata(video);
-       struct v4l2_meta_format *meta = &f->fmt.meta;
-
-       if (f->type != video->queue->type)
-               return -EINVAL;
-
-       memset(meta, 0, sizeof(*meta));
-       meta->dataformat = stats->vdev_fmt.fmt.meta.dataformat;
-       meta->buffersize = stats->vdev_fmt.fmt.meta.buffersize;
-
-       return 0;
-}
-
-static int rkisp1_stats_querycap(struct file *file,
-                                void *priv, struct v4l2_capability *cap)
-{
-       struct video_device *vdev = video_devdata(file);
-
-       strscpy(cap->driver, RKISP1_DRIVER_NAME, sizeof(cap->driver));
-       strscpy(cap->card, vdev->name, sizeof(cap->card));
-       strscpy(cap->bus_info, RKISP1_BUS_INFO, sizeof(cap->bus_info));
-
-       return 0;
-}
-
-/* ISP video device IOCTLs */
-static const struct v4l2_ioctl_ops rkisp1_stats_ioctl = {
-       .vidioc_reqbufs = vb2_ioctl_reqbufs,
-       .vidioc_querybuf = vb2_ioctl_querybuf,
-       .vidioc_create_bufs = vb2_ioctl_create_bufs,
-       .vidioc_qbuf = vb2_ioctl_qbuf,
-       .vidioc_dqbuf = vb2_ioctl_dqbuf,
-       .vidioc_prepare_buf = vb2_ioctl_prepare_buf,
-       .vidioc_expbuf = vb2_ioctl_expbuf,
-       .vidioc_streamon = vb2_ioctl_streamon,
-       .vidioc_streamoff = vb2_ioctl_streamoff,
-       .vidioc_enum_fmt_meta_cap = rkisp1_stats_enum_fmt_meta_cap,
-       .vidioc_g_fmt_meta_cap = rkisp1_stats_g_fmt_meta_cap,
-       .vidioc_s_fmt_meta_cap = rkisp1_stats_g_fmt_meta_cap,
-       .vidioc_try_fmt_meta_cap = rkisp1_stats_g_fmt_meta_cap,
-       .vidioc_querycap = rkisp1_stats_querycap,
-       .vidioc_subscribe_event = v4l2_ctrl_subscribe_event,
-       .vidioc_unsubscribe_event = v4l2_event_unsubscribe,
-};
-
-static const struct v4l2_file_operations rkisp1_stats_fops = {
-       .mmap = vb2_fop_mmap,
-       .unlocked_ioctl = video_ioctl2,
-       .poll = vb2_fop_poll,
-       .open = v4l2_fh_open,
-       .release = vb2_fop_release
-};
-
-static int rkisp1_stats_vb2_queue_setup(struct vb2_queue *vq,
-                                       unsigned int *num_buffers,
-                                       unsigned int *num_planes,
-                                       unsigned int sizes[],
-                                       struct device *alloc_devs[])
-{
-       struct rkisp1_stats *stats = vq->drv_priv;
-
-       *num_planes = 1;
-
-       *num_buffers = clamp_t(u32, *num_buffers, RKISP1_ISP_STATS_REQ_BUFS_MIN,
-                              RKISP1_ISP_STATS_REQ_BUFS_MAX);
-
-       sizes[0] = sizeof(struct rkisp1_stat_buffer);
-
-       INIT_LIST_HEAD(&stats->stat);
-
-       return 0;
-}
-
-static void rkisp1_stats_vb2_buf_queue(struct vb2_buffer *vb)
-{
-       struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
-       struct rkisp1_buffer *stats_buf =
-               container_of(vbuf, struct rkisp1_buffer, vb);
-       struct vb2_queue *vq = vb->vb2_queue;
-       struct rkisp1_stats *stats_dev = vq->drv_priv;
-
-       stats_buf->vaddr = vb2_plane_vaddr(vb, 0);
-
-       spin_lock_irq(&stats_dev->lock);
-       list_add_tail(&stats_buf->queue, &stats_dev->stat);
-       spin_unlock_irq(&stats_dev->lock);
-}
-
-static int rkisp1_stats_vb2_buf_prepare(struct vb2_buffer *vb)
-{
-       if (vb2_plane_size(vb, 0) < sizeof(struct rkisp1_stat_buffer))
-               return -EINVAL;
-
-       vb2_set_plane_payload(vb, 0, sizeof(struct rkisp1_stat_buffer));
-
-       return 0;
-}
-
-static void rkisp1_stats_vb2_stop_streaming(struct vb2_queue *vq)
-{
-       struct rkisp1_stats *stats = vq->drv_priv;
-       struct rkisp1_buffer *buf;
-       unsigned int i;
-
-       spin_lock_irq(&stats->lock);
-       stats->is_streaming = false;
-       for (i = 0; i < RKISP1_ISP_STATS_REQ_BUFS_MAX; i++) {
-               if (list_empty(&stats->stat))
-                       break;
-               buf = list_first_entry(&stats->stat,
-                                      struct rkisp1_buffer, queue);
-               list_del(&buf->queue);
-               vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_ERROR);
-       }
-       spin_unlock_irq(&stats->lock);
-}
-
-static int
-rkisp1_stats_vb2_start_streaming(struct vb2_queue *queue, unsigned int count)
-{
-       struct rkisp1_stats *stats = queue->drv_priv;
-
-       spin_lock_irq(&stats->lock);
-       stats->is_streaming = true;
-       spin_unlock_irq(&stats->lock);
-
-       return 0;
-}
-
-static const struct vb2_ops rkisp1_stats_vb2_ops = {
-       .queue_setup = rkisp1_stats_vb2_queue_setup,
-       .buf_queue = rkisp1_stats_vb2_buf_queue,
-       .buf_prepare = rkisp1_stats_vb2_buf_prepare,
-       .wait_prepare = vb2_ops_wait_prepare,
-       .wait_finish = vb2_ops_wait_finish,
-       .stop_streaming = rkisp1_stats_vb2_stop_streaming,
-       .start_streaming = rkisp1_stats_vb2_start_streaming,
-};
-
-static int
-rkisp1_stats_init_vb2_queue(struct vb2_queue *q, struct rkisp1_stats *stats)
-{
-       struct rkisp1_vdev_node *node;
-
-       node = container_of(q, struct rkisp1_vdev_node, buf_queue);
-
-       q->type = V4L2_BUF_TYPE_META_CAPTURE;
-       q->io_modes = VB2_MMAP | VB2_USERPTR | VB2_DMABUF;
-       q->drv_priv = stats;
-       q->ops = &rkisp1_stats_vb2_ops;
-       q->mem_ops = &vb2_vmalloc_memops;
-       q->buf_struct_size = sizeof(struct rkisp1_buffer);
-       q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
-       q->lock = &node->vlock;
-
-       return vb2_queue_init(q);
-}
-
-static void rkisp1_stats_get_awb_meas(struct rkisp1_stats *stats,
-                                     struct rkisp1_stat_buffer *pbuf)
-{
-       /* Protect against concurrent access from ISR? */
-       struct rkisp1_device *rkisp1 = stats->rkisp1;
-       u32 reg_val;
-
-       pbuf->meas_type |= RKISP1_CIF_ISP_STAT_AWB;
-       reg_val = rkisp1_read(rkisp1, RKISP1_CIF_ISP_AWB_WHITE_CNT);
-       pbuf->params.awb.awb_mean[0].cnt =
-                               RKISP1_CIF_ISP_AWB_GET_PIXEL_CNT(reg_val);
-       reg_val = rkisp1_read(rkisp1, RKISP1_CIF_ISP_AWB_MEAN);
-
-       pbuf->params.awb.awb_mean[0].mean_cr_or_r =
-                               RKISP1_CIF_ISP_AWB_GET_MEAN_CR_R(reg_val);
-       pbuf->params.awb.awb_mean[0].mean_cb_or_b =
-                               RKISP1_CIF_ISP_AWB_GET_MEAN_CB_B(reg_val);
-       pbuf->params.awb.awb_mean[0].mean_y_or_g =
-                               RKISP1_CIF_ISP_AWB_GET_MEAN_Y_G(reg_val);
-}
-
-static void rkisp1_stats_get_aec_meas(struct rkisp1_stats *stats,
-                                     struct rkisp1_stat_buffer *pbuf)
-{
-       struct rkisp1_device *rkisp1 = stats->rkisp1;
-       unsigned int i;
-
-       pbuf->meas_type |= RKISP1_CIF_ISP_STAT_AUTOEXP;
-       for (i = 0; i < RKISP1_CIF_ISP_AE_MEAN_MAX; i++)
-               pbuf->params.ae.exp_mean[i] =
-                       (u8)rkisp1_read(rkisp1,
-                                       RKISP1_CIF_ISP_EXP_MEAN_00 + i * 4);
-}
-
-static void rkisp1_stats_get_afc_meas(struct rkisp1_stats *stats,
-                                     struct rkisp1_stat_buffer *pbuf)
-{
-       struct rkisp1_device *rkisp1 = stats->rkisp1;
-       struct rkisp1_cif_isp_af_stat *af;
-
-       pbuf->meas_type |= RKISP1_CIF_ISP_STAT_AFM;
-
-       af = &pbuf->params.af;
-       af->window[0].sum = rkisp1_read(rkisp1, RKISP1_CIF_ISP_AFM_SUM_A);
-       af->window[0].lum = rkisp1_read(rkisp1, RKISP1_CIF_ISP_AFM_LUM_A);
-       af->window[1].sum = rkisp1_read(rkisp1, RKISP1_CIF_ISP_AFM_SUM_B);
-       af->window[1].lum = rkisp1_read(rkisp1, RKISP1_CIF_ISP_AFM_LUM_B);
-       af->window[2].sum = rkisp1_read(rkisp1, RKISP1_CIF_ISP_AFM_SUM_C);
-       af->window[2].lum = rkisp1_read(rkisp1, RKISP1_CIF_ISP_AFM_LUM_C);
-}
-
-static void rkisp1_stats_get_hst_meas(struct rkisp1_stats *stats,
-                                     struct rkisp1_stat_buffer *pbuf)
-{
-       struct rkisp1_device *rkisp1 = stats->rkisp1;
-       unsigned int i;
-
-       pbuf->meas_type |= RKISP1_CIF_ISP_STAT_HIST;
-       for (i = 0; i < RKISP1_CIF_ISP_HIST_BIN_N_MAX; i++)
-               pbuf->params.hist.hist_bins[i] =
-                       (u8)rkisp1_read(rkisp1,
-                                       RKISP1_CIF_ISP_HIST_BIN_0 + i * 4);
-}
-
-static void rkisp1_stats_get_bls_meas(struct rkisp1_stats *stats,
-                                     struct rkisp1_stat_buffer *pbuf)
-{
-       struct rkisp1_device *rkisp1 = stats->rkisp1;
-       const struct rkisp1_isp_mbus_info *in_fmt = rkisp1->isp.sink_fmt;
-       struct rkisp1_cif_isp_bls_meas_val *bls_val;
-
-       bls_val = &pbuf->params.ae.bls_val;
-       if (in_fmt->bayer_pat == RKISP1_RAW_BGGR) {
-               bls_val->meas_b =
-                       rkisp1_read(rkisp1, RKISP1_CIF_ISP_BLS_A_MEASURED);
-               bls_val->meas_gb =
-                       rkisp1_read(rkisp1, RKISP1_CIF_ISP_BLS_B_MEASURED);
-               bls_val->meas_gr =
-                       rkisp1_read(rkisp1, RKISP1_CIF_ISP_BLS_C_MEASURED);
-               bls_val->meas_r =
-                       rkisp1_read(rkisp1, RKISP1_CIF_ISP_BLS_D_MEASURED);
-       } else if (in_fmt->bayer_pat == RKISP1_RAW_GBRG) {
-               bls_val->meas_gb =
-                       rkisp1_read(rkisp1, RKISP1_CIF_ISP_BLS_A_MEASURED);
-               bls_val->meas_b =
-                       rkisp1_read(rkisp1, RKISP1_CIF_ISP_BLS_B_MEASURED);
-               bls_val->meas_r =
-                       rkisp1_read(rkisp1, RKISP1_CIF_ISP_BLS_C_MEASURED);
-               bls_val->meas_gr =
-                       rkisp1_read(rkisp1, RKISP1_CIF_ISP_BLS_D_MEASURED);
-       } else if (in_fmt->bayer_pat == RKISP1_RAW_GRBG) {
-               bls_val->meas_gr =
-                       rkisp1_read(rkisp1, RKISP1_CIF_ISP_BLS_A_MEASURED);
-               bls_val->meas_r =
-                       rkisp1_read(rkisp1, RKISP1_CIF_ISP_BLS_B_MEASURED);
-               bls_val->meas_b =
-                       rkisp1_read(rkisp1, RKISP1_CIF_ISP_BLS_C_MEASURED);
-               bls_val->meas_gb =
-                       rkisp1_read(rkisp1, RKISP1_CIF_ISP_BLS_D_MEASURED);
-       } else if (in_fmt->bayer_pat == RKISP1_RAW_RGGB) {
-               bls_val->meas_r =
-                       rkisp1_read(rkisp1, RKISP1_CIF_ISP_BLS_A_MEASURED);
-               bls_val->meas_gr =
-                       rkisp1_read(rkisp1, RKISP1_CIF_ISP_BLS_B_MEASURED);
-               bls_val->meas_gb =
-                       rkisp1_read(rkisp1, RKISP1_CIF_ISP_BLS_C_MEASURED);
-               bls_val->meas_b =
-                       rkisp1_read(rkisp1, RKISP1_CIF_ISP_BLS_D_MEASURED);
-       }
-}
-
-static void
-rkisp1_stats_send_measurement(struct rkisp1_stats *stats, u32 isp_ris)
-{
-       struct rkisp1_stat_buffer *cur_stat_buf;
-       struct rkisp1_buffer *cur_buf = NULL;
-       unsigned int frame_sequence = stats->rkisp1->isp.frame_sequence;
-       u64 timestamp = ktime_get_ns();
-
-       /* get one empty buffer */
-       if (!list_empty(&stats->stat)) {
-               cur_buf = list_first_entry(&stats->stat,
-                                          struct rkisp1_buffer, queue);
-               list_del(&cur_buf->queue);
-       }
-
-       if (!cur_buf)
-               return;
-
-       cur_stat_buf =
-               (struct rkisp1_stat_buffer *)(cur_buf->vaddr);
-
-       if (isp_ris & RKISP1_CIF_ISP_AWB_DONE)
-               rkisp1_stats_get_awb_meas(stats, cur_stat_buf);
-
-       if (isp_ris & RKISP1_CIF_ISP_AFM_FIN)
-               rkisp1_stats_get_afc_meas(stats, cur_stat_buf);
-
-       if (isp_ris & RKISP1_CIF_ISP_EXP_END) {
-               rkisp1_stats_get_aec_meas(stats, cur_stat_buf);
-               rkisp1_stats_get_bls_meas(stats, cur_stat_buf);
-       }
-
-       if (isp_ris & RKISP1_CIF_ISP_HIST_MEASURE_RDY)
-               rkisp1_stats_get_hst_meas(stats, cur_stat_buf);
-
-       vb2_set_plane_payload(&cur_buf->vb.vb2_buf, 0,
-                             sizeof(struct rkisp1_stat_buffer));
-       cur_buf->vb.sequence = frame_sequence;
-       cur_buf->vb.vb2_buf.timestamp = timestamp;
-       vb2_buffer_done(&cur_buf->vb.vb2_buf, VB2_BUF_STATE_DONE);
-}
-
-void rkisp1_stats_isr(struct rkisp1_stats *stats, u32 isp_ris)
-{
-       struct rkisp1_device *rkisp1 = stats->rkisp1;
-       unsigned int isp_mis_tmp = 0;
-
-       spin_lock(&stats->lock);
-
-       rkisp1_write(rkisp1, RKISP1_STATS_MEAS_MASK, RKISP1_CIF_ISP_ICR);
-
-       isp_mis_tmp = rkisp1_read(rkisp1, RKISP1_CIF_ISP_MIS);
-       if (isp_mis_tmp & RKISP1_STATS_MEAS_MASK)
-               rkisp1->debug.stats_error++;
-
-       if (!stats->is_streaming)
-               goto unlock;
-       if (isp_ris & RKISP1_STATS_MEAS_MASK)
-               rkisp1_stats_send_measurement(stats, isp_ris);
-
-unlock:
-       spin_unlock(&stats->lock);
-}
-
-static void rkisp1_init_stats(struct rkisp1_stats *stats)
-{
-       stats->vdev_fmt.fmt.meta.dataformat =
-               V4L2_META_FMT_RK_ISP1_STAT_3A;
-       stats->vdev_fmt.fmt.meta.buffersize =
-               sizeof(struct rkisp1_stat_buffer);
-}
-
-int rkisp1_stats_register(struct rkisp1_device *rkisp1)
-{
-       struct rkisp1_stats *stats = &rkisp1->stats;
-       struct rkisp1_vdev_node *node = &stats->vnode;
-       struct video_device *vdev = &node->vdev;
-       int ret;
-
-       stats->rkisp1 = rkisp1;
-       mutex_init(&node->vlock);
-       INIT_LIST_HEAD(&stats->stat);
-       spin_lock_init(&stats->lock);
-
-       strscpy(vdev->name, RKISP1_STATS_DEV_NAME, sizeof(vdev->name));
-
-       video_set_drvdata(vdev, stats);
-       vdev->ioctl_ops = &rkisp1_stats_ioctl;
-       vdev->fops = &rkisp1_stats_fops;
-       vdev->release = video_device_release_empty;
-       vdev->lock = &node->vlock;
-       vdev->v4l2_dev = &rkisp1->v4l2_dev;
-       vdev->queue = &node->buf_queue;
-       vdev->device_caps = V4L2_CAP_META_CAPTURE | V4L2_CAP_STREAMING;
-       vdev->vfl_dir =  VFL_DIR_RX;
-       rkisp1_stats_init_vb2_queue(vdev->queue, stats);
-       rkisp1_init_stats(stats);
-       video_set_drvdata(vdev, stats);
-
-       node->pad.flags = MEDIA_PAD_FL_SINK;
-       ret = media_entity_pads_init(&vdev->entity, 1, &node->pad);
-       if (ret)
-               goto err_mutex_destroy;
-
-       ret = video_register_device(vdev, VFL_TYPE_VIDEO, -1);
-       if (ret) {
-               dev_err(&vdev->dev,
-                       "failed to register %s, ret=%d\n", vdev->name, ret);
-               goto err_cleanup_media_entity;
-       }
-
-       return 0;
-
-err_cleanup_media_entity:
-       media_entity_cleanup(&vdev->entity);
-err_mutex_destroy:
-       mutex_destroy(&node->vlock);
-       return ret;
-}
-
-void rkisp1_stats_unregister(struct rkisp1_device *rkisp1)
-{
-       struct rkisp1_stats *stats = &rkisp1->stats;
-       struct rkisp1_vdev_node *node = &stats->vnode;
-       struct video_device *vdev = &node->vdev;
-
-       vb2_video_unregister_device(vdev);
-       media_entity_cleanup(&vdev->entity);
-       mutex_destroy(&node->vlock);
-}
diff --git a/drivers/staging/media/rkisp1/uapi/rkisp1-config.h b/drivers/staging/media/rkisp1/uapi/rkisp1-config.h
deleted file mode 100644 (file)
index 432cb6b..0000000
+++ /dev/null
@@ -1,888 +0,0 @@
-/* SPDX-License-Identifier: (GPL-2.0+ OR MIT) */
-/*
- * Rockchip ISP1 userspace API
- * Copyright (C) 2017 Rockchip Electronics Co., Ltd.
- */
-
-#ifndef _UAPI_RKISP1_CONFIG_H
-#define _UAPI_RKISP1_CONFIG_H
-
-#include <linux/types.h>
-
-/* Vendor specific - used for RK_ISP1 camera sub-system */
-#define V4L2_META_FMT_RK_ISP1_PARAMS   v4l2_fourcc('R', 'K', '1', 'P') /* Rockchip ISP1 params */
-#define V4L2_META_FMT_RK_ISP1_STAT_3A  v4l2_fourcc('R', 'K', '1', 'S') /* Rockchip ISP1 3A statistics */
-
-/* Defect Pixel Cluster Detection */
-#define RKISP1_CIF_ISP_MODULE_DPCC             (1U << 0)
-/* Black Level Subtraction */
-#define RKISP1_CIF_ISP_MODULE_BLS              (1U << 1)
-/* Sensor De-gamma */
-#define RKISP1_CIF_ISP_MODULE_SDG              (1U << 2)
-/* Histogram */
-#define RKISP1_CIF_ISP_MODULE_HST              (1U << 3)
-/* Lens Shade Control */
-#define RKISP1_CIF_ISP_MODULE_LSC              (1U << 4)
-/* Auto White Balance Gain */
-#define RKISP1_CIF_ISP_MODULE_AWB_GAIN         (1U << 5)
-/* Filter */
-#define RKISP1_CIF_ISP_MODULE_FLT              (1U << 6)
-/* Bayer Demosaic */
-#define RKISP1_CIF_ISP_MODULE_BDM              (1U << 7)
-/* Cross Talk */
-#define RKISP1_CIF_ISP_MODULE_CTK              (1U << 8)
-/* Gamma Out Curve */
-#define RKISP1_CIF_ISP_MODULE_GOC              (1U << 9)
-/* Color Processing */
-#define RKISP1_CIF_ISP_MODULE_CPROC            (1U << 10)
-/* Auto Focus Control */
-#define RKISP1_CIF_ISP_MODULE_AFC              (1U << 11)
-/* Auto White Balancing */
-#define RKISP1_CIF_ISP_MODULE_AWB              (1U << 12)
-/* Image Effect */
-#define RKISP1_CIF_ISP_MODULE_IE               (1U << 13)
-/* Auto Exposure Control */
-#define RKISP1_CIF_ISP_MODULE_AEC              (1U << 14)
-/* Wide Dynamic Range */
-#define RKISP1_CIF_ISP_MODULE_WDR              (1U << 15)
-/* Denoise Pre-Filter */
-#define RKISP1_CIF_ISP_MODULE_DPF              (1U << 16)
-/* Denoise Pre-Filter Strength */
-#define RKISP1_CIF_ISP_MODULE_DPF_STRENGTH     (1U << 17)
-
-#define RKISP1_CIF_ISP_CTK_COEFF_MAX            0x100
-#define RKISP1_CIF_ISP_CTK_OFFSET_MAX           0x800
-
-#define RKISP1_CIF_ISP_AE_MEAN_MAX              25
-#define RKISP1_CIF_ISP_HIST_BIN_N_MAX           16
-#define RKISP1_CIF_ISP_AFM_MAX_WINDOWS          3
-#define RKISP1_CIF_ISP_DEGAMMA_CURVE_SIZE       17
-
-#define RKISP1_CIF_ISP_BDM_MAX_TH               0xff
-
-/*
- * Black level compensation
- */
-/* maximum value for horizontal start address */
-#define RKISP1_CIF_ISP_BLS_START_H_MAX             0x00000fff
-/* maximum value for horizontal stop address */
-#define RKISP1_CIF_ISP_BLS_STOP_H_MAX              0x00000fff
-/* maximum value for vertical start address */
-#define RKISP1_CIF_ISP_BLS_START_V_MAX             0x00000fff
-/* maximum value for vertical stop address */
-#define RKISP1_CIF_ISP_BLS_STOP_V_MAX              0x00000fff
-/* maximum is 2^18 = 262144*/
-#define RKISP1_CIF_ISP_BLS_SAMPLES_MAX             0x00000012
-/* maximum value for fixed black level */
-#define RKISP1_CIF_ISP_BLS_FIX_SUB_MAX             0x00000fff
-/* minimum value for fixed black level */
-#define RKISP1_CIF_ISP_BLS_FIX_SUB_MIN             0xfffff000
-/* 13 bit range (signed)*/
-#define RKISP1_CIF_ISP_BLS_FIX_MASK                0x00001fff
-
-/*
- * Automatic white balance measurements
- */
-#define RKISP1_CIF_ISP_AWB_MAX_GRID                1
-#define RKISP1_CIF_ISP_AWB_MAX_FRAMES              7
-
-/*
- * Gamma out
- */
-/* Maximum number of color samples supported */
-#define RKISP1_CIF_ISP_GAMMA_OUT_MAX_SAMPLES       17
-
-/*
- * Lens shade correction
- */
-#define RKISP1_CIF_ISP_LSC_SECTORS_TBL_SIZE        8
-
-/*
- * The following matches the tuning process,
- * not the max capabilities of the chip.
- */
-#define RKISP1_CIF_ISP_LSC_SAMPLES_MAX             17
-
-/*
- * Histogram calculation
- */
-/* Last 3 values unused. */
-#define RKISP1_CIF_ISP_HISTOGRAM_WEIGHT_GRIDS_SIZE 28
-
-/*
- * Defect Pixel Cluster Correction
- */
-#define RKISP1_CIF_ISP_DPCC_METHODS_MAX       3
-
-/*
- * Denoising pre filter
- */
-#define RKISP1_CIF_ISP_DPF_MAX_NLF_COEFFS      17
-#define RKISP1_CIF_ISP_DPF_MAX_SPATIAL_COEFFS  6
-
-/*
- * Measurement types
- */
-#define RKISP1_CIF_ISP_STAT_AWB           (1U << 0)
-#define RKISP1_CIF_ISP_STAT_AUTOEXP       (1U << 1)
-#define RKISP1_CIF_ISP_STAT_AFM           (1U << 2)
-#define RKISP1_CIF_ISP_STAT_HIST          (1U << 3)
-
-enum rkisp1_cif_isp_histogram_mode {
-       RKISP1_CIF_ISP_HISTOGRAM_MODE_DISABLE,
-       RKISP1_CIF_ISP_HISTOGRAM_MODE_RGB_COMBINED,
-       RKISP1_CIF_ISP_HISTOGRAM_MODE_R_HISTOGRAM,
-       RKISP1_CIF_ISP_HISTOGRAM_MODE_G_HISTOGRAM,
-       RKISP1_CIF_ISP_HISTOGRAM_MODE_B_HISTOGRAM,
-       RKISP1_CIF_ISP_HISTOGRAM_MODE_Y_HISTOGRAM
-};
-
-enum rkisp1_cif_isp_awb_mode_type {
-       RKISP1_CIF_ISP_AWB_MODE_MANUAL,
-       RKISP1_CIF_ISP_AWB_MODE_RGB,
-       RKISP1_CIF_ISP_AWB_MODE_YCBCR
-};
-
-enum rkisp1_cif_isp_flt_mode {
-       RKISP1_CIF_ISP_FLT_STATIC_MODE,
-       RKISP1_CIF_ISP_FLT_DYNAMIC_MODE
-};
-
-/**
- * enum rkisp1_cif_isp_exp_ctrl_autostop - stop modes
- * @RKISP1_CIF_ISP_EXP_CTRL_AUTOSTOP_0: continuous measurement
- * @RKISP1_CIF_ISP_EXP_CTRL_AUTOSTOP_1: stop measuring after a complete frame
- */
-enum rkisp1_cif_isp_exp_ctrl_autostop {
-       RKISP1_CIF_ISP_EXP_CTRL_AUTOSTOP_0 = 0,
-       RKISP1_CIF_ISP_EXP_CTRL_AUTOSTOP_1 = 1,
-};
-
-/**
- * enum rkisp1_cif_isp_exp_meas_mode - Exposure measure mode
- * @RKISP1_CIF_ISP_EXP_MEASURING_MODE_0: Y = 16 + 0.25R + 0.5G + 0.1094B
- * @RKISP1_CIF_ISP_EXP_MEASURING_MODE_1: Y = (R + G + B) x (85/256)
- */
-enum rkisp1_cif_isp_exp_meas_mode {
-       RKISP1_CIF_ISP_EXP_MEASURING_MODE_0,
-       RKISP1_CIF_ISP_EXP_MEASURING_MODE_1,
-};
-
-/*---------- PART1: Input Parameters ------------*/
-
-/**
- * struct rkisp1_cif_isp_window -  measurement window.
- *
- * Measurements are calculated per window inside the frame.
- * This struct represents a window for a measurement.
- *
- * @h_offs: the horizontal offset of the window from the left of the frame in pixels.
- * @v_offs: the vertical offset of the window from the top of the frame in pixels.
- * @h_size: the horizontal size of the window in pixels
- * @v_size: the vertical size of the window in pixels.
- */
-struct rkisp1_cif_isp_window {
-       __u16 h_offs;
-       __u16 v_offs;
-       __u16 h_size;
-       __u16 v_size;
-};
-
-/**
- * struct rkisp1_cif_isp_bls_fixed_val - BLS fixed subtraction values
- *
- * The values will be subtracted from the sensor
- * values. Therefore a negative value means addition instead of subtraction!
- *
- * @r: Fixed (signed!) subtraction value for Bayer pattern R
- * @gr: Fixed (signed!) subtraction value for Bayer pattern Gr
- * @gb: Fixed (signed!) subtraction value for Bayer pattern Gb
- * @b: Fixed (signed!) subtraction value for Bayer pattern B
- */
-struct rkisp1_cif_isp_bls_fixed_val {
-       __s16 r;
-       __s16 gr;
-       __s16 gb;
-       __s16 b;
-};
-
-/**
- * struct rkisp1_cif_isp_bls_config - Configuration used by black level subtraction
- *
- * @enable_auto: Automatic mode activated means that the measured values
- *              are subtracted. Otherwise the fixed subtraction
- *              values will be subtracted.
- * @en_windows: enabled window
- * @bls_window1: Measurement window 1 size
- * @bls_window2: Measurement window 2 size
- * @bls_samples: Set amount of measured pixels for each Bayer position
- *              (A, B,C and D) to 2^bls_samples.
- * @fixed_val: Fixed subtraction values
- */
-struct rkisp1_cif_isp_bls_config {
-       __u8 enable_auto;
-       __u8 en_windows;
-       struct rkisp1_cif_isp_window bls_window1;
-       struct rkisp1_cif_isp_window bls_window2;
-       __u8 bls_samples;
-       struct rkisp1_cif_isp_bls_fixed_val fixed_val;
-};
-
-/**
- * struct rkisp1_cif_isp_dpcc_methods_config - Methods Configuration used by DPCC
- *
- * Methods Configuration used by Defect Pixel Cluster Correction
- *
- * @method: Method enable bits
- * @line_thresh: Line threshold
- * @line_mad_fac: Line MAD factor
- * @pg_fac: Peak gradient factor
- * @rnd_thresh: Rank Neighbor Difference threshold
- * @rg_fac: Rank gradient factor
- */
-struct rkisp1_cif_isp_dpcc_methods_config {
-       __u32 method;
-       __u32 line_thresh;
-       __u32 line_mad_fac;
-       __u32 pg_fac;
-       __u32 rnd_thresh;
-       __u32 rg_fac;
-};
-
-/**
- * struct rkisp1_cif_isp_dpcc_config - Configuration used by DPCC
- *
- * Configuration used by Defect Pixel Cluster Correction
- *
- * @mode: dpcc output mode
- * @output_mode: whether use hard coded methods
- * @set_use: stage1 methods set
- * @methods: methods config
- * @ro_limits: rank order limits
- * @rnd_offs: differential rank offsets for rank neighbor difference
- */
-struct rkisp1_cif_isp_dpcc_config {
-       __u32 mode;
-       __u32 output_mode;
-       __u32 set_use;
-       struct rkisp1_cif_isp_dpcc_methods_config methods[RKISP1_CIF_ISP_DPCC_METHODS_MAX];
-       __u32 ro_limits;
-       __u32 rnd_offs;
-};
-
-/**
- * struct rkisp1_cif_isp_gamma_corr_curve - gamma curve point definition y-axis (output).
- *
- * The reset values define a linear curve which has the same effect as bypass. Reset values are:
- * gamma_y[0] = 0x0000, gamma_y[1] = 0x0100, ... gamma_y[15] = 0x0f00, gamma_y[16] = 0xfff
- *
- * @gamma_y: the values for the y-axis of gamma curve points. Each value is 12 bit.
- */
-struct rkisp1_cif_isp_gamma_corr_curve {
-       __u16 gamma_y[RKISP1_CIF_ISP_DEGAMMA_CURVE_SIZE];
-};
-
-/**
- * struct rkisp1_cif_isp_gamma_curve_x_axis_pnts - De-Gamma Curve definition x increments
- *             (sampling points). gamma_dx0 is for the lower samples (1-8), gamma_dx1 is for the
- *             higher samples (9-16). The reset values for both fields is 0x44444444. This means
- *             that each sample is 4 units away from the previous one on the x-axis.
- *
- * @gamma_dx0: gamma curve sample points definitions. Bits 0:2 for sample 1. Bit 3 unused.
- *             Bits 4:6 for sample 2. bit 7 unused ... Bits 28:30 for sample 8. Bit 31 unused
- * @gamma_dx1: gamma curve sample points definitions. Bits 0:2 for sample 9. Bit 3 unused.
- *             Bits 4:6 for sample 10. bit 7 unused ... Bits 28:30 for sample 16. Bit 31 unused
- */
-struct rkisp1_cif_isp_gamma_curve_x_axis_pnts {
-       __u32 gamma_dx0;
-       __u32 gamma_dx1;
-};
-
-/**
- * struct rkisp1_cif_isp_sdg_config - Configuration used by sensor degamma
- *
- * @curve_r: gamma curve point definition axis for red
- * @curve_g: gamma curve point definition axis for green
- * @curve_b: gamma curve point definition axis for blue
- * @xa_pnts: x axis increments
- */
-struct rkisp1_cif_isp_sdg_config {
-       struct rkisp1_cif_isp_gamma_corr_curve curve_r;
-       struct rkisp1_cif_isp_gamma_corr_curve curve_g;
-       struct rkisp1_cif_isp_gamma_corr_curve curve_b;
-       struct rkisp1_cif_isp_gamma_curve_x_axis_pnts xa_pnts;
-};
-
-/**
- * struct rkisp1_cif_isp_lsc_config - Configuration used by Lens shading correction
- *
- * @r_data_tbl: sample table red
- * @gr_data_tbl: sample table green (red)
- * @gb_data_tbl: sample table green (blue)
- * @b_data_tbl: sample table blue
- * @x_grad_tbl: gradient table x
- * @y_grad_tbl: gradient table y
- * @x_size_tbl: size table x
- * @y_size_tbl: size table y
- * @config_width: not used at the moment
- * @config_height: not used at the moment
- */
-struct rkisp1_cif_isp_lsc_config {
-       __u16 r_data_tbl[RKISP1_CIF_ISP_LSC_SAMPLES_MAX][RKISP1_CIF_ISP_LSC_SAMPLES_MAX];
-       __u16 gr_data_tbl[RKISP1_CIF_ISP_LSC_SAMPLES_MAX][RKISP1_CIF_ISP_LSC_SAMPLES_MAX];
-       __u16 gb_data_tbl[RKISP1_CIF_ISP_LSC_SAMPLES_MAX][RKISP1_CIF_ISP_LSC_SAMPLES_MAX];
-       __u16 b_data_tbl[RKISP1_CIF_ISP_LSC_SAMPLES_MAX][RKISP1_CIF_ISP_LSC_SAMPLES_MAX];
-
-       __u16 x_grad_tbl[RKISP1_CIF_ISP_LSC_SECTORS_TBL_SIZE];
-       __u16 y_grad_tbl[RKISP1_CIF_ISP_LSC_SECTORS_TBL_SIZE];
-
-       __u16 x_size_tbl[RKISP1_CIF_ISP_LSC_SECTORS_TBL_SIZE];
-       __u16 y_size_tbl[RKISP1_CIF_ISP_LSC_SECTORS_TBL_SIZE];
-       __u16 config_width;
-       __u16 config_height;
-};
-
-/**
- * struct rkisp1_cif_isp_ie_config - Configuration used by image effects
- *
- * @effect: values from 'enum v4l2_colorfx'. Possible values are: V4L2_COLORFX_SEPIA,
- *             V4L2_COLORFX_SET_CBCR, V4L2_COLORFX_AQUA, V4L2_COLORFX_EMBOSS,
- *             V4L2_COLORFX_SKETCH,   V4L2_COLORFX_BW,   V4L2_COLORFX_NEGATIVE
- * @color_sel: bits 0:2 - colors bitmask (001 - blue, 010 - green, 100 - red).
- *             bits 8:15 - Threshold value of the RGB colors for the color selection effect.
- * @eff_mat_1: 3x3 Matrix Coefficients for Emboss Effect 1
- * @eff_mat_2: 3x3 Matrix Coefficients for Emboss Effect 2
- * @eff_mat_3: 3x3 Matrix Coefficients for Emboss 3/Sketch 1
- * @eff_mat_4: 3x3 Matrix Coefficients for Sketch Effect 2
- * @eff_mat_5: 3x3 Matrix Coefficients for Sketch Effect 3
- * @eff_tint: Chrominance increment values of tint (used for sepia effect)
- */
-struct rkisp1_cif_isp_ie_config {
-       __u16 effect;
-       __u16 color_sel;
-       __u16 eff_mat_1;
-       __u16 eff_mat_2;
-       __u16 eff_mat_3;
-       __u16 eff_mat_4;
-       __u16 eff_mat_5;
-       __u16 eff_tint;
-};
-
-/**
- * struct rkisp1_cif_isp_cproc_config - Configuration used by Color Processing
- *
- * @c_out_range: Chrominance pixel clipping range at output.
- *              (0 for limit, 1 for full)
- * @y_in_range: Luminance pixel clipping range at output.
- * @y_out_range: Luminance pixel clipping range at output.
- * @contrast: 00~ff, 0.0~1.992
- * @brightness: 80~7F, -128~+127
- * @sat: saturation, 00~FF, 0.0~1.992
- * @hue: 80~7F, -90~+87.188
- */
-struct rkisp1_cif_isp_cproc_config {
-       __u8 c_out_range;
-       __u8 y_in_range;
-       __u8 y_out_range;
-       __u8 contrast;
-       __u8 brightness;
-       __u8 sat;
-       __u8 hue;
-};
-
-/**
- * struct rkisp1_cif_isp_awb_meas_config - Configuration used by auto white balance
- *
- * @awb_mode: the awb meas mode. From enum rkisp1_cif_isp_awb_mode_type.
- * @awb_wnd: white balance measurement window (in pixels)
- * @max_y: only pixels values < max_y contribute to awb measurement, set to 0
- *        to disable this feature
- * @min_y: only pixels values > min_y contribute to awb measurement
- * @max_csum: Chrominance sum maximum value, only consider pixels with Cb+Cr,
- *           smaller than threshold for awb measurements
- * @min_c: Chrominance minimum value, only consider pixels with Cb/Cr
- *        each greater than threshold value for awb measurements
- * @frames: number of frames - 1 used for mean value calculation
- *         (ucFrames=0 means 1 Frame)
- * @awb_ref_cr: reference Cr value for AWB regulation, target for AWB
- * @awb_ref_cb: reference Cb value for AWB regulation, target for AWB
- * @enable_ymax_cmp: enable Y_MAX compare (Not valid in RGB measurement mode.)
- */
-struct rkisp1_cif_isp_awb_meas_config {
-       /*
-        * Note: currently the h and v offsets are mapped to grid offsets
-        */
-       struct rkisp1_cif_isp_window awb_wnd;
-       __u32 awb_mode;
-       __u8 max_y;
-       __u8 min_y;
-       __u8 max_csum;
-       __u8 min_c;
-       __u8 frames;
-       __u8 awb_ref_cr;
-       __u8 awb_ref_cb;
-       __u8 enable_ymax_cmp;
-};
-
-/**
- * struct rkisp1_cif_isp_awb_gain_config - Configuration used by auto white balance gain
- *
- * All fields in this struct are 10 bit, where:
- * 0x100h = 1, unsigned integer value, range 0 to 4 with 8 bit fractional part.
- *
- * out_data_x = ( AWB_GAIN_X * in_data + 128) >> 8
- *
- * @gain_red: gain value for red component.
- * @gain_green_r: gain value for green component in red line.
- * @gain_blue: gain value for blue component.
- * @gain_green_b: gain value for green component in blue line.
- */
-struct rkisp1_cif_isp_awb_gain_config {
-       __u16 gain_red;
-       __u16 gain_green_r;
-       __u16 gain_blue;
-       __u16 gain_green_b;
-};
-
-/**
- * struct rkisp1_cif_isp_flt_config - Configuration used by ISP filtering
- *
- * All 4 threshold fields (thresh_*) are 10 bits.
- * All 6 factor fields (fac_*) are 6 bits.
- *
- * @mode: ISP_FILT_MODE register fields (from enum rkisp1_cif_isp_flt_mode)
- * @grn_stage1: Green filter stage 1 select (range 0x0...0x8)
- * @chr_h_mode: Chroma filter horizontal mode
- * @chr_v_mode: Chroma filter vertical mode
- * @thresh_bl0: If thresh_bl1 < sum_grad < thresh_bl0 then fac_bl0 is selected (blurring th)
- * @thresh_bl1: If sum_grad < thresh_bl1 then fac_bl1 is selected (blurring th)
- * @thresh_sh0: If thresh_sh0 < sum_grad < thresh_sh1 then thresh_sh0 is selected (sharpening th)
- * @thresh_sh1: If thresh_sh1 < sum_grad then thresh_sh1 is selected (sharpening th)
- * @lum_weight: Parameters for luminance weight function.
- * @fac_sh1: filter factor for sharp1 level
- * @fac_sh0: filter factor for sharp0 level
- * @fac_mid: filter factor for mid level and for static filter mode
- * @fac_bl0: filter factor for blur 0 level
- * @fac_bl1: filter factor for blur 1 level (max blur)
- */
-struct rkisp1_cif_isp_flt_config {
-       __u32 mode;
-       __u8 grn_stage1;
-       __u8 chr_h_mode;
-       __u8 chr_v_mode;
-       __u32 thresh_bl0;
-       __u32 thresh_bl1;
-       __u32 thresh_sh0;
-       __u32 thresh_sh1;
-       __u32 lum_weight;
-       __u32 fac_sh1;
-       __u32 fac_sh0;
-       __u32 fac_mid;
-       __u32 fac_bl0;
-       __u32 fac_bl1;
-};
-
-/**
- * struct rkisp1_cif_isp_bdm_config - Configuration used by Bayer DeMosaic
- *
- * @demosaic_th: threshold for bayer demosaicing texture detection
- */
-struct rkisp1_cif_isp_bdm_config {
-       __u8 demosaic_th;
-};
-
-/**
- * struct rkisp1_cif_isp_ctk_config - Configuration used by Cross Talk correction
- *
- * @coeff: color correction matrix. Values are 11-bit signed fixed-point numbers with 4 bit integer
- *             and 7 bit fractional part, ranging from -8 (0x400) to +7.992 (0x3FF). 0 is
- *             represented by 0x000 and a coefficient value of 1 as 0x080.
- * @ct_offset: Red, Green, Blue offsets for the crosstalk correction matrix
- */
-struct rkisp1_cif_isp_ctk_config {
-       __u16 coeff[3][3];
-       __u16 ct_offset[3];
-};
-
-enum rkisp1_cif_isp_goc_mode {
-       RKISP1_CIF_ISP_GOC_MODE_LOGARITHMIC,
-       RKISP1_CIF_ISP_GOC_MODE_EQUIDISTANT
-};
-
-/**
- * struct rkisp1_cif_isp_goc_config - Configuration used by Gamma Out correction
- *
- * @mode: goc mode (from enum rkisp1_cif_isp_goc_mode)
- * @gamma_y: gamma out curve y-axis for all color components
- */
-struct rkisp1_cif_isp_goc_config {
-       __u32 mode;
-       __u16 gamma_y[RKISP1_CIF_ISP_GAMMA_OUT_MAX_SAMPLES];
-};
-
-/**
- * struct rkisp1_cif_isp_hst_config - Configuration used by Histogram
- *
- * @mode: histogram mode (from enum rkisp1_cif_isp_histogram_mode)
- * @histogram_predivider: process every stepsize pixel, all other pixels are
- *                       skipped
- * @meas_window: coordinates of the measure window
- * @hist_weight: weighting factor for sub-windows
- */
-struct rkisp1_cif_isp_hst_config {
-       __u32 mode;
-       __u8 histogram_predivider;
-       struct rkisp1_cif_isp_window meas_window;
-       __u8 hist_weight[RKISP1_CIF_ISP_HISTOGRAM_WEIGHT_GRIDS_SIZE];
-};
-
-/**
- * struct rkisp1_cif_isp_aec_config - Configuration used by Auto Exposure Control
- *
- * @mode: Exposure measure mode (from enum rkisp1_cif_isp_exp_meas_mode)
- * @autostop: stop mode (from enum rkisp1_cif_isp_exp_ctrl_autostop)
- * @meas_window: coordinates of the measure window
- */
-struct rkisp1_cif_isp_aec_config {
-       __u32 mode;
-       __u32 autostop;
-       struct rkisp1_cif_isp_window meas_window;
-};
-
-/**
- * struct rkisp1_cif_isp_afc_config - Configuration used by Auto Focus Control
- *
- * @num_afm_win: max RKISP1_CIF_ISP_AFM_MAX_WINDOWS
- * @afm_win: coordinates of the meas window
- * @thres: threshold used for minimizing the influence of noise
- * @var_shift: the number of bits for the shift operation at the end of the
- *            calculation chain.
- */
-struct rkisp1_cif_isp_afc_config {
-       __u8 num_afm_win;
-       struct rkisp1_cif_isp_window afm_win[RKISP1_CIF_ISP_AFM_MAX_WINDOWS];
-       __u32 thres;
-       __u32 var_shift;
-};
-
-/**
- * enum rkisp1_cif_isp_dpf_gain_usage - dpf gain usage
- * @RKISP1_CIF_ISP_DPF_GAIN_USAGE_DISABLED: don't use any gains in preprocessing stage
- * @RKISP1_CIF_ISP_DPF_GAIN_USAGE_NF_GAINS: use only the noise function gains from
- *                                 registers DPF_NF_GAIN_R, ...
- * @RKISP1_CIF_ISP_DPF_GAIN_USAGE_LSC_GAINS:  use only the gains from LSC module
- * @RKISP1_CIF_ISP_DPF_GAIN_USAGE_NF_LSC_GAINS: use the noise function gains and the
- *                                     gains from LSC module
- * @RKISP1_CIF_ISP_DPF_GAIN_USAGE_AWB_GAINS: use only the gains from AWB module
- * @RKISP1_CIF_ISP_DPF_GAIN_USAGE_AWB_LSC_GAINS: use the gains from AWB and LSC module
- * @RKISP1_CIF_ISP_DPF_GAIN_USAGE_MAX: upper border (only for an internal evaluation)
- */
-enum rkisp1_cif_isp_dpf_gain_usage {
-       RKISP1_CIF_ISP_DPF_GAIN_USAGE_DISABLED,
-       RKISP1_CIF_ISP_DPF_GAIN_USAGE_NF_GAINS,
-       RKISP1_CIF_ISP_DPF_GAIN_USAGE_LSC_GAINS,
-       RKISP1_CIF_ISP_DPF_GAIN_USAGE_NF_LSC_GAINS,
-       RKISP1_CIF_ISP_DPF_GAIN_USAGE_AWB_GAINS,
-       RKISP1_CIF_ISP_DPF_GAIN_USAGE_AWB_LSC_GAINS,
-       RKISP1_CIF_ISP_DPF_GAIN_USAGE_MAX
-};
-
-/**
- * enum rkisp1_cif_isp_dpf_rb_filtersize - Red and blue filter sizes
- * @RKISP1_CIF_ISP_DPF_RB_FILTERSIZE_13x9: red and blue filter kernel size 13x9
- *                                (means 7x5 active pixel)
- * @RKISP1_CIF_ISP_DPF_RB_FILTERSIZE_9x9: red and blue filter kernel size 9x9
- *                                (means 5x5 active pixel)
- */
-enum rkisp1_cif_isp_dpf_rb_filtersize {
-       RKISP1_CIF_ISP_DPF_RB_FILTERSIZE_13x9,
-       RKISP1_CIF_ISP_DPF_RB_FILTERSIZE_9x9,
-};
-
-/**
- * enum rkisp1_cif_isp_dpf_nll_scale_mode - dpf noise level scale mode
- * @RKISP1_CIF_ISP_NLL_SCALE_LINEAR: use a linear scaling
- * @RKISP1_CIF_ISP_NLL_SCALE_LOGARITHMIC: use a logarithmic scaling
- */
-enum rkisp1_cif_isp_dpf_nll_scale_mode {
-       RKISP1_CIF_ISP_NLL_SCALE_LINEAR,
-       RKISP1_CIF_ISP_NLL_SCALE_LOGARITHMIC,
-};
-
-/**
- * struct rkisp1_cif_isp_dpf_nll - Noise level lookup
- *
- * @coeff: Noise level Lookup coefficient
- * @scale_mode: dpf noise level scale mode (from enum rkisp1_cif_isp_dpf_nll_scale_mode)
- */
-struct rkisp1_cif_isp_dpf_nll {
-       __u16 coeff[RKISP1_CIF_ISP_DPF_MAX_NLF_COEFFS];
-       __u32 scale_mode;
-};
-
-/**
- * struct rkisp1_cif_isp_dpf_rb_flt - Red blue filter config
- *
- * @fltsize: The filter size for the red and blue pixels
- *          (from enum rkisp1_cif_isp_dpf_rb_filtersize)
- * @spatial_coeff: Spatial weights
- * @r_enable: enable filter processing for red pixels
- * @b_enable: enable filter processing for blue pixels
- */
-struct rkisp1_cif_isp_dpf_rb_flt {
-       __u32 fltsize;
-       __u8 spatial_coeff[RKISP1_CIF_ISP_DPF_MAX_SPATIAL_COEFFS];
-       __u8 r_enable;
-       __u8 b_enable;
-};
-
-/**
- * struct rkisp1_cif_isp_dpf_g_flt - Green filter Configuration
- *
- * @spatial_coeff: Spatial weights
- * @gr_enable: enable filter processing for green pixels in green/red lines
- * @gb_enable: enable filter processing for green pixels in green/blue lines
- */
-struct rkisp1_cif_isp_dpf_g_flt {
-       __u8 spatial_coeff[RKISP1_CIF_ISP_DPF_MAX_SPATIAL_COEFFS];
-       __u8 gr_enable;
-       __u8 gb_enable;
-};
-
-/**
- * struct rkisp1_cif_isp_dpf_gain - Noise function Configuration
- *
- * @mode: dpf gain usage  (from enum rkisp1_cif_isp_dpf_gain_usage)
- * @nf_r_gain: Noise function Gain that replaces the AWB gain for red pixels
- * @nf_b_gain: Noise function Gain that replaces the AWB gain for blue pixels
- * @nf_gr_gain: Noise function Gain that replaces the AWB gain
- *             for green pixels in a red line
- * @nf_gb_gain: Noise function Gain that replaces the AWB gain
- *             for green pixels in a blue line
- */
-struct rkisp1_cif_isp_dpf_gain {
-       __u32 mode;
-       __u16 nf_r_gain;
-       __u16 nf_b_gain;
-       __u16 nf_gr_gain;
-       __u16 nf_gb_gain;
-};
-
-/**
- * struct rkisp1_cif_isp_dpf_config - Configuration used by De-noising pre-filter
- *
- * @gain: noise function gain
- * @g_flt: green filter config
- * @rb_flt: red blue filter config
- * @nll: noise level lookup
- */
-struct rkisp1_cif_isp_dpf_config {
-       struct rkisp1_cif_isp_dpf_gain gain;
-       struct rkisp1_cif_isp_dpf_g_flt g_flt;
-       struct rkisp1_cif_isp_dpf_rb_flt rb_flt;
-       struct rkisp1_cif_isp_dpf_nll nll;
-};
-
-/**
- * struct rkisp1_cif_isp_dpf_strength_config - strength of the filter
- *
- * @r: filter strength of the RED filter
- * @g: filter strength of the GREEN filter
- * @b: filter strength of the BLUE filter
- */
-struct rkisp1_cif_isp_dpf_strength_config {
-       __u8 r;
-       __u8 g;
-       __u8 b;
-};
-
-/**
- * struct rkisp1_cif_isp_isp_other_cfg - Parameters for some blocks in rockchip isp1
- *
- * @dpcc_config: Defect Pixel Cluster Correction config
- * @bls_config: Black Level Subtraction config
- * @sdg_config: sensor degamma config
- * @lsc_config: Lens Shade config
- * @awb_gain_config: Auto White balance gain config
- * @flt_config: filter config
- * @bdm_config: demosaic config
- * @ctk_config: cross talk config
- * @goc_config: gamma out config
- * @bls_config: black level subtraction config
- * @dpf_config: De-noising pre-filter config
- * @dpf_strength_config: dpf strength config
- * @cproc_config: color process config
- * @ie_config: image effects config
- */
-struct rkisp1_cif_isp_isp_other_cfg {
-       struct rkisp1_cif_isp_dpcc_config dpcc_config;
-       struct rkisp1_cif_isp_bls_config bls_config;
-       struct rkisp1_cif_isp_sdg_config sdg_config;
-       struct rkisp1_cif_isp_lsc_config lsc_config;
-       struct rkisp1_cif_isp_awb_gain_config awb_gain_config;
-       struct rkisp1_cif_isp_flt_config flt_config;
-       struct rkisp1_cif_isp_bdm_config bdm_config;
-       struct rkisp1_cif_isp_ctk_config ctk_config;
-       struct rkisp1_cif_isp_goc_config goc_config;
-       struct rkisp1_cif_isp_dpf_config dpf_config;
-       struct rkisp1_cif_isp_dpf_strength_config dpf_strength_config;
-       struct rkisp1_cif_isp_cproc_config cproc_config;
-       struct rkisp1_cif_isp_ie_config ie_config;
-};
-
-/**
- * struct rkisp1_cif_isp_isp_meas_cfg - Rockchip ISP1 Measure Parameters
- *
- * @awb_meas_config: auto white balance config
- * @hst_config: histogram config
- * @aec_config: auto exposure config
- * @afc_config: auto focus config
- */
-struct rkisp1_cif_isp_isp_meas_cfg {
-       struct rkisp1_cif_isp_awb_meas_config awb_meas_config;
-       struct rkisp1_cif_isp_hst_config hst_config;
-       struct rkisp1_cif_isp_aec_config aec_config;
-       struct rkisp1_cif_isp_afc_config afc_config;
-};
-
-/**
- * struct rkisp1_params_cfg - Rockchip ISP1 Input Parameters Meta Data
- *
- * @module_en_update: mask the enable bits of which module should be updated
- * @module_ens: mask the enable value of each module, only update the module
- *             which correspond bit was set in module_en_update
- * @module_cfg_update: mask the config bits of which module should be updated
- * @meas: measurement config
- * @others: other config
- */
-struct rkisp1_params_cfg {
-       __u32 module_en_update;
-       __u32 module_ens;
-       __u32 module_cfg_update;
-
-       struct rkisp1_cif_isp_isp_meas_cfg meas;
-       struct rkisp1_cif_isp_isp_other_cfg others;
-};
-
-/*---------- PART2: Measurement Statistics ------------*/
-
-/**
- * struct rkisp1_cif_isp_awb_meas - AWB measured values
- *
- * @cnt: White pixel count, number of "white pixels" found during last
- *      measurement
- * @mean_y_or_g: Mean value of Y within window and frames,
- *              Green if RGB is selected.
- * @mean_cb_or_b: Mean value of Cb within window and frames,
- *               Blue if RGB is selected.
- * @mean_cr_or_r: Mean value of Cr within window and frames,
- *               Red if RGB is selected.
- */
-struct rkisp1_cif_isp_awb_meas {
-       __u32 cnt;
-       __u8 mean_y_or_g;
-       __u8 mean_cb_or_b;
-       __u8 mean_cr_or_r;
-};
-
-/**
- * struct rkisp1_cif_isp_awb_stat - statistics automatic white balance data
- *
- * @awb_mean: Mean measured data
- */
-struct rkisp1_cif_isp_awb_stat {
-       struct rkisp1_cif_isp_awb_meas awb_mean[RKISP1_CIF_ISP_AWB_MAX_GRID];
-};
-
-/**
- * struct rkisp1_cif_isp_bls_meas_val - BLS measured values
- *
- * @meas_r: Mean measured value for Bayer pattern R
- * @meas_gr: Mean measured value for Bayer pattern Gr
- * @meas_gb: Mean measured value for Bayer pattern Gb
- * @meas_b: Mean measured value for Bayer pattern B
- */
-struct rkisp1_cif_isp_bls_meas_val {
-       __u16 meas_r;
-       __u16 meas_gr;
-       __u16 meas_gb;
-       __u16 meas_b;
-};
-
-/**
- * struct rkisp1_cif_isp_ae_stat - statistics auto exposure data
- *
- * @exp_mean: Mean luminance value of block xx
- * @bls_val:  BLS measured values
- *
- * Image is divided into 5x5 blocks.
- */
-struct rkisp1_cif_isp_ae_stat {
-       __u8 exp_mean[RKISP1_CIF_ISP_AE_MEAN_MAX];
-       struct rkisp1_cif_isp_bls_meas_val bls_val;
-};
-
-/**
- * struct rkisp1_cif_isp_af_meas_val - AF measured values
- *
- * @sum: sharpness value
- * @lum: luminance value
- */
-struct rkisp1_cif_isp_af_meas_val {
-       __u32 sum;
-       __u32 lum;
-};
-
-/**
- * struct rkisp1_cif_isp_af_stat - statistics auto focus data
- *
- * @window: AF measured value of window x
- *
- * The module measures the sharpness in 3 windows of selectable size via
- * register settings(ISP_AFM_*_A/B/C)
- */
-struct rkisp1_cif_isp_af_stat {
-       struct rkisp1_cif_isp_af_meas_val window[RKISP1_CIF_ISP_AFM_MAX_WINDOWS];
-};
-
-/**
- * struct rkisp1_cif_isp_hist_stat - statistics histogram data
- *
- * @hist_bins: measured bin counters
- *
- * Measurement window divided into 25 sub-windows, set
- * with ISP_HIST_XXX
- */
-struct rkisp1_cif_isp_hist_stat {
-       __u16 hist_bins[RKISP1_CIF_ISP_HIST_BIN_N_MAX];
-};
-
-/**
- * struct rkisp1_cif_isp_stat - Rockchip ISP1 Statistics Data
- *
- * @awb: statistics data for automatic white balance
- * @ae: statistics data for auto exposure
- * @af: statistics data for auto focus
- * @hist: statistics histogram data
- */
-struct rkisp1_cif_isp_stat {
-       struct rkisp1_cif_isp_awb_stat awb;
-       struct rkisp1_cif_isp_ae_stat ae;
-       struct rkisp1_cif_isp_af_stat af;
-       struct rkisp1_cif_isp_hist_stat hist;
-};
-
-/**
- * struct rkisp1_stat_buffer - Rockchip ISP1 Statistics Meta Data
- *
- * @meas_type: measurement types (RKISP1_CIF_ISP_STAT_* definitions)
- * @frame_id: frame ID for sync
- * @params: statistics data
- */
-struct rkisp1_stat_buffer {
-       __u32 meas_type;
-       __u32 frame_id;
-       struct rkisp1_cif_isp_stat params;
-};
-
-#endif /* _UAPI_RKISP1_CONFIG_H */
index d25c4a3..552e0bd 100644 (file)
@@ -1038,10 +1038,8 @@ static int rkvdec_probe(struct platform_device *pdev)
        vb2_dma_contig_set_max_seg_size(&pdev->dev, DMA_BIT_MASK(32));
 
        irq = platform_get_irq(pdev, 0);
-       if (irq <= 0) {
-               dev_err(&pdev->dev, "Could not get vdec IRQ\n");
+       if (irq <= 0)
                return -ENXIO;
-       }
 
        ret = devm_request_threaded_irq(&pdev->dev, irq, NULL,
                                        rkvdec_irq_handler, IRQF_ONESHOT,
index e0e3550..9a102b7 100644 (file)
@@ -508,6 +508,11 @@ static const struct cedrus_variant sun8i_h3_cedrus_variant = {
        .mod_rate       = 402000000,
 };
 
+static const struct cedrus_variant sun8i_r40_cedrus_variant = {
+       .capabilities   = CEDRUS_CAPABILITY_UNTILED,
+       .mod_rate       = 297000000,
+};
+
 static const struct cedrus_variant sun50i_a64_cedrus_variant = {
        .capabilities   = CEDRUS_CAPABILITY_UNTILED |
                          CEDRUS_CAPABILITY_H265_DEC,
@@ -548,6 +553,10 @@ static const struct of_device_id cedrus_dt_match[] = {
                .compatible = "allwinner,sun8i-h3-video-engine",
                .data = &sun8i_h3_cedrus_variant,
        },
+       {
+               .compatible = "allwinner,sun8i-r40-video-engine",
+               .data = &sun8i_r40_cedrus_variant,
+       },
        {
                .compatible = "allwinner,sun50i-a64-video-engine",
                .data = &sun50i_a64_cedrus_variant,
index 667b86d..911f607 100644 (file)
@@ -479,8 +479,10 @@ static int cedrus_start_streaming(struct vb2_queue *vq, unsigned int count)
 
        if (V4L2_TYPE_IS_OUTPUT(vq->type)) {
                ret = pm_runtime_get_sync(dev->dev);
-               if (ret < 0)
+               if (ret < 0) {
+                       pm_runtime_put_noidle(dev->dev);
                        goto err_cleanup;
+               }
 
                if (dev->dec_ops[ctx->current_codec]->start) {
                        ret = dev->dec_ops[ctx->current_codec]->start(ctx);
index 808196e..d9f8b21 100644 (file)
@@ -666,7 +666,7 @@ static int zoran_g_selection(struct file *file, void *__fh, struct v4l2_selectio
 
        if (sel->type != V4L2_BUF_TYPE_VIDEO_OUTPUT &&
            sel->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
-               pci_err(zr->pci_dev, "%s invalid combinaison\n", __func__);
+               pci_err(zr->pci_dev, "%s invalid selection type combination\n", __func__);
                return -EINVAL;
        }
 
index e547cbe..b04a38b 100644 (file)
@@ -321,7 +321,7 @@ int dvb_create_media_graph(struct dvb_adapter *adap,
 int dvb_generic_open(struct inode *inode, struct file *file);
 
 /**
- * dvb_generic_close - Digital TV close function, used by DVB devices
+ * dvb_generic_release - Digital TV close function, used by DVB devices
  *
  * @inode: pointer to &struct inode.
  * @file: pointer to &struct file.
index ec47991..893e213 100644 (file)
 #define V4L2_CTRL_TYPE_H264_DECODE_PARAMS      0x0114
 #define V4L2_CTRL_TYPE_H264_PRED_WEIGHTS       0x0115
 
+/**
+ * enum v4l2_mpeg_video_h264_decode_mode - Decoding mode
+ *
+ * @V4L2_MPEG_VIDEO_H264_DECODE_MODE_SLICE_BASED: indicates that decoding
+ * is performed one slice at a time. In this mode,
+ * V4L2_CID_MPEG_VIDEO_H264_SLICE_PARAMS must contain the parsed slice
+ * parameters and the OUTPUT buffer must contain a single slice.
+ * V4L2_BUF_CAP_SUPPORTS_M2M_HOLD_CAPTURE_BUF feature is used
+ * in order to support multislice frames.
+ * @V4L2_MPEG_VIDEO_H264_DECODE_MODE_FRAME_BASED: indicates that
+ * decoding is performed per frame. The OUTPUT buffer must contain
+ * all slices and also both fields. This mode is typically supported
+ * by device drivers that are able to parse the slice(s) header(s)
+ * in hardware. When this mode is selected,
+ * V4L2_CID_MPEG_VIDEO_H264_SLICE_PARAMS is not used.
+ */
 enum v4l2_mpeg_video_h264_decode_mode {
        V4L2_MPEG_VIDEO_H264_DECODE_MODE_SLICE_BASED,
        V4L2_MPEG_VIDEO_H264_DECODE_MODE_FRAME_BASED,
 };
 
+/**
+ * enum v4l2_mpeg_video_h264_start_code - Start code
+ *
+ * @V4L2_MPEG_VIDEO_H264_START_CODE_NONE: slices are passed
+ * to the driver without any start code.
+ * @V4L2_MPEG_VIDEO_H264_START_CODE_ANNEX_B: slices are passed
+ * to the driver with an Annex B start code prefix
+ * (legal start codes can be 3-bytes 0x000001 or 4-bytes 0x00000001).
+ * This mode is typically supported by device drivers that parse
+ * the start code in hardware.
+ */
 enum v4l2_mpeg_video_h264_start_code {
        V4L2_MPEG_VIDEO_H264_START_CODE_NONE,
        V4L2_MPEG_VIDEO_H264_START_CODE_ANNEX_B,
@@ -71,6 +98,31 @@ enum v4l2_mpeg_video_h264_start_code {
 #define V4L2_H264_SPS_FLAG_MB_ADAPTIVE_FRAME_FIELD             0x20
 #define V4L2_H264_SPS_FLAG_DIRECT_8X8_INFERENCE                        0x40
 
+/**
+ * struct v4l2_ctrl_h264_sps - H264 sequence parameter set
+ *
+ * All the members on this sequence parameter set structure match the
+ * sequence parameter set syntax as specified by the H264 specification.
+ *
+ * @profile_idc: see H264 specification.
+ * @constraint_set_flags: see H264 specification.
+ * @level_idc: see H264 specification.
+ * @seq_parameter_set_id: see H264 specification.
+ * @chroma_format_idc: see H264 specification.
+ * @bit_depth_luma_minus8: see H264 specification.
+ * @bit_depth_chroma_minus8: see H264 specification.
+ * @log2_max_frame_num_minus4: see H264 specification.
+ * @pic_order_cnt_type: see H264 specification.
+ * @log2_max_pic_order_cnt_lsb_minus4: see H264 specification.
+ * @max_num_ref_frames: see H264 specification.
+ * @num_ref_frames_in_pic_order_cnt_cycle: see H264 specification.
+ * @offset_for_ref_frame: see H264 specification.
+ * @offset_for_non_ref_pic: see H264 specification.
+ * @offset_for_top_to_bottom_field: see H264 specification.
+ * @pic_width_in_mbs_minus1: see H264 specification.
+ * @pic_height_in_map_units_minus1: see H264 specification.
+ * @flags: see V4L2_H264_SPS_FLAG_{}.
+ */
 struct v4l2_ctrl_h264_sps {
        __u8 profile_idc;
        __u8 constraint_set_flags;
@@ -101,6 +153,31 @@ struct v4l2_ctrl_h264_sps {
 #define V4L2_H264_PPS_FLAG_TRANSFORM_8X8_MODE                          0x0040
 #define V4L2_H264_PPS_FLAG_SCALING_MATRIX_PRESENT                      0x0080
 
+/**
+ * struct v4l2_ctrl_h264_pps - H264 picture parameter set
+ *
+ * Except where noted, all the members on this picture parameter set
+ * structure match the sequence parameter set syntax as specified
+ * by the H264 specification.
+ *
+ * In particular, V4L2_H264_PPS_FLAG_SCALING_MATRIX_PRESENT flag
+ * has a specific meaning. This flag should be set if a non-flat
+ * scaling matrix applies to the picture. In this case, applications
+ * are expected to use V4L2_CID_MPEG_VIDEO_H264_SCALING_MATRIX,
+ * to pass the values of the non-flat matrices.
+ *
+ * @pic_parameter_set_id: see H264 specification.
+ * @seq_parameter_set_id: see H264 specification.
+ * @num_slice_groups_minus1: see H264 specification.
+ * @num_ref_idx_l0_default_active_minus1: see H264 specification.
+ * @num_ref_idx_l1_default_active_minus1: see H264 specification.
+ * @weighted_bipred_idc: see H264 specification.
+ * @pic_init_qp_minus26: see H264 specification.
+ * @pic_init_qs_minus26: see H264 specification.
+ * @chroma_qp_index_offset: see H264 specification.
+ * @second_chroma_qp_index_offset: see H264 specification.
+ * @flags: see V4L2_H264_PPS_FLAG_{}.
+ */
 struct v4l2_ctrl_h264_pps {
        __u8 pic_parameter_set_id;
        __u8 seq_parameter_set_id;
@@ -115,6 +192,23 @@ struct v4l2_ctrl_h264_pps {
        __u16 flags;
 };
 
+/**
+ * struct v4l2_ctrl_h264_scaling_matrix - H264 scaling matrices
+ *
+ * @scaling_list_4x4: scaling matrix after applying the inverse
+ * scanning process. Expected list order is Intra Y, Intra Cb,
+ * Intra Cr, Inter Y, Inter Cb, Inter Cr. The values on each
+ * scaling list are expected in raster scan order.
+ * @scaling_list_8x8: scaling matrix after applying the inverse
+ * scanning process. Expected list order is Intra Y, Inter Y,
+ * Intra Cb, Inter Cb, Intra Cr, Inter Cr. The values on each
+ * scaling list are expected in raster scan order.
+ *
+ * Note that the list order is different for the 4x4 and 8x8
+ * matrices as per the H264 specification, see table 7-2 "Assignment
+ * of mnemonic names to scaling list indices and specification of
+ * fall-back rule".
+ */
 struct v4l2_ctrl_h264_scaling_matrix {
        __u8 scaling_list_4x4[6][16];
        __u8 scaling_list_8x8[6][64];
@@ -134,6 +228,16 @@ struct v4l2_h264_weight_factors {
         ((pps)->weighted_bipred_idc == 1 && \
          (slice)->slice_type == V4L2_H264_SLICE_TYPE_B))
 
+/**
+ * struct v4l2_ctrl_h264_pred_weights - Prediction weight table
+ *
+ * Prediction weight table, which matches the syntax specified
+ * by the H264 specification.
+ *
+ * @luma_log2_weight_denom: see H264 specification.
+ * @chroma_log2_weight_denom: see H264 specification.
+ * @weight_factors: luma and chroma weight factors.
+ */
 struct v4l2_ctrl_h264_pred_weights {
        __u16 luma_log2_weight_denom;
        __u16 chroma_log2_weight_denom;
@@ -153,19 +257,55 @@ struct v4l2_ctrl_h264_pred_weights {
 #define V4L2_H264_BOTTOM_FIELD_REF                     0x2
 #define V4L2_H264_FRAME_REF                            0x3
 
+/**
+ * struct v4l2_h264_reference - H264 picture reference
+ *
+ * @fields: indicates how the picture is referenced.
+ * Valid values are V4L2_H264_{}_REF.
+ * @index: index into v4l2_ctrl_h264_decode_params.dpb[].
+ */
 struct v4l2_h264_reference {
        __u8 fields;
-
-       /* Index into v4l2_ctrl_h264_decode_params.dpb[] */
        __u8 index;
 };
 
+/**
+ * struct v4l2_ctrl_h264_slice_params - H264 slice parameters
+ *
+ * This structure holds the H264 syntax elements that are specified
+ * as non-invariant for the slices in a given frame.
+ *
+ * Slice invariant syntax elements are contained in struct
+ * v4l2_ctrl_h264_decode_params. This is done to reduce the API surface
+ * on frame-based decoders, where slice header parsing is done by the
+ * hardware.
+ *
+ * Slice invariant syntax elements are specified in specification section
+ * "7.4.3 Slice header semantics".
+ *
+ * Except where noted, the members on this struct match the slice header syntax.
+ *
+ * @header_bit_size: offset in bits to slice_data() from the beginning of this slice.
+ * @first_mb_in_slice: see H264 specification.
+ * @slice_type: see H264 specification.
+ * @colour_plane_id: see H264 specification.
+ * @redundant_pic_cnt: see H264 specification.
+ * @cabac_init_idc: see H264 specification.
+ * @slice_qp_delta: see H264 specification.
+ * @slice_qs_delta: see H264 specification.
+ * @disable_deblocking_filter_idc: see H264 specification.
+ * @slice_alpha_c0_offset_div2: see H264 specification.
+ * @slice_beta_offset_div2: see H264 specification.
+ * @num_ref_idx_l0_active_minus1: see H264 specification.
+ * @num_ref_idx_l1_active_minus1: see H264 specification.
+ * @reserved: padding field. Should be zeroed by applications.
+ * @ref_pic_list0: reference picture list 0 after applying the per-slice modifications.
+ * @ref_pic_list1: reference picture list 1 after applying the per-slice modifications.
+ * @flags: see V4L2_H264_SLICE_FLAG_{}.
+ */
 struct v4l2_ctrl_h264_slice_params {
-       /* Offset in bits to slice_data() from the beginning of this slice. */
        __u32 header_bit_size;
-
        __u32 first_mb_in_slice;
-
        __u8 slice_type;
        __u8 colour_plane_id;
        __u8 redundant_pic_cnt;
@@ -191,22 +331,59 @@ struct v4l2_ctrl_h264_slice_params {
 #define V4L2_H264_DPB_ENTRY_FLAG_LONG_TERM     0x04
 #define V4L2_H264_DPB_ENTRY_FLAG_FIELD         0x08
 
+/**
+ * struct v4l2_h264_dpb_entry - H264 decoded picture buffer entry
+ *
+ * @reference_ts: timestamp of the V4L2 capture buffer to use as reference.
+ * The timestamp refers to the timestamp field in struct v4l2_buffer.
+ * Use v4l2_timeval_to_ns() to convert the struct timeval to a __u64.
+ * @pic_num: matches PicNum variable assigned during the reference
+ * picture lists construction process.
+ * @frame_num: frame identifier which matches frame_num syntax element.
+ * @fields: indicates how the DPB entry is referenced. Valid values are
+ * V4L2_H264_{}_REF.
+ * @reserved: padding field. Should be zeroed by applications.
+ * @top_field_order_cnt: matches TopFieldOrderCnt picture value.
+ * @bottom_field_order_cnt: matches BottomFieldOrderCnt picture value.
+ * Note that picture field is indicated by v4l2_buffer.field.
+ * @flags: see V4L2_H264_DPB_ENTRY_FLAG_{}.
+ */
 struct v4l2_h264_dpb_entry {
        __u64 reference_ts;
        __u32 pic_num;
        __u16 frame_num;
        __u8 fields;
        __u8 reserved[5];
-       /* Note that field is indicated by v4l2_buffer.field */
        __s32 top_field_order_cnt;
        __s32 bottom_field_order_cnt;
-       __u32 flags; /* V4L2_H264_DPB_ENTRY_FLAG_* */
+       __u32 flags;
 };
 
 #define V4L2_H264_DECODE_PARAM_FLAG_IDR_PIC            0x01
 #define V4L2_H264_DECODE_PARAM_FLAG_FIELD_PIC          0x02
 #define V4L2_H264_DECODE_PARAM_FLAG_BOTTOM_FIELD       0x04
 
+/**
+ * struct v4l2_ctrl_h264_decode_params - H264 decoding parameters
+ *
+ * @dpb: decoded picture buffer.
+ * @nal_ref_idc: slice header syntax element.
+ * @frame_num: slice header syntax element.
+ * @top_field_order_cnt: matches TopFieldOrderCnt picture value.
+ * @bottom_field_order_cnt: matches BottomFieldOrderCnt picture value.
+ * Note that picture field is indicated by v4l2_buffer.field.
+ * @idr_pic_id: slice header syntax element.
+ * @pic_order_cnt_lsb: slice header syntax element.
+ * @delta_pic_order_cnt_bottom: slice header syntax element.
+ * @delta_pic_order_cnt0: slice header syntax element.
+ * @delta_pic_order_cnt1: slice header syntax element.
+ * @dec_ref_pic_marking_bit_size: size in bits of dec_ref_pic_marking()
+ * syntax element.
+ * @pic_order_cnt_bit_size: size in bits of pic order count syntax.
+ * @slice_group_change_cycle: slice header syntax element.
+ * @reserved: padding field. Should be zeroed by applications.
+ * @flags: see V4L2_H264_DECODE_PARAM_FLAG_{}.
+ */
 struct v4l2_ctrl_h264_decode_params {
        struct v4l2_h264_dpb_entry dpb[V4L2_H264_NUM_DPB_ENTRIES];
        __u16 nal_ref_idc;
@@ -218,14 +395,12 @@ struct v4l2_ctrl_h264_decode_params {
        __s32 delta_pic_order_cnt_bottom;
        __s32 delta_pic_order_cnt0;
        __s32 delta_pic_order_cnt1;
-       /* Size in bits of dec_ref_pic_marking() syntax element. */
        __u32 dec_ref_pic_marking_bit_size;
-       /* Size in bits of pic order count syntax. */
        __u32 pic_order_cnt_bit_size;
        __u32 slice_group_change_cycle;
 
        __u32 reserved;
-       __u32 flags; /* V4L2_H264_DECODE_PARAM_FLAG_* */
+       __u32 flags;
 };
 
 #endif
index 7dbb91c..fa270f1 100644 (file)
@@ -263,6 +263,7 @@ struct rc_map *rc_map_get(const char *name);
 #define RC_MAP_IT913X_V2                 "rc-it913x-v2"
 #define RC_MAP_KAIOMY                    "rc-kaiomy"
 #define RC_MAP_KHADAS                    "rc-khadas"
+#define RC_MAP_KHAMSIN                   "rc-khamsin"
 #define RC_MAP_KWORLD_315U               "rc-kworld-315u"
 #define RC_MAP_KWORLD_PC150U             "rc-kworld-pc150u"
 #define RC_MAP_KWORLD_PLUS_TV_ANALOG     "rc-kworld-plus-tv-analog"
index d6e3123..0e04b5b 100644 (file)
@@ -27,7 +27,7 @@ struct v4l2_async_notifier;
  * @V4L2_ASYNC_MATCH_I2C: Match will check for I2C adapter ID and address
  * @V4L2_ASYNC_MATCH_FWNODE: Match will use firmware node
  *
- * This enum is used by the asyncrhronous sub-device logic to define the
+ * This enum is used by the asynchronous sub-device logic to define the
  * algorithm that will be used to match an asynchronous device.
  */
 enum v4l2_async_match_type {
index a308352..be36cbd 100644 (file)
@@ -519,6 +519,27 @@ int v4l2_fill_pixfmt(struct v4l2_pix_format *pixfmt, u32 pixelformat,
 int v4l2_fill_pixfmt_mp(struct v4l2_pix_format_mplane *pixfmt, u32 pixelformat,
                        u32 width, u32 height);
 
+/**
+ * v4l2_get_link_rate - Get link rate from transmitter
+ *
+ * @handler: The transmitter's control handler
+ * @mul: The multiplier between pixel rate and link frequency. Bits per pixel on
+ *      D-PHY, samples per clock on parallel. 0 otherwise.
+ * @div: The divisor between pixel rate and link frequency. Number of data lanes
+ *      times two on D-PHY, 1 on parallel. 0 otherwise.
+ *
+ * This function is intended for obtaining the link frequency from the
+ * transmitter sub-devices. It returns the link rate, either from the
+ * V4L2_CID_LINK_FREQ control implemented by the transmitter, or value
+ * calculated based on the V4L2_CID_PIXEL_RATE implemented by the transmitter.
+ *
+ * Returns link frequency on success, otherwise a negative error code:
+ *     -ENOENT: Link frequency or pixel rate control not found
+ *     -EINVAL: Invalid link frequency value
+ */
+s64 v4l2_get_link_rate(struct v4l2_ctrl_handler *handler, unsigned int mul,
+                      unsigned int div);
+
 static inline u64 v4l2_buffer_get_timestamp(const struct v4l2_buffer *buf)
 {
        /*
index cb25f34..4fbace0 100644 (file)
@@ -1292,7 +1292,7 @@ static inline void v4l2_ctrl_request_hdl_put(struct v4l2_ctrl_handler *hdl)
 }
 
 /**
- * v4l2_ctrl_request_ctrl_find() - Find a control with the given ID.
+ * v4l2_ctrl_request_hdl_ctrl_find() - Find a control with the given ID.
  *
  * @hdl: The control handler from the request.
  * @id: The ID of the control to find.
index ad2d419..6a4afd4 100644 (file)
@@ -43,8 +43,8 @@ enum vfl_devnode_type {
 };
 
 /**
- * enum  vfl_direction - Identifies if a &struct video_device corresponds
- *     to a receiver, a transmitter or a mem-to-mem device.
+ * enum  vfl_devnode_direction - Identifies if a &struct video_device
+ *     corresponds to a receiver, a transmitter or a mem-to-mem device.
  *
  * @VFL_DIR_RX:                device is a receiver.
  * @VFL_DIR_TX:                device is a transmitter.
index 64ec4de..8a8977a 100644 (file)
@@ -174,7 +174,7 @@ int __must_check v4l2_device_register_subdev(struct v4l2_device *v4l2_dev,
 void v4l2_device_unregister_subdev(struct v4l2_subdev *sd);
 
 /**
- * __v4l2_device_register_ro_subdev_nodes - Registers device nodes for
+ * __v4l2_device_register_subdev_nodes - Registers device nodes for
  *      all subdevs of the v4l2 device that are marked with the
  *      %V4L2_SUBDEV_FL_HAS_DEVNODE flag.
  *
index 2cc0cab..8fa9633 100644 (file)
@@ -224,7 +224,7 @@ static inline  bool can_reduce_fps(struct v4l2_bt_timings *bt)
 }
 
 /**
- * struct v4l2_hdmi_rx_colorimetry - describes the HDMI colorimetry information
+ * struct v4l2_hdmi_colorimetry - describes the HDMI colorimetry information
  * @colorspace:                enum v4l2_colorspace, the colorspace
  * @ycbcr_enc:         enum v4l2_ycbcr_encoding, Y'CbCr encoding
  * @quantization:      enum v4l2_quantization, colorspace quantization
index c090742..4e1f6e1 100644 (file)
@@ -219,23 +219,35 @@ struct v4l2_fwnode_connector {
  * @vep: pointer to the V4L2 fwnode data structure
  *
  * This function parses the V4L2 fwnode endpoint specific parameters from the
- * firmware. The caller is responsible for assigning @vep.bus_type to a valid
- * media bus type. The caller may also set the default configuration for the
- * endpoint --- a configuration that shall be in line with the DT binding
- * documentation. Should a device support multiple bus types, the caller may
- * call this function once the correct type is found --- with a default
- * configuration valid for that type.
- *
- * It is also allowed to set @vep.bus_type to V4L2_MBUS_UNKNOWN. USING THIS
- * FEATURE REQUIRES "bus-type" PROPERTY IN DT BINDINGS. For old drivers,
- * guessing @vep.bus_type between CSI-2 D-PHY, parallel and BT.656 busses is
- * supported. NEVER RELY ON GUESSING @vep.bus_type IN NEW DRIVERS!
+ * firmware. There are two ways to use this function, either by letting it
+ * obtain the type of the bus (by setting the @vep.bus_type field to
+ * V4L2_MBUS_UNKNOWN) or specifying the bus type explicitly to one of the &enum
+ * v4l2_mbus_type types.
+ *
+ * When @vep.bus_type is V4L2_MBUS_UNKNOWN, the function will use the "bus-type"
+ * property to determine the type when it is available. The caller is
+ * responsible for validating the contents of @vep.bus_type field after the call
+ * returns.
+ *
+ * As a deprecated functionality to support older DT bindings without "bus-type"
+ * property for devices that support multiple types, if the "bus-type" property
+ * does not exist, the function will attempt to guess the type based on the
+ * endpoint properties available. NEVER RELY ON GUESSING THE BUS TYPE IN NEW
+ * DRIVERS OR BINDINGS.
+ *
+ * It is also possible to set @vep.bus_type corresponding to an actual bus. In
+ * this case the function will only attempt to parse properties related to this
+ * bus, and it will return an error if the value of the "bus-type" property
+ * corresponds to a different bus.
+ *
+ * The caller is required to initialise all fields of @vep, either with
+ * explicitly values, or by zeroing them.
  *
  * The function does not change the V4L2 fwnode endpoint state if it fails.
  *
- * NOTE: This function does not parse properties the size of which is variable
- * without a low fixed limit. Please use v4l2_fwnode_endpoint_alloc_parse() in
- * new drivers instead.
+ * NOTE: This function does not parse "link-frequencies" property as its size is
+ * not known in advance. Please use v4l2_fwnode_endpoint_alloc_parse() if you
+ * need properties of variable size.
  *
  * Return: %0 on success or a negative error code on failure:
  *        %-ENOMEM on memory allocation failure
@@ -261,17 +273,29 @@ void v4l2_fwnode_endpoint_free(struct v4l2_fwnode_endpoint *vep);
  * @vep: pointer to the V4L2 fwnode data structure
  *
  * This function parses the V4L2 fwnode endpoint specific parameters from the
- * firmware. The caller is responsible for assigning @vep.bus_type to a valid
- * media bus type. The caller may also set the default configuration for the
- * endpoint --- a configuration that shall be in line with the DT binding
- * documentation. Should a device support multiple bus types, the caller may
- * call this function once the correct type is found --- with a default
- * configuration valid for that type.
- *
- * It is also allowed to set @vep.bus_type to V4L2_MBUS_UNKNOWN. USING THIS
- * FEATURE REQUIRES "bus-type" PROPERTY IN DT BINDINGS. For old drivers,
- * guessing @vep.bus_type between CSI-2 D-PHY, parallel and BT.656 busses is
- * supported. NEVER RELY ON GUESSING @vep.bus_type IN NEW DRIVERS!
+ * firmware. There are two ways to use this function, either by letting it
+ * obtain the type of the bus (by setting the @vep.bus_type field to
+ * V4L2_MBUS_UNKNOWN) or specifying the bus type explicitly to one of the &enum
+ * v4l2_mbus_type types.
+ *
+ * When @vep.bus_type is V4L2_MBUS_UNKNOWN, the function will use the "bus-type"
+ * property to determine the type when it is available. The caller is
+ * responsible for validating the contents of @vep.bus_type field after the call
+ * returns.
+ *
+ * As a deprecated functionality to support older DT bindings without "bus-type"
+ * property for devices that support multiple types, if the "bus-type" property
+ * does not exist, the function will attempt to guess the type based on the
+ * endpoint properties available. NEVER RELY ON GUESSING THE BUS TYPE IN NEW
+ * DRIVERS OR BINDINGS.
+ *
+ * It is also possible to set @vep.bus_type corresponding to an actual bus. In
+ * this case the function will only attempt to parse properties related to this
+ * bus, and it will return an error if the value of the "bus-type" property
+ * corresponds to a different bus.
+ *
+ * The caller is required to initialise all fields of @vep, either with
+ * explicitly values, or by zeroing them.
  *
  * The function does not change the V4L2 fwnode endpoint state if it fails.
  *
@@ -514,7 +538,7 @@ v4l2_async_notifier_parse_fwnode_endpoints_by_port(struct device *dev,
                                                   parse_endpoint_func parse_endpoint);
 
 /**
- * v4l2_fwnode_reference_parse_sensor_common - parse common references on
+ * v4l2_async_notifier_parse_fwnode_sensor_common - parse common references on
  *                                            sensors for async sub-devices
  * @dev: the device node the properties of which are parsed for references
  * @notifier: the async notifier where the async subdevs will be added
index 86878fb..edb733f 100644 (file)
@@ -686,6 +686,16 @@ long int v4l2_compat_ioctl32(struct file *file, unsigned int cmd,
                             unsigned long arg);
 #endif
 
+unsigned int v4l2_compat_translate_cmd(unsigned int cmd);
+int v4l2_compat_get_user(void __user *arg, void *parg, unsigned int cmd);
+int v4l2_compat_put_user(void __user *arg, void *parg, unsigned int cmd);
+int v4l2_compat_get_array_args(struct file *file, void *mbuf,
+                              void __user *user_ptr, size_t array_size,
+                              unsigned int cmd, void *arg);
+int v4l2_compat_put_array_args(struct file *file, void __user *user_ptr,
+                              void *mbuf, size_t array_size,
+                              unsigned int cmd, void *arg);
+
 /**
  * typedef v4l2_kioctl - Typedef used to pass an ioctl handler.
  *
index 59b1de1..841e190 100644 (file)
  * @V4L2_MBUS_CCP2:    CCP2 (Compact Camera Port 2)
  * @V4L2_MBUS_CSI2_DPHY: MIPI CSI-2 serial interface, with D-PHY
  * @V4L2_MBUS_CSI2_CPHY: MIPI CSI-2 serial interface, with C-PHY
+ * @V4L2_MBUS_INVALID: invalid bus type (keep as last)
  */
 enum v4l2_mbus_type {
        V4L2_MBUS_UNKNOWN,
@@ -112,6 +113,7 @@ enum v4l2_mbus_type {
        V4L2_MBUS_CCP2,
        V4L2_MBUS_CSI2_DPHY,
        V4L2_MBUS_CSI2_CPHY,
+       V4L2_MBUS_INVALID,
 };
 
 /**
@@ -145,7 +147,7 @@ v4l2_fill_pix_format(struct v4l2_pix_format *pix_fmt,
 }
 
 /**
- * v4l2_fill_pix_format - Ancillary routine that fills a &struct
+ * v4l2_fill_mbus_format - Ancillary routine that fills a &struct
  *     v4l2_mbus_framefmt from a &struct v4l2_pix_format and a
  *     data format code.
  *
@@ -168,7 +170,7 @@ static inline void v4l2_fill_mbus_format(struct v4l2_mbus_framefmt *mbus_fmt,
 }
 
 /**
- * v4l2_fill_pix_format - Ancillary routine that fills a &struct
+ * v4l2_fill_pix_format_mplane - Ancillary routine that fills a &struct
  *     v4l2_pix_format_mplane fields from a media bus structure.
  *
  * @pix_mp_fmt:        pointer to &struct v4l2_pix_format_mplane to be filled
@@ -188,7 +190,7 @@ v4l2_fill_pix_format_mplane(struct v4l2_pix_format_mplane *pix_mp_fmt,
 }
 
 /**
- * v4l2_fill_pix_format - Ancillary routine that fills a &struct
+ * v4l2_fill_mbus_format_mplane - Ancillary routine that fills a &struct
  *     v4l2_mbus_framefmt from a &struct v4l2_pix_format_mplane.
  *
  * @mbus_fmt:  pointer to &struct v4l2_mbus_framefmt to be filled
index 1de960b..d0e9a5b 100644 (file)
@@ -309,7 +309,7 @@ struct v4l2_subdev_audio_ops {
 };
 
 /**
- * enum v4l2_mbus_frame_desc_entry - media bus frame description flags
+ * enum v4l2_mbus_frame_desc_flags - media bus frame description flags
  *
  * @V4L2_MBUS_FRAME_DESC_FL_LEN_MAX:
  *     Indicates that &struct v4l2_mbus_frame_desc_entry->length field
index bbb3f26..6196940 100644 (file)
@@ -1043,7 +1043,7 @@ __poll_t vb2_core_poll(struct vb2_queue *q, struct file *file,
 size_t vb2_read(struct vb2_queue *q, char __user *data, size_t count,
                loff_t *ppos, int nonblock);
 /**
- * vb2_read() - implements write() syscall logic.
+ * vb2_write() - implements write() syscall logic.
  * @q:         pointer to &struct vb2_queue with videobuf2 queue.
  * @data:      pointed to target userspace buffer
  * @count:     number of bytes to write
index f99d9dc..c45a4ea 100644 (file)
  */
 #define LIRC_GET_REC_TIMEOUT          _IOR('i', 0x00000024, __u32)
 
-/*
+/**
  * struct lirc_scancode - decoded scancode with protocol for use with
  *     LIRC_MODE_SCANCODE
  *
@@ -196,6 +196,7 @@ struct lirc_scancode {
  * @RC_PROTO_RCMM24: RC-MM protocol 24 bits
  * @RC_PROTO_RCMM32: RC-MM protocol 32 bits
  * @RC_PROTO_XBOX_DVD: Xbox DVD Movie Playback Kit protocol
+ * @RC_PROTO_MAX: Maximum value of enum rc_proto
  */
 enum rc_proto {
        RC_PROTO_UNKNOWN        = 0,
@@ -226,6 +227,7 @@ enum rc_proto {
        RC_PROTO_RCMM24         = 25,
        RC_PROTO_RCMM32         = 26,
        RC_PROTO_XBOX_DVD       = 27,
+       RC_PROTO_MAX            = RC_PROTO_XBOX_DVD,
 };
 
 #endif
index 84fa53f..2ce3d89 100644 (file)
 /* HSV - next is       0x6002 */
 #define MEDIA_BUS_FMT_AHSV8888_1X32            0x6001
 
+/*
+ * This format should be used when the same driver handles
+ * both sides of the link and the bus format is a fixed
+ * metadata format that is not configurable from userspace.
+ * Width and height will be set to 0 for this format.
+ */
+#define MEDIA_BUS_FMT_METADATA_FIXED           0x7001
+
 #endif /* __LINUX_MEDIA_BUS_FORMAT_H */
diff --git a/include/uapi/linux/rkisp1-config.h b/include/uapi/linux/rkisp1-config.h
new file mode 100644 (file)
index 0000000..6e449e7
--- /dev/null
@@ -0,0 +1,884 @@
+/* SPDX-License-Identifier: ((GPL-2.0+ WITH Linux-syscall-note) OR MIT) */
+/*
+ * Rockchip ISP1 userspace API
+ * Copyright (C) 2017 Rockchip Electronics Co., Ltd.
+ */
+
+#ifndef _UAPI_RKISP1_CONFIG_H
+#define _UAPI_RKISP1_CONFIG_H
+
+#include <linux/types.h>
+
+/* Defect Pixel Cluster Detection */
+#define RKISP1_CIF_ISP_MODULE_DPCC             (1U << 0)
+/* Black Level Subtraction */
+#define RKISP1_CIF_ISP_MODULE_BLS              (1U << 1)
+/* Sensor De-gamma */
+#define RKISP1_CIF_ISP_MODULE_SDG              (1U << 2)
+/* Histogram */
+#define RKISP1_CIF_ISP_MODULE_HST              (1U << 3)
+/* Lens Shade Control */
+#define RKISP1_CIF_ISP_MODULE_LSC              (1U << 4)
+/* Auto White Balance Gain */
+#define RKISP1_CIF_ISP_MODULE_AWB_GAIN         (1U << 5)
+/* Filter */
+#define RKISP1_CIF_ISP_MODULE_FLT              (1U << 6)
+/* Bayer Demosaic */
+#define RKISP1_CIF_ISP_MODULE_BDM              (1U << 7)
+/* Cross Talk */
+#define RKISP1_CIF_ISP_MODULE_CTK              (1U << 8)
+/* Gamma Out Curve */
+#define RKISP1_CIF_ISP_MODULE_GOC              (1U << 9)
+/* Color Processing */
+#define RKISP1_CIF_ISP_MODULE_CPROC            (1U << 10)
+/* Auto Focus Control */
+#define RKISP1_CIF_ISP_MODULE_AFC              (1U << 11)
+/* Auto White Balancing */
+#define RKISP1_CIF_ISP_MODULE_AWB              (1U << 12)
+/* Image Effect */
+#define RKISP1_CIF_ISP_MODULE_IE               (1U << 13)
+/* Auto Exposure Control */
+#define RKISP1_CIF_ISP_MODULE_AEC              (1U << 14)
+/* Wide Dynamic Range */
+#define RKISP1_CIF_ISP_MODULE_WDR              (1U << 15)
+/* Denoise Pre-Filter */
+#define RKISP1_CIF_ISP_MODULE_DPF              (1U << 16)
+/* Denoise Pre-Filter Strength */
+#define RKISP1_CIF_ISP_MODULE_DPF_STRENGTH     (1U << 17)
+
+#define RKISP1_CIF_ISP_CTK_COEFF_MAX            0x100
+#define RKISP1_CIF_ISP_CTK_OFFSET_MAX           0x800
+
+#define RKISP1_CIF_ISP_AE_MEAN_MAX              25
+#define RKISP1_CIF_ISP_HIST_BIN_N_MAX           16
+#define RKISP1_CIF_ISP_AFM_MAX_WINDOWS          3
+#define RKISP1_CIF_ISP_DEGAMMA_CURVE_SIZE       17
+
+#define RKISP1_CIF_ISP_BDM_MAX_TH               0xff
+
+/*
+ * Black level compensation
+ */
+/* maximum value for horizontal start address */
+#define RKISP1_CIF_ISP_BLS_START_H_MAX             0x00000fff
+/* maximum value for horizontal stop address */
+#define RKISP1_CIF_ISP_BLS_STOP_H_MAX              0x00000fff
+/* maximum value for vertical start address */
+#define RKISP1_CIF_ISP_BLS_START_V_MAX             0x00000fff
+/* maximum value for vertical stop address */
+#define RKISP1_CIF_ISP_BLS_STOP_V_MAX              0x00000fff
+/* maximum is 2^18 = 262144*/
+#define RKISP1_CIF_ISP_BLS_SAMPLES_MAX             0x00000012
+/* maximum value for fixed black level */
+#define RKISP1_CIF_ISP_BLS_FIX_SUB_MAX             0x00000fff
+/* minimum value for fixed black level */
+#define RKISP1_CIF_ISP_BLS_FIX_SUB_MIN             0xfffff000
+/* 13 bit range (signed)*/
+#define RKISP1_CIF_ISP_BLS_FIX_MASK                0x00001fff
+
+/*
+ * Automatic white balance measurements
+ */
+#define RKISP1_CIF_ISP_AWB_MAX_GRID                1
+#define RKISP1_CIF_ISP_AWB_MAX_FRAMES              7
+
+/*
+ * Gamma out
+ */
+/* Maximum number of color samples supported */
+#define RKISP1_CIF_ISP_GAMMA_OUT_MAX_SAMPLES       17
+
+/*
+ * Lens shade correction
+ */
+#define RKISP1_CIF_ISP_LSC_SECTORS_TBL_SIZE        8
+
+/*
+ * The following matches the tuning process,
+ * not the max capabilities of the chip.
+ */
+#define RKISP1_CIF_ISP_LSC_SAMPLES_MAX             17
+
+/*
+ * Histogram calculation
+ */
+/* Last 3 values unused. */
+#define RKISP1_CIF_ISP_HISTOGRAM_WEIGHT_GRIDS_SIZE 28
+
+/*
+ * Defect Pixel Cluster Correction
+ */
+#define RKISP1_CIF_ISP_DPCC_METHODS_MAX       3
+
+/*
+ * Denoising pre filter
+ */
+#define RKISP1_CIF_ISP_DPF_MAX_NLF_COEFFS      17
+#define RKISP1_CIF_ISP_DPF_MAX_SPATIAL_COEFFS  6
+
+/*
+ * Measurement types
+ */
+#define RKISP1_CIF_ISP_STAT_AWB           (1U << 0)
+#define RKISP1_CIF_ISP_STAT_AUTOEXP       (1U << 1)
+#define RKISP1_CIF_ISP_STAT_AFM           (1U << 2)
+#define RKISP1_CIF_ISP_STAT_HIST          (1U << 3)
+
+enum rkisp1_cif_isp_histogram_mode {
+       RKISP1_CIF_ISP_HISTOGRAM_MODE_DISABLE,
+       RKISP1_CIF_ISP_HISTOGRAM_MODE_RGB_COMBINED,
+       RKISP1_CIF_ISP_HISTOGRAM_MODE_R_HISTOGRAM,
+       RKISP1_CIF_ISP_HISTOGRAM_MODE_G_HISTOGRAM,
+       RKISP1_CIF_ISP_HISTOGRAM_MODE_B_HISTOGRAM,
+       RKISP1_CIF_ISP_HISTOGRAM_MODE_Y_HISTOGRAM
+};
+
+enum rkisp1_cif_isp_awb_mode_type {
+       RKISP1_CIF_ISP_AWB_MODE_MANUAL,
+       RKISP1_CIF_ISP_AWB_MODE_RGB,
+       RKISP1_CIF_ISP_AWB_MODE_YCBCR
+};
+
+enum rkisp1_cif_isp_flt_mode {
+       RKISP1_CIF_ISP_FLT_STATIC_MODE,
+       RKISP1_CIF_ISP_FLT_DYNAMIC_MODE
+};
+
+/**
+ * enum rkisp1_cif_isp_exp_ctrl_autostop - stop modes
+ * @RKISP1_CIF_ISP_EXP_CTRL_AUTOSTOP_0: continuous measurement
+ * @RKISP1_CIF_ISP_EXP_CTRL_AUTOSTOP_1: stop measuring after a complete frame
+ */
+enum rkisp1_cif_isp_exp_ctrl_autostop {
+       RKISP1_CIF_ISP_EXP_CTRL_AUTOSTOP_0 = 0,
+       RKISP1_CIF_ISP_EXP_CTRL_AUTOSTOP_1 = 1,
+};
+
+/**
+ * enum rkisp1_cif_isp_exp_meas_mode - Exposure measure mode
+ * @RKISP1_CIF_ISP_EXP_MEASURING_MODE_0: Y = 16 + 0.25R + 0.5G + 0.1094B
+ * @RKISP1_CIF_ISP_EXP_MEASURING_MODE_1: Y = (R + G + B) x (85/256)
+ */
+enum rkisp1_cif_isp_exp_meas_mode {
+       RKISP1_CIF_ISP_EXP_MEASURING_MODE_0,
+       RKISP1_CIF_ISP_EXP_MEASURING_MODE_1,
+};
+
+/*---------- PART1: Input Parameters ------------*/
+
+/**
+ * struct rkisp1_cif_isp_window -  measurement window.
+ *
+ * Measurements are calculated per window inside the frame.
+ * This struct represents a window for a measurement.
+ *
+ * @h_offs: the horizontal offset of the window from the left of the frame in pixels.
+ * @v_offs: the vertical offset of the window from the top of the frame in pixels.
+ * @h_size: the horizontal size of the window in pixels
+ * @v_size: the vertical size of the window in pixels.
+ */
+struct rkisp1_cif_isp_window {
+       __u16 h_offs;
+       __u16 v_offs;
+       __u16 h_size;
+       __u16 v_size;
+};
+
+/**
+ * struct rkisp1_cif_isp_bls_fixed_val - BLS fixed subtraction values
+ *
+ * The values will be subtracted from the sensor
+ * values. Therefore a negative value means addition instead of subtraction!
+ *
+ * @r: Fixed (signed!) subtraction value for Bayer pattern R
+ * @gr: Fixed (signed!) subtraction value for Bayer pattern Gr
+ * @gb: Fixed (signed!) subtraction value for Bayer pattern Gb
+ * @b: Fixed (signed!) subtraction value for Bayer pattern B
+ */
+struct rkisp1_cif_isp_bls_fixed_val {
+       __s16 r;
+       __s16 gr;
+       __s16 gb;
+       __s16 b;
+};
+
+/**
+ * struct rkisp1_cif_isp_bls_config - Configuration used by black level subtraction
+ *
+ * @enable_auto: Automatic mode activated means that the measured values
+ *              are subtracted. Otherwise the fixed subtraction
+ *              values will be subtracted.
+ * @en_windows: enabled window
+ * @bls_window1: Measurement window 1 size
+ * @bls_window2: Measurement window 2 size
+ * @bls_samples: Set amount of measured pixels for each Bayer position
+ *              (A, B,C and D) to 2^bls_samples.
+ * @fixed_val: Fixed subtraction values
+ */
+struct rkisp1_cif_isp_bls_config {
+       __u8 enable_auto;
+       __u8 en_windows;
+       struct rkisp1_cif_isp_window bls_window1;
+       struct rkisp1_cif_isp_window bls_window2;
+       __u8 bls_samples;
+       struct rkisp1_cif_isp_bls_fixed_val fixed_val;
+};
+
+/**
+ * struct rkisp1_cif_isp_dpcc_methods_config - Methods Configuration used by DPCC
+ *
+ * Methods Configuration used by Defect Pixel Cluster Correction
+ *
+ * @method: Method enable bits
+ * @line_thresh: Line threshold
+ * @line_mad_fac: Line MAD factor
+ * @pg_fac: Peak gradient factor
+ * @rnd_thresh: Rank Neighbor Difference threshold
+ * @rg_fac: Rank gradient factor
+ */
+struct rkisp1_cif_isp_dpcc_methods_config {
+       __u32 method;
+       __u32 line_thresh;
+       __u32 line_mad_fac;
+       __u32 pg_fac;
+       __u32 rnd_thresh;
+       __u32 rg_fac;
+};
+
+/**
+ * struct rkisp1_cif_isp_dpcc_config - Configuration used by DPCC
+ *
+ * Configuration used by Defect Pixel Cluster Correction
+ *
+ * @mode: dpcc output mode
+ * @output_mode: whether use hard coded methods
+ * @set_use: stage1 methods set
+ * @methods: methods config
+ * @ro_limits: rank order limits
+ * @rnd_offs: differential rank offsets for rank neighbor difference
+ */
+struct rkisp1_cif_isp_dpcc_config {
+       __u32 mode;
+       __u32 output_mode;
+       __u32 set_use;
+       struct rkisp1_cif_isp_dpcc_methods_config methods[RKISP1_CIF_ISP_DPCC_METHODS_MAX];
+       __u32 ro_limits;
+       __u32 rnd_offs;
+};
+
+/**
+ * struct rkisp1_cif_isp_gamma_corr_curve - gamma curve point definition y-axis (output).
+ *
+ * The reset values define a linear curve which has the same effect as bypass. Reset values are:
+ * gamma_y[0] = 0x0000, gamma_y[1] = 0x0100, ... gamma_y[15] = 0x0f00, gamma_y[16] = 0xfff
+ *
+ * @gamma_y: the values for the y-axis of gamma curve points. Each value is 12 bit.
+ */
+struct rkisp1_cif_isp_gamma_corr_curve {
+       __u16 gamma_y[RKISP1_CIF_ISP_DEGAMMA_CURVE_SIZE];
+};
+
+/**
+ * struct rkisp1_cif_isp_gamma_curve_x_axis_pnts - De-Gamma Curve definition x increments
+ *             (sampling points). gamma_dx0 is for the lower samples (1-8), gamma_dx1 is for the
+ *             higher samples (9-16). The reset values for both fields is 0x44444444. This means
+ *             that each sample is 4 units away from the previous one on the x-axis.
+ *
+ * @gamma_dx0: gamma curve sample points definitions. Bits 0:2 for sample 1. Bit 3 unused.
+ *             Bits 4:6 for sample 2. bit 7 unused ... Bits 28:30 for sample 8. Bit 31 unused
+ * @gamma_dx1: gamma curve sample points definitions. Bits 0:2 for sample 9. Bit 3 unused.
+ *             Bits 4:6 for sample 10. bit 7 unused ... Bits 28:30 for sample 16. Bit 31 unused
+ */
+struct rkisp1_cif_isp_gamma_curve_x_axis_pnts {
+       __u32 gamma_dx0;
+       __u32 gamma_dx1;
+};
+
+/**
+ * struct rkisp1_cif_isp_sdg_config - Configuration used by sensor degamma
+ *
+ * @curve_r: gamma curve point definition axis for red
+ * @curve_g: gamma curve point definition axis for green
+ * @curve_b: gamma curve point definition axis for blue
+ * @xa_pnts: x axis increments
+ */
+struct rkisp1_cif_isp_sdg_config {
+       struct rkisp1_cif_isp_gamma_corr_curve curve_r;
+       struct rkisp1_cif_isp_gamma_corr_curve curve_g;
+       struct rkisp1_cif_isp_gamma_corr_curve curve_b;
+       struct rkisp1_cif_isp_gamma_curve_x_axis_pnts xa_pnts;
+};
+
+/**
+ * struct rkisp1_cif_isp_lsc_config - Configuration used by Lens shading correction
+ *
+ * @r_data_tbl: sample table red
+ * @gr_data_tbl: sample table green (red)
+ * @gb_data_tbl: sample table green (blue)
+ * @b_data_tbl: sample table blue
+ * @x_grad_tbl: gradient table x
+ * @y_grad_tbl: gradient table y
+ * @x_size_tbl: size table x
+ * @y_size_tbl: size table y
+ * @config_width: not used at the moment
+ * @config_height: not used at the moment
+ */
+struct rkisp1_cif_isp_lsc_config {
+       __u16 r_data_tbl[RKISP1_CIF_ISP_LSC_SAMPLES_MAX][RKISP1_CIF_ISP_LSC_SAMPLES_MAX];
+       __u16 gr_data_tbl[RKISP1_CIF_ISP_LSC_SAMPLES_MAX][RKISP1_CIF_ISP_LSC_SAMPLES_MAX];
+       __u16 gb_data_tbl[RKISP1_CIF_ISP_LSC_SAMPLES_MAX][RKISP1_CIF_ISP_LSC_SAMPLES_MAX];
+       __u16 b_data_tbl[RKISP1_CIF_ISP_LSC_SAMPLES_MAX][RKISP1_CIF_ISP_LSC_SAMPLES_MAX];
+
+       __u16 x_grad_tbl[RKISP1_CIF_ISP_LSC_SECTORS_TBL_SIZE];
+       __u16 y_grad_tbl[RKISP1_CIF_ISP_LSC_SECTORS_TBL_SIZE];
+
+       __u16 x_size_tbl[RKISP1_CIF_ISP_LSC_SECTORS_TBL_SIZE];
+       __u16 y_size_tbl[RKISP1_CIF_ISP_LSC_SECTORS_TBL_SIZE];
+       __u16 config_width;
+       __u16 config_height;
+};
+
+/**
+ * struct rkisp1_cif_isp_ie_config - Configuration used by image effects
+ *
+ * @effect: values from 'enum v4l2_colorfx'. Possible values are: V4L2_COLORFX_SEPIA,
+ *             V4L2_COLORFX_SET_CBCR, V4L2_COLORFX_AQUA, V4L2_COLORFX_EMBOSS,
+ *             V4L2_COLORFX_SKETCH,   V4L2_COLORFX_BW,   V4L2_COLORFX_NEGATIVE
+ * @color_sel: bits 0:2 - colors bitmask (001 - blue, 010 - green, 100 - red).
+ *             bits 8:15 - Threshold value of the RGB colors for the color selection effect.
+ * @eff_mat_1: 3x3 Matrix Coefficients for Emboss Effect 1
+ * @eff_mat_2: 3x3 Matrix Coefficients for Emboss Effect 2
+ * @eff_mat_3: 3x3 Matrix Coefficients for Emboss 3/Sketch 1
+ * @eff_mat_4: 3x3 Matrix Coefficients for Sketch Effect 2
+ * @eff_mat_5: 3x3 Matrix Coefficients for Sketch Effect 3
+ * @eff_tint: Chrominance increment values of tint (used for sepia effect)
+ */
+struct rkisp1_cif_isp_ie_config {
+       __u16 effect;
+       __u16 color_sel;
+       __u16 eff_mat_1;
+       __u16 eff_mat_2;
+       __u16 eff_mat_3;
+       __u16 eff_mat_4;
+       __u16 eff_mat_5;
+       __u16 eff_tint;
+};
+
+/**
+ * struct rkisp1_cif_isp_cproc_config - Configuration used by Color Processing
+ *
+ * @c_out_range: Chrominance pixel clipping range at output.
+ *              (0 for limit, 1 for full)
+ * @y_in_range: Luminance pixel clipping range at output.
+ * @y_out_range: Luminance pixel clipping range at output.
+ * @contrast: 00~ff, 0.0~1.992
+ * @brightness: 80~7F, -128~+127
+ * @sat: saturation, 00~FF, 0.0~1.992
+ * @hue: 80~7F, -90~+87.188
+ */
+struct rkisp1_cif_isp_cproc_config {
+       __u8 c_out_range;
+       __u8 y_in_range;
+       __u8 y_out_range;
+       __u8 contrast;
+       __u8 brightness;
+       __u8 sat;
+       __u8 hue;
+};
+
+/**
+ * struct rkisp1_cif_isp_awb_meas_config - Configuration used by auto white balance
+ *
+ * @awb_mode: the awb meas mode. From enum rkisp1_cif_isp_awb_mode_type.
+ * @awb_wnd: white balance measurement window (in pixels)
+ * @max_y: only pixels values < max_y contribute to awb measurement, set to 0
+ *        to disable this feature
+ * @min_y: only pixels values > min_y contribute to awb measurement
+ * @max_csum: Chrominance sum maximum value, only consider pixels with Cb+Cr,
+ *           smaller than threshold for awb measurements
+ * @min_c: Chrominance minimum value, only consider pixels with Cb/Cr
+ *        each greater than threshold value for awb measurements
+ * @frames: number of frames - 1 used for mean value calculation
+ *         (ucFrames=0 means 1 Frame)
+ * @awb_ref_cr: reference Cr value for AWB regulation, target for AWB
+ * @awb_ref_cb: reference Cb value for AWB regulation, target for AWB
+ * @enable_ymax_cmp: enable Y_MAX compare (Not valid in RGB measurement mode.)
+ */
+struct rkisp1_cif_isp_awb_meas_config {
+       /*
+        * Note: currently the h and v offsets are mapped to grid offsets
+        */
+       struct rkisp1_cif_isp_window awb_wnd;
+       __u32 awb_mode;
+       __u8 max_y;
+       __u8 min_y;
+       __u8 max_csum;
+       __u8 min_c;
+       __u8 frames;
+       __u8 awb_ref_cr;
+       __u8 awb_ref_cb;
+       __u8 enable_ymax_cmp;
+};
+
+/**
+ * struct rkisp1_cif_isp_awb_gain_config - Configuration used by auto white balance gain
+ *
+ * All fields in this struct are 10 bit, where:
+ * 0x100h = 1, unsigned integer value, range 0 to 4 with 8 bit fractional part.
+ *
+ * out_data_x = ( AWB_GAIN_X * in_data + 128) >> 8
+ *
+ * @gain_red: gain value for red component.
+ * @gain_green_r: gain value for green component in red line.
+ * @gain_blue: gain value for blue component.
+ * @gain_green_b: gain value for green component in blue line.
+ */
+struct rkisp1_cif_isp_awb_gain_config {
+       __u16 gain_red;
+       __u16 gain_green_r;
+       __u16 gain_blue;
+       __u16 gain_green_b;
+};
+
+/**
+ * struct rkisp1_cif_isp_flt_config - Configuration used by ISP filtering
+ *
+ * All 4 threshold fields (thresh_*) are 10 bits.
+ * All 6 factor fields (fac_*) are 6 bits.
+ *
+ * @mode: ISP_FILT_MODE register fields (from enum rkisp1_cif_isp_flt_mode)
+ * @grn_stage1: Green filter stage 1 select (range 0x0...0x8)
+ * @chr_h_mode: Chroma filter horizontal mode
+ * @chr_v_mode: Chroma filter vertical mode
+ * @thresh_bl0: If thresh_bl1 < sum_grad < thresh_bl0 then fac_bl0 is selected (blurring th)
+ * @thresh_bl1: If sum_grad < thresh_bl1 then fac_bl1 is selected (blurring th)
+ * @thresh_sh0: If thresh_sh0 < sum_grad < thresh_sh1 then thresh_sh0 is selected (sharpening th)
+ * @thresh_sh1: If thresh_sh1 < sum_grad then thresh_sh1 is selected (sharpening th)
+ * @lum_weight: Parameters for luminance weight function.
+ * @fac_sh1: filter factor for sharp1 level
+ * @fac_sh0: filter factor for sharp0 level
+ * @fac_mid: filter factor for mid level and for static filter mode
+ * @fac_bl0: filter factor for blur 0 level
+ * @fac_bl1: filter factor for blur 1 level (max blur)
+ */
+struct rkisp1_cif_isp_flt_config {
+       __u32 mode;
+       __u8 grn_stage1;
+       __u8 chr_h_mode;
+       __u8 chr_v_mode;
+       __u32 thresh_bl0;
+       __u32 thresh_bl1;
+       __u32 thresh_sh0;
+       __u32 thresh_sh1;
+       __u32 lum_weight;
+       __u32 fac_sh1;
+       __u32 fac_sh0;
+       __u32 fac_mid;
+       __u32 fac_bl0;
+       __u32 fac_bl1;
+};
+
+/**
+ * struct rkisp1_cif_isp_bdm_config - Configuration used by Bayer DeMosaic
+ *
+ * @demosaic_th: threshold for bayer demosaicing texture detection
+ */
+struct rkisp1_cif_isp_bdm_config {
+       __u8 demosaic_th;
+};
+
+/**
+ * struct rkisp1_cif_isp_ctk_config - Configuration used by Cross Talk correction
+ *
+ * @coeff: color correction matrix. Values are 11-bit signed fixed-point numbers with 4 bit integer
+ *             and 7 bit fractional part, ranging from -8 (0x400) to +7.992 (0x3FF). 0 is
+ *             represented by 0x000 and a coefficient value of 1 as 0x080.
+ * @ct_offset: Red, Green, Blue offsets for the crosstalk correction matrix
+ */
+struct rkisp1_cif_isp_ctk_config {
+       __u16 coeff[3][3];
+       __u16 ct_offset[3];
+};
+
+enum rkisp1_cif_isp_goc_mode {
+       RKISP1_CIF_ISP_GOC_MODE_LOGARITHMIC,
+       RKISP1_CIF_ISP_GOC_MODE_EQUIDISTANT
+};
+
+/**
+ * struct rkisp1_cif_isp_goc_config - Configuration used by Gamma Out correction
+ *
+ * @mode: goc mode (from enum rkisp1_cif_isp_goc_mode)
+ * @gamma_y: gamma out curve y-axis for all color components
+ */
+struct rkisp1_cif_isp_goc_config {
+       __u32 mode;
+       __u16 gamma_y[RKISP1_CIF_ISP_GAMMA_OUT_MAX_SAMPLES];
+};
+
+/**
+ * struct rkisp1_cif_isp_hst_config - Configuration used by Histogram
+ *
+ * @mode: histogram mode (from enum rkisp1_cif_isp_histogram_mode)
+ * @histogram_predivider: process every stepsize pixel, all other pixels are
+ *                       skipped
+ * @meas_window: coordinates of the measure window
+ * @hist_weight: weighting factor for sub-windows
+ */
+struct rkisp1_cif_isp_hst_config {
+       __u32 mode;
+       __u8 histogram_predivider;
+       struct rkisp1_cif_isp_window meas_window;
+       __u8 hist_weight[RKISP1_CIF_ISP_HISTOGRAM_WEIGHT_GRIDS_SIZE];
+};
+
+/**
+ * struct rkisp1_cif_isp_aec_config - Configuration used by Auto Exposure Control
+ *
+ * @mode: Exposure measure mode (from enum rkisp1_cif_isp_exp_meas_mode)
+ * @autostop: stop mode (from enum rkisp1_cif_isp_exp_ctrl_autostop)
+ * @meas_window: coordinates of the measure window
+ */
+struct rkisp1_cif_isp_aec_config {
+       __u32 mode;
+       __u32 autostop;
+       struct rkisp1_cif_isp_window meas_window;
+};
+
+/**
+ * struct rkisp1_cif_isp_afc_config - Configuration used by Auto Focus Control
+ *
+ * @num_afm_win: max RKISP1_CIF_ISP_AFM_MAX_WINDOWS
+ * @afm_win: coordinates of the meas window
+ * @thres: threshold used for minimizing the influence of noise
+ * @var_shift: the number of bits for the shift operation at the end of the
+ *            calculation chain.
+ */
+struct rkisp1_cif_isp_afc_config {
+       __u8 num_afm_win;
+       struct rkisp1_cif_isp_window afm_win[RKISP1_CIF_ISP_AFM_MAX_WINDOWS];
+       __u32 thres;
+       __u32 var_shift;
+};
+
+/**
+ * enum rkisp1_cif_isp_dpf_gain_usage - dpf gain usage
+ * @RKISP1_CIF_ISP_DPF_GAIN_USAGE_DISABLED: don't use any gains in preprocessing stage
+ * @RKISP1_CIF_ISP_DPF_GAIN_USAGE_NF_GAINS: use only the noise function gains from
+ *                                 registers DPF_NF_GAIN_R, ...
+ * @RKISP1_CIF_ISP_DPF_GAIN_USAGE_LSC_GAINS:  use only the gains from LSC module
+ * @RKISP1_CIF_ISP_DPF_GAIN_USAGE_NF_LSC_GAINS: use the noise function gains and the
+ *                                     gains from LSC module
+ * @RKISP1_CIF_ISP_DPF_GAIN_USAGE_AWB_GAINS: use only the gains from AWB module
+ * @RKISP1_CIF_ISP_DPF_GAIN_USAGE_AWB_LSC_GAINS: use the gains from AWB and LSC module
+ * @RKISP1_CIF_ISP_DPF_GAIN_USAGE_MAX: upper border (only for an internal evaluation)
+ */
+enum rkisp1_cif_isp_dpf_gain_usage {
+       RKISP1_CIF_ISP_DPF_GAIN_USAGE_DISABLED,
+       RKISP1_CIF_ISP_DPF_GAIN_USAGE_NF_GAINS,
+       RKISP1_CIF_ISP_DPF_GAIN_USAGE_LSC_GAINS,
+       RKISP1_CIF_ISP_DPF_GAIN_USAGE_NF_LSC_GAINS,
+       RKISP1_CIF_ISP_DPF_GAIN_USAGE_AWB_GAINS,
+       RKISP1_CIF_ISP_DPF_GAIN_USAGE_AWB_LSC_GAINS,
+       RKISP1_CIF_ISP_DPF_GAIN_USAGE_MAX
+};
+
+/**
+ * enum rkisp1_cif_isp_dpf_rb_filtersize - Red and blue filter sizes
+ * @RKISP1_CIF_ISP_DPF_RB_FILTERSIZE_13x9: red and blue filter kernel size 13x9
+ *                                (means 7x5 active pixel)
+ * @RKISP1_CIF_ISP_DPF_RB_FILTERSIZE_9x9: red and blue filter kernel size 9x9
+ *                                (means 5x5 active pixel)
+ */
+enum rkisp1_cif_isp_dpf_rb_filtersize {
+       RKISP1_CIF_ISP_DPF_RB_FILTERSIZE_13x9,
+       RKISP1_CIF_ISP_DPF_RB_FILTERSIZE_9x9,
+};
+
+/**
+ * enum rkisp1_cif_isp_dpf_nll_scale_mode - dpf noise level scale mode
+ * @RKISP1_CIF_ISP_NLL_SCALE_LINEAR: use a linear scaling
+ * @RKISP1_CIF_ISP_NLL_SCALE_LOGARITHMIC: use a logarithmic scaling
+ */
+enum rkisp1_cif_isp_dpf_nll_scale_mode {
+       RKISP1_CIF_ISP_NLL_SCALE_LINEAR,
+       RKISP1_CIF_ISP_NLL_SCALE_LOGARITHMIC,
+};
+
+/**
+ * struct rkisp1_cif_isp_dpf_nll - Noise level lookup
+ *
+ * @coeff: Noise level Lookup coefficient
+ * @scale_mode: dpf noise level scale mode (from enum rkisp1_cif_isp_dpf_nll_scale_mode)
+ */
+struct rkisp1_cif_isp_dpf_nll {
+       __u16 coeff[RKISP1_CIF_ISP_DPF_MAX_NLF_COEFFS];
+       __u32 scale_mode;
+};
+
+/**
+ * struct rkisp1_cif_isp_dpf_rb_flt - Red blue filter config
+ *
+ * @fltsize: The filter size for the red and blue pixels
+ *          (from enum rkisp1_cif_isp_dpf_rb_filtersize)
+ * @spatial_coeff: Spatial weights
+ * @r_enable: enable filter processing for red pixels
+ * @b_enable: enable filter processing for blue pixels
+ */
+struct rkisp1_cif_isp_dpf_rb_flt {
+       __u32 fltsize;
+       __u8 spatial_coeff[RKISP1_CIF_ISP_DPF_MAX_SPATIAL_COEFFS];
+       __u8 r_enable;
+       __u8 b_enable;
+};
+
+/**
+ * struct rkisp1_cif_isp_dpf_g_flt - Green filter Configuration
+ *
+ * @spatial_coeff: Spatial weights
+ * @gr_enable: enable filter processing for green pixels in green/red lines
+ * @gb_enable: enable filter processing for green pixels in green/blue lines
+ */
+struct rkisp1_cif_isp_dpf_g_flt {
+       __u8 spatial_coeff[RKISP1_CIF_ISP_DPF_MAX_SPATIAL_COEFFS];
+       __u8 gr_enable;
+       __u8 gb_enable;
+};
+
+/**
+ * struct rkisp1_cif_isp_dpf_gain - Noise function Configuration
+ *
+ * @mode: dpf gain usage  (from enum rkisp1_cif_isp_dpf_gain_usage)
+ * @nf_r_gain: Noise function Gain that replaces the AWB gain for red pixels
+ * @nf_b_gain: Noise function Gain that replaces the AWB gain for blue pixels
+ * @nf_gr_gain: Noise function Gain that replaces the AWB gain
+ *             for green pixels in a red line
+ * @nf_gb_gain: Noise function Gain that replaces the AWB gain
+ *             for green pixels in a blue line
+ */
+struct rkisp1_cif_isp_dpf_gain {
+       __u32 mode;
+       __u16 nf_r_gain;
+       __u16 nf_b_gain;
+       __u16 nf_gr_gain;
+       __u16 nf_gb_gain;
+};
+
+/**
+ * struct rkisp1_cif_isp_dpf_config - Configuration used by De-noising pre-filter
+ *
+ * @gain: noise function gain
+ * @g_flt: green filter config
+ * @rb_flt: red blue filter config
+ * @nll: noise level lookup
+ */
+struct rkisp1_cif_isp_dpf_config {
+       struct rkisp1_cif_isp_dpf_gain gain;
+       struct rkisp1_cif_isp_dpf_g_flt g_flt;
+       struct rkisp1_cif_isp_dpf_rb_flt rb_flt;
+       struct rkisp1_cif_isp_dpf_nll nll;
+};
+
+/**
+ * struct rkisp1_cif_isp_dpf_strength_config - strength of the filter
+ *
+ * @r: filter strength of the RED filter
+ * @g: filter strength of the GREEN filter
+ * @b: filter strength of the BLUE filter
+ */
+struct rkisp1_cif_isp_dpf_strength_config {
+       __u8 r;
+       __u8 g;
+       __u8 b;
+};
+
+/**
+ * struct rkisp1_cif_isp_isp_other_cfg - Parameters for some blocks in rockchip isp1
+ *
+ * @dpcc_config: Defect Pixel Cluster Correction config
+ * @bls_config: Black Level Subtraction config
+ * @sdg_config: sensor degamma config
+ * @lsc_config: Lens Shade config
+ * @awb_gain_config: Auto White balance gain config
+ * @flt_config: filter config
+ * @bdm_config: demosaic config
+ * @ctk_config: cross talk config
+ * @goc_config: gamma out config
+ * @bls_config: black level subtraction config
+ * @dpf_config: De-noising pre-filter config
+ * @dpf_strength_config: dpf strength config
+ * @cproc_config: color process config
+ * @ie_config: image effects config
+ */
+struct rkisp1_cif_isp_isp_other_cfg {
+       struct rkisp1_cif_isp_dpcc_config dpcc_config;
+       struct rkisp1_cif_isp_bls_config bls_config;
+       struct rkisp1_cif_isp_sdg_config sdg_config;
+       struct rkisp1_cif_isp_lsc_config lsc_config;
+       struct rkisp1_cif_isp_awb_gain_config awb_gain_config;
+       struct rkisp1_cif_isp_flt_config flt_config;
+       struct rkisp1_cif_isp_bdm_config bdm_config;
+       struct rkisp1_cif_isp_ctk_config ctk_config;
+       struct rkisp1_cif_isp_goc_config goc_config;
+       struct rkisp1_cif_isp_dpf_config dpf_config;
+       struct rkisp1_cif_isp_dpf_strength_config dpf_strength_config;
+       struct rkisp1_cif_isp_cproc_config cproc_config;
+       struct rkisp1_cif_isp_ie_config ie_config;
+};
+
+/**
+ * struct rkisp1_cif_isp_isp_meas_cfg - Rockchip ISP1 Measure Parameters
+ *
+ * @awb_meas_config: auto white balance config
+ * @hst_config: histogram config
+ * @aec_config: auto exposure config
+ * @afc_config: auto focus config
+ */
+struct rkisp1_cif_isp_isp_meas_cfg {
+       struct rkisp1_cif_isp_awb_meas_config awb_meas_config;
+       struct rkisp1_cif_isp_hst_config hst_config;
+       struct rkisp1_cif_isp_aec_config aec_config;
+       struct rkisp1_cif_isp_afc_config afc_config;
+};
+
+/**
+ * struct rkisp1_params_cfg - Rockchip ISP1 Input Parameters Meta Data
+ *
+ * @module_en_update: mask the enable bits of which module should be updated
+ * @module_ens: mask the enable value of each module, only update the module
+ *             which correspond bit was set in module_en_update
+ * @module_cfg_update: mask the config bits of which module should be updated
+ * @meas: measurement config
+ * @others: other config
+ */
+struct rkisp1_params_cfg {
+       __u32 module_en_update;
+       __u32 module_ens;
+       __u32 module_cfg_update;
+
+       struct rkisp1_cif_isp_isp_meas_cfg meas;
+       struct rkisp1_cif_isp_isp_other_cfg others;
+};
+
+/*---------- PART2: Measurement Statistics ------------*/
+
+/**
+ * struct rkisp1_cif_isp_awb_meas - AWB measured values
+ *
+ * @cnt: White pixel count, number of "white pixels" found during last
+ *      measurement
+ * @mean_y_or_g: Mean value of Y within window and frames,
+ *              Green if RGB is selected.
+ * @mean_cb_or_b: Mean value of Cb within window and frames,
+ *               Blue if RGB is selected.
+ * @mean_cr_or_r: Mean value of Cr within window and frames,
+ *               Red if RGB is selected.
+ */
+struct rkisp1_cif_isp_awb_meas {
+       __u32 cnt;
+       __u8 mean_y_or_g;
+       __u8 mean_cb_or_b;
+       __u8 mean_cr_or_r;
+};
+
+/**
+ * struct rkisp1_cif_isp_awb_stat - statistics automatic white balance data
+ *
+ * @awb_mean: Mean measured data
+ */
+struct rkisp1_cif_isp_awb_stat {
+       struct rkisp1_cif_isp_awb_meas awb_mean[RKISP1_CIF_ISP_AWB_MAX_GRID];
+};
+
+/**
+ * struct rkisp1_cif_isp_bls_meas_val - BLS measured values
+ *
+ * @meas_r: Mean measured value for Bayer pattern R
+ * @meas_gr: Mean measured value for Bayer pattern Gr
+ * @meas_gb: Mean measured value for Bayer pattern Gb
+ * @meas_b: Mean measured value for Bayer pattern B
+ */
+struct rkisp1_cif_isp_bls_meas_val {
+       __u16 meas_r;
+       __u16 meas_gr;
+       __u16 meas_gb;
+       __u16 meas_b;
+};
+
+/**
+ * struct rkisp1_cif_isp_ae_stat - statistics auto exposure data
+ *
+ * @exp_mean: Mean luminance value of block xx
+ * @bls_val:  BLS measured values
+ *
+ * Image is divided into 5x5 blocks.
+ */
+struct rkisp1_cif_isp_ae_stat {
+       __u8 exp_mean[RKISP1_CIF_ISP_AE_MEAN_MAX];
+       struct rkisp1_cif_isp_bls_meas_val bls_val;
+};
+
+/**
+ * struct rkisp1_cif_isp_af_meas_val - AF measured values
+ *
+ * @sum: sharpness value
+ * @lum: luminance value
+ */
+struct rkisp1_cif_isp_af_meas_val {
+       __u32 sum;
+       __u32 lum;
+};
+
+/**
+ * struct rkisp1_cif_isp_af_stat - statistics auto focus data
+ *
+ * @window: AF measured value of window x
+ *
+ * The module measures the sharpness in 3 windows of selectable size via
+ * register settings(ISP_AFM_*_A/B/C)
+ */
+struct rkisp1_cif_isp_af_stat {
+       struct rkisp1_cif_isp_af_meas_val window[RKISP1_CIF_ISP_AFM_MAX_WINDOWS];
+};
+
+/**
+ * struct rkisp1_cif_isp_hist_stat - statistics histogram data
+ *
+ * @hist_bins: measured bin counters
+ *
+ * Measurement window divided into 25 sub-windows, set
+ * with ISP_HIST_XXX
+ */
+struct rkisp1_cif_isp_hist_stat {
+       __u16 hist_bins[RKISP1_CIF_ISP_HIST_BIN_N_MAX];
+};
+
+/**
+ * struct rkisp1_cif_isp_stat - Rockchip ISP1 Statistics Data
+ *
+ * @awb: statistics data for automatic white balance
+ * @ae: statistics data for auto exposure
+ * @af: statistics data for auto focus
+ * @hist: statistics histogram data
+ */
+struct rkisp1_cif_isp_stat {
+       struct rkisp1_cif_isp_awb_stat awb;
+       struct rkisp1_cif_isp_ae_stat ae;
+       struct rkisp1_cif_isp_af_stat af;
+       struct rkisp1_cif_isp_hist_stat hist;
+};
+
+/**
+ * struct rkisp1_stat_buffer - Rockchip ISP1 Statistics Meta Data
+ *
+ * @meas_type: measurement types (RKISP1_CIF_ISP_STAT_* definitions)
+ * @frame_id: frame ID for sync
+ * @params: statistics data
+ */
+struct rkisp1_stat_buffer {
+       __u32 meas_type;
+       __u32 frame_id;
+       struct rkisp1_cif_isp_stat params;
+};
+
+#endif /* _UAPI_RKISP1_CONFIG_H */
index a184c49..7035f4f 100644 (file)
@@ -198,6 +198,12 @@ enum v4l2_colorfx {
  */
 #define V4L2_CID_USER_ATMEL_ISC_BASE           (V4L2_CID_USER_BASE + 0x10c0)
 
+/*
+ * The base for the CODA driver controls.
+ * We reserve 16 controls for this driver.
+ */
+#define V4L2_CID_USER_CODA_BASE                        (V4L2_CID_USER_BASE + 0x10e0)
+
 /* MPEG-class control IDs */
 /* The MPEG controls are applicable to all codec controls
  * and the 'MPEG' part of the define is historical */
index 534eaa4..761ac9d 100644 (file)
@@ -221,9 +221,7 @@ enum v4l2_colorspace {
        V4L2_COLORSPACE_470_SYSTEM_M  = 5,
 
        /*
-        * EBU Tech 3213 PAL/SECAM colorspace. This only makes sense when
-        * dealing with really old PAL/SECAM recordings. Superseded by
-        * SMPTE 170M.
+        * EBU Tech 3213 PAL/SECAM colorspace.
         */
        V4L2_COLORSPACE_470_SYSTEM_BG = 6,
 
@@ -770,6 +768,10 @@ struct v4l2_pix_format {
 #define V4L2_META_FMT_D4XX        v4l2_fourcc('D', '4', 'X', 'X') /* D4XX Payload Header metadata */
 #define V4L2_META_FMT_VIVID      v4l2_fourcc('V', 'I', 'V', 'D') /* Vivid Metadata */
 
+/* Vendor specific - used for RK_ISP1 camera sub-system */
+#define V4L2_META_FMT_RK_ISP1_PARAMS   v4l2_fourcc('R', 'K', '1', 'P') /* Rockchip ISP1 3A Parameters */
+#define V4L2_META_FMT_RK_ISP1_STAT_3A  v4l2_fourcc('R', 'K', '1', 'S') /* Rockchip ISP1 3A Statistics */
+
 /* priv field value to indicates that subsequent fields are valid. */
 #define V4L2_PIX_FMT_PRIV_MAGIC                0xfeedcafe
 
@@ -1185,7 +1187,7 @@ struct v4l2_window {
        struct v4l2_rect        w;
        __u32                   field;   /* enum v4l2_field */
        __u32                   chromakey;
-       struct v4l2_clip        __user *clips;
+       struct v4l2_clip        *clips;
        __u32                   clipcount;
        void                    __user *bitmap;
        __u8                    global_alpha;