aboutsummaryrefslogtreecommitdiffstats
path: root/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas
diff options
context:
space:
mode:
Diffstat (limited to 'meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas')
-rw-r--r--meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0001-spi-sh-msiof-fixes.patch33
-rw-r--r--meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0002-spi-spidev-add-spi-gpio-into-spidev.patch27
-rw-r--r--meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0003-spi-spi-gpio-fix-CPOL-mode.patch42
-rw-r--r--meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0004-xhci-rcar-add-firmware-for-R-Car-H2-M2-USB-3.0-host-.patch205
-rw-r--r--meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0005-usb-host-xhci-plat-add-support-for-the-R-Car-H3-xHCI.patch174
-rw-r--r--meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0006-spi-spi-gpio-fix-set-CPOL-default-inverted.patch30
-rw-r--r--meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0008-arm64-do-not-set-dma-masks-that-device-connection-ca.patch132
-rw-r--r--meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0009-swiotlb-ensure-that-page-sized-mappings-are-page-ali.patch38
-rw-r--r--meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0010-can-rcar_can-add-enable-and-standby-control-pins.patch156
-rw-r--r--meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0011-can-rcar_canfd-add-enable-and-standby-control-pins.patch119
-rw-r--r--meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0012-mtd-Add-RPC-HyperFlash-driver.patch1028
-rw-r--r--meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0013-IMR-driver-interim-patch.patch2104
-rw-r--r--meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0014-lib-swiotlb-reduce-verbosity.patch40
-rw-r--r--meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0015-gpio-max732x-fix-gpio-set.patch29
-rw-r--r--meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0016-gpio-gpiolib-suppress-gpiod-warning.patch29
-rw-r--r--meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0017-media-soc_camera-add-legacy-VIN-CSI2.patch5055
-rw-r--r--meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0018-arm64-renesas-r8a7797-Add-Renesas-R8A7797-SoC-suppor.patch5139
-rw-r--r--meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0019-Revert-media-v4l2-async-remove-unneeded-.registered_.patch54
-rw-r--r--meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0020-ti-st-add-device-tree-support.patch236
-rw-r--r--meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0021-btwilink-add-minimal-device-tree-support.patch54
-rw-r--r--meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0022-ASoC-Modify-check-condition-of-multiple-bindings-of-.patch88
-rw-r--r--meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0023-ASoC-add-dummy-Si468x-driver.patch123
-rw-r--r--meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0024-wl18xx-do-not-invert-IRQ-on-WLxxxx-side.patch48
-rw-r--r--meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0025-drm-adv7511-Enable-HPD-interrupts-to-support-hotplug.patch46
-rw-r--r--meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0026-drm-adv7511-add-polling-mode-when-no-irq-available.patch30
-rw-r--r--meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0027-usb-host-xhci-plat-add-firmware-for-the-R-Car-M3-W-x.patch179
-rw-r--r--meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0028-usb-host-xhci-rcar-update-firmware-for-R-Car-H3-and-.patch206
-rw-r--r--meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0029-i2c-mux-pca954x-fix-i2c-mux-selection-caching.patch51
-rw-r--r--meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0030-Gen3-LVDS-cameras.patch7616
-rw-r--r--meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0031-media-i2c-Add-ov5647-sensor.patch952
-rw-r--r--meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0032-media-i2c-Add-ov5642-sensor.patch2173
-rw-r--r--meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0033-media-soc-camera-fix-parallel-i-f-in-VIN.patch69
-rw-r--r--meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0034-media-soc_camera-Fix-VIDIOC_S_SELECTION-ioctl-miscal.patch67
-rw-r--r--meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0040-arm64-dts-renesas-add-ADAS-boards.patch17596
-rw-r--r--meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0041-arm64-dts-renesas-ulcb-enlarge-cma-region.patch56
-rw-r--r--meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0042-arm64-dts-renesas-r8a7795-es1-h3ulcb-disable-eMMC.patch28
-rw-r--r--meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0043-arm64-dts-renesas-ulcb-use-versaclock-for-du-rgb-and-lvds.patch143
-rw-r--r--meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0044-pinctrl-r8a779x-add-mlb-pinmux.patch154
-rw-r--r--meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0045-clk-r8a779x-add-mlp-clock.patch38
-rw-r--r--meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0046-arm64-dts-renesas-r8a779x-add-mlp-nodes.patch87
-rw-r--r--meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0047-arm64-dts-renesas-ulcb-kf-enable-sd3.patch28
-rw-r--r--meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0048-arm64-dts-renesas-ulcb-kf-enable-most.patch28
-rw-r--r--meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0050-arm64-dts-Gen3-view-boards-TYPE1-first-4-cameras.patch302
-rw-r--r--meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0051-arm64-dts-Gen3-view-boards-TYPE1-second-4-cameras.patch206
-rw-r--r--meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0052-arm64-dts-Gen3-view-boards-TYPE2-first-4-cameras.patch527
-rw-r--r--meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0062-IIO-lsm9ds0-add-IMU-driver.patch972
-rw-r--r--meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0063-ASoC-PCM3168A-add-TDM-modes-merge-ADC-and-DAC.patch479
-rw-r--r--meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0064-ADV7511-limit-maximum-pixelclock.patch76
-rw-r--r--meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0066-pci-pcie-rcar-add-regulators-support.patch107
-rw-r--r--meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0067-ti-st-use-proper-way-to-get-shutdown-gpio.patch61
-rw-r--r--meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0068-drm-adv7511-use-smbus-to-retrieve-edid.patch53
-rw-r--r--meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0070-clk-clk-5p49x-add-5P49V5925-chip.patch49
-rw-r--r--meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0071-ASoC-add-dummy-device-for-WL18xx-PCM-audio.patch128
-rw-r--r--meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0072-usb-hub-disable-autosuspend-for-SMSC-hubs.patch51
-rw-r--r--meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0073-MOST-dim2-add-device-tree-support.patch169
-rw-r--r--meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0074-MOST-dim2-add-R-Car3-related-initialization.patch63
-rw-r--r--meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0075-MOST-core-fix-memory-allocation-at-arm64.patch54
-rw-r--r--meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0076-MOST-dim2-Renesas-R-Car3-variant.patch120
-rw-r--r--meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0077-MOST-dim2-add-timeouts.patch46
-rw-r--r--meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0078-MOST-aim-fix-null-pointer-crash.patch29
-rw-r--r--meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0100-LVDS-ar0132-use-raw12.patch152
-rw-r--r--meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0101-LVDS-ar0132-use-context-swwitch.patch119
-rw-r--r--meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/eagle.cfg28
-rw-r--r--meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/hyperflash.cfg2
-rw-r--r--meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/salvator-x.cfg31
-rw-r--r--meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/sdhi_seq.cfg2
-rw-r--r--meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/ulcb.cfg80
-rw-r--r--meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/v3msk.cfg32
68 files changed, 48468 insertions, 0 deletions
diff --git a/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0001-spi-sh-msiof-fixes.patch b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0001-spi-sh-msiof-fixes.patch
new file mode 100644
index 0000000..d8806ba
--- /dev/null
+++ b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0001-spi-sh-msiof-fixes.patch
@@ -0,0 +1,33 @@
+From 32db8cc989d7dfdf0315d286b06234e008e56d7c Mon Sep 17 00:00:00 2001
+From: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+Date: Sun, 15 May 2016 21:53:13 +0300
+Subject: [PATCH] spi: sh-msiof: fixes
+
+speed up polling of CTR register
+
+Signed-off-by: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+---
+ drivers/spi/spi-sh-msiof.c | 30 ++++++++++++++++++++----------
+ 1 file changed, 20 insertions(+), 10 deletions(-)
+
+diff --git a/drivers/spi/spi-sh-msiof.c b/drivers/spi/spi-sh-msiof.c
+index d096f5a..6817304 100644
+--- a/drivers/spi/spi-sh-msiof.c
++++ b/drivers/spi/spi-sh-msiof.c
+@@ -228,11 +228,11 @@ static int sh_msiof_modify_ctr_wait(struct sh_msiof_spi_priv *p,
+ data |= set;
+ sh_msiof_write(p, CTR, data);
+
+- for (k = 100; k > 0; k--) {
++ for (k = 1000; k > 0; k--) {
+ if ((sh_msiof_read(p, CTR) & mask) == set)
+ break;
+
+- udelay(10);
++ udelay(1);
+ }
+
+ return k > 0 ? 0 : -ETIMEDOUT;
+--
+1.9.1
+
diff --git a/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0002-spi-spidev-add-spi-gpio-into-spidev.patch b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0002-spi-spidev-add-spi-gpio-into-spidev.patch
new file mode 100644
index 0000000..2aec664
--- /dev/null
+++ b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0002-spi-spidev-add-spi-gpio-into-spidev.patch
@@ -0,0 +1,27 @@
+From 4f85719492ae77bc166f90a046e97bb169396062 Mon Sep 17 00:00:00 2001
+From: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+Date: Sun, 15 May 2016 21:47:02 +0300
+Subject: [PATCH] spi: spidev: add spi-gpio into spidev
+
+Add spi-gpio to spidev
+
+Signed-off-by: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+---
+ drivers/spi/spidev.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/spi/spidev.c b/drivers/spi/spidev.c
+index b016a5a..bcee148 100644
+--- a/drivers/spi/spidev.c
++++ b/drivers/spi/spidev.c
+@@ -697,6 +697,7 @@ static const struct of_device_id spidev_dt_ids[] = {
+ { .compatible = "rohm,dh2228fv" },
+ { .compatible = "lineartechnology,ltc2488" },
+ { .compatible = "renesas,sh-msiof" },
++ { .compatible = "spi-gpio" },
+ {},
+ };
+ MODULE_DEVICE_TABLE(of, spidev_dt_ids);
+--
+1.9.1
+
diff --git a/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0003-spi-spi-gpio-fix-CPOL-mode.patch b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0003-spi-spi-gpio-fix-CPOL-mode.patch
new file mode 100644
index 0000000..e802f68
--- /dev/null
+++ b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0003-spi-spi-gpio-fix-CPOL-mode.patch
@@ -0,0 +1,42 @@
+From db37427756bc9e42723f58067a3f387a2861fbbb Mon Sep 17 00:00:00 2001
+From: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+Date: Sun, 29 May 2016 23:18:49 +0300
+Subject: [PATCH] spi: spi-gpio: fix CPOL mode
+
+This fixes the SPI SPOL mode, since the cs_gpios is already used
+in generic code spi.c
+
+Signed-off-by: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+---
+ drivers/spi/spi-gpio.c | 10 +++++-----
+ 1 file changed, 5 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/spi/spi-gpio.c b/drivers/spi/spi-gpio.c
+index 1c34c93..428417d 100644
+--- a/drivers/spi/spi-gpio.c
++++ b/drivers/spi/spi-gpio.c
+@@ -218,10 +218,6 @@ static void spi_gpio_chipselect(struct spi_device *spi, int is_active)
+ struct spi_gpio *spi_gpio = spi_to_spi_gpio(spi);
+ unsigned long cs = spi_gpio->cs_gpios[spi->chip_select];
+
+- /* set initial clock polarity */
+- if (is_active)
+- setsck(spi, spi->mode & SPI_CPOL);
+-
+ if (cs != SPI_GPIO_NO_CHIPSELECT) {
+ /* SPI is normally active-low */
+ gpio_set_value_cansleep(cs, (spi->mode & SPI_CS_HIGH) ? is_active : !is_active);
+@@ -257,6 +253,10 @@ static int spi_gpio_setup(struct spi_device *spi)
+ !(spi->mode & SPI_CS_HIGH));
+ }
+ }
++
++ /* set initial clock polarity */
++ setsck(spi, spi->mode & SPI_CPOL);
++
+ if (!status) {
+ /* in case it was initialized from static board data */
+ spi_gpio->cs_gpios[spi->chip_select] = cs;
+--
+1.9.1
+
diff --git a/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0004-xhci-rcar-add-firmware-for-R-Car-H2-M2-USB-3.0-host-.patch b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0004-xhci-rcar-add-firmware-for-R-Car-H2-M2-USB-3.0-host-.patch
new file mode 100644
index 0000000..8487d5f
--- /dev/null
+++ b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0004-xhci-rcar-add-firmware-for-R-Car-H2-M2-USB-3.0-host-.patch
@@ -0,0 +1,205 @@
+From 63aa7951b66cc771b23a002748a20a5555cf847f Mon Sep 17 00:00:00 2001
+From: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
+Date: Thu, 10 Jul 2014 10:41:55 +0900
+Subject: [PATCH] xhci-rcar: add firmware for R-Car H2/M2 USB 3.0 host
+ controller
+
+This patch adds a firmware for the USB 3.0 host controller of Renesas
+R-Car H2 and M2 SoCs.
+
+Signed-off-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
+Signed-off-by: Kyle McMartin <kyle@kernel.org>
+---
+ firmware/LICENCE.r8a779x_usb3 | 26 ++++++++++++++++++++++++++
+ firmware/WHENCE | 8 ++++++++
+ firmware/r8a779x_usb3_v1.dlmem | Bin 0 -> 9452 bytes
+ 3 files changed, 34 insertions(+)
+ create mode 100644 firmware/LICENCE.r8a779x_usb3
+ create mode 100644 firmware/r8a779x_usb3_v1.dlmem
+
+diff --git a/firmware/LICENCE.r8a779x_usb3 b/firmware/LICENCE.r8a779x_usb3
+new file mode 100644
+index 0000000..e2afcc9
+--- /dev/null
++++ b/firmware/LICENCE.r8a779x_usb3
+@@ -0,0 +1,26 @@
++Copyright (c) 2014, Renesas Electronics Corporation
++All rights reserved.
++
++Redistribution and use in binary form, without modification, are permitted
++provided that the following conditions are met:
++
++1. Redistribution in binary form must reproduce the above copyright notice,
++ this list of conditions and the following disclaimer in the documentation
++ and/or other materials provided with the distribution.
++2. The name of Renesas Electronics Corporation may not be used to endorse or
++ promote products derived from this software without specific prior written
++ permission.
++3. Reverse engineering, decompilation, or disassembly of this software is
++ not permitted.
++
++THIS SOFTWARE IS PROVIDED "AS IS" AND RENESAS ELECTRONICS CORPORATION DISCLAIMS
++ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
++WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, AND
++NONINFRINGEMENT OF THIRD PARTY RIGHTS. IN NO EVENT SHALL RENESAS ELECTRONICS
++CORPORATION BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
++OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
++SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
++INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
++CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
++ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
++POSSIBILITY OF SUCH DAMAGE.
+diff --git a/firmware/WHENCE b/firmware/WHENCE
+index 8388f02..4b45ad1 100644
+--- a/firmware/WHENCE
++++ b/firmware/WHENCE
+@@ -852,3 +852,11 @@ Licence:
+ Found in hex form in kernel source.
+
+ --------------------------------------------------------------------------
++
++Driver: xhci-rcar -- Renesas R-Car H2/M2 USB 3.0 host controller driver
++
++File: r8a779x_usb3_v1.dlmem
++
++Licence: Redistributable. See LICENCE.r8a779x_usb3 for details.
++
++--------------------------------------------------------------------------
+diff --git a/firmware/r8a779x_usb3_v1.dlmem b/firmware/r8a779x_usb3_v1.dlmem
+new file mode 100644
+index 0000000000000000000000000000000000000000..d094157084173b3c741d3d3d214bdd83f2c48d6b
+GIT binary patch
+literal 9452
+zcmai44O~=J+J9z-JD0DEGZ$tq5~HKdn7P^_tEi-cgshqM3Mwd?%7<iTW^K8>tsf%}
+zN@k|M>6%}e4VGlBlDK6#(FA717NCr1io*zgj4mLntf_S0|G5L=zU}*4e!u@c=bn4c
+zbDrlp&w0*so}qZ!Zx2LJEwR7LL>5+Z=2=lWvWjeSA9@gFa?}dyZt<$RTWow5S+!gH
+zsEK=o5*e%=WE-U2aF*zWX@j&8=ZFF%(ftS1eFma=8Fd9NV;iZp9@%HINY<t|#nYVG
+zNV;6qEt0|gu6WR7ZMCjW&=!)KRI$s5Vx96PjVIO1v04*qM>tBmY4G>@1ic8o*w~%o
+z=bTesCzMMOZp$voePRTWQ?8z<N=wwPpjQqL)o$xWl%UNGBU(ZEjQ6*C+bk_anwSLb
+z4N!WKtZNLm0orOdcYK02P^G5DWNPC$6*p#iAZeB*8p)<N2!<eorGq+yxW1ysVEv=X
+z_TUH=^$~L={j3D-Sd3akNtl!AM|;^RhYHIwRK&P&^1*_|XqE<PX@{&?tIy^8Nowsi
+z`E|k4VU|?GHC(><w8$A&K%#z9ioV3e+SSv7buO`7pPev73O1@pW3XgAEO}GE;BtAZ
+z1U-UY3;vWo8ABxh%&V2TJ@`IjR`B$d;z7Z4Ws_i$IB4oL=PzqILnbr6hHBl9_UPu<
+z>zd403o0>LsuAq1HA0rJk#h+-z8axjC^gvR6vFzLZ1RqXn}SU?sw(h|SC?`&d9KDL
+zJ0dDL71mBI*%NAn&Qa~>`fEvFT&y0&TI-EB>lg=YPN%#T>szVxZoyl8v{PPvujMSP
+zab$o^-V@L__AB|zU!3xSd*8~SFTtHJUNJc3ACj;(ZZeqD<?9pmDg%?0*_maR%6(!D
+z3|#u$oh!8kI^{w4#@onmPj}URt8>a>_rB#~UUvYj!lDLGmrb73cFfYE?&dVPYwSpk
+z-xfV<=Bk)vuNqWo$r;sxU%JK^#s}5DDeePDjMo}v4GP5f1j{aRpOBcf1}EEOFV#Ko
+zl%pnCq${WFVog`?jhJ&lAB&`NZ-t$gf2DRadfOovY%(Ahb$|bToT}C@@kXpQo98s=
+zsX2n3ai)*8^<aL2wgG&y9mBru8}6y`4QCozDgJD=OaBP;=#N-cJ}c~8-B3<-22;#x
+z@U^!dD=Z9xl|On(g+0_iKut@r>Xlsin$O%t!Z;tZGIiQY5%Z_{uAFLS*79>;`CFlG
+zPt6(3o@utp2Q-OVIYzNAWsffa6}HEn@=K7e!O(374%k_ic*J0rW;A*9?SfNoPqMZ?
+zZ%fc_!wB%ctC#ykU!r8bMzQAt@d{V|P>I_nZ=$;K*4ED<Wx3MRlj_3UeIkp-U_UiM
+z7XtGl4dK?-uhHkS(udi0(Gd2%Q1Kv>`!mn<x>BE{)YmF?x5X*nQe;-e9+jW^g^gGV
+zihgd-z`p!kmA@MbP6jCZy+_t`&Tkz~IUBMrGBQ~eAJp0#a=nbNnwVu>mXv?5?>eJX
+zK4fIx#oB6O^5YBBmqqgXmqx53<6<TBFsjKeevLi1fhxLma9ru_*TLGz&10;sb&%TA
+zMcvw}UzMP}ru1=0|70tV(Q#~tsqJ{r7W1wC_DYjeUN}D3<CMn^wYD~bMt?2i!`gZs
+z^+%MtQ+_Sh)7TDeCyi%5+9}@{jMctR#_8zSBV!)k*xJLQeeg|OIZr;=sFCg6>4wB~
+z9R=%WKvPjtkMvu+X8pJzLF?$MGwqdhQFh8t-Pik=(xclC_Z2~T77x!I0{@MACue{k
+z?Vu~1foG+gGiVL@;zpq_{5a=kr=b7O+N#1F5xiewc0OE#hgai#7}(X;58sC=b-xAo
+zqoZ=w9ka2Tw{(2g%NAivm*tgH^QW$gFdL)E(h(VWAUq)L;1rEm68>qpD)Z3H(kUxv
+znbVI`{#5hq4XRbM%(HXJKC58r>VP!?=JeZCi1xv%*JrIo89{HLZ<%J@R4#4Xl<iZr
+z**kKA7VLa(*UWdP?4I&oPH^U)ndaF#dVi)m(=oGX=HBoR!aoe(H?w%=N8$U!KMwz7
+z%3o$CY7@FVt~rwJ9Bb>7u!UQS3{Lq-<iA>{80cR)2mC{pxE3cj=iVWHXMpDkRCFbF
+z>xyWc_>8!v)8FGDm(2eIem2Sq8-xulvi7WHE@-mV=iG_uq?xF9VXa3-;k`3oZ0y?A
+z8#^}(JtMX#BiMTO?3?{voZ&1O;7MhErfmTH`a?aVs_u=l@%^xK%ny4~OVID)pl%&l
+zTZbavxS{m(Tkeur|2j4<rdsC5rUfeg@P`<Ux?z~cB9;2omn(hSd@f@Gd9S#JpELF)
+zZ(Jyq57kPC-X0Kl;O%;GhnOW^H`Q`E@b4}|k!h6TH#38n->ftEz36=9tyn9|E<sgW
+zBs_X4h!V8Rl~#6oj-_$FbLk0`oN?G!SCNR5A9m`~7%~m_&%gF)R_$%h+Bym=cm!jY
+z!Sl$Andi~A<xbax*Jtj?tQX%Ak3g#`8?+rWQD19i^-6J@sGjUfD^DGifiHPvo0OVw
+z3emR7H8{JjX5dtvGrZ{ucz*RruQ3$+{mFuIz4!Ou^-7LS&<+Up&&AH}MjEZ9{>8<X
+z4hPM>Y}c>|As-RKMxjKgga6*2REL;g7!~2Ugl<Crw~{J2HGJ{4FndA~b&jg#qDQg!
+z<6(AbAHf%$W8Q;F;b<))MsJfLN1<8-dIKM0PxoVtk~z78(_rMDFo!}ZUqF2EI~HFA
+zp!L<TuC*k4>j&hx^Z}W4YVF_U#wU{~oQ%|)qNy+SCo2u4-_Rp8l!nm=il;G@NRQFu
+zlmeRxNG=)!`pGwkJ7q_5#c-Rvl{VvflA4Fu<Oo$Mo*$|T@bswatTy=<brGHixSNQH
+zPI48n{Q1vr#&h(7W<*N?S{5_)(H6ksKU>JO6YxBf=D_nznpYQ9aE$Mhf<55_=tYqx
+znMo6f)?&ed*1MxNF&U?^R&$&V9Bx9CA(KP;fSwgUG9^(kh0+5QMmju2ionx|*mG^N
+zlOH|a$$tnO2Zp6M`KiEx6fV}uXA3L3D15I_FoA{+G>i%b6Gei8@%K)?4VeA7lV3N%
+z$xoi><Q>4<cwhg77F43UsHnA<<eKqG&~FN6H$lh!=s{@tA$k~k9zwr`rhiAn@pS}^
+zqDP_c6iNWbVU}%AIQds6Ir#xkViw>Uu=gn^Kls0#eBNXyuS<3EDS!tUoaW@?r#Shg
+zQ=PmIh)8$x6Mz!H2c%4Q@`q>e;4DA1TfR3G`FcaXFz}}XL?8k)PtSDnZeY<&Cw~$c
+zJ<G|bKMl?E$z7wfaMtD<a>VOgt&l5vIjk8!_GufBRp3+R1fgdXdamXh7u!eZ11&~-
+zzV>p3&vk{J&*Y_AOM`=7g?Pm=;!_^ClZDOmoU*RiB&q1MxKqp(w+ZL|sU<JB^Ab<0
+z+IsK1-Y+D97%l6Mf5Q&nBdDoCd{<PD{BKg>OxsU8!gp#sHThOg;~Bvu8Q>$PUOgx7
+z62B2$*ZYbpoN`5m?w+QM5UNb?OXJdfQW?z=cZOR!4)H2Z!<GMeYFK%%sbP;M2vp8b
+z4b#ByeL#H7*4Xdkx5pogcgnW|EphwFY)m9g8>n(tY3C}-*r{Q`i6Ij>*z!d#Me#fR
+z6f4TYN!o766*pSj4SC{9lULY`-4G9t-@CIy+$<)EE~AE$r3k42yCGJ^_Cf3%<{$Q|
+z*gg=mD!5=+d{waDPb1QqbC9>RICu;ERETb?;<>6)J$h(FdtScI4T28g-E2vSK0;zE
+zo@SmdDb+j86(>`O?t9UC$z<OSy&(b$V_rBpLl?M~g69ibm3)NbVoS$YED&_%`u@^8
+z`7R?*Sz`N`9MLyCSXUsr@-$QlFR#k<&MBkZXL?Jn>`<le<G$QECg}-1yU*T}Y>DQc
+zoJ`6V{kG2XXNTOQTLSwj7Rs{*OON}KX4G<8Mb{Mub6hwbP3VRFJn*?X!G9xJ-^(8-
+zu@!WXJ$zL-+vzOov&?qzh(B?Q7}c~2<wqkhl3%{SF6jd+a9iw_BS&oK*w|GXm1qwy
+zg6HooSu#u#yDj!-9He%0j++hFvo3XlJ;NX|{(bt}+(+Px@rNC`U<DQ8EVVpy&{vzi
+zEj!dG%UR;5kZF_QS+QMsPOKH47fY}zt#ZDgHvS!7zu{)!Jly`IJp+4Uwmm;sS0R3{
+z&&n?0va^o}{u8Lcwm$7N?)Evn3MYgm<N2#O894DWUc9Pl(@eu^KEO@mIblj=x`x)K
+z+vv?HVKe)q$M>^6RJo`x2{YEuJel@R+FMgX5pQLsUErQgb8*4o!pG&qs=poEi|RN_
+z!a-kE{Em1{j8mQ*z$u!afM|&M&VRSJkIi=S4RhcL=7wNzj}7ehA^*RZojey_HOtAD
+z0Ulsdwv%57__9Mm;V$o|kcInSiI6S2xH@={v|RX{c>=zlz3;o1%kJ_pne&`{WS*0^
+z<%OZoXFN_^9lPIG_{y&=<6qBT#=i+{1U3Wj06T&A^0l5d#Mk4De9j~l<UcSnI>zs1
+zDzU>BEiA=z_d?i{4)hlD_1h`1dK(2D*LrqPG-xyL<+@^up?GtO8CIFBjgEO>WK?4B
+z2{@k?M#nI(<$w26UCU0iMa+Noo)DGDW@GaVd!ZT6`7f~97QKMk5S#RH-_2pnV#eW^
+z7JELM!%xo#pD=haqt{Jq`C>-PvzXBmU-WaHMNAXr;MT#pt_+ko;-|ks>dESu>a?wC
+z!DCglhBm}zW$qc0lj$<$W)=@W15cX;&E|;t!aQ*gB9uT_!{CCOR#t|sE>+65)i+J-
+z{qUMnlYc}BH&0{|y;N8PNtYJh6#ljSwL-?-?n1`hvBK`04~t>$=kVLs0Qgl#r$Ont
+z;q_%1oN`-S%QwpAxG$k;_qyQS$c?Pa$zVB$YLo#ee?Y0lE@VB9qaN5*FGoEXZ5=2>
+zQMRBALwOCQuB*>Q)Dfl^(-A76O2g%En7#tAx@~jopDD}n+&FJmM?%_J>r8D~I^QL;
+z`a*_=F3jP`Cz;jrCjZoUHN&hvt9PYdn8Q=9?kZZd>nrsaGJ+`2<5NbvPCMn8b!@Du
+z?We}M)fc1?ij2vr_ntDVaSQiTM$Zcw0x0+DqI~8wqx_RXS>H{$no$m?ym}wTM#i{m
+zaOYjeW;t{E?&tfs=+EvP+{Zm|z|@jR<0{{w+{&+a8jvGXPcBbg@YPWba%F!#rx{ng
+zndTQ?FPMl3n??UxDFC*>){J?ztoVb|Ttjl=YsPpDx$$S7%n}<puaJXhzR*10DMvdh
+z@LcZLjOW~<W<-F|drQaM->Y=EQ?7k~GoHg7%|oDXM=72k78MM+zgL0PDKB}y8S$U*
+z{Zc%)I12DgE2=Zx-;14paqpMnS@wPbo=J{64(C8o5%MYi6R;oIrLTJ-9|CXwS+8ef
+z3N^6R{T4~zX=nH6zJZ-xCuJKuIdF49j9zK*-?ESaEL$mFxkTi@$&^v4DO$<wR2>Vx
+z?732cJdaJ@O=Cu=Xw-R@;R!IR=}(je4|?uL4V56Pv{@MEWmz83L9WW%xTe{ELdBqG
+zBytx~$Rx^bY;P;MAl&Ma3+l=wl~Hq7CTZ5OV2`KKD@0?y7#fZF{CA<3L1iiCEBRF}
+z>Dy+424vl=r~&XdgS09{YdNTWFTNp8)F-BkIG=oiT1=6UVfi<IEO%|`un0Dd*?5*#
+zhO5Q=@Ku^z{$ZgoTqV99?!Uj-TN{HMml}gix@W}g)+7p~5JZQ1M1>MXA%3;Vi*RqV
+z$!ay*`{~s;u||8UEASL+HX~{osb+g$SIhQ(*a>?=V^F6*O3(90>CAs#Q#sJy6}|t_
+z-=2u}lPbH^8068H;Lf*S3t4gRVNq0L5IZH>6+gx17);IRv4z+iEq`;$u3CErxRx#i
+zc~fg)6<-E9!i$h&OHl4j;IGQRUe|~CSLzHj<j=Xhawj-uy;x(iOIfp6^yKRF*BWFm
+z@>s9jIq_SfW}%!<zSG_A>g;YWUz2>tPj6sk_YJTRKF&W^<MS5jy)qVuP1JA0jk6yz
+z1;})6dC*;pj9t&SJx^;`My712VX|SOzGRx8;!;rT=5ReS48P{jhj?e_9hWwgZr`+Q
+zdF4*+Ux>=z$}Ll7c$ct8YH+IF#;*mccuG=FbjrUBRpXRz46;aBW%=TF$VoH?l_IZB
+zWtn5957#9fm4E2881DwMsMc&OLw4P4Br|8QN*}MZ#C;jW;#=NuR6cNff|959uZ&0U
+z<#G{O&BGb88CI~mimiWD6<eFhSepSgJ!?~fn*z%ZK3;Z$hYo(VPVqmo_0JQ}Am)1#
+z88usPrdMlgD(dT$dUsw4S+-icWC(`m5Lj-3`6@R1#acG|p%ZNO^(VXi1#-N>zkxN$
+zGNnDC&&ElYxFv?#^|&o=8H&<Bw*4d<TU*D*UPdmSSr4K+jHNW!Y{br5o9r`e#ff>)
+zz-)1)ut#_S@g1{$qnph>z|APcxfzAgZbrc&^#YG8mHyYk;|qQ*@x$CsJ`=D3+uUsD
+zF|WpEQe&2%1uv)8E|;%#NmZ@T^(b_2D|A_3))V<f-h4`}U7^&HPT|gXs+;ToEb-k_
+zjNeb{8NbKs8NW>bs<b?j(Y;Z>;$Pk~PcuGY-z`*O!U=icv?(qKyVivgCn|16XHe^{
+z)U;<zakwR*?HJkyD7E&}{?+TDa1Gx$P`J_cr4hf9Ee-PDIZB{mmOWkY6Wc2VV$Bd_
+zRtk%Y9jz~hB=d_yvXq=kj?X2`^VJG@KCi$$k?Sm5jfit>H4dL+(uFp#4ANe5B)k~X
+zIm(OdiaE}PyySfB^cO=s`n6s86*l+i|1<ZdpI~QKJ*k`U%fLMzsu&L$p~-xD=)dRT
+zu$S==c!BZYy1;lyZ(=<B0v<9#yLq61qjJ+-yOa^y!$THwGk*v%>7Em}4^P6aycayY
+z0r`dps1LFR7UT>DA!C5d`MJ$jn>>ryS$gdpJ4+)Q*jc)$p$<NINdxoD%Nv+J#Pf_7
+z`+3I8k@Jj~>ho;1AMw}|{s4U_`IC429+*@|<+QuqYvceYSw3dtIlhBJEwt>{u+GCM
+z#(5aUmpqK3%fl$X)adA;_(c~*^--DbQM9+t2>s8p?YYn+TgL?^+tel|+mR+Fo41L{
+z7TnBa>(k6Qxz)@#$-KxoS$vUkqP}ELm;pU2vYqSVB=D%b<W7%lGq83mAr&%d0(@7O
+zY)uy##js0^V$@|ualvIqao1%>55<-)in^n+<sL=mQ&)@c2xg<1a#2^uvi;D};%Kdd
+zrJTNJDPJ2(pvkWVzb?hAY`&3K*?eVJ*?g93Y`#6$90_&Z63AWinUBhcZabvYu$ME+
+zFNF>Gb#}0h5GfMv0;2UqnLrY<@>7AmsJ8%nu{kFLH-IJKM8~U$?gB6Ujp#!l_y?jY
+z;4osO@*jyJtBJCKI7A|k)SwR#P)qbOPz?+_LG%ldeG<Qu0~71e4#eWOg4X~q5Pyp3
+z5HP78rxIX1O*9{90^-gPl>h-hfnUH5IDmSfKYlTv46t9$j{)qL^K4)>um?B-`~Y}?
+zTY%U=G!PgI*nwYwlJi6tfhZ4X0jq&8fp+%ZNVEf}21GA-xB#9}Mxt~8gPMo}kAWB9
+zsc(rE0ILBvkawIY<~yRfz<S^~&;Z;8238U+1U3MBfF_{ud-R8%(|}i-p?e?r0v23F
+zKb&SxpraLYw-Mb&eRPzX`dlYU0di4)8yMRTy#c#`19(6F59l1YhWcG#?G2*P2h{Ww
+zu>2<K9pDdG3+w?(fV04Sd~X60f5tikvwwk3Wax}k<l$7*f@rco@(tO*THqEiD^Nwd
+zfXhMX6QUw}sETd?`GSge17Tq*nhP8PB73PQ4_E{&0S*Hv0e2tB(hqa>2hR^ePe6>7
+zl)sZGCq0C<z%LGmh7nZ`C;B9g=#de?Nbm^gMnN86J#ZJ8A5XLu_yGue6#am?zyhF&
+z(Ls4+G|_}HL?;2;SfT+5m=3=O#3Vv5fN>mtF$J1{fsf%m8GB$n_5<)Ca2J@ILbMKO
+z05<#{^$Ea4qWvfjpuGPtauSgTZS9aT_bJ%VBJj2l<!j&rI0BpjZUOm!BB})vmqJ!x
+zhh9zBfJ{+Mc02ZP0qhZ|1ZJ-$n!W~l1NIbx*6T!5*TU`qT<qyA&<;#mhrI^OeiQZu
+zEL@L0`WD`S8$iki%nw9wL>*WUd;;7Cnl=&b{vYfo!16Ze0);>&5V{$B0;_@jTZlUT
+z%zTNOO148UfVcxZg{!G}Cy{v<_y!IEQSTBh2i!pLZs-+#s!;0QBT5H00bXGJ9?14S
+zXgkms7*s?wcrW%lu=E4`7XZ)%m_Gz<AYvbA0kOr<2XN~ntl!7r0XP7peS$Rt3jac+
+zJ^&ek;)6tOCHVd+{Nf>^#XwXk))#mc*alPq9l(Uc;OVc>A@KHRu(1d=E%^exehEKu
+z6m7s(Cun_zeFd}wbIaf>fazbuUjbp?fCl_%A<F7<yjOrOPzW3cn!@4#BA_2&FVFzA
+z11SdhNr3%#&?F=10_%ZFpbh9FVLgGZfD>o};v-@AKot<*8#Lkb^H8n_Dxu#)F6=wB
+Ty<7#|>98+>v#~@WEkyqdyL9e;
+
+literal 0
+HcmV?d00001
+
+--
+1.9.1
+
diff --git a/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0005-usb-host-xhci-plat-add-support-for-the-R-Car-H3-xHCI.patch b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0005-usb-host-xhci-plat-add-support-for-the-R-Car-H3-xHCI.patch
new file mode 100644
index 0000000..564d4fe
--- /dev/null
+++ b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0005-usb-host-xhci-plat-add-support-for-the-R-Car-H3-xHCI.patch
@@ -0,0 +1,174 @@
+From 98d922b9bc891f33efd04b9cf8efde22d7949213 Mon Sep 17 00:00:00 2001
+From: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
+Date: Mon, 5 Oct 2015 21:05:56 +0900
+Subject: [PATCH] usb: host: xhci-plat: add support for the R-Car H3 xHCI
+ controllers
+
+This patch adds a firmware for the USB 3.0 host controllers of Renesas
+R-Car H3 SoC.
+This firmware is possible to use on R-Car H2 and M2. However, this
+version causes performance degradation on R-Car H2 and M2. So, we would
+like to keep the v1 firmware.
+
+Signed-off-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
+Signed-off-by: Kyle McMartin <kyle@kernel.org>
+---
+ firmware/WHENCE | 3 ++-
+ firmware/r8a779x_usb3_v2.dlmem | Bin 0 -> 9472 bytes
+ 2 files changed, 2 insertions(+), 1 deletion(-)
+ create mode 100644 r8a779x_usb3_v2.dlmem
+
+diff --git a/WHENCE b/WHENCE
+index c310c8b..2890465 100644
+--- a/firmware/WHENCE
++++ b/firmware/WHENCE
+@@ -853,9 +853,10 @@ Licence:
+
+ --------------------------------------------------------------------------
+
+-Driver: xhci-rcar -- Renesas R-Car H2/M2 USB 3.0 host controller driver
++Driver: xhci-rcar -- Renesas R-Car H2/M2/H3 USB 3.0 host controller driver
+
+ File: r8a779x_usb3_v1.dlmem
++File: r8a779x_usb3_v2.dlmem
+
+ Licence: Redistributable. See LICENCE.r8a779x_usb3 for details.
+
+diff --git a/firmware/r8a779x_usb3_v2.dlmem b/firmware/r8a779x_usb3_v2.dlmem
+new file mode 100644
+index 0000000000000000000000000000000000000000..7db71726f45943e7162d8e21ce7d80885bd79184
+GIT binary patch
+literal 9472
+zcmai44O~=J+J9z-JD0DE%!QeY<mgB<W~{cz`bjBB=$cutpn@Ny@*$Ox*>2nRww5Cf
+zN@k|M>6%}e4W?AC61Zi0qY280H9#4W6o(P~7+pbD-BR(s|8ob#ecSi9{C@v?&b{~C
+z=R9BMInQ~9k{Q48Mp8YozY7#;Wv$+l8J(kO$gcFK`_ZOEFQuL*UQN#vJD){1{m1>a
+z#63hw47M9&kJYa|MfAdqSbgMaq5w&B{~mpxk!V3iL!rymL0Y{>@tLiXt@SPOBxf;E
+zcrN-@$>@Gh+;6tE+g2p%i%3hF_}7TyWo5n2lj`MIuNA$69Hm`1`bX`>D8eZA?Kbgq
+zPF7Y6l~SbJx?OS~8$~25wUaezN&2Pq%=KaV&3%Xx^|@h0OR0eI{&rux^$L+LE>V9C
+zlwKs;N~3*{zLw3Mkf;yTXlXH-J2+0mjeR|kbgw0u$ZjwS#vr5h26Y8-14NzC_D8e*
+z{!tq0FXl>y%tZY-e6@&@F(=cH{(`K83a@2oh;bqF!GhIfkz)0<Rne_7<njY0t^Ts|
+zhG4y6ku)Q8T!HwM$QhSHqJh#xL#dfP*UktIcZrpT?8Ko`ut`HYqc!6}$(#BGm&@BE
+z=n?d;;7=WsF;w!;yh5GZgZHyCgJ&)i_Y0nj>jkUCK~pC=e_PiTGL`W)Oz(cUS2w@3
+zYYJa0Xv7q$PH?o>30b}t&L!md>V!_A+-O%O66|BPD|;ia3wFh%slqiuTh7^)`8vCD
+zAhL?nz;;^6kys~mjp;lcqbEa2iFOQo+Gx7oz&K!Y%E~6#w^|*21$PPkWM#$OC#T?z
+zqXX>9&VT{&Un+<0$jZXI?<$}#!CfF;G|I}+WZ1?{MoYSKb+SQYWRfyJvu@Y8kF6w(
+z{M?-@bp*;v?A`C}<oBoBTEExHO4!|ZxtP}-Fi78O)q<xBW>0D-X1Sv6;WVZD+tE6|
+zFM3wa*D%RmF>2CMGHM0CbS-g=52}Al+yjmnuXU;o3dQ#Y>vnP<lbE*#r`Q!QH9RjX
+z(UYvw#S;#(u6y)4%sHsPRnoXO!Ottd)VdkHEszU78IX&<fBYU!Q}35}9c<0!ImvnI
+z4q|0A^|!U}FG$okgHN_%*t<O=JaxViOe4$0pKT85AAugjL7T>BgP&`gE2+U~j#~k~
+zb~VDnLM*)e;qw}-p_l+IErHdmxyqHFxr>GIKIUcGv}GdZPxD<o(Z;;x=fKLhL*1Ub
+zCd@wDVpm+cB)t-+dY8J!7lH~~<FfKQNY`xa@dGFPEK59SbV##WJ%&y}Ryvby?a$j2
+z^_%epc;DW~eQW?x3SX!CbD?;Vt9+o;ZCBP)!vtIV=a8~e9qCDRVebA>#bdFaTA>Sp
+zMUmzRTl-fSb3q-$e7krkdtanRkf|{&GQFYpr>Ol^YTs>@m7i3ZHSvd)C-1N?mVu(5
+z+a~yzpR3CELcz%(b-nk>n$G#XLsqgO>mn1ARgFRIeIeINc&m$ht=p3d?v7n;l9e(O
+zi!QcyGm{^0n7*u%KfbiUj*N?C(8HKkhxirN+*+#Y*1-{Vv|k6SqBe}RwKqU&Pd9a2
+zyJ2~v{<1p8DgBdK9$!zw3M<n(aGxy}*!<6{&9ag|A=o1;<A&MVTR<a5&-k#lUq$~R
+zwJ$5L#(P>iq3z@eEJn-9wIQ(fJu=S3xLz6aaK~&9kM<!pag{vz;G-tCc4r!s(!(j(
+zFbkTBmU^Y%)IIAbg^7A+cb{pmw41W5JbBOPZ`2Vzad?0T%9%VOcL?G)`dyq6ar6dV
+z<cvIP-JDTxED+ZT0}#hKH`@jMf3|iF=7{9|60`l`G9tVd`@`VwX9MwmxZ3x7@IX4O
+z)ZDU|YI*C8&-&OS?dgiLY<j`;<&hRsKeFD43fvbFkhXuCPArZ1G(t1GY)<*KWto=r
+zBUCWmGIy<Jd8TD<E;%v_r>_WD8DL4jNkw=*MDs@GDzuUGCdO9iR!`^BHc#6!O`p9r
+zCurfe=eEyzZ`zJ&@8<;1-Z{rIH=I70qn+)XQ#@x^#D@{PBlgTGne$P^#}S`I?49<P
+zIZ66NHR3{UPm0m9QRzrC6qrae0U8gBVr$9P{sg=uIMDBJyQBWqU#)n~Z0SVA$P!m!
+zFX!A_#qW%WMS-gJ#2)PtjTfI5H+K0)?B`PWe<1P(+TfM&s!Ut2bzfHJV&jt1NjKTx
+z0xyH2ao<%Swsf!abzK{T-Y<5mUoZ>zt|YmeGg+BA$dk$<PxByIiF%;-tLD33+4+H3
+zOJNUsQcE%Jcx;bWZ0*C4f#`#n?0#R)jrUu&Wii#W$TlNTjgUv<blT?OI;&Lf(_X0d
+zZT7iLiR8WL8gbe*fV?9^sdAWJDtl+p$bIiLid)4j@v6C=%R$6<8H>$h)JU3-S(YHq
+z`s3=W>RpLmQCxzizF2tpd=Mq-*Q!t1emaiE`%b4PQcA`FUqe+AasgP-r!&qr-aG%Q
+z!&&t=Ia~V}Sg=Nw0xNMbi$(g5+?l$F#@SnEH;V6y2ccDs9omkYY^b-fezmw+)J}D!
+zRi?&f;7uOcr=%8`L-ZX=9d@%z8Q5p%jc9!wdx3Ve*A$8f@I+yy!Ta0q`lQ4s>PH7N
+zjdg2^9??@wNs0A_ljdJ==vdBBfSh5SP%1PaqHj)aK$b9^igA6Ju0#LllB+l^qH|N2
+zBe9se#?*8D#<2SXVGd~zAv&FA@q|g?Y%eB8Z@n=`rCJPnrbpSe@=-=9ETxLm;mfsQ
+zPL)!DfQ;ieEaM2k)4Z@A4jt_ulJoqBWDeKr|E{z=kxUU}qQ2CR22c#yXfXYX9-?71
+zoJLUsjin@dlpdpr@R`m>i^qa~%JmV*PE)Ez*p*GR0oUWyHq@>}YRYllttrISqiL|&
+zl{?yET=#L;ktH4Hs^IzQ&u+jqc3~UxrvN?6qWbF#;qkljnRYt!nKav<XVT;?s^S>m
+zF2RxbA@rh3lftA4#M4cJ6HjlCS<hsg!Jb-1hJ!;p@(u;-^Fw-8{K%Y4!4yjOQ5c2e
+zDpDk_CS;?pq{w{i1exCm8~|b_%6u}geIgex^HYVT-4wo8DVRYc95hTS1v5o~Lcnij
+zz8RSEn9RRAN#@5*mihHS0q&PPt_PLiZYo;+d8KYbGW0tUvzwvgfpkB#`~W=&JrAW{
+zL({*Z5qLX_#?Zsi_e4qr#$%SE$7Mcmip)nofmwhi;GHLBKKj38e)?3IzXJ?UmHDGU
+zbehZ$o+k4Pr^|dJpiP(gk-!e15g0yG=AE;6aJD$KN4_^z`T9b>Fz^=+h(IJ}o;X|P
+zD}l^8GVcOnGi5&IDQKRL@BTUqyKjLpN4(0_3%R0~gU$FMPuY1`fge6E2qObAas}VA
+z*fGiwXf-(s^cSjpu8VBPCNI@no1Oe}WH8QApYpOI=eI48l{<UPl7>!-+r(UPvvB&K
+zdh&AH&hw<HZ}h(B{X!Cm(X##UH>~h7K}*fzd!lyqf0G8g+{d&vVw=uWS77tBGzn(O
+zh!`>b(rIzK__gS|IzZH5-zzruj5KG2P<8qM8lUEqDrla#Ey8-EjMs2FuJX^*!z%ks
+z4|_OKph|vvm=1C8L*nB$#ebi$CE=R{<idg0ksp)Altj7?P~~jWw&m7w)5C(3LMCzW
+z<>TB$HSP>ly(kNNYo{?+TxaVv=84P9USR`PLjp2@zFk$~1~FN5nRJvQMM{NO4e=Vb
+z4lMIneAuO7>wvPVxL|nv!C-%!M(#6jKX1L_<gJKPA>o_U$W@c-G3*qy`ZLN^E*3gO
+zbh9TT9|?)CdWuE5<W%nr*GPpz!oL@7=gp2S&|9LuGmJ&yl#KAeRTTV;pw}n|IWE3@
+zLe)YcywVUOy<6Zi@suTYj?EE$BZ9*VMOU7VsuATiv%T{wDEH~Uk}Eq@9s8Iscb-{#
+z+`vw_cO`pScUMj(<rTx`uF7YJ-lba#|0xkFvxZ2I`I2YVb9z<RRYuFm2s)hD2kY7N
+zT!Y|0qwMJ8&zzVAo#cpE9>G>R%LA=*ojfv9oGZq(E=T*(D16E1FLX$Tz$%;{d*sLw
+zJ3034a-BwWL=+?P_m!*}W{I62V;BdiJ)GmL!}Z#wL2zUkCC0zcaFhE8d@=s8A{Q>D
+zBJ8Esr}z8nvo~jlniM5V{1h^+H$E$N3eSo4!t-J&tkSL&2wKzM@%C$O7WTs}PdGBL
+zCgwT{g2SuC?+sbmrCfIQLBYQR724ONoy2KBhu2_-ux31eDJKIvUdD@;bRD`Gu;zW-
+z44xCFRj2D{Rl1$tnie)E1|z<o>!IpJ14x*)X3p`nchlaU7K#ikEA1@zY?_M;1{XfA
+z0ABs=xIWatSrhmBY7(|4=;Dyy25_q8Cm}y#vGd=p?XtNtUo#JpV15YJ_K?7y81nx|
+z*>Up`RkLJ%FK`q{$d>upKx1|&DEN3kg)E#1ONDIF#Wf&;B;_LJED-R%`kwb*F1tIz
+zOj;oG`aGFmloy6EyLda_63$NiRldrLukmjbyvDx;tOGUx?*iL^_Y3r%mBcq<k9^K7
+z6&Bn#x?h|>%2Z>8W#*UTx+Wj~6b^ce`Nl02Si6~mj_5sGsUK*w=;gX-j-v$2L<_t!
+zUf(b7zR}T1eJ5dm%I_D)qL%;OPjwaB(H61z)pt^K5}S?96Z1kFuIVqZ*)m_iY{*S|
+zx$ohy|6<1B*ei|#Hiw^{4>2KnF{9T*D}OPgb#yVKMKAg}&myLYN^tAsTo(sR9Pu;X
+zB<)mfTy5H>wBT_XT1ji;vu5ucnlsyF&YfK{q6v{U3!2Rl3xoyYPGl&7@P_EZ>o(Tj
+zE-Y8u<`vh??B2Pu-0c6Nlv^M&iRKp-L(+vs*M)z5{!9_$ZcP#6uB@o13dC}ldpZ2J
+zJpgf)(Wy~KzW&B*8JwC&t>Rl0%g95}bmi*c9kTMx>YNN#g^<w(pgn|Ek5$M<96&#?
+zyI+caFrKxd4MlqjZ5Y}nwBg-jj-!t>y@U=@DODRUe9iO~0PA+lZ+yBU$8+tBMH>Za
+zC$BblWQF_ATeN30baZweM?T4-T`={>mP;8H?J0vR_3S*Ja>Fm-X?A0^;cP|_<#~MS
+z*RGQ|eXnNUnmc}MnO}QW3ZbaDoJQ{nixzb;KV^(On<0R5pKi)cCmH1*Rmz4Q%C(Gg
+z1m!jQ@NHC_t4>zL)ohlglea(L!}a^@*8V-*ef!K;l4yMOyOdk~)ixulX4<KhsSCe6
+ztV8weucvk6OE%CmC07e4Bg1Cdzg`M}FEE?2sFszme}-#lPD0&SuQ4~F>4_|{h4TtI
+zxE2U)6HuLTR^giO+<@zo#cjv{gLjpWy?0dk2wAE4U<0l(&bFb@x3e7Ajm3pS?;TZW
+zla<^L+K~S>eo&69!&!)HQgMUv-cfA-vwl#H>)sCvagB2}aM%Zmi&0_m?|=izA$`>c
+z6%s`A&-y$YSEPfleq@ylT@H4l9uU~oy;F9uodYKq<mji2EJs&sf)&fei|2{_Cz%Q=
+zH}_L(JqN!DzTml7ipq~&*+FARX=uzDR`W5LwDc#+LIgeigN{m3XWAf)_cBVLgX)#H
+zWo4Uxhf2oCD4Y(XQCn0x*xFXBLpbN7I@DcTs-U*++S252f<2xVuh0+k#nB^}&wmzL
+z0V+!{U+FKZOW(E;G@yiMMh`-~iPdY6t>vKiz4)d$*^rbjVt?`pT5+O;n#;fWW7TZy
+z4Xa?+Sxl#BS%g+Bh*+-6<sTG^A~fO~5v&^7LXP&9Am{m(AanTB;uc#n1yTsILj$rx
+ziK3Ce+Lc8(x7ih~maYAi+Uu~<+S)2yscr+ZmeE?a_V3iOwST+bk=PQ{<<HXd{8>7S
+zpG_Jko_A;OfAl|3!gH6#A+-c~45c{peXNJ9;D}{WEkSIT=v3nrn_~#IVZ=sabDa8{
+ztn90IWPoewY>+p#9$s-M$Qe<Ls+<3`5B_TW_PRRMZ>h`BkiQD^hg-pMYs5OUL(0lz
+z*^{fw-)mO9sBHb=*0Em`wF#Ac%B`N~uCAWvl`B(j`ROG@^_&2U5aaxFwLEW?-mhSJ
+z*kr?IoHz%fQh?g$#{1p%sNwa#+xe7^)o3b)8K)X28%k&RDXsy<9uC)_!thJ}e8_jU
+z-E!$e>E?Co#y{Mu{|iy&+qo6$4DS)vNF8?7oA~`elR(MZ$+B{Jm=?QyOORE{swfb@
+zLrtP3s2r7cs+c`?=7{j*!^)v9tLb(i%W5sA3e?*zCbDowoAk*t>&QbvEWhQAhn4L&
+zC#jWdzhyiIFPDqVY613;4e)}OYMA{G)-c<QgKZ+~dTmpRlLD(4K2~vzhYo&Wr@=ok
+z`{#*G$oZZ?jct8jrdL~gD*D^izW)r%>KD({J0xQ;B8R|g3oKT#*^k$=*>@gevoAT`
+z6E9Hp4gM9pNl_^6aYHtCx}=S9)M;3cb{Ja!x1Qtd+lmJEtsB*O<~_*n@GYge<|232
+z+ZCU26L!q~M&^slgq^|*$nTi%2e{enk#0u8>Sh#T-Hd`$>H{8^spGGL#~1us;$z%0
+zKM7a_6uH^TV^NLGq{S>h3tmpEe_grQEtRa&J*v{ZpweYy*+^6z`LGjO{Zh3TcLHa=
+z6Fpr2XNi3$7{6N^8NX$Xj9;dIO<JDF=z1HM{>%NOlZ;RJ_Z6x#V~5;+(mXN<me_|D
+zJ1R~_N6_o5_O79aQv#lqp*KkFc~1JR*Gr)Z?>JEKcE4%C?`BJa{AZ3*XqeSgXa306
+zN}*Uc6qS{tk`ib8iy<le;*c!0rjp}x2@8DnLY~hnut>D;6tjl*G_!{DG?VV;X;wkn
+zMb5+*L%POzQC+c&w4+j)j+Opmh{v$1yS~Eae&qkmZT}H|cFB{v9={db<)Mc0kP(`~
+zr-%M~9-Lmr!woOvVc%KCLrN>-;SPAn2<_p40uC$nw;fVOXfF?0h`zrMF^4}VZW)n`
+zQ+Xdmcq8f!_fdaT4Xmgc#G+y#D^pKzu-TPNVtZ-RX||W@o7rBP+1!AboZHMIbAB_^
+z2c2QO{O%0nW%n7zi+qMzyPwCA_<QI>t)IN>kHDlktR&s;v5^y;Wciqn=lJ#u_0Y0k
+z!*^7QRu7{%-@_>G^Dv6@Tb#WVzv!l@J*-^0)kD$IJ}dM;%eMAxuWYSnnQY0eOt#&v
+zOt#uqCfiS~Ot#QACfm6-#>u2}jFY+N7$+U)9Er1_XH~Y--JAp-R&wuh;shs5wtC3c
+zA|Q5k%T|AmQM`SQQ4GAmD9*gVD6YQX?4@|6n_~E3MZ8Oq#nctzyMo1Jp<MK}@oYV`
+zUU9ZJz*A1%^^~uSrO@P8f?t<(iOo0Y5}R-DB{rXUna#KMvNN%vM*^jLKFeWc=S`<{
+z68_Sp{&q;zj9+YrgcEW_qU}IG1JP_C8I}6!z%KN!0K2d}rvlf2mm`Rd)DYbUe)l(`
+z-9YeBq8i``vZTr%h@xtVvVlp+MINfd7$BgY=p~>Q7=DcC4v>8uznue<8}J;6$L|NP
+z0$w2D1W_3<r4joQU^+?k4A2UUY$7TJ0)7O)fCF#>jX(^3MV|_=U(>$<*stl?zzSd|
+za1b~Oc!8e)v6*NvFb;44cYx9}MCX8L4`=}^fI~nhyKf=d3e*Ck7d)H=&uF92I)T_$
+zqQGy!3-IK(L<@lxfE&m=LKOEM(R^SHa0F-uZUcj>iSmK9z)qkQDEc1bq31N<l{V<!
+z2fl!XmoNtVSuJp*9dmaOg+^=XNud8#qKUxE=<fo?bwY2zcEE-EBmaQTfjj7j-KV8h
+z*NFO~oe#Wz9dvGhKVTKG6DS2v0k7iy4It@fq65I(JJ5*&osot-oQAF-pNv7pAsbi)
+z`~+kMYG^xfAqZnaG~@`?&^4ey(9jMbEKEc5fifVfkB0JqMZn9z0pK{`?hpSQh`C~j
+zF5eG50dY1`|Bj=b@&Ig!-zLh26IG8O+B=fyp;5qS@CbyDfjqz(;5P6~0?{VmC=m8A
+z#sTwzg}@C)2kpT};Jagqjsx~_M1vAxYy2V*mjt~4rt$a{6=($pKZ^Sltbqww55R8V
+zHZXM}(Q2R>So>S_Cjpa*K1RC_?Y)0dQ;0lx)(IJNpM?J`0&n?fUj-k)L7)lv2`Kmz
+zQ9Y2f1hO(1v~&l^7q#SYU=0_-RzNi{cLmYRmCzfovk0`_Aez1keh1)aPp5!RV9IK&
+zHDK;r@Gl^L4c6$}xCgEQ6W3yXpx-+5fi=Kh;3m+zo@mGazy^Tz9nb}efNCIg1Na11
+z03UCJe*aAL8Tc&S0=)p@R;=F$EtPB|vTO(6Kp7DI9?|Q78wlP3AH$d$wBhd)r332$
+zFR*4OWcvWLofr$m784EGh4l_B`4ImZ0JH*@-JlIb?tzVf_!8&?_~|3q?-S?+*axKT
+zg^hrszYuBnK}MitKT$_1-hYa?SVpuMh%SeHfmeXdKn-vMm~;R<{S`U{-uVnRjnvZ1
+zUx3#`h!cnL4A>-t)|XgUKqoN20<i*^`4!?75cW0ni8xw>wzd-YRiFzL0Y`w=2*kfg
+z=m*#ZGy|Q$L?hxP!2V-siV1XqH9$4c0rZz(Phb-u1Fb+p6#O2j0TTLxCSrab+BHBm
+Z^jqe_y2G=VYM{GttV`fjJa~cL{uf;D@)rOA
+
+literal 0
+HcmV?d00001
+
+--
+1.9.1
+
diff --git a/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0006-spi-spi-gpio-fix-set-CPOL-default-inverted.patch b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0006-spi-spi-gpio-fix-set-CPOL-default-inverted.patch
new file mode 100644
index 0000000..d7b42f3
--- /dev/null
+++ b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0006-spi-spi-gpio-fix-set-CPOL-default-inverted.patch
@@ -0,0 +1,30 @@
+From db37427756bc9e42723f58067a3f387a2861fbbb Mon Sep 17 00:00:00 2001
+From: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+Date: Sun, 29 May 2016 23:18:49 +0300
+Subject: [PATCH] spi: spi-gpio: set CPOL default inverted
+
+Workaround:
+ Set default value at probe to 1 due to issue with H3ULCB.HAD FPGA
+ ethernet switch
+
+Signed-off-by: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+---
+ drivers/spi/spi-gpio.c | 10 +++++-----
+ 1 file changed, 5 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/spi/spi-gpio.c b/drivers/spi/spi-gpio.c
+index 1c34c93..428417d 100644
+--- a/drivers/spi/spi-gpio.c
++++ b/drivers/spi/spi-gpio.c
+@@ -289,7 +289,7 @@ static int spi_gpio_alloc(unsigned pin, const char *label, bool is_in)
+ if (is_in)
+ value = gpio_direction_input(pin);
+ else
+- value = gpio_direction_output(pin, 0);
++ value = gpio_direction_output(pin, 1);
+ }
+ return value;
+ }
+--
+1.9.1
+
diff --git a/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0008-arm64-do-not-set-dma-masks-that-device-connection-ca.patch b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0008-arm64-do-not-set-dma-masks-that-device-connection-ca.patch
new file mode 100644
index 0000000..14612cd
--- /dev/null
+++ b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0008-arm64-do-not-set-dma-masks-that-device-connection-ca.patch
@@ -0,0 +1,132 @@
+From e3218ab51b0bf3f193a9f64e5c0dafe74e292ad2 Mon Sep 17 00:00:00 2001
+From: Nikita Yushchenko <nikita.yoush@cogentembedded.com>
+Date: Fri, 6 Jan 2017 17:12:49 +0300
+Subject: [PATCH] arm64: do not set dma masks that device connection can't
+ handle
+
+It is possible that device is capable of 64-bit DMA addresses, and
+device driver tries to set wide DMA mask, but bridge or bus used to
+connect device to the system can't handle wide addresses.
+
+With swiotlb, memory above 4G still can be used by drivers for streaming
+DMA, but *dev->mask and dev->dma_coherent_mask must still keep values
+that hardware handles physically.
+
+This patch enforces that. Based on original version by
+Arnd Bergmann <arnd@arndb.de>, extended with coherent mask hadnling.
+
+Signed-off-by: Nikita Yushchenko <nikita.yoush@cogentembedded.com>
+CC: Arnd Bergmann <arnd@arndb.de>
+---
+ arch/arm64/Kconfig | 3 +++
+ arch/arm64/include/asm/device.h | 1 +
+ arch/arm64/mm/dma-mapping.c | 51 +++++++++++++++++++++++++++++++++++++++++
+ 3 files changed, 55 insertions(+)
+
+diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
+index 76747d92bc72..9513d2eb5c8a 100644
+--- a/arch/arm64/Kconfig
++++ b/arch/arm64/Kconfig
+@@ -191,6 +191,9 @@ config NEED_DMA_MAP_STATE
+ config NEED_SG_DMA_LENGTH
+ def_bool y
+
++config ARCH_HAS_DMA_SET_COHERENT_MASK
++ def_bool y
++
+ config SMP
+ def_bool y
+
+diff --git a/arch/arm64/include/asm/device.h b/arch/arm64/include/asm/device.h
+index 243ef256b8c9..a57e7bb10e71 100644
+--- a/arch/arm64/include/asm/device.h
++++ b/arch/arm64/include/asm/device.h
+@@ -22,6 +22,7 @@ struct dev_archdata {
+ void *iommu; /* private IOMMU data */
+ #endif
+ bool dma_coherent;
++ u64 parent_dma_mask;
+ };
+
+ struct pdev_archdata {
+diff --git a/arch/arm64/mm/dma-mapping.c b/arch/arm64/mm/dma-mapping.c
+index 46a4157adc17..04b9bce96f1b 100644
+--- a/arch/arm64/mm/dma-mapping.c
++++ b/arch/arm64/mm/dma-mapping.c
+@@ -351,6 +351,30 @@ static int __swiotlb_dma_supported(struct device *hwdev, u64 mask)
+ return 1;
+ }
+
++static int __swiotlb_set_dma_mask(struct device *dev, u64 mask)
++{
++ /* device is not DMA capable */
++ if (!dev->dma_mask)
++ return -EIO;
++
++ /* mask is below swiotlb bounce buffer, so fail */
++ if (!swiotlb_dma_supported(dev, mask))
++ return -EIO;
++
++ /*
++ * because of the swiotlb, we can return success for
++ * larger masks, but need to ensure that bounce buffers
++ * are used above parent_dma_mask, so set that as
++ * the effective mask.
++ */
++ if (mask > dev->archdata.parent_dma_mask)
++ mask = dev->archdata.parent_dma_mask;
++
++ *dev->dma_mask = mask;
++
++ return 0;
++}
++
+ static struct dma_map_ops swiotlb_dma_ops = {
+ .alloc = __dma_alloc,
+ .free = __dma_free,
+@@ -366,8 +390,23 @@ static struct dma_map_ops swiotlb_dma_ops = {
+ .sync_sg_for_device = __swiotlb_sync_sg_for_device,
+ .dma_supported = __swiotlb_dma_supported,
+ .mapping_error = swiotlb_dma_mapping_error,
++ .set_dma_mask = __swiotlb_set_dma_mask,
+ };
+
++int dma_set_coherent_mask(struct device *dev, u64 mask)
++{
++ if (!dma_supported(dev, mask))
++ return -EIO;
++
++ if (get_dma_ops(dev) == &swiotlb_dma_ops &&
++ mask > dev->archdata.parent_dma_mask)
++ mask = dev->archdata.parent_dma_mask;
++
++ dev->coherent_dma_mask = mask;
++ return 0;
++}
++EXPORT_SYMBOL(dma_set_coherent_mask);
++
+ static int __init atomic_pool_init(void)
+ {
+ pgprot_t prot = __pgprot(PROT_NORMAL_NC);
+@@ -971,6 +1010,18 @@ void arch_setup_dma_ops(struct device *dev, u64 dma_base, u64 size,
+ if (!dev->archdata.dma_ops)
+ dev->archdata.dma_ops = &swiotlb_dma_ops;
+
++ /*
++ * we don't yet support buses that have a non-zero mapping.
++ * Let's hope we won't need it
++ */
++ WARN_ON(dma_base != 0);
++
++ /*
++ * Whatever the parent bus can set. A device must not set
++ * a DMA mask larger than this.
++ */
++ dev->archdata.parent_dma_mask = size - 1;
++
+ dev->archdata.dma_coherent = coherent;
+ __iommu_setup_dma_ops(dev, dma_base, size, iommu);
+ }
+--
+2.11.0
+
diff --git a/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0009-swiotlb-ensure-that-page-sized-mappings-are-page-ali.patch b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0009-swiotlb-ensure-that-page-sized-mappings-are-page-ali.patch
new file mode 100644
index 0000000..cccc80d
--- /dev/null
+++ b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0009-swiotlb-ensure-that-page-sized-mappings-are-page-ali.patch
@@ -0,0 +1,38 @@
+From c92eeec67eb96b79fe3d01b0045789de52fd5af3 Mon Sep 17 00:00:00 2001
+From: Nikita Yushchenko <nikita.yoush@cogentembedded.com>
+Date: Tue, 3 Jan 2017 14:24:58 +0300
+Subject: [PATCH] swiotlb: ensure that page-sized mappings are page-aligned
+
+Some drivers (e.g. nvme) do depend on page mappings to be page
+aligned.
+
+Swiotlb already enforces such alignment for mappings greater than page,
+extend that to page-sized mappings as well.
+
+Signed-off-by: Nikita Yushchenko <nikita.yoush@cogentembedded.com>
+---
+ lib/swiotlb.c | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/lib/swiotlb.c b/lib/swiotlb.c
+index 76f29ecba8f4..771234d050c7 100644
+--- a/lib/swiotlb.c
++++ b/lib/swiotlb.c
+@@ -452,11 +452,11 @@ phys_addr_t swiotlb_tbl_map_single(struct device *hwdev,
+ : 1UL << (BITS_PER_LONG - IO_TLB_SHIFT);
+
+ /*
+- * For mappings greater than a page, we limit the stride (and
+- * hence alignment) to a page size.
++ * For mappings greater than or equal to a page, we limit the stride
++ * (and hence alignment) to a page size.
+ */
+ nslots = ALIGN(size, 1 << IO_TLB_SHIFT) >> IO_TLB_SHIFT;
+- if (size > PAGE_SIZE)
++ if (size >= PAGE_SIZE)
+ stride = (1 << (PAGE_SHIFT - IO_TLB_SHIFT));
+ else
+ stride = 1;
+--
+2.11.0
+
diff --git a/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0010-can-rcar_can-add-enable-and-standby-control-pins.patch b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0010-can-rcar_can-add-enable-and-standby-control-pins.patch
new file mode 100644
index 0000000..38d8e09
--- /dev/null
+++ b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0010-can-rcar_can-add-enable-and-standby-control-pins.patch
@@ -0,0 +1,156 @@
+From 5d5eef59a48e3b8e0f67c2ab0963d380c7a7399d Mon Sep 17 00:00:00 2001
+From: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+Date: Mon, 2 May 2016 22:05:53 +0300
+Subject: [PATCH] can: rcar_can: add enable and standby control pins
+
+Add enable and standby can transceiver control pins
+
+Signed-off-by: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+---
+ .../devicetree/bindings/net/can/rcar_can.txt | 4 ++
+ drivers/net/can/rcar/rcar_can.c | 58 +++++++++++++++++-----
+ include/linux/can/platform/rcar_can.h | 2 +
+ 3 files changed, 51 insertions(+), 13 deletions(-)
+
+diff --git a/Documentation/devicetree/bindings/net/can/rcar_can.txt b/Documentation/devicetree/bindings/net/can/rcar_can.txt
+index 8d40ab2..9293cf8 100644
+--- a/Documentation/devicetree/bindings/net/can/rcar_can.txt
++++ b/Documentation/devicetree/bindings/net/can/rcar_can.txt
+@@ -38,6 +38,7 @@ Optional properties:
+ <0x0> (default) : Peripheral clock (clkp1)
+ <0x1> : Peripheral clock (clkp2)
+ <0x3> : Externally input clock
++- gpios: GPIO used for controlling the enable pin and standby pin
+
+ Example
+ -------
+@@ -59,5 +60,8 @@ Board specific .dts file:
+ &can0 {
+ pinctrl-0 = <&can0_pins>;
+ pinctrl-names = "default";
++ gpios = <&gpio5 29 GPIO_ACTIVE_HIGH /* enable */
++ &gpio5 30 GPIO_ACTIVE_LOW /* standby */
++ >;
+ status = "okay";
+ };
+diff --git a/drivers/net/can/rcar/rcar_can.c b/drivers/net/can/rcar/rcar_can.c
+index 788459f..887ca37 100644
+--- a/drivers/net/can/rcar/rcar_can.c
++++ b/drivers/net/can/rcar/rcar_can.c
+@@ -21,6 +21,7 @@
+ #include <linux/clk.h>
+ #include <linux/can/platform/rcar_can.h>
+ #include <linux/of.h>
++#include <linux/of_gpio.h>
+
+ #define RCAR_CAN_DRV_NAME "rcar_can"
+
+@@ -94,6 +95,8 @@ struct rcar_can_priv {
+ u32 tx_tail;
+ u8 clock_select;
+ u8 ier;
++ unsigned int enable_pin; /* transceiver enable */
++ unsigned int standby_pin; /* transceiver standby */
+ };
+
+ static const struct can_bittiming_const rcar_can_bittiming_const = {
+@@ -505,6 +508,10 @@ static int rcar_can_open(struct net_device *ndev)
+ struct rcar_can_priv *priv = netdev_priv(ndev);
+ int err;
+
++ /* transceiver normal mode */
++ if (gpio_is_valid(priv->standby_pin))
++ gpio_set_value(priv->standby_pin, 1);
++
+ err = clk_prepare_enable(priv->clk);
+ if (err) {
+ netdev_err(ndev,
+@@ -581,6 +588,9 @@ static int rcar_can_close(struct net_device *ndev)
+ clk_disable_unprepare(priv->clk);
+ close_candev(ndev);
+ can_led_event(ndev, CAN_LED_EVENT_STOP);
++ /* transceiver stanby mode */
++ if (gpio_is_valid(priv->standby_pin))
++ gpio_set_value(priv->standby_pin, 0);
+ return 0;
+ }
+
+@@ -743,20 +753,9 @@ static int rcar_can_probe(struct platform_device *pdev)
+ struct resource *mem;
+ void __iomem *addr;
+ u32 clock_select = CLKR_CLKP1;
+- int err = -ENODEV;
++ int err = -ENODEV, ret;
+ int irq;
+-
+- if (pdev->dev.of_node) {
+- of_property_read_u32(pdev->dev.of_node,
+- "renesas,can-clock-select", &clock_select);
+- } else {
+- pdata = dev_get_platdata(&pdev->dev);
+- if (!pdata) {
+- dev_err(&pdev->dev, "No platform data provided!\n");
+- goto fail;
+- }
+- clock_select = pdata->clock_select;
+- }
++ enum of_gpio_flags enable_flags, standby_flags;
+
+ irq = platform_get_irq(pdev, 0);
+ if (irq < 0) {
+@@ -826,6 +825,39 @@ static int rcar_can_probe(struct platform_device *pdev)
+
+ devm_can_led_init(ndev);
+
++ if (pdev->dev.of_node) {
++ of_property_read_u32(pdev->dev.of_node,
++ "renesas,can-clock-select", &clock_select);
++ priv->enable_pin = of_get_gpio_flags(pdev->dev.of_node, 0, &enable_flags);
++ priv->standby_pin = of_get_gpio_flags(pdev->dev.of_node, 1, &standby_flags);
++ } else {
++ pdata = dev_get_platdata(&pdev->dev);
++ if (!pdata) {
++ dev_err(&pdev->dev, "No platform data provided!\n");
++ goto fail;
++ }
++ clock_select = pdata->clock_select;
++ priv->enable_pin = pdata->enable_pin;
++ priv->standby_pin = pdata->standby_pin;
++ }
++
++ if (gpio_is_valid(priv->enable_pin)) {
++ int val = enable_flags & OF_GPIO_ACTIVE_LOW ?
++ GPIOF_OUT_INIT_LOW : GPIOF_OUT_INIT_HIGH;
++ ret = devm_gpio_request_one(&pdev->dev, priv->enable_pin, val, "enable");
++ if (ret)
++ dev_info(&pdev->dev, "Failed to request enable pin\n");
++ }
++
++ if (gpio_is_valid(priv->standby_pin)) {
++ int val = standby_flags & OF_GPIO_ACTIVE_LOW ?
++ GPIOF_OUT_INIT_LOW : GPIOF_OUT_INIT_HIGH;
++ /* transceiver standby mode */
++ ret = devm_gpio_request_one(&pdev->dev, priv->standby_pin, val, "standby");
++ if (ret)
++ dev_info(&pdev->dev, "Failed to request standby pin\n");
++ }
++
+ dev_info(&pdev->dev, "device registered (regs @ %p, IRQ%d)\n",
+ priv->regs, ndev->irq);
+
+diff --git a/include/linux/can/platform/rcar_can.h b/include/linux/can/platform/rcar_can.h
+index 0f4a2f3..7ef810d 100644
+--- a/include/linux/can/platform/rcar_can.h
++++ b/include/linux/can/platform/rcar_can.h
+@@ -12,6 +12,8 @@ enum CLKR {
+
+ struct rcar_can_platform_data {
+ enum CLKR clock_select; /* Clock source select */
++ unsigned int enable_pin;
++ unsigned int standby_pin;
+ };
+
+ #endif /* !_CAN_PLATFORM_RCAR_CAN_H_ */
+--
+1.9.1
+
diff --git a/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0011-can-rcar_canfd-add-enable-and-standby-control-pins.patch b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0011-can-rcar_canfd-add-enable-and-standby-control-pins.patch
new file mode 100644
index 0000000..60834a9
--- /dev/null
+++ b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0011-can-rcar_canfd-add-enable-and-standby-control-pins.patch
@@ -0,0 +1,119 @@
+From 0f55d888c83aed7ea5a10761edaff52de8dc06a1 Mon Sep 17 00:00:00 2001
+From: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+Date: Mon, 30 May 2016 01:51:47 +0300
+Subject: [PATCH] can: rcar_canfd: add enable and standby control pins
+
+Add enable and standby can transceiver control pins
+
+Signed-off-by: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+---
+ .../devicetree/bindings/net/can/rcar_canfd.txt | 5 +++
+ drivers/net/can/rcar/rcar_canfd.c | 48 ++++++++++++++++++----
+ 2 files changed, 44 insertions(+), 9 deletions(-)
+
+diff --git a/Documentation/devicetree/bindings/net/can/rcar_canfd.txt b/Documentation/devicetree/bindings/net/can/rcar_canfd.txt
+index 4299bd8..eede77a 100644
+--- a/Documentation/devicetree/bindings/net/can/rcar_canfd.txt
++++ b/Documentation/devicetree/bindings/net/can/rcar_canfd.txt
+@@ -16,6 +16,7 @@ Required properties:
+ - clock-names: 3 clock input name strings: "fck", "canfd", "can_clk".
+ - pinctrl-0: pin control group to be used for this controller.
+ - pinctrl-names: must be "default".
++- gpios: GPIO used for controlling the enable pin and standby pin
+
+ Required child nodes:
+ The controller supports two channels and each is represented as a child node.
+@@ -49,6 +50,10 @@ SoC common .dtsi file:
+ power-domains = <&cpg>;
+ status = "disabled";
+
++ gpios = <&gpio5 29 GPIO_ACTIVE_HIGH /* enable */
++ &gpio5 30 GPIO_ACTIVE_LOW /* standby */
++ >;
++
+ channel0 {
+ status = "disabled";
+ };
+diff --git a/drivers/net/can/rcar/rcar_canfd.c b/drivers/net/can/rcar/rcar_canfd.c
+index 15a14c5..4aa670d 100644
+--- a/drivers/net/can/rcar/rcar_canfd.c
++++ b/drivers/net/can/rcar/rcar_canfd.c
+@@ -21,6 +21,7 @@
+ #include <linux/clk.h>
+ #include <linux/of.h>
+ #include <linux/of_device.h>
++#include <linux/of_gpio.h>
+ #include <linux/bitmap.h>
+ #include <linux/bitops.h>
+ #include <linux/iopoll.h>
+@@ -386,6 +387,8 @@ struct rcar_canfd_global {
+ enum rcar_canfd_fcanclk fcan; /* CANFD or Ext clock */
+ unsigned long channels_mask; /* Enabled channels mask */
+ bool fdmode; /* CAN FD or Classical CAN only mode */
++ unsigned int enable_pin; /* transceiver enable */
++ unsigned int standby_pin; /* transceiver standby */
+ };
+
+ /* CAN FD mode nominal rate constants */
+@@ -1063,6 +1066,10 @@ static int rcar_canfd_open(struct net_device *ndev)
+ struct rcar_canfd_global *gpriv = priv->gpriv;
+ int err;
+
++ /* transceiver normal mode */
++ if (gpio_is_valid(gpriv->standby_pin))
++ gpio_set_value(gpriv->standby_pin, 1);
++
+ /* Peripheral clock is already enabled in probe */
+ err = clk_prepare_enable(gpriv->can_clk);
+ if (err) {
+@@ -1131,6 +1138,9 @@ static int rcar_canfd_close(struct net_device *ndev)
+ clk_disable_unprepare(gpriv->can_clk);
+ close_candev(ndev);
+ can_led_event(ndev, CAN_LED_EVENT_STOP);
++ /* transceiver stanby mode */
++ if (gpio_is_valid(gpriv->standby_pin))
++ gpio_set_value(gpriv->standby_pin, 0);
+ return 0;
+ }
+
+@@ -1409,8 +1419,9 @@ static int rcar_canfd_probe(struct platform_device *pdev)
+ struct rcar_canfd_global *gpriv;
+ struct device_node *of_child;
+ unsigned long channels_mask = 0;
+- int err, ch_irq, g_irq;
++ int err, ret, ch_irq, g_irq;
+ bool fdmode = true; /* CAN FD only mode - default */
++ enum of_gpio_flags enable_flags, standby_flags;
+
+ if (of_property_read_bool(pdev->dev.of_node, "renesas,no-can-fd"))
+ fdmode = false; /* Classical CAN only mode */
+@@ -1552,6 +1555,26 @@ static int rcar_canfd_probe(struct platform_device *pdev)
+ goto fail_channel;
+ }
+
++ gpriv->enable_pin = of_get_gpio_flags(pdev->dev.of_node, 0, &enable_flags);
++ gpriv->standby_pin = of_get_gpio_flags(pdev->dev.of_node, 1, &standby_flags);
++
++ if (gpio_is_valid(gpriv->enable_pin)) {
++ int val = enable_flags & OF_GPIO_ACTIVE_LOW ?
++ GPIOF_OUT_INIT_LOW : GPIOF_OUT_INIT_HIGH;
++ ret = devm_gpio_request_one(&pdev->dev, gpriv->enable_pin, val, "enable");
++ if (ret)
++ dev_info(&pdev->dev, "Failed to request enable pin\n");
++ }
++
++ if (gpio_is_valid(gpriv->standby_pin)) {
++ int val = standby_flags & OF_GPIO_ACTIVE_LOW ?
++ GPIOF_OUT_INIT_LOW : GPIOF_OUT_INIT_HIGH;
++ /* transceiver standby mode */
++ ret = devm_gpio_request_one(&pdev->dev, gpriv->standby_pin, val, "standby");
++ if (ret)
++ dev_info(&pdev->dev, "Failed to request standby pin\n");
++ }
++
+ platform_set_drvdata(pdev, gpriv);
+ dev_info(&pdev->dev, "global operational state (clk %d, fdmode %d)\n",
+ gpriv->fcan, gpriv->fdmode);
+--
+1.9.1
+
diff --git a/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0012-mtd-Add-RPC-HyperFlash-driver.patch b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0012-mtd-Add-RPC-HyperFlash-driver.patch
new file mode 100644
index 0000000..a6d08e7
--- /dev/null
+++ b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0012-mtd-Add-RPC-HyperFlash-driver.patch
@@ -0,0 +1,1028 @@
+From cc3bccbe6c479d8ad76a09b62fb63126403d0bab Mon Sep 17 00:00:00 2001
+From: Valentine Barshak <valentine.barshak@cogentembedded.com>
+Date: Fri, 3 Jun 2016 23:04:20 +0300
+Subject: [PATCH] mtd: Add RPC HyperFlash driver
+
+This adds RPC HyperFlash driver.
+
+Signed-off-by: Valentine Barshak <valentine.barshak@cogentembedded.com>
+---
+ drivers/mtd/Kconfig | 5 +
+ drivers/mtd/Makefile | 1 +
+ drivers/mtd/rpc_hyperflash.c | 976 +++++++++++++++++++++++++++++++++++++++++++
+ 3 files changed, 982 insertions(+)
+ create mode 100644 drivers/mtd/rpc_hyperflash.c
+
+diff --git a/drivers/mtd/Kconfig b/drivers/mtd/Kconfig
+index 42cc953..0c58a89 100644
+--- a/drivers/mtd/Kconfig
++++ b/drivers/mtd/Kconfig
+@@ -11,6 +11,11 @@ menuconfig MTD
+ particular hardware and users of MTD devices. If unsure, say N.
+
+ if MTD
++config MTD_RPC_HYPERFLASH
++ tristate "MTD Renesas R-Car Gen3 RPC HyperFlash"
++ depends on ARCH_R8A7795
++ ---help---
++ This option includes Renesas R-Car Gen3 RPC HyperFlash support.
+
+ config MTD_TESTS
+ tristate "MTD tests support (DANGEROUS)"
+diff --git a/drivers/mtd/Makefile b/drivers/mtd/Makefile
+index 99bb9a1..3b81efb 100644
+--- a/drivers/mtd/Makefile
++++ b/drivers/mtd/Makefile
+@@ -13,6 +13,7 @@ obj-$(CONFIG_MTD_AFS_PARTS) += afs.o
+ obj-$(CONFIG_MTD_AR7_PARTS) += ar7part.o
+ obj-$(CONFIG_MTD_BCM63XX_PARTS) += bcm63xxpart.o
+ obj-$(CONFIG_MTD_BCM47XX_PARTS) += bcm47xxpart.o
++obj-$(CONFIG_MTD_RPC_HYPERFLASH) += rpc_hyperflash.o
+
+ # 'Users' - code which presents functionality to userspace.
+ obj-$(CONFIG_MTD_BLKDEVS) += mtd_blkdevs.o
+diff --git a/drivers/mtd/rpc_hyperflash.c b/drivers/mtd/rpc_hyperflash.c
+new file mode 100644
+index 0000000..f8a2c90
+--- /dev/null
++++ b/drivers/mtd/rpc_hyperflash.c
+@@ -0,0 +1,976 @@
++/*
++ * Linux driver for R-Car Gen3 RPC HyperFlash
++ *
++ * Copyright (C) 2016 Renesas Electronics Corporation
++ * Copyright (C) 2016 Cogent Embedded, Inc.
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License version 2 as
++ * published by the Free Software Foundation.
++ */
++
++#include <linux/delay.h>
++#include <linux/io.h>
++#include <linux/module.h>
++#include <linux/mtd/mtd.h>
++#include <linux/mtd/partitions.h>
++#include <linux/of.h>
++#include <linux/rwsem.h>
++#include <linux/slab.h>
++
++/* RPC */
++#define RPC_BASE 0xEE200000
++#define RPC_SIZE 0x8100
++#define RPC_FLASH_BASE 0x08000000
++#define RPC_FLASH_SIZE 0x04000000
++
++#define RPC_CMNCR 0x0000 /* R/W */
++#define RPC_CMNCR_MD (0x1 << 31)
++#define RPC_CMNCR_MOIIO0(val) (((val) & 0x3) << 16)
++#define RPC_CMNCR_MOIIO1(val) (((val) & 0x3) << 18)
++#define RPC_CMNCR_MOIIO2(val) (((val) & 0x3) << 20)
++#define RPC_CMNCR_MOIIO3(val) (((val) & 0x3) << 22)
++#define RPC_CMNCR_MOIIO_HIZ (RPC_CMNCR_MOIIO0(3) | RPC_CMNCR_MOIIO1(3) | \
++ RPC_CMNCR_MOIIO2(3) | RPC_CMNCR_MOIIO3(3))
++#define RPC_CMNCR_IO0FV(val) (((val) & 0x3) << 8)
++#define RPC_CMNCR_IO2FV(val) (((val) & 0x3) << 12)
++#define RPC_CMNCR_IO3FV(val) (((val) & 0x3) << 14)
++#define RPC_CMNCR_IOFV_HIZ (RPC_CMNCR_IO0FV(3) | RPC_CMNCR_IO2FV(3) | \
++ RPC_CMNCR_IO3FV(3))
++#define RPC_CMNCR_BSZ(val) (((val) & 0x3) << 0)
++
++#define RPC_SSLDR 0x0004 /* R/W */
++#define RPC_SSLDR_SPNDL(d) (((d) & 0x7) << 16)
++#define RPC_SSLDR_SLNDL(d) (((d) & 0x7) << 8)
++#define RPC_SSLDR_SCKDL(d) (((d) & 0x7) << 0)
++
++#define RPC_DRCR 0x000C /* R/W */
++#define RPC_DRCR_SSLN (0x1 << 24)
++#define RPC_DRCR_RBURST(v) (((v) & 0x1F) << 16)
++#define RPC_DRCR_RCF (0x1 << 9)
++#define RPC_DRCR_RBE (0x1 << 8)
++#define RPC_DRCR_SSLE (0x1 << 0)
++
++#define RPC_DRCMR 0x0010 /* R/W */
++#define RPC_DRCMR_CMD(c) (((c) & 0xFF) << 16)
++#define RPC_DRCMR_OCMD(c) (((c) & 0xFF) << 0)
++
++#define RPC_DREAR 0x0014 /* R/W */
++#define RPC_DREAR_EAV(v) (((v) & 0xFF) << 16)
++#define RPC_DREAR_EAC(v) (((v) & 0x7) << 0)
++
++#define RPC_DROPR 0x0018 /* R/W */
++#define RPC_DROPR_OPD3(o) (((o) & 0xFF) << 24)
++#define RPC_DROPR_OPD2(o) (((o) & 0xFF) << 16)
++#define RPC_DROPR_OPD1(o) (((o) & 0xFF) << 8)
++#define RPC_DROPR_OPD0(o) (((o) & 0xFF) << 0)
++
++#define RPC_DRENR 0x001C /* R/W */
++#define RPC_DRENR_CDB(o) (((o) & 0x3) << 30)
++#define RPC_DRENR_OCDB(o) (((o) & 0x3) << 28)
++#define RPC_DRENR_ADB(o) (((o) & 0x3) << 24)
++#define RPC_DRENR_OPDB(o) (((o) & 0x3) << 20)
++#define RPC_DRENR_SPIDB(o) (((o) & 0x3) << 16)
++#define RPC_DRENR_DME (0x1 << 15)
++#define RPC_DRENR_CDE (0x1 << 14)
++#define RPC_DRENR_OCDE (0x1 << 12)
++#define RPC_DRENR_ADE(v) (((v) & 0xF) << 8)
++#define RPC_DRENR_OPDE(v) (((v) & 0xF) << 4)
++
++#define RPC_SMCR 0x0020 /* R/W */
++#define RPC_SMCR_SSLKP (0x1 << 8)
++#define RPC_SMCR_SPIRE (0x1 << 2)
++#define RPC_SMCR_SPIWE (0x1 << 1)
++#define RPC_SMCR_SPIE (0x1 << 0)
++
++#define RPC_SMCMR 0x0024 /* R/W */
++#define RPC_SMCMR_CMD(c) (((c) & 0xFF) << 16)
++#define RPC_SMCMR_OCMD(c) (((c) & 0xFF) << 0)
++
++#define RPC_SMADR 0x0028 /* R/W */
++#define RPC_SMOPR 0x002C /* R/W */
++#define RPC_SMOPR_OPD0(o) (((o) & 0xFF) << 0)
++#define RPC_SMOPR_OPD1(o) (((o) & 0xFF) << 8)
++#define RPC_SMOPR_OPD2(o) (((o) & 0xFF) << 16)
++#define RPC_SMOPR_OPD3(o) (((o) & 0xFF) << 24)
++
++#define RPC_SMENR 0x0030 /* R/W */
++#define RPC_SMENR_CDB(o) (((o) & 0x3) << 30)
++#define RPC_SMENR_OCDB(o) (((o) & 0x3) << 28)
++#define RPC_SMENR_ADB(o) (((o) & 0x3) << 24)
++#define RPC_SMENR_OPDB(o) (((o) & 0x3) << 20)
++#define RPC_SMENR_SPIDB(o) (((o) & 0x3) << 16)
++#define RPC_SMENR_DME (0x1 << 15)
++#define RPC_SMENR_CDE (0x1 << 14)
++#define RPC_SMENR_OCDE (0x1 << 12)
++#define RPC_SMENR_ADE(v) (((v) & 0xF) << 8)
++#define RPC_SMENR_OPDE(v) (((v) & 0xF) << 4)
++#define RPC_SMENR_SPIDE(v) (((v) & 0xF) << 0)
++
++#define RPC_SMRDR0 0x0038 /* R */
++#define RPC_SMRDR1 0x003C /* R */
++#define RPC_SMWDR0 0x0040 /* R/W */
++#define RPC_SMWDR1 0x0044 /* R/W */
++#define RPC_CMNSR 0x0048 /* R */
++#define RPC_CMNSR_SSLF (0x1 << 1)
++#define RPC_CMNSR_TEND (0x1 << 0)
++
++#define RPC_DRDMCR 0x0058 /* R/W */
++#define RPC_DRDMCR_DMCYC(v) (((v) & 0xF) << 0)
++
++#define RPC_DRDRENR 0x005C /* R/W */
++#define RPC_DRDRENR_HYPE (0x5 << 12)
++#define RPC_DRDRENR_ADDRE (0x1 << 0x8)
++#define RPC_DRDRENR_OPDRE (0x1 << 0x4)
++#define RPC_DRDRENR_DRDRE (0x1 << 0x0)
++
++#define RPC_SMDMCR 0x0060 /* R/W */
++#define RPC_SMDMCR_DMCYC(v) (((v) & 0xF) << 0)
++
++#define RPC_SMDRENR 0x0064 /* R/W */
++#define RPC_SMDRENR_HYPE (0x5 << 12)
++#define RPC_SMDRENR_ADDRE (0x1 << 0x8)
++#define RPC_SMDRENR_OPDRE (0x1 << 0x4)
++#define RPC_SMDRENR_SPIDRE (0x1 << 0x0)
++
++#define RPC_PHYCNT 0x007C /* R/W */
++#define RPC_PHYCNT_CAL (0x1 << 31)
++#define PRC_PHYCNT_OCTA_AA (0x1 << 22)
++#define PRC_PHYCNT_OCTA_SA (0x2 << 22)
++#define PRC_PHYCNT_EXDS (0x1 << 21)
++#define RPC_PHYCNT_OCT (0x1 << 20)
++#define RPC_PHYCNT_WBUF2 (0x1 << 4)
++#define RPC_PHYCNT_WBUF (0x1 << 2)
++#define RPC_PHYCNT_MEM(v) (((v) & 0x3) << 0)
++
++#define RPC_PHYINT 0x0088 /* R/W */
++#define RPC_PHYINT_RSTEN (0x1 << 18)
++#define RPC_PHYINT_WPEN (0x1 << 17)
++#define RPC_PHYINT_INTEN (0x1 << 16)
++#define RPC_PHYINT_RST (0x1 << 2)
++#define RPC_PHYINT_WP (0x1 << 1)
++#define RPC_PHYINT_INT (0x1 << 0)
++
++#define RPC_WBUF 0x8000 /* R/W size=4/8/16/32/64Bytes */
++#define RPC_WBUF_SIZE 0x100
++
++struct rpc_info {
++ struct rw_semaphore lock;
++ void __iomem *rpc_base;
++ void __iomem *flash_base;
++ struct resource *rpc_res;
++ struct resource *flash_res;
++ u32 flash_id;
++ struct mtd_info mtd;
++};
++
++static inline void __iomem *rpc_addr(struct rpc_info *info, u32 offset)
++{
++ return info->rpc_base + offset;
++}
++
++static inline u32 rpc_readl(struct rpc_info *info, u32 offset)
++{
++ u32 val;
++
++ val = readl(rpc_addr(info, offset));
++ return val;
++}
++
++static inline void rpc_writel(struct rpc_info *info, u32 offset, u32 val)
++{
++ writel(val, rpc_addr(info, offset));
++}
++
++static inline void rpc_setl(struct rpc_info *info, u32 offset, u32 mask, u32 set)
++{
++ void __iomem *addr;
++ u32 val;
++
++ addr = rpc_addr(info, offset);
++ val = readl(addr);
++ val &= mask;
++ val |= set;
++ writel(val, addr);
++}
++
++static void rpc_wait_tend(struct rpc_info *info)
++{
++ while (!(rpc_readl(info, RPC_CMNSR) & RPC_CMNSR_TEND))
++ cpu_relax();
++}
++
++/* RPC HyperFlash */
++#define RPC_HF_CMD_CA47 (0x1 << 7) /* Read */
++#define RPC_HF_CMD_CA46 (0x1 << 6) /* Register space */
++#define RPC_HF_CMD_CA45 (0x1 << 5) /* Liner burst */
++
++#define RPC_HF_CMD_READ_REG (RPC_HF_CMD_CA47 | RPC_HF_CMD_CA46)
++#define RPC_HF_CMD_READ_MEM RPC_HF_CMD_CA47
++#define RPC_HF_CMD_WRITE_REG RPC_HF_CMD_CA46
++#define RPC_HF_CMD_WRITE_MEM 0x0
++
++#define RPC_HF_ERASE_SIZE 0x40000
++
++#define RPC_CFI_STATUS_DRB (0x1 << 7)
++#define RPC_CFI_STATUS_ESSB (0x1 << 6)
++#define RPC_CFI_STATUS_ESB (0x1 << 5)
++#define RPC_CFI_STATUS_PSB (0x1 << 4)
++#define RPC_CFI_STATUS_WBASB (0x1 << 3)
++#define RPC_CFI_STATUS_PSSB (0x1 << 2)
++#define RPC_CFI_STATUS_SLSB (0x1 << 1)
++#define RPC_CFI_STATUS_ESTAT (0x1 << 0)
++
++#define RPC_CFI_UNLOCK1 (0x555 << 1)
++#define RPC_CFI_UNLOCK2 (0x2AA << 1)
++
++#define RPC_CFI_CMD_UNLOCK_START 0xAA
++#define RPC_CFI_CMD_UNLOCK_ACK 0x55
++#define RPC_CFI_CMD_RESET 0xF0
++#define RPC_CFI_CMD_READ_STATUS 0x70
++#define RPC_CFI_CMD_READ_ID 0x90
++#define RPC_CFI_CMD_WRITE 0xA0
++#define RPC_CFI_CMD_ERASE_START 0x80
++#define RPC_CFI_CMD_ERASE_SECTOR 0x30
++
++#define RPC_CFI_ID_MASK 0x000F
++#define RPC_CFI_ID_MAN_SPANSION 0x0001
++#define RPC_CFI_ID_TYPE_HYPERFLASH 0x000E
++
++enum rpc_hf_size {
++ RPC_HF_SIZE_16BIT = RPC_SMENR_SPIDE(0x8),
++ RPC_HF_SIZE_32BIT = RPC_SMENR_SPIDE(0xC),
++ RPC_HF_SIZE_64BIT = RPC_SMENR_SPIDE(0xF),
++};
++
++struct rpc_info *rpc_info;
++
++static void rpc_hf_mode_man(struct rpc_info *info)
++{
++ rpc_wait_tend(info);
++
++ /*
++ * RPC_PHYCNT = 0x80000263
++ * bit31 CAL = 1 : PHY calibration
++ * bit1-0 PHYMEM[1:0] = 11 : HyperFlash
++ */
++ rpc_setl(info, RPC_PHYCNT,
++ ~(RPC_PHYCNT_WBUF | RPC_PHYCNT_WBUF2 |
++ RPC_PHYCNT_CAL | RPC_PHYCNT_MEM(3)),
++ RPC_PHYCNT_CAL | RPC_PHYCNT_MEM(3));
++
++ /*
++ * RPC_CMNCR = 0x81FFF301
++ * bit31 MD = 1 : Manual mode
++ * bit1-0 BSZ[1:0] = 01 : QSPI Flash x 2 or HyperFlash
++ */
++ rpc_setl(info, RPC_CMNCR,
++ ~(RPC_CMNCR_MD | RPC_CMNCR_BSZ(3)),
++ RPC_CMNCR_MOIIO_HIZ | RPC_CMNCR_IOFV_HIZ |
++ RPC_CMNCR_MD | RPC_CMNCR_BSZ(1));
++}
++
++static void rpc_hf_mode_ext(struct rpc_info *info)
++{
++ rpc_wait_tend(info);
++
++ /*
++ * RPC_PHYCNT = 0x80000263
++ * bit31 CAL = 1 : PHY calibration
++ * bit1-0 PHYMEM[1:0] = 11 : HyperFlash
++ */
++ rpc_setl(info, RPC_PHYCNT,
++ ~(RPC_PHYCNT_WBUF | RPC_PHYCNT_WBUF2 |
++ RPC_PHYCNT_CAL | RPC_PHYCNT_MEM(3)),
++ RPC_PHYCNT_CAL | RPC_PHYCNT_MEM(3));
++
++ /*
++ * RPC_CMNCR = 0x81FFF301
++ * bit31 MD = 1 : Manual mode
++ * bit1-0 BSZ[1:0] = 01 : QSPI Flash x 2 or HyperFlash
++ */
++ rpc_setl(info, RPC_CMNCR,
++ ~(RPC_CMNCR_MD | RPC_CMNCR_BSZ(3)),
++ RPC_CMNCR_MOIIO_HIZ | RPC_CMNCR_IOFV_HIZ |
++ RPC_CMNCR_BSZ(1));
++
++ /*
++ * RPC_DRCR = 0x001F0100
++ * bit21-16 RBURST[4:0] = 11111 : Read burst 32 64-bit data units
++ * bit9 RCF = 1 : Clear cache
++ * bit8 RBE = 1 : Read burst enable
++ */
++ rpc_writel(info, RPC_DRCR,
++ RPC_DRCR_RBURST(0x1F) | RPC_DRCR_RCF | RPC_DRCR_RBE);
++
++ rpc_writel(info, RPC_DRCMR, RPC_DRCMR_CMD(0xA0));
++ rpc_writel(info, RPC_DRENR,
++ RPC_DRENR_CDB(2) | RPC_DRENR_OCDB(2) |
++ RPC_DRENR_ADB(2) | RPC_DRENR_SPIDB(2) |
++ RPC_DRENR_CDE | RPC_DRENR_OCDE | RPC_DRENR_ADE(4));
++ rpc_writel(info, RPC_DRDMCR, RPC_DRDMCR_DMCYC(0xE));
++ rpc_writel(info, RPC_DRDRENR,
++ RPC_DRDRENR_HYPE | RPC_DRDRENR_ADDRE | RPC_DRDRENR_DRDRE);
++
++ /* Dummy read */
++ rpc_readl(info, RPC_DRCR);
++}
++
++static void rpc_hf_xfer(struct rpc_info *info, u32 addr, u16 *data,
++ enum rpc_hf_size size, u8 cmd)
++{
++ u32 val;
++
++ rpc_hf_mode_man(info);
++
++ /*
++ * bit23-21 CMD[7:5] : CA47-45
++ * CA47 = 0/1 : Write/Read
++ * CA46 = 0/1 : Memory Space/Register Space
++ * CA45 = 0/1 : Wrapped Burst/Linear Burst
++ */
++ rpc_writel(info, RPC_SMCMR, RPC_SMCMR_CMD(cmd));
++
++ rpc_writel(info, RPC_SMADR, addr >> 1);
++
++ rpc_writel(info, RPC_SMOPR, 0x0);
++
++ /*
++ * RPC_SMDRENR = 0x00005101
++ * bit14-12 HYPE = 101: Hyperflash mode
++ * bit8 ADDRE = 1 : Address DDR transfer
++ * bit0 SPIDRE = 1 : DATA DDR transfer
++ */
++ rpc_writel(info, RPC_SMDRENR,
++ RPC_SMDRENR_HYPE | RPC_SMDRENR_ADDRE | RPC_SMDRENR_SPIDRE);
++
++ val = RPC_SMENR_CDB(2) | RPC_SMENR_OCDB(2) |
++ RPC_SMENR_ADB(2) | RPC_SMENR_SPIDB(2) |
++ RPC_SMENR_CDE | RPC_SMENR_OCDE | RPC_SMENR_ADE(4) | size;
++
++ if (cmd & RPC_HF_CMD_CA47)
++ goto read_transfer;
++
++ /*
++ * RPC_SMENR = 0xA222540x
++ * bit31-30 CDB[1:0] = 10 : 4bit width command
++ * bit25-24 ADB[1:0] = 10 : 4bit width address
++ * bit17-16 SPIDB[1:0] = 10 : 4bit width transfer data
++ * bit15 DME = 0 : dummy cycle disable
++ * bit14 CDE = 1 : Command enable
++ * bit12 OCDE = 1 : Option Command enable
++ * bit11-8 ADE[3:0] = 0100 : ADR[23:0] output
++ * bit7-4 OPDE[3:0] = 0000 : Option data disable
++ * bit3-0 SPIDE[3:0] = xxxx : Transfer size
++ */
++ rpc_writel(info, RPC_SMENR, val);
++
++ switch (size) {
++ case RPC_HF_SIZE_64BIT:
++ val = cmd & RPC_HF_CMD_CA46 ?
++ cpu_to_be16(data[0]) | cpu_to_be16(data[1]) << 16 :
++ data[0] | data[1] << 16;
++ rpc_writel(info, RPC_SMWDR1, val);
++ val = cmd & RPC_HF_CMD_CA46 ?
++ cpu_to_be16(data[2]) | cpu_to_be16(data[3]) << 16 :
++ data[2] | data[3] << 16;
++ break;
++ case RPC_HF_SIZE_32BIT:
++ val = cmd & RPC_HF_CMD_CA46 ?
++ cpu_to_be16(data[0]) | cpu_to_be16(data[1]) << 16 :
++ data[0] | data[1] << 16;
++ break;
++ default:
++ val = cmd & RPC_HF_CMD_CA46 ?
++ cpu_to_be16(data[0]) << 16 :
++ data[0] << 16;
++ break;
++ }
++
++ rpc_writel(info, RPC_SMWDR0, val);
++ /*
++ * RPC_SMCR = 0x00000003
++ * bit1 SPIWE = 1 : Data write enable
++ * bit0 SPIE = 1 : SPI transfer start
++ */
++ rpc_writel(info, RPC_SMCR, RPC_SMCR_SPIWE | RPC_SMCR_SPIE);
++ return;
++
++read_transfer:
++ rpc_writel(info, RPC_SMDMCR, RPC_SMDMCR_DMCYC(0xE));
++ val |= RPC_SMENR_DME;
++
++ /*
++ * RPC_SMENR = 0xA222D40x
++ * bit31-30 CDB[1:0] = 10 : 4bit width command
++ * bit25-24 ADB[1:0] = 10 : 4bit width address
++ * bit17-16 SPIDB[1:0] = 10 : 4bit width transfer data
++ * bit15 DME = 1 : dummy cycle disable
++ * bit14 CDE = 1 : Command enable
++ * bit12 OCDE = 1 : Option Command enable
++ * bit11-8 ADE[3:0] = 0100 : ADR[23:0] output (24 Bit Address)
++ * bit7-4 OPDE[3:0] = 0000 : Option data disable
++ * bit3-0 SPIDE[3:0] = xxxx : Transfer size
++ */
++ rpc_writel(info, RPC_SMENR, val);
++
++ /*
++ * RPC_SMCR = 0x00000005
++ * bit2 SPIRE = 1 : Data read disable
++ * bit0 SPIE = 1 : SPI transfer start
++ */
++ rpc_writel(info, RPC_SMCR, RPC_SMCR_SPIRE | RPC_SMCR_SPIE);
++
++ rpc_wait_tend(info);
++ val = rpc_readl(info, RPC_SMRDR0);
++
++ /*
++ * Read data from either register or memory space.
++ * Register space is always big-endian.
++ */
++ switch (size) {
++ case RPC_HF_SIZE_64BIT:
++ if (cmd & RPC_HF_CMD_CA46) {
++ data[3] = be16_to_cpu((val >> 16) & 0xFFFF);
++ data[2] = be16_to_cpu(val & 0xFFFF);
++ } else {
++ data[3] = (val >> 16) & 0xFFFF;
++ data[2] = val & 0xFFFF;
++ }
++ val = rpc_readl(info, RPC_SMRDR1);
++ if (cmd & RPC_HF_CMD_CA46) {
++ data[1] = be16_to_cpu((val >> 16) & 0xFFFF);
++ data[0] = be16_to_cpu(val & 0xFFFF);
++ } else {
++ data[1] = (val >> 16) & 0xFFFF;
++ data[0] = val & 0xFFFF;
++ }
++ break;
++ case RPC_HF_SIZE_32BIT:
++ if (cmd & RPC_HF_CMD_CA46) {
++ data[1] = be16_to_cpu((val >> 16) & 0xFFFF);
++ data[0] = be16_to_cpu(val & 0xFFFF);
++ } else {
++ data[1] = (val >> 16) & 0xFFFF;
++ data[0] = val & 0xFFFF;
++ }
++ break;
++ default:
++ data[0] = cmd & RPC_HF_CMD_CA46 ?
++ be16_to_cpu((val >> 16) & 0xFFFF) :
++ (val >> 16) & 0xFFFF;
++ break;
++ }
++}
++
++static void rpc_hf_wbuf_enable(struct rpc_info *info)
++{
++ rpc_wait_tend(info);
++
++ /*
++ * RPC_PHYCNT = 0x80000277
++ * bit31 CAL = 1 : PHY calibration
++ * bit4 WBUF2 = 1 : Write buffer enable 2
++ * bit2 WBUF = 1 : Write buffer enable
++ * bit1-0 PHYMEM[1:0] = 11 : HyperFlash
++ */
++ rpc_setl(info, RPC_PHYCNT,
++ ~(RPC_PHYCNT_WBUF2 | RPC_PHYCNT_WBUF |
++ RPC_PHYCNT_CAL | RPC_PHYCNT_MEM(3)),
++ RPC_PHYCNT_WBUF2 | RPC_PHYCNT_WBUF |
++ RPC_PHYCNT_CAL | RPC_PHYCNT_MEM(3));
++
++ /*
++ * RPC_DRCR = 0x001F0100
++ * bit21-16 RBURST[4:0] = 11111 : Read burst 32 64-bit data units
++ * bit9 RCF = 1 : Clear cache
++ * bit8 RBE = 1 : Read burst enable
++ */
++ rpc_writel(info, RPC_DRCR,
++ RPC_DRCR_RBURST(0x1F) | RPC_DRCR_RCF | RPC_DRCR_RBE);
++
++ rpc_writel(info, RPC_SMCMR, RPC_SMCMR_CMD(RPC_HF_CMD_WRITE_MEM));
++
++ rpc_writel(info, RPC_SMOPR, 0x0);
++
++ /*
++ * RPC_SMDRENR = 0x00005101
++ * bit14-12 HYPE = 101:Hyperflash mode
++ * bit8 ADDRE = 1 : Address DDR transfer
++ * bit0 SPIDRE = 1 : DATA DDR transfer
++ */
++ rpc_writel(info, RPC_SMDRENR,
++ RPC_SMDRENR_HYPE | RPC_SMDRENR_ADDRE | RPC_SMDRENR_SPIDRE);
++
++ /*
++ * RPC_SMENR = 0xA222540F
++ * bit31-30 CDB[1:0] = 10 : 4bit width command
++ * bit25-24 ADB[1:0] = 10 : 4bit width address
++ * bit17-16 SPIDB[1:0] = 10 : 4bit width transfer data
++ * bit15 DME = 0 : dummy cycle disable
++ * bit14 CDE = 1 : Command enable
++ * bit12 OCDE = 1 : Option Command enable
++ * bit11-8 ADE[3:0] = 0100 : ADR[23:0] output (24 Bit Address)
++ * bit7-4 OPDE[3:0] = 0000 : Option data disable
++ * bit3-0 SPIDE[3:0] = 1111 : 64-bit transfer size
++ */
++ rpc_writel(info, RPC_SMENR,
++ RPC_SMENR_CDB(2) | RPC_SMENR_OCDB(2) |
++ RPC_SMENR_ADB(2) | RPC_SMENR_SPIDB(2) |
++ RPC_SMENR_CDE | RPC_SMENR_OCDE |
++ RPC_SMENR_ADE(4) | RPC_HF_SIZE_64BIT);
++
++ /* Dummy read */
++ rpc_readl(info, RPC_DRCR);
++}
++
++static inline void rpc_hf_write_cmd(struct rpc_info *info, u32 addr, u16 cmd)
++{
++ rpc_hf_xfer(info, addr, &cmd, RPC_HF_SIZE_16BIT, RPC_HF_CMD_WRITE_REG);
++}
++
++static inline void rpc_hf_read_reg(struct rpc_info *info, u32 addr, u16 *data,
++ enum rpc_hf_size size)
++{
++ rpc_hf_xfer(info, addr, data, size, RPC_HF_CMD_READ_REG);
++}
++
++static inline void rpc_hf_write_reg(struct rpc_info *info, u32 addr, u16 *data,
++ enum rpc_hf_size size)
++{
++ rpc_hf_xfer(info, addr, data, size, RPC_HF_CMD_WRITE_REG);
++}
++
++static inline void rpc_hf_read_mem(struct rpc_info *info, u32 addr, u16 *data,
++ enum rpc_hf_size size)
++{
++ rpc_hf_xfer(info, addr, data, size, RPC_HF_CMD_READ_MEM);
++}
++
++static inline void rpc_hf_write_mem(struct rpc_info *info, u32 addr, u16 *data,
++ enum rpc_hf_size size)
++{
++ rpc_hf_xfer(info, addr, data, size, RPC_HF_CMD_WRITE_MEM);
++}
++
++static void rpc_hf_wp(struct rpc_info *info, int enable)
++{
++ rpc_setl(info, RPC_PHYINT, ~RPC_PHYINT_WP, enable ? RPC_PHYINT_WP : 0);
++}
++
++static void rpc_hf_unlock(struct rpc_info *info, u32 addr)
++{
++ rpc_hf_write_cmd(info, addr + RPC_CFI_UNLOCK1,
++ RPC_CFI_CMD_UNLOCK_START);
++ rpc_hf_write_cmd(info, addr + RPC_CFI_UNLOCK2,
++ RPC_CFI_CMD_UNLOCK_ACK);
++}
++
++static inline int rpc_hf_status(struct rpc_info *info, u32 addr,
++ int iterations, int delay)
++{
++ int retval;
++ u16 status = 0;
++
++ while (iterations-- > 0) {
++ rpc_hf_write_cmd(info, addr + RPC_CFI_UNLOCK1, RPC_CFI_CMD_READ_STATUS);
++ rpc_hf_read_reg(info, addr, &status, RPC_HF_SIZE_16BIT);
++
++ if (status & RPC_CFI_STATUS_DRB)
++ break;
++
++ if (delay < 10000)
++ usleep_range(delay, delay * 2);
++ else
++ msleep(delay / 1000);
++ }
++
++ if (!(status & RPC_CFI_STATUS_DRB)) {
++ retval = -ETIMEDOUT;
++ goto out;
++ }
++
++ if (status & (RPC_CFI_STATUS_PSB | RPC_CFI_STATUS_ESB)) {
++ retval = -EIO;
++ goto out;
++ }
++
++ return 0;
++
++out:
++ /* Reset the flash */
++ rpc_hf_write_cmd(info, 0, RPC_CFI_CMD_RESET);
++ return retval;
++}
++
++static int rpc_hf_sector_erase(struct rpc_info *info, u32 addr)
++{
++ rpc_hf_unlock(info, addr);
++ rpc_hf_write_cmd(info, addr + RPC_CFI_UNLOCK1, RPC_CFI_CMD_ERASE_START);
++ rpc_hf_unlock(info, addr);
++ rpc_hf_write_cmd(info, addr, RPC_CFI_CMD_ERASE_SECTOR);
++
++ return rpc_hf_status(info, addr, 1000, 10000);
++}
++
++/* Flash read */
++static int rpc_hf_mtd_read(struct mtd_info *mtd, loff_t from, size_t len,
++ size_t *retlen, u_char *buf)
++{
++ struct rpc_info *info = mtd->priv;
++
++ down_read(&info->lock);
++ memcpy_fromio(buf, info->flash_base + from, len);
++ up_read(&info->lock);
++
++ *retlen = len;
++ return 0;
++}
++
++/* Flash erase */
++static int rpc_hf_mtd_erase(struct mtd_info *mtd, struct erase_info *instr)
++{
++ struct rpc_info *info = mtd->priv;
++ u32 addr, end;
++ int retval = 0;
++
++ if (mtd_mod_by_eb(instr->addr, mtd)) {
++ pr_debug("%s: unaligned address\n", __func__);
++ return -EINVAL;
++ }
++
++ if (mtd_mod_by_eb(instr->len, mtd)) {
++ pr_debug("%s: unaligned length\n", __func__);
++ return -EINVAL;
++ }
++
++ end = instr->addr + instr->len;
++
++ down_write(&info->lock);
++ for (addr = instr->addr; addr < end; addr += mtd->erasesize) {
++ retval = rpc_hf_sector_erase(info, addr);
++
++ if (retval)
++ break;
++ }
++
++ rpc_hf_mode_ext(info);
++ up_write(&info->lock);
++
++ instr->state = retval ? MTD_ERASE_FAILED : MTD_ERASE_DONE;
++ mtd_erase_callback(instr);
++
++ return retval;
++}
++
++/* Copy memory to flash */
++static int rpc_hf_mtd_write(struct mtd_info *mtd, loff_t offset, size_t len,
++ size_t *retlen, const u_char *src)
++{
++ struct rpc_info *info = mtd->priv;
++ union {
++ u8 b[4];
++ u16 w[2];
++ u32 d;
++ } data;
++ loff_t addr;
++ size_t size, cnt;
++ int retval, idx;
++ u8 last;
++
++ retval = 0;
++ *retlen = 0;
++ cnt = len;
++ idx = 0;
++
++ down_write(&info->lock);
++
++ /* Handle unaligned start */
++ if (offset & 0x1) {
++ offset--;
++ data.b[idx] = readb(info->flash_base + offset);
++ idx++;
++ }
++
++ /* Handle unaligned end */
++ addr = offset + idx + len;
++ last = addr & 0x1 ? readb(info->flash_base + addr) : 0xFF;
++
++ addr = offset - mtd_mod_by_eb(offset, mtd);
++ size = mtd->erasesize - (offset - addr);
++
++ while (cnt) {
++ if (size > cnt)
++ size = cnt;
++
++ cnt -= size;
++ while (size) {
++ rpc_hf_unlock(info, addr);
++ rpc_hf_write_cmd(info,
++ addr + RPC_CFI_UNLOCK1,
++ RPC_CFI_CMD_WRITE);
++
++ if (size > 0x7) {
++ u32 wbuf = RPC_WBUF;
++ int block = size >= RPC_WBUF_SIZE ?
++ RPC_WBUF_SIZE : size & ~0x7;
++
++ rpc_hf_wbuf_enable(info);
++
++ rpc_writel(info, RPC_SMADR, offset >> 1);
++ offset += block;
++
++ block >>= 3;
++ while (block--) {
++ while (idx < 4) {
++ data.b[idx++] = *src++;
++ size--;
++ }
++ rpc_writel(info, wbuf, data.d);
++ wbuf += 4;
++
++ idx = 0;
++ while (idx < 4) {
++ data.b[idx++] = *src++;
++ size--;
++ }
++ rpc_writel(info, wbuf, data.d);
++ wbuf += 4;
++
++ idx = 0;
++ }
++
++ rpc_writel(info, RPC_SMCR,
++ RPC_SMCR_SPIWE | RPC_SMCR_SPIE);
++ } else {
++ enum rpc_hf_size bits;
++
++ while (idx < 4) {
++ data.b[idx++] = *src++;
++ size--;
++
++ if (!size)
++ break;
++ }
++
++ if (idx & 0x1)
++ data.b[idx++] = last;
++
++ switch (idx) {
++ case 2:
++ bits = RPC_HF_SIZE_16BIT;
++ break;
++ default:
++ bits = RPC_HF_SIZE_32BIT;
++ break;
++ }
++
++ rpc_hf_write_mem(info, offset, data.w, bits);
++ offset += idx;
++ idx = 0;
++ }
++
++ retval = rpc_hf_status(info, addr, 1000000, 10);
++ if (retval)
++ goto out;
++ }
++
++ size = mtd->erasesize;
++ addr += size;
++ offset = addr;
++ *retlen = len - cnt;
++ }
++
++out:
++ rpc_hf_mode_ext(info);
++ up_write(&info->lock);
++ return retval;
++}
++
++static struct mtd_partition partition_info[]={
++ {
++ .name = "bootparam",
++ .offset = 0,
++ .size = 0x40000,
++ }, {
++ .name = "bl2",
++ .offset = MTDPART_OFS_APPEND,
++ .size = 0x140000
++ }, {
++ .name = "cert_header",
++ .offset = MTDPART_OFS_APPEND,
++ .size = 0x40000,
++ }, {
++ .name = "bl31",
++ .offset = MTDPART_OFS_APPEND,
++ .size = 0x40000,
++ }, {
++ .name = "optee",
++ .offset = MTDPART_OFS_APPEND,
++ .size = 0x440000,
++ }, {
++ .name = "u-boot",
++ .offset = MTDPART_OFS_APPEND,
++ .size = 0x80000,
++ }, {
++ .name = "reserved",
++ .offset = MTDPART_OFS_APPEND,
++ .size = 0x80000,
++ }, {
++ .name = "u-boot-env",
++ .offset = MTDPART_OFS_APPEND,
++ .size = 0x40000,
++ }, {
++ .name = "dtb",
++ .offset = MTDPART_OFS_APPEND,
++ .size = 0x80000,
++ }, {
++ .name = "kernel",
++ .offset = MTDPART_OFS_APPEND,
++ .size = 0x1000000,
++ }, {
++ .name = "user",
++ .offset = MTDPART_OFS_APPEND,
++ .size = MTDPART_SIZ_FULL,
++ },
++};
++
++static int rpc_hf_init_mtd(struct rpc_info *info)
++{
++ struct mtd_info *mtd = &info->mtd;
++ u16 data[2] = { 0, 0 };
++ u32 id, size;
++ int retval;
++
++ rpc_hf_mode_ext(info);
++
++ rpc_hf_wp(info, 0);
++
++ rpc_hf_unlock(info, 0);
++ rpc_hf_write_cmd(info, RPC_CFI_UNLOCK1, RPC_CFI_CMD_READ_ID);
++
++ rpc_hf_read_reg(info, 0x0, data, RPC_HF_SIZE_32BIT);
++ if ((data[0] & RPC_CFI_ID_MASK) != RPC_CFI_ID_MAN_SPANSION ||
++ (data[1] & RPC_CFI_ID_MASK) != RPC_CFI_ID_TYPE_HYPERFLASH) {
++ retval = -ENODEV;
++ goto out;
++ }
++
++ id = data[0] | data[1] << 16;
++
++ rpc_hf_read_reg(info, 0x27 << 1, data, RPC_HF_SIZE_16BIT);
++ size = 1 << data[0];
++
++ if (size > resource_size(info->flash_res))
++ size = resource_size(info->flash_res);
++
++ if (size & (RPC_HF_ERASE_SIZE - 1)) {
++ retval = -EINVAL;
++ goto out;
++ }
++
++ init_rwsem(&info->lock);
++ info->flash_id = id;
++ mtd->name = "HyperFlash";
++ mtd->type = MTD_NORFLASH;
++ mtd->flags = MTD_CAP_NORFLASH;
++ mtd->size = size;
++ mtd->writesize = 1;
++ mtd->writebufsize = RPC_WBUF_SIZE;
++ mtd->erasesize = RPC_HF_ERASE_SIZE;
++ mtd->owner = THIS_MODULE;
++ mtd->priv = info;
++ mtd->_erase = rpc_hf_mtd_erase;
++ mtd->_write = rpc_hf_mtd_write;
++ mtd->_read = rpc_hf_mtd_read;
++ retval = mtd_device_register(mtd, partition_info,
++ ARRAY_SIZE(partition_info));
++out:
++ rpc_hf_write_cmd(info, 0, RPC_CFI_CMD_RESET);
++ rpc_hf_mode_ext(info);
++ return retval;
++}
++
++static int rpc_flash_init(void)
++{
++ struct rpc_info *info;
++ struct resource *res;
++ void __iomem *base;
++ int retval = -ENODEV;
++
++ if (!of_machine_is_compatible("renesas,r8a7795"))
++ return -ENODEV;
++
++ info = kzalloc(sizeof(*info), GFP_KERNEL);
++ if (!info)
++ return -ENOMEM;
++
++ res = request_mem_region(RPC_BASE, RPC_SIZE, "RPC");
++ if (!res)
++ goto out_info;
++
++ info->rpc_res = res;
++ base = ioremap(res->start, resource_size(res));
++ if (!base)
++ goto out_rpc_res;
++
++ info->rpc_base = base;
++ res = request_mem_region(RPC_FLASH_BASE, RPC_FLASH_SIZE, "RPC-ext");
++ if (!res)
++ goto out_rpc_base;
++
++ info->flash_res = res;
++ base = ioremap(res->start, resource_size(res));
++ if (!base)
++ goto out_flash_res;
++
++ info->flash_base = base;
++ retval = rpc_hf_init_mtd(info);
++ if (retval)
++ goto out_flash_base;
++
++ pr_info("HyperFlash Id: %x\n", info->flash_id);
++
++ rpc_info = info;
++ return 0;
++
++out_flash_base:
++ iounmap(info->flash_base);
++out_flash_res:
++ release_mem_region(info->flash_res->start,
++ resource_size(info->flash_res));
++out_rpc_base:
++ iounmap(info->rpc_base);
++out_rpc_res:
++ release_mem_region(info->rpc_res->start,
++ resource_size(info->rpc_res));
++out_info:
++ kfree(info);
++ return retval;
++}
++
++static void rpc_flash_exit(void)
++{
++ struct rpc_info *info = rpc_info;
++
++ if (!info)
++ return;
++
++ rpc_info = NULL;
++
++ mtd_device_unregister(&info->mtd);
++
++ iounmap(info->flash_base);
++ release_mem_region(info->flash_res->start,
++ resource_size(info->flash_res));
++ iounmap(info->rpc_base);
++ release_mem_region(info->rpc_res->start,
++ resource_size(info->rpc_res));
++ kfree(info);
++}
++
++module_init(rpc_flash_init);
++module_exit(rpc_flash_exit);
++
++MODULE_LICENSE("GPL v2");
++MODULE_DESCRIPTION("Renesas RPC HyperFlash MTD driver");
+--
+2.7.4
+
diff --git a/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0013-IMR-driver-interim-patch.patch b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0013-IMR-driver-interim-patch.patch
new file mode 100644
index 0000000..30cf006
--- /dev/null
+++ b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0013-IMR-driver-interim-patch.patch
@@ -0,0 +1,2104 @@
+From 240504b182a2816696c6a02fe37a5048925cc1fb Mon Sep 17 00:00:00 2001
+From: Konstantin Kozhevnikov <Konstantin.Kozhevnikov@cogentembedded.com>
+Date: Wed, 7 Sep 2016 22:55:37 +0300
+Subject: [PATCH] IMR driver - interim patch
+
+Signed-off-by: Konstantin Kozhevnikov <Konstantin.Kozhevnikov@cogentembedded.com>
+---
+ arch/arm64/boot/dts/renesas/r8a7795-es1.dtsi | 32 +
+ arch/arm64/boot/dts/renesas/r8a7795.dtsi | 32 +
+ drivers/clk/renesas/r8a7795-cpg-mssr.c | 4 +
+ drivers/media/platform/Kconfig | 11 +
+ drivers/media/platform/Makefile | 1 +
+ drivers/media/platform/rcar_imr.c | 1840 ++++++++++++++++++++++++++
+ include/uapi/linux/rcar-imr.h | 98 ++
+ 7 files changed, 2018 insertions(+)
+ create mode 100644 drivers/media/platform/rcar_imr.c
+ create mode 100644 include/uapi/linux/rcar-imr.h
+
+diff --git a/arch/arm64/boot/dts/renesas/r8a7795-es1.dtsi b/arch/arm64/boot/dts/renesas/r8a7795-es1.dtsi
+index 09e1284..d530100 100644
+--- a/arch/arm64/boot/dts/renesas/r8a7795-es1.dtsi
++++ b/arch/arm64/boot/dts/renesas/r8a7795-es1.dtsi
+@@ -2713,5 +2713,37 @@
+ };
+ };
+ };
++
++ imrlx4_ch0: imr-lx4@fe860000 {
++ compatible = "renesas,imr-lx4";
++ reg = <0 0xfe860000 0 0x2000>;
++ interrupts = <GIC_SPI 192 IRQ_TYPE_LEVEL_HIGH>;
++ clocks = <&cpg CPG_MOD 823>;
++ power-domains = <&sysc R8A7795_PD_A3VC>;
++ };
++
++ imrlx4_ch1: imr-lx4@fe870000 {
++ compatible = "renesas,imr-lx4";
++ reg = <0 0xfe870000 0 0x2000>;
++ interrupts = <GIC_SPI 193 IRQ_TYPE_LEVEL_HIGH>;
++ clocks = <&cpg CPG_MOD 822>;
++ power-domains = <&sysc R8A7795_PD_A3VC>;
++ };
++
++ imrlx4_ch2: imr-lx4@fe880000 {
++ compatible = "renesas,imr-lx4";
++ reg = <0 0xfe880000 0 0x2000>;
++ interrupts = <GIC_SPI 194 IRQ_TYPE_LEVEL_HIGH>;
++ clocks = <&cpg CPG_MOD 821>;
++ power-domains = <&sysc R8A7795_PD_A3VC>;
++ };
++
++ imrlx4_ch3: imr-lx4@fe890000 {
++ compatible = "renesas,imr-lx4";
++ reg = <0 0xfe890000 0 0x2000>;
++ interrupts = <GIC_SPI 195 IRQ_TYPE_LEVEL_HIGH>;
++ clocks = <&cpg CPG_MOD 820>;
++ power-domains = <&sysc R8A7795_PD_A3VC>;
++ };
+ };
+ };
+diff --git a/arch/arm64/boot/dts/renesas/r8a7795.dtsi b/arch/arm64/boot/dts/renesas/r8a7795.dtsi
+index 82ebfd4..9b4ee2f 100644
+--- a/arch/arm64/boot/dts/renesas/r8a7795.dtsi
++++ b/arch/arm64/boot/dts/renesas/r8a7795.dtsi
+@@ -2699,5 +2699,37 @@
+ };
+ };
+ };
++
++ imrlx4_ch0: imr-lx4@fe860000 {
++ compatible = "renesas,imr-lx4";
++ reg = <0 0xfe860000 0 0x2000>;
++ interrupts = <GIC_SPI 192 IRQ_TYPE_LEVEL_HIGH>;
++ clocks = <&cpg CPG_MOD 823>;
++ power-domains = <&sysc R8A7795_PD_A3VC>;
++ };
++
++ imrlx4_ch1: imr-lx4@fe870000 {
++ compatible = "renesas,imr-lx4";
++ reg = <0 0xfe870000 0 0x2000>;
++ interrupts = <GIC_SPI 193 IRQ_TYPE_LEVEL_HIGH>;
++ clocks = <&cpg CPG_MOD 822>;
++ power-domains = <&sysc R8A7795_PD_A3VC>;
++ };
++
++ imrlx4_ch2: imr-lx4@fe880000 {
++ compatible = "renesas,imr-lx4";
++ reg = <0 0xfe880000 0 0x2000>;
++ interrupts = <GIC_SPI 194 IRQ_TYPE_LEVEL_HIGH>;
++ clocks = <&cpg CPG_MOD 821>;
++ power-domains = <&sysc R8A7795_PD_A3VC>;
++ };
++
++ imrlx4_ch3: imr-lx4@fe890000 {
++ compatible = "renesas,imr-lx4";
++ reg = <0 0xfe890000 0 0x2000>;
++ interrupts = <GIC_SPI 195 IRQ_TYPE_LEVEL_HIGH>;
++ clocks = <&cpg CPG_MOD 820>;
++ power-domains = <&sysc R8A7795_PD_A3VC>;
++ };
+ };
+ };
+diff --git a/drivers/clk/renesas/r8a7795-cpg-mssr.c b/drivers/clk/renesas/r8a7795-cpg-mssr.c
+index 718afd6..f833031 100644
+--- a/drivers/clk/renesas/r8a7795-cpg-mssr.c
++++ b/drivers/clk/renesas/r8a7795-cpg-mssr.c
+@@ -229,6 +229,10 @@ enum clk_ids {
+ DEF_MOD("vin0", 811, R8A7795_CLK_S0D2),
+ DEF_MOD("etheravb", 812, R8A7795_CLK_S0D6),
+ DEF_MOD("sata0", 815, R8A7795_CLK_S3D2),
++ DEF_MOD("imr3", 820, R8A7795_CLK_S2D1),
++ DEF_MOD("imr2", 821, R8A7795_CLK_S2D1),
++ DEF_MOD("imr1", 822, R8A7795_CLK_S2D1),
++ DEF_MOD("imr0", 823, R8A7795_CLK_S2D1),
+ DEF_MOD("gpio7", 905, R8A7795_CLK_S3D4),
+ DEF_MOD("gpio6", 906, R8A7795_CLK_S3D4),
+ DEF_MOD("gpio5", 907, R8A7795_CLK_S3D4),
+diff --git a/drivers/media/platform/Kconfig b/drivers/media/platform/Kconfig
+index ba2b892..f4d12f5 100644
+--- a/drivers/media/platform/Kconfig
++++ b/drivers/media/platform/Kconfig
+@@ -315,6 +315,17 @@ config VIDEO_RENESAS_FCP
+ To compile this driver as a module, choose M here: the module
+ will be called rcar-fcp.
+
++config VIDEO_RENESAS_IMR
++ tristate "Renesas Image Renderer (Distortion Correction) Unit"
++ depends on VIDEO_DEV && VIDEO_V4L2
++ select VIDEOBUF2_DMA_CONTIG
++ select V4L2_MEM2MEM_DEV
++ ---help---
++ This is a V4L2 driver for the Renesas IMR-X2/LX2/LX4 Processing Unit.
++
++ To compile this driver as a module, choose M here: the module
++ will be called rcar_imr.
++
+ config VIDEO_RENESAS_VSP1
+ tristate "Renesas VSP1 Video Processing Engine"
+ depends on VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API && HAS_DMA
+diff --git a/drivers/media/platform/Makefile b/drivers/media/platform/Makefile
+index 40b18d1..9e9464c 100644
+--- a/drivers/media/platform/Makefile
++++ b/drivers/media/platform/Makefile
+@@ -49,6 +49,7 @@ obj-$(CONFIG_SOC_CAMERA) += soc_camera/
+
+ obj-$(CONFIG_VIDEO_RENESAS_FCP) += rcar-fcp.o
+ obj-$(CONFIG_VIDEO_RENESAS_JPU) += rcar_jpu.o
++obj-$(CONFIG_VIDEO_RENESAS_IMR) += rcar_imr.o
+ obj-$(CONFIG_VIDEO_RENESAS_VSP1) += vsp1/
+
+ obj-y += omap/
+diff --git a/drivers/media/platform/rcar_imr.c b/drivers/media/platform/rcar_imr.c
+new file mode 100644
+index 0000000..30c6742
+--- /dev/null
++++ b/drivers/media/platform/rcar_imr.c
+@@ -0,0 +1,1840 @@
++/*
++ * rcar_imr.c -- R-Car IMR-LX4 Driver
++ *
++ * Copyright (C) 2015 Cogent Embedded, Inc. <source@cogentembedded.com>
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ */
++
++#include <linux/kernel.h>
++#include <linux/module.h>
++#include <linux/platform_device.h>
++#include <linux/clk.h>
++#include <linux/interrupt.h>
++#include <linux/pm_runtime.h>
++#include <linux/delay.h>
++#include <linux/rcar-imr.h>
++#include <media/v4l2-device.h>
++#include <media/v4l2-ctrls.h>
++#include <media/v4l2-fh.h>
++#include <media/v4l2-mem2mem.h>
++#include <media/v4l2-ioctl.h>
++#include <media/videobuf2-dma-contig.h>
++
++#define DRV_NAME "rcar_imr"
++
++/*******************************************************************************
++ * Module parameters
++ ******************************************************************************/
++
++static int debug;
++module_param(debug, int, 0644);
++MODULE_PARM_DESC(debug, "Debug level (0-4)");
++
++/*******************************************************************************
++ * Local types definitions
++ ******************************************************************************/
++
++/* ...configuration data */
++struct imr_cfg {
++ /* ...display-list main program data */
++ void *dl_vaddr;
++ dma_addr_t dl_dma_addr;
++ u32 dl_size;
++ u32 dl_start_offset;
++
++ /* ...pointers to the source/destination planes */
++ u32 *src_pa_ptr[2];
++ u32 *dst_pa_ptr[2];
++
++ /* ...subpixel destination coordinates space */
++ int dst_subpixel;
++
++ /* ...reference counter */
++ u32 refcount;
++
++ /* ...identifier (for debug output) */
++ u32 id;
++};
++
++struct imr_buffer {
++ /* ...standard M2M buffer descriptor */
++ struct v4l2_m2m_buffer buf;
++
++ /* ...pointer to mesh configuration for processing */
++ struct imr_cfg *cfg;
++};
++
++struct imr_q_data {
++ /* ...latched pixel format */
++ struct v4l2_pix_format fmt;
++
++ /* ...current format flags */
++ u32 flags;
++};
++
++struct imr_format_info {
++ char *name;
++ u32 fourcc;
++ u32 flags;
++};
++
++/* ...per-device data */
++struct imr_device {
++ struct device *dev;
++ struct clk *clock;
++ void __iomem *mmio;
++ int irq;
++ struct mutex mutex;
++ spinlock_t lock;
++
++ struct v4l2_device v4l2_dev;
++ struct video_device video_dev;
++ struct v4l2_m2m_dev *m2m_dev;
++
++ /* ...do we need that counter really? framework counts fh structures for us - tbd */
++ int refcount;
++
++ /* ...should we include media-dev? likely, no - tbd */
++};
++
++/* ...per file-handle context */
++struct imr_ctx {
++ struct v4l2_fh fh;
++ struct imr_device *imr;
++ struct v4l2_m2m_ctx *m2m_ctx;
++ struct imr_q_data queue[2];
++
++ /* ...current job configuration */
++ struct imr_cfg *cfg;
++
++ /* ...frame sequence counter */
++ u32 sequence;
++
++ /* ...cropping parameters (in pixels) */
++ u16 crop[4];
++
++ /* ...number of active configurations (debugging) */
++ u32 cfg_num;
++};
++
++/*******************************************************************************
++ * IMR registers
++ ******************************************************************************/
++
++#define IMR_CR 0x08
++#define IMR_CR_RS (1 << 0)
++#define IMR_CR_SWRST (1 << 15)
++
++#define IMR_SR 0x0C
++#define IMR_SRCR 0x10
++#define IMR_SR_TRA (1 << 0)
++#define IMR_SR_IER (1 << 1)
++#define IMR_SR_INT (1 << 2)
++#define IMR_SR_REN (1 << 5)
++
++#define IMR_ICR 0x14
++#define IMR_IMR 0x18
++#define IMR_ICR_TRAEN (1 << 0)
++#define IMR_ICR_IEREN (1 << 1)
++#define IMR_ICR_INTEN (1 << 2)
++
++#define IMR_DLSP 0x1C
++#define IMR_DLSR 0x20
++#define IMR_DLSAR 0x30
++
++#define IMR_DSAR 0x34
++#define IMR_SSAR 0x38
++#define IMR_DSTR 0x3C
++#define IMR_SSTR 0x40
++#define IMR_DSOR 0x50
++
++#define IMR_CMRCR 0x54
++#define IMR_CMRCSR 0x58
++#define IMR_CMRCCR 0x5C
++#define IMR_CMR_LUCE (1 << 1)
++#define IMR_CMR_CLCE (1 << 2)
++#define IMR_CMR_DUV_SHIFT 3
++#define IMR_CMR_DUV_MASK (3 << IMR_CMR_DUV_SHIFT)
++#define IMR_CMR_SUV_SHIFT 5
++#define IMR_CMR_SUV_MASK (3 << IMR_CMR_SUV_SHIFT)
++#define IMR_CMR_YISM (1 << 7)
++#define IMR_CMR_DY10 (1 << 8)
++#define IMR_CMR_DY12 (1 << 9)
++#define IMR_CMR_SY10 (1 << 11)
++#define IMR_CMR_SY12 (1 << 12)
++#define IMR_CMR_YCM (1 << 14)
++#define IMR_CMR_CP16E (1 << 15)
++
++#define IMR_CMRCR2 0xE4
++#define IMR_CMRCSR2 0xE8
++#define IMR_CMRCCR2 0xEC
++#define IMR_CMR2_LUTE (1 << 0)
++#define IMR_CMR2_YUV422E (1 << 2)
++#define IMR_CMR2_YUV422FORM (1 << 5)
++#define IMR_CMR2_UVFORM (1 << 6)
++#define IMR_CMR2_TCTE (1 << 12)
++#define IMR_CMR2_DCTE (1 << 15)
++
++#define IMR_TRIMR 0x60
++#define IMR_TRIMSR 0x64
++#define IMR_TRIMCR 0x68
++#define IMR_TRIM_TME (1 << 0)
++#define IMR_TRIM_BFE (1 << 1)
++#define IMR_TRIM_AUTODG (1 << 2)
++#define IMR_TRIM_AUTOSG (1 << 3)
++#define IMR_TRIM_DYDXM (1 << 4)
++#define IMR_TRIM_DUDVM (1 << 5)
++#define IMR_TRIM_TCM (1 << 6)
++
++#define IMR_TRICR 0x6C
++#define IMR_TRIC_YCFORM (1 << 31)
++
++#define IMR_UVDPOR 0x70
++#define IMR_SUSR 0x74
++#define IMR_SVSR 0x78
++
++#define IMR_XMINR 0x80
++#define IMR_YMINR 0x84
++#define IMR_XMAXR 0x88
++#define IMR_YMAXR 0x8C
++
++#define IMR_AMXSR 0x90
++#define IMR_AMYSR 0x94
++#define IMR_AMXOR 0x98
++#define IMR_AMYOR 0x9C
++
++#define IMR_CPDPOR 0xD0
++#define IMR_CPDP_YLDPO_SHIFT 8
++#define IMR_CPDP_UBDPO_SHIFT 4
++#define IMR_CPDP_VRDPO_SHIFT 0
++
++/*******************************************************************************
++ * Auxiliary helpers
++ ******************************************************************************/
++
++static inline struct imr_ctx * fh_to_ctx(struct v4l2_fh *fh)
++{
++ return container_of(fh, struct imr_ctx, fh);
++}
++
++static inline struct imr_buffer * to_imr_buffer(struct vb2_v4l2_buffer *vbuf)
++{
++ struct v4l2_m2m_buffer *b = container_of(vbuf, struct v4l2_m2m_buffer, vb);
++
++ return container_of(b, struct imr_buffer, buf);
++}
++
++/*******************************************************************************
++ * Local constants definition
++ ******************************************************************************/
++
++#define IMR_F_Y8 (1 << 0)
++#define IMR_F_Y10 (1 << 1)
++#define IMR_F_Y12 (1 << 2)
++#define IMR_F_UV8 (1 << 3)
++#define IMR_F_UV10 (1 << 4)
++#define IMR_F_UV12 (1 << 5)
++#define IMR_F_PLANAR (1 << 6)
++#define IMR_F_INTERLEAVED (1 << 7)
++#define IMR_F_PLANES_MASK ((1 << 8) - 1)
++#define IMR_F_UV_SWAP (1 << 8)
++#define IMR_F_YUV_SWAP (1 << 9)
++
++/* ...get common planes bits */
++static inline u32 __imr_flags_common(u32 iflags, u32 oflags)
++{
++ return (iflags & oflags) & IMR_F_PLANES_MASK;
++}
++
++static const struct imr_format_info imr_lx4_formats[] = {
++ {
++ .name = "YUV 4:2:2 semiplanar (NV16)",
++ .fourcc = V4L2_PIX_FMT_NV16,
++ .flags = IMR_F_Y8 | IMR_F_UV8 | IMR_F_PLANAR,
++ },
++ {
++ .name = "YVU 4:2:2 semiplanar (NV61)",
++ .fourcc = V4L2_PIX_FMT_NV61,
++ .flags = IMR_F_Y8 | IMR_F_UV8 | IMR_F_PLANAR | IMR_F_UV_SWAP,
++ },
++ {
++ .name = "YUV 4:2:2 interleaved (YUYV)",
++ .fourcc = V4L2_PIX_FMT_YUYV,
++ .flags = IMR_F_Y8 | IMR_F_UV8,
++ },
++ {
++ .name = "YUV 4:2:2 interleaved (UYVY)",
++ .fourcc = V4L2_PIX_FMT_UYVY,
++ .flags = IMR_F_Y8 | IMR_F_UV8 | IMR_F_YUV_SWAP,
++ },
++ {
++ .name = "YUV 4:2:2 interleaved (YVYU)",
++ .fourcc = V4L2_PIX_FMT_YVYU,
++ .flags = IMR_F_Y8 | IMR_F_UV8 | IMR_F_UV_SWAP,
++ },
++ {
++ .name = "YUV 4:2:2 interleaved (UYVY)",
++ .fourcc = V4L2_PIX_FMT_VYUY,
++ .flags = IMR_F_Y8 | IMR_F_UV8 | IMR_F_UV_SWAP | IMR_F_YUV_SWAP,
++ },
++ {
++ .name = "Greyscale 8-bit",
++ .fourcc = V4L2_PIX_FMT_GREY,
++ .flags = IMR_F_Y8 | IMR_F_PLANAR,
++ },
++ {
++ .name = "Greyscale 10-bit",
++ .fourcc = V4L2_PIX_FMT_Y10,
++ .flags = IMR_F_Y8 | IMR_F_Y10 | IMR_F_PLANAR,
++ },
++ {
++ .name = "Greyscale 12-bit",
++ .fourcc = V4L2_PIX_FMT_Y12,
++ .flags = IMR_F_Y8 | IMR_F_Y10 | IMR_F_Y12 | IMR_F_PLANAR,
++ },
++ {
++ .name = "Chrominance UV 8-bit",
++ .fourcc = V4L2_PIX_FMT_UV8,
++ .flags = IMR_F_UV8 | IMR_F_PLANAR,
++ },
++};
++
++/* ...mesh configuration constructor */
++static struct imr_cfg * imr_cfg_create(struct imr_ctx *ctx, u32 dl_size, u32 dl_start)
++{
++ struct imr_device *imr = ctx->imr;
++ struct imr_cfg *cfg;
++
++ /* ...allocate configuration descriptor */
++ cfg = kmalloc(sizeof(*cfg), GFP_KERNEL);
++ if (!cfg) {
++ v4l2_err(&imr->v4l2_dev, "failed to allocate configuration descriptor\n");
++ return ERR_PTR(-ENOMEM);
++ }
++
++ /* ...allocate contiguous memory for a display list */
++ cfg->dl_vaddr = dma_alloc_writecombine(imr->dev, dl_size, &cfg->dl_dma_addr, GFP_KERNEL);
++ if (!cfg->dl_vaddr) {
++ v4l2_err(&imr->v4l2_dev, "failed to allocate %u bytes for a DL\n", dl_size);
++ kfree(cfg);
++ return ERR_PTR(-ENOMEM);
++ }
++
++ cfg->dl_size = dl_size;
++ cfg->dl_start_offset = dl_start;
++ cfg->refcount = 1;
++ cfg->id = ctx->sequence;
++
++ /* ...for debugging purposes, advance number of active configurations */
++ ctx->cfg_num++;
++
++ return cfg;
++}
++
++/* ...add reference to the current configuration */
++static inline struct imr_cfg * imr_cfg_ref(struct imr_ctx *ctx)
++{
++ struct imr_cfg *cfg = ctx->cfg;
++
++ BUG_ON(!cfg);
++ cfg->refcount++;
++ return cfg;
++}
++
++/* ...mesh configuration destructor */
++static void imr_cfg_unref(struct imr_ctx *ctx, struct imr_cfg *cfg)
++{
++ struct imr_device *imr = ctx->imr;
++
++ /* ...no atomicity is required as operation is locked with device mutex */
++ if (!cfg || --cfg->refcount)
++ return;
++
++ /* ...release memory allocated for a display list */
++ if (cfg->dl_vaddr)
++ dma_free_writecombine(imr->dev, cfg->dl_size, cfg->dl_vaddr, cfg->dl_dma_addr);
++
++ /* ...destroy the configuration structure */
++ kfree(cfg);
++
++ /* ...decrement number of active configurations (debugging) */
++ WARN_ON(!ctx->cfg_num--);
++}
++
++
++
++/*******************************************************************************
++ * Context processing queue
++ ******************************************************************************/
++
++static int imr_queue_setup(struct vb2_queue *vq,
++ unsigned int *nbuffers, unsigned int *nplanes,
++ unsigned int sizes[], struct device *alloc_devs[])
++{
++ struct imr_ctx *ctx = vb2_get_drv_priv(vq);
++ struct imr_q_data *q_data = &ctx->queue[V4L2_TYPE_IS_OUTPUT(vq->type) ? 0 : 1];
++ int w = q_data->fmt.width;
++ int h = q_data->fmt.height;
++
++ /* ...we use only single-plane formats */
++ *nplanes = 1;
++
++ /* ...specify plane size */
++ switch (q_data->fmt.pixelformat) {
++ case V4L2_PIX_FMT_UYVY:
++ case V4L2_PIX_FMT_YUYV:
++ case V4L2_PIX_FMT_VYUY:
++ case V4L2_PIX_FMT_YVYU:
++ case V4L2_PIX_FMT_NV16:
++ case V4L2_PIX_FMT_Y10:
++ case V4L2_PIX_FMT_Y16:
++ sizes[0] = w * h * 2;
++ break;
++
++ case V4L2_PIX_FMT_UV8:
++ case V4L2_PIX_FMT_GREY:
++ sizes[0] = w * h;
++ break;
++
++ default:
++ return -EINVAL;
++ }
++
++ return 0;
++}
++
++static int imr_buf_prepare(struct vb2_buffer *vb)
++{
++ /* ...unclear yet if we want to prepare a buffer somehow (cache invalidation? - tbd) */
++ return 0;
++}
++
++static void imr_buf_queue(struct vb2_buffer *vb)
++{
++ struct vb2_queue *q = vb->vb2_queue;
++ struct imr_ctx *ctx = vb2_get_drv_priv(q);
++ struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
++
++ WARN_ON_ONCE(!mutex_is_locked(&ctx->imr->mutex));
++
++ v4l2_dbg(3, debug, &ctx->imr->v4l2_dev, "%sput buffer <0x%08llx> submitted\n",
++ q->is_output ? "in" : "out",
++ vb2_dma_contig_plane_dma_addr(vb, 0));
++
++ /* ...for input buffer, put current configuration pointer (add reference) */
++ if (q->is_output)
++ to_imr_buffer(vbuf)->cfg = imr_cfg_ref(ctx);
++
++ v4l2_m2m_buf_queue(ctx->m2m_ctx, vbuf);
++}
++
++static void imr_buf_finish(struct vb2_buffer *vb)
++{
++ struct vb2_queue *q = vb->vb2_queue;
++ struct imr_ctx *ctx = vb2_get_drv_priv(q);
++ struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
++
++ WARN_ON(!mutex_is_locked(&ctx->imr->mutex));
++
++ /* ...any special processing of completed buffer? - tbd */
++ v4l2_dbg(3, debug, &ctx->imr->v4l2_dev, "%sput buffer <0x%08llx> done\n",
++ q->is_output ? "in" : "out",
++ vb2_dma_contig_plane_dma_addr(vb, 0));
++
++ /* ...unref configuration pointer as needed */
++ if (q->is_output)
++ imr_cfg_unref(ctx, to_imr_buffer(vbuf)->cfg);
++}
++
++static int imr_start_streaming(struct vb2_queue *vq, unsigned int count)
++{
++ struct imr_ctx *ctx = vb2_get_drv_priv(vq);
++ int ret;
++
++ ret = 0;//pm_runtime_get_sync(ctx->imr->dev);
++ if (ret < 0) {
++ v4l2_err(&ctx->imr->v4l2_dev, "failed to start %s streaming: %d\n",
++ (V4L2_TYPE_IS_OUTPUT(vq->type) ? "output" : "capture"), ret);
++ return ret;
++ } else {
++ v4l2_dbg(1, debug, &ctx->imr->v4l2_dev, "%s streaming started\n",
++ (V4L2_TYPE_IS_OUTPUT(vq->type) ? "output" : "capture"));
++ return 0;
++ }
++}
++
++static void imr_stop_streaming(struct vb2_queue *vq)
++{
++ struct imr_ctx *ctx = vb2_get_drv_priv(vq);
++ struct vb2_v4l2_buffer *vb;
++ unsigned long flags;
++
++ spin_lock_irqsave(&ctx->imr->lock, flags);
++
++ /* ...purge all buffers from a queue */
++ if (V4L2_TYPE_IS_OUTPUT(vq->type)) {
++ while ((vb = v4l2_m2m_src_buf_remove(ctx->m2m_ctx)) != NULL)
++ v4l2_m2m_buf_done(vb, VB2_BUF_STATE_ERROR);
++ } else {
++ while ((vb = v4l2_m2m_dst_buf_remove(ctx->m2m_ctx)) != NULL)
++ v4l2_m2m_buf_done(vb, VB2_BUF_STATE_ERROR);
++ }
++
++ spin_unlock_irqrestore(&ctx->imr->lock, flags);
++
++ v4l2_dbg(1, debug, &ctx->imr->v4l2_dev, "%s streaming stopped\n",
++ (V4L2_TYPE_IS_OUTPUT(vq->type) ? "output" : "capture"));
++
++ //pm_runtime_put(ctx->imr->dev);
++}
++
++/* ...buffer queue operations */
++static struct vb2_ops imr_qops = {
++ .queue_setup = imr_queue_setup,
++ .buf_prepare = imr_buf_prepare,
++ .buf_queue = imr_buf_queue,
++ .buf_finish = imr_buf_finish,
++ .start_streaming = imr_start_streaming,
++ .stop_streaming = imr_stop_streaming,
++ .wait_prepare = vb2_ops_wait_prepare,
++ .wait_finish = vb2_ops_wait_finish,
++};
++
++/* ...M2M device processing queue initialization */
++static int imr_queue_init(void *priv, struct vb2_queue *src_vq,
++ struct vb2_queue *dst_vq)
++{
++ struct imr_ctx *ctx = priv;
++ int ret;
++
++ memset(src_vq, 0, sizeof(*src_vq));
++ src_vq->type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
++ src_vq->io_modes = VB2_MMAP | VB2_USERPTR | VB2_DMABUF;
++ src_vq->drv_priv = ctx;
++ src_vq->buf_struct_size = sizeof(struct imr_buffer);
++ src_vq->ops = &imr_qops;
++ src_vq->mem_ops = &vb2_dma_contig_memops;
++ src_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
++ src_vq->lock = &ctx->imr->mutex;
++ src_vq->dev = ctx->imr->v4l2_dev.dev;
++ ret = vb2_queue_init(src_vq);
++ if (ret)
++ return ret;
++
++ memset(dst_vq, 0, sizeof(*dst_vq));
++ dst_vq->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
++ dst_vq->io_modes = VB2_MMAP | VB2_USERPTR | VB2_DMABUF;
++ dst_vq->drv_priv = ctx;
++ dst_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer);
++ dst_vq->ops = &imr_qops;
++ dst_vq->mem_ops = &vb2_dma_contig_memops;
++ dst_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
++ dst_vq->lock = &ctx->imr->mutex;
++ ret = vb2_queue_init(dst_vq);
++ if (ret)
++ return ret;
++
++ return 0;
++}
++
++/*******************************************************************************
++ * Display list commands
++ ******************************************************************************/
++
++/* ...display list opcodes */
++#define IMR_OP_TRI(n) ((0x8A << 24) | ((n) & 0xFFFF))
++#define IMR_OP_LINE(n) ((0x8B << 24) | ((n) & 0xFFFF))
++#define IMR_OP_NOP(n) ((0x80 << 24) | ((n) & 0xFFFF))
++#define IMR_OP_TRAP ((0x8F << 24))
++#define IMR_OP_WTL(add, n) ((0x81 << 24) | (((add) / 4) << 16) | ((n) & 0xFFFF))
++#define IMR_OP_WTS(add, data) ((0x82 << 24) | (((add) / 4) << 16) | ((data) & 0xFFFF))
++#define IMR_OP_WTL2(add, n) ((0x83 << 24) | (((add) / 4) << 10) | ((n) & 0x3FF))
++#define IMR_OP_INT ((0x88 << 24))
++#define IMR_OP_SYNCM ((0x86 << 24))
++#define IMR_OP_GOSUB ((0x8C << 24))
++#define IMR_OP_RET ((0x8D << 24))
++
++/*******************************************************************************
++ * Operation type decoding helpers
++ ******************************************************************************/
++
++static inline u16 __imr_auto_sg_dg_tcm(u32 type)
++{
++ return (type & IMR_MAP_AUTOSG ? IMR_TRIM_AUTOSG : (type & IMR_MAP_AUTODG ? IMR_TRIM_AUTODG : 0)) |
++ (type & IMR_MAP_TCM ? IMR_TRIM_TCM : 0);
++}
++
++static inline u16 __imr_uvdp(u32 type)
++{
++ return __IMR_MAP_UVDPOR(type) | (type & IMR_MAP_DDP ? (1 << 8) : 0);
++}
++
++static inline u16 __imr_cpdp(u32 type)
++{
++ return (__IMR_MAP_YLDPO(type) << 8) | (__IMR_MAP_UBDPO(type) << 4) | __IMR_MAP_VRDPO(type);
++}
++
++static inline u16 __imr_luce(u32 type)
++{
++ return (type & IMR_MAP_LUCE ? IMR_CMR_LUCE : 0);
++}
++
++static inline u16 __imr_clce(u32 type)
++{
++ return (type & IMR_MAP_CLCE ? IMR_CMR_CLCE : 0);
++}
++
++/*******************************************************************************
++ * Type A (absolute coordinates of source/destination) mapping
++ ******************************************************************************/
++
++/* ...return size of the subroutine for type "a" mapping */
++static inline u32 imr_tri_type_a_get_length(struct imr_mesh *mesh, int item_size)
++{
++ return ((mesh->columns * (item_size / 2) + 1) * (mesh->rows - 1) + 1) * sizeof(u32);
++}
++
++/* ...set a mesh rows * columns using absolute coordinates */
++static inline u32 * imr_tri_set_type_a(u32 *dl, void *map, struct imr_mesh *mesh, int item_size)
++{
++ int rows = mesh->rows;
++ int columns = mesh->columns;
++ u32 stride = item_size * columns;
++ int i, j;
++
++ /* ...convert lattice into set of stripes */
++ for (i = 0; i < rows - 1; i++) {
++ *dl++ = IMR_OP_TRI(columns * 2);
++ for (j = 0; j < columns; j++) {
++ memcpy((void *)dl, map, item_size);
++ memcpy((void *)dl + item_size, map + stride, item_size);
++ dl += item_size / 2;
++ map += item_size;
++ }
++ }
++
++ *dl++ = IMR_OP_RET;
++ return dl;
++}
++
++/*******************************************************************************
++ * Type B mapping (automatically generated source or destination coordinates)
++ ******************************************************************************/
++
++/* ...calculate length of a type "b" mapping */
++static inline u32 imr_tri_type_b_get_length(struct imr_mesh *mesh, int item_size)
++{
++ return ((mesh->columns * (item_size / 2) + 2) * (mesh->rows - 1) + 4) * sizeof(u32);
++}
++
++/* ...set an auto-generated mesh n * m for a source/destination */
++static inline u32 * imr_tri_set_type_b(u32 *dl, void *map, struct imr_mesh *mesh, int item_size)
++{
++ int rows = mesh->rows;
++ int columns = mesh->columns;
++ int x0 = mesh->x0;
++ int y0 = mesh->y0;
++ int dx = mesh->dx;
++ int dy = mesh->dy;
++ int stride = item_size * columns;
++ int i, j;
++
++ /* ...set mesh configuration */
++ *dl++ = IMR_OP_WTS(IMR_AMXSR, dx);
++ *dl++ = IMR_OP_WTS(IMR_AMYSR, dy);
++
++ /* ...origin by "x" coordinate is the same across all rows */
++ *dl++ = IMR_OP_WTS(IMR_AMXOR, x0);
++
++ /* ...convert lattice into set of stripes */
++ for (i = 0; i < rows - 1; i++, y0 += dy) {
++ /* ...set origin by "y" coordinate for a current row */
++ *dl++ = IMR_OP_WTS(IMR_AMYOR, y0);
++ *dl++ = IMR_OP_TRI(2 * columns);
++
++ /* ...fill single row */
++ for (j = 0; j < columns; j++) {
++ memcpy((void *)dl, map, item_size);
++ memcpy((void *)dl + item_size, map + stride, item_size);
++ dl += item_size / 2;
++ map += item_size;
++ }
++ }
++
++ *dl++ = IMR_OP_RET;
++ return dl;
++}
++
++/*******************************************************************************
++ * Type C mapping (vertex-buffer-object)
++ ******************************************************************************/
++
++/* ...calculate length of a type "c" mapping */
++static inline u32 imr_tri_type_c_get_length(struct imr_vbo *vbo, int item_size)
++{
++ return ((4 + 3 * item_size) * vbo->num + 4);
++}
++
++/* ...set a VBO mapping using absolute coordinates */
++static inline u32 * imr_tri_set_type_c(u32 *dl, void *map, struct imr_vbo *vbo, int item_size)
++{
++ int num = vbo->num;
++ int i;
++
++ /* ...prepare list of triangles to draw */
++ for (i = 0; i < num; i++) {
++ *dl++ = IMR_OP_TRI(3);
++ memcpy((void *)dl, map, 3 * item_size);
++ dl += 3 * item_size / 4;
++ map += 3 * item_size;
++ }
++
++ *dl++ = IMR_OP_RET;
++ return dl;
++}
++
++/*******************************************************************************
++ * DL program creation
++ ******************************************************************************/
++
++/* ...return length of a DL main program */
++static inline u32 imr_dl_program_length(struct imr_ctx *ctx)
++{
++ u32 iflags = ctx->queue[0].flags;
++ u32 oflags = ctx->queue[1].flags;
++ u32 cflags = __imr_flags_common(iflags, oflags);
++
++ /* ...check if formats are compatible */
++ if (((iflags & IMR_F_PLANAR) != 0 && (oflags & IMR_F_PLANAR) == 0) || (cflags == 0)) {
++ v4l2_err(&ctx->imr->v4l2_dev, "formats are incompatible: if=%x, of=%x, cf=%x\n", iflags, oflags, cflags);
++ return 0;
++ }
++
++ /* ...maximal possible length of the program is 27 32-bits words; round up to 32 */
++ return 32 << 2;
++}
++
++/* ...setup DL for Y/YUV planar/interleaved processing */
++static inline void imr_dl_program_setup(struct imr_ctx *ctx, struct imr_cfg *cfg, u32 type, u32 *dl, u32 subaddr)
++{
++ u32 iflags = ctx->queue[0].flags;
++ u32 oflags = ctx->queue[1].flags;
++ u32 cflags = __imr_flags_common(iflags, oflags);
++ u16 src_y_fmt = (iflags & IMR_F_Y12 ? IMR_CMR_SY12 : (iflags & IMR_F_Y10 ? IMR_CMR_SY10 : 0));
++ u16 src_uv_fmt = (iflags & IMR_F_UV12 ? 2 : (iflags & IMR_F_UV10 ? 1 : 0)) << IMR_CMR_SUV_SHIFT;
++ u16 dst_y_fmt = (cflags & IMR_F_Y12 ? IMR_CMR_DY12 : (cflags & IMR_F_Y10 ? IMR_CMR_DY10 : 0));
++ u16 dst_uv_fmt = (cflags & IMR_F_UV12 ? 2 : (cflags & IMR_F_UV10 ? 1 : 0)) << IMR_CMR_DUV_SHIFT;
++ int w = ctx->queue[0].fmt.width;
++ int h = ctx->queue[0].fmt.height;
++ int W = ctx->queue[1].fmt.width;
++ int H = ctx->queue[1].fmt.height;
++
++ v4l2_dbg(2, debug, &ctx->imr->v4l2_dev, "setup %u*%u -> %u*%u mapping (type=%x)\n", w, h, W, H, type);
++
++ /* ...set triangle mode register from user-supplied descriptor */
++ *dl++ = IMR_OP_WTS(IMR_TRIMCR, 0xFFFF);
++
++ /* ...set automatic source / destination coordinates generation flags */
++ *dl++ = IMR_OP_WTS(IMR_TRIMSR, __imr_auto_sg_dg_tcm(type) | IMR_TRIM_BFE | IMR_TRIM_TME);
++
++ /* ...set source / destination coordinate precision */
++ *dl++ = IMR_OP_WTS(IMR_UVDPOR, __imr_uvdp(type));
++
++ /* ...set luminance/chromacity correction parameters precision */
++ *dl++ = IMR_OP_WTS(IMR_CPDPOR, __imr_cpdp(type));
++
++ /* ...reset rendering mode registers */
++ *dl++ = IMR_OP_WTS(IMR_CMRCCR, 0xFFFF);
++ *dl++ = IMR_OP_WTS(IMR_CMRCCR2, 0xFFFF);
++
++ /* ...set source/destination addresses of Y/UV plane */
++ *dl++ = IMR_OP_WTL(IMR_DSAR, 2);
++ cfg->dst_pa_ptr[0] = dl++;
++ cfg->src_pa_ptr[0] = dl++;
++
++ /* ...select planar/interleaved mode basing on input format */
++ if (iflags & IMR_F_PLANAR) {
++ /* ...planar input means planar output; set Y-plane precision */
++ if (cflags & IMR_F_Y8) {
++ /* ...setup Y-plane processing: YCM=0, SY/DY=xx, SUV/DUV=0 */
++ *dl++ = IMR_OP_WTS(IMR_CMRCSR, src_y_fmt | src_uv_fmt | dst_y_fmt | dst_uv_fmt | __imr_luce(type));
++
++ /* ...set source/destination strides basing on Y-plane precision */
++ *dl++ = IMR_OP_WTS(IMR_DSTR, W << (cflags & IMR_F_Y10 ? 1 : 0));
++ *dl++ = IMR_OP_WTS(IMR_SSTR, w << (iflags & IMR_F_Y10 ? 1 : 0));
++ } else {
++ /* ...setup UV-plane processing only */
++ *dl++ = IMR_OP_WTS(IMR_CMRCSR, IMR_CMR_YCM | src_uv_fmt | dst_uv_fmt | __imr_clce(type));
++
++ /* ...set source/destination strides basing on UV-plane precision */
++ *dl++ = IMR_OP_WTS(IMR_DSTR, W << (cflags & IMR_F_UV10 ? 1 : 0));
++ *dl++ = IMR_OP_WTS(IMR_SSTR, w << (iflags & IMR_F_UV10 ? 1 : 0));
++ }
++ } else {
++ u16 src_fmt = (iflags & IMR_F_UV_SWAP ? IMR_CMR2_UVFORM : 0) | (iflags & IMR_F_YUV_SWAP ? IMR_CMR2_YUV422FORM : 0);
++ u32 dst_fmt = (oflags & IMR_F_YUV_SWAP ? IMR_TRIC_YCFORM : 0);
++
++ /* ...interleaved input; output is either interleaved or planar */
++ *dl++ = IMR_OP_WTS(IMR_CMRCSR2, IMR_CMR2_YUV422E | src_fmt);
++
++ /* ...destination is always YUYV or UYVY */
++ *dl++ = IMR_OP_WTL(IMR_TRICR, 1);
++ *dl++ = dst_fmt;
++
++ /* ...set precision of Y/UV planes and required correction */
++ *dl++ = IMR_OP_WTS(IMR_CMRCSR, src_y_fmt | src_uv_fmt | dst_y_fmt | dst_uv_fmt | __imr_clce(type) | __imr_luce(type));
++
++ /* ...set source stride basing on precision (2 or 4 bytes/pixel) */
++ *dl++ = IMR_OP_WTS(IMR_SSTR, w << (iflags & IMR_F_Y10 ? 2 : 1));
++
++ /* ...if output is planar, put the offset value */
++ if (oflags & IMR_F_PLANAR) {
++ /* ...specify offset of a destination UV plane */
++ *dl++ = IMR_OP_WTL(IMR_DSOR, 1);
++ *dl++ = W * H;
++
++ /* ...destination stride is 1 or 2 bytes/pixel (same for both Y and UV planes) */
++ *dl++ = IMR_OP_WTS(IMR_DSTR, W << (cflags & IMR_F_Y10 ? 1 : 0));
++ } else {
++ /* ...destination stride if 2 or 4 bytes/pixel (Y and UV planes interleaved) */
++ *dl++ = IMR_OP_WTS(IMR_DSTR, W << (cflags & IMR_F_Y10 ? 2 : 1));
++ }
++ }
++
++ /* ...set source width/height of Y/UV plane (for Y plane upper part of SUSR is ignored) */
++ *dl++ = IMR_OP_WTL(IMR_SUSR, 2);
++ *dl++ = ((w - 2) << 16) | (w - 1);
++ *dl++ = h - 1;
++
++ /* ...invoke subroutine for triangles drawing */
++ *dl++ = IMR_OP_GOSUB;
++ *dl++ = subaddr;
++
++ /* ...if we have a planar output with both Y and UV planes available */
++ if ((cflags & (IMR_F_PLANAR | IMR_F_Y8 | IMR_F_UV8)) == (IMR_F_PLANAR | IMR_F_Y8 | IMR_F_UV8)) {
++ /* ...select UV-plane processing mode; put sync before switching */
++ *dl++ = IMR_OP_SYNCM;
++
++ /* ...setup UV-plane source/destination addresses */
++ *dl++ = IMR_OP_WTL(IMR_DSAR, 2);
++ cfg->dst_pa_ptr[1] = dl++;
++ cfg->src_pa_ptr[1] = dl++;
++
++ /* ...select correction mode */
++ *dl++ = IMR_OP_WTS(IMR_CMRCSR, IMR_CMR_YCM | __imr_clce(type));
++
++ /* ...luminance correction bit must be cleared (if it was set) */
++ *dl++ = IMR_OP_WTS(IMR_CMRCCR, IMR_CMR_LUCE);
++
++ /* ...draw triangles */
++ *dl++ = IMR_OP_GOSUB;
++ *dl++ = subaddr;
++ } else {
++ /* ...clear pointers to the source/destination UV-planes addresses */
++ cfg->src_pa_ptr[1] = cfg->dst_pa_ptr[1] = NULL;
++ }
++
++ /* ...signal completion of the operation */
++ *dl++ = IMR_OP_SYNCM;
++ *dl++ = IMR_OP_TRAP;
++}
++
++/*******************************************************************************
++ * Mapping specification processing
++ ******************************************************************************/
++
++/* ...set mapping data (function called with video device lock held) */
++static int imr_ioctl_map(struct imr_ctx *ctx, struct imr_map_desc *desc)
++{
++ struct imr_device *imr = ctx->imr;
++ struct imr_mesh *mesh;
++ struct imr_vbo *vbo;
++ struct imr_cfg *cfg;
++ void *buf, *map;
++ u32 type;
++ u32 length, item_size;
++ u32 tri_length;
++ void *dl_vaddr;
++ u32 dl_size;
++ u32 dl_start_offset;
++ dma_addr_t dl_dma_addr;
++ int ret;
++
++ /* ...read remainder of data into temporary buffer */
++ length = desc->size;
++ buf = kmalloc(length, GFP_KERNEL);
++ if (!buf) {
++ v4l2_err(&imr->v4l2_dev, "failed to allocate %u bytes for mapping reading\n", length);
++ return -ENOMEM;
++ }
++
++ /* ...copy mesh data */
++ if (copy_from_user(buf, (void __user *)desc->data, length)) {
++ v4l2_err(&imr->v4l2_dev, "failed to read %u bytes of mapping specification\n", length);
++ ret = -EFAULT;
++ goto out;
++ }
++
++ type = desc->type;
++
++ /* ...mesh item size calculation */
++ item_size = (type & IMR_MAP_LUCE ? 4 : 0) + (type & IMR_MAP_CLCE ? 4 : 0);
++
++ /* ...calculate the length of a display list */
++ if (type & IMR_MAP_MESH) {
++ /* ...assure we have proper mesh descriptor */
++ if (length < sizeof(struct imr_mesh)) {
++ v4l2_err(&imr->v4l2_dev, "invalid mesh specification size: %u\n", length);
++ ret = -EINVAL;
++ goto out;
++ }
++
++ mesh = (struct imr_mesh *)buf;
++ length -= sizeof(struct imr_mesh);
++ map = buf + sizeof(struct imr_mesh);
++
++ if (type & (IMR_MAP_AUTODG | IMR_MAP_AUTOSG)) {
++ /* ...source / destination vertex size is 4 bytes */
++ item_size += 4;
++
++ /* ...mapping is given using automatic generation pattern; check size */
++ if (mesh->rows * mesh->columns * item_size != length) {
++ v4l2_err(&imr->v4l2_dev, "invalid mesh size: %u*%u*%u != %u\n", mesh->rows, mesh->columns, item_size, length);
++ ret = -EINVAL;
++ goto out;
++ }
++
++ /* ...calculate size of triangles drawing subroutine */
++ tri_length = imr_tri_type_b_get_length(mesh, item_size);
++ } else {
++ /* ...source / destination vertes size if 8 bytes */
++ item_size += 8;
++
++ /* ...mapping is done with absolute coordinates */
++ if (mesh->rows * mesh->columns * item_size != length) {
++ v4l2_err(&imr->v4l2_dev, "invalid mesh size: %u*%u*%u != %u\n", mesh->rows, mesh->columns, item_size, length);
++ ret = -EINVAL;
++ goto out;
++ }
++
++ /* ...calculate size of triangles drawing subroutine */
++ tri_length = imr_tri_type_a_get_length(mesh, item_size);
++ }
++ } else {
++ /* ...assure we have proper VBO descriptor */
++ if (length < sizeof(struct imr_vbo)) {
++ v4l2_err(&imr->v4l2_dev, "invalid vbo specification size: %u\n", length);
++ ret = -EINVAL;
++ goto out;
++ }
++
++ /* ...make sure there is no automatic-generation flags */
++ if (type & (IMR_MAP_AUTODG | IMR_MAP_AUTOSG)) {
++ v4l2_err(&imr->v4l2_dev, "invalid auto-dg/sg flags: 0x%x\n", type);
++ ret = -EINVAL;
++ goto out;
++ }
++
++ vbo = (struct imr_vbo *)buf;
++ length -= sizeof(struct imr_vbo);
++ map = buf + sizeof(struct imr_vbo);
++
++ /* ...vertex is given with absolute coordinates */
++ item_size += 8;
++
++ /* ...check the length is sane */
++ if (length != vbo->num * 3 * item_size) {
++ v4l2_err(&imr->v4l2_dev, "invalid vbo size: %u*%u*3 != %u\n", vbo->num, item_size, length);
++ ret = -EINVAL;
++ goto out;
++ }
++
++ /* ...calculate size of trangles drawing subroutine */
++ tri_length = imr_tri_type_c_get_length(vbo, item_size);
++ }
++
++ /* ...DL main program shall start with 8-byte aligned address */
++ dl_start_offset = (tri_length + 7) & ~7;
++
++ /* ...calculate main routine length */
++ dl_size = imr_dl_program_length(ctx);
++ if (!dl_size) {
++ v4l2_err(&imr->v4l2_dev, "format configuration error\n");
++ ret = -EINVAL;
++ goto out;
++ }
++
++ /* ...we use a single display list, with TRI subroutine prepending MAIN */
++ dl_size += dl_start_offset;
++
++ /* ...unref current configuration (will not be used by subsequent jobs) */
++ imr_cfg_unref(ctx, ctx->cfg);
++
++ /* ...create new configuration */
++ ctx->cfg = cfg = imr_cfg_create(ctx, dl_size, dl_start_offset);
++ if (IS_ERR(cfg)) {
++ ret = PTR_ERR(cfg);
++ v4l2_err(&imr->v4l2_dev, "failed to create configuration: %d\n", ret);
++ goto out;
++ }
++
++ /* ...get pointer to the new display list */
++ dl_vaddr = cfg->dl_vaddr;
++ dl_dma_addr = cfg->dl_dma_addr;
++
++ /* ...prepare a triangles drawing subroutine */
++ if (type & IMR_MAP_MESH) {
++ if (type & (IMR_MAP_AUTOSG | IMR_MAP_AUTODG)) {
++ imr_tri_set_type_b(dl_vaddr, map, mesh, item_size);
++ } else {
++ imr_tri_set_type_a(dl_vaddr, map, mesh, item_size);
++ }
++ } else {
++ imr_tri_set_type_c(dl_vaddr, map, vbo, item_size);
++ }
++
++ /* ...prepare main DL-program */
++ imr_dl_program_setup(ctx, cfg, type, dl_vaddr + dl_start_offset, (u32)dl_dma_addr);
++
++ /* ...update cropping parameters */
++ cfg->dst_subpixel = (type & IMR_MAP_DDP ? 2 : 0);
++
++ /* ...display list updated successfully */
++ v4l2_dbg(2, debug, &ctx->imr->v4l2_dev, "display-list created: #%u[%08X]:%u[%u]\n",
++ cfg->id, (u32)dl_dma_addr, dl_size, dl_start_offset);
++
++ if (debug >= 4)
++ print_hex_dump_bytes("DL-", DUMP_PREFIX_OFFSET, dl_vaddr + dl_start_offset, dl_size - dl_start_offset);
++
++ /* ...success */
++ ret = 0;
++
++out:
++ /* ...release interim buffer */
++ kfree(buf);
++
++ return ret;
++}
++
++/*******************************************************************************
++ * V4L2 I/O controls
++ ******************************************************************************/
++
++/* ...test for a format supported */
++static int __imr_try_fmt(struct imr_ctx *ctx, struct v4l2_format *f)
++{
++ struct v4l2_pix_format *pix = &f->fmt.pix;
++ u32 fourcc = pix->pixelformat;
++ int i;
++
++ /* ...both output and capture interface have the same set of supported formats */
++ for (i = 0; i < ARRAY_SIZE(imr_lx4_formats); i++) {
++ if (fourcc == imr_lx4_formats[i].fourcc) {
++ /* ...fix-up format specification as needed */
++ pix->field = V4L2_FIELD_NONE;
++
++ v4l2_dbg(1, debug, &ctx->imr->v4l2_dev, "format request: '%c%c%c%c', %d*%d\n",
++ (fourcc >> 0) & 0xff, (fourcc >> 8) & 0xff,
++ (fourcc >> 16) & 0xff, (fourcc >> 24) & 0xff,
++ pix->width, pix->height);
++
++ /* ...verify source/destination image dimensions */
++ if (V4L2_TYPE_IS_OUTPUT(f->type))
++ v4l_bound_align_image(&pix->width, 128, 2048, 7, &pix->height, 1, 2048, 0, 0);
++ else
++ v4l_bound_align_image(&pix->width, 64, 2048, 6, &pix->height, 1, 2048, 0, 0);
++
++ return i;
++ }
++ }
++
++ v4l2_err(&ctx->imr->v4l2_dev, "unsupported format request: '%c%c%c%c'\n",
++ (fourcc >> 0) & 0xff, (fourcc >> 8) & 0xff,
++ (fourcc >> 16) & 0xff, (fourcc >> 24) & 0xff);
++
++ return -EINVAL;
++}
++
++/* ...capabilities query */
++static int imr_querycap(struct file *file, void *priv, struct v4l2_capability *cap)
++{
++ strlcpy(cap->driver, DRV_NAME, sizeof(cap->driver));
++ strlcpy(cap->card, DRV_NAME, sizeof(cap->card));
++ strlcpy(cap->bus_info, DRV_NAME, sizeof(cap->bus_info));
++
++ cap->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_VIDEO_OUTPUT |
++ V4L2_CAP_VIDEO_M2M | V4L2_CAP_STREAMING;
++
++ cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS;
++
++ return 0;
++}
++
++/* ...enumerate supported formats */
++static int imr_enum_fmt(struct file *file, void *priv, struct v4l2_fmtdesc *f)
++{
++ /* ...no distinction between output/capture formats */
++ if (f->index < ARRAY_SIZE(imr_lx4_formats)) {
++ const struct imr_format_info *fmt = &imr_lx4_formats[f->index];
++ strlcpy(f->description, fmt->name, sizeof(f->description));
++ f->pixelformat = fmt->fourcc;
++ return 0;
++ }
++
++ return -EINVAL;
++}
++
++/* ...retrieve current queue format; operation is locked ? */
++static int imr_g_fmt(struct file *file, void *priv, struct v4l2_format *f)
++{
++ struct imr_ctx *ctx = fh_to_ctx(priv);
++ struct vb2_queue *vq;
++ struct imr_q_data *q_data;
++
++ vq = v4l2_m2m_get_vq(ctx->m2m_ctx, f->type);
++ if (!vq)
++ return -EINVAL;
++
++ q_data = &ctx->queue[V4L2_TYPE_IS_OUTPUT(f->type) ? 0 : 1];
++
++ /* ...processing is locked? tbd */
++ f->fmt.pix = q_data->fmt;
++
++ return 0;
++}
++
++/* ...test particular format; operation is not locked */
++static int imr_try_fmt(struct file *file, void *priv, struct v4l2_format *f)
++{
++ struct imr_ctx *ctx = fh_to_ctx(priv);
++ struct vb2_queue *vq;
++
++ /* ...make sure we have a queue of particular type */
++ vq = v4l2_m2m_get_vq(ctx->m2m_ctx, f->type);
++ if (!vq)
++ return -EINVAL;
++
++ /* ...test if format is supported (adjust as appropriate) */
++ return (__imr_try_fmt(ctx, f) >= 0 ? 0 : -EINVAL);
++}
++
++/* ...apply queue format; operation is locked ? */
++static int imr_s_fmt(struct file *file, void *priv, struct v4l2_format *f)
++{
++ struct imr_ctx *ctx = fh_to_ctx(priv);
++ struct vb2_queue *vq;
++ struct imr_q_data *q_data;
++ int i;
++
++ vq = v4l2_m2m_get_vq(ctx->m2m_ctx, f->type);
++ if (!vq)
++ return -EINVAL;
++
++ /* ...check if queue is busy */
++ if (vb2_is_busy(vq))
++ return -EBUSY;
++
++ /* ...test if format is supported (adjust as appropriate) */
++ i = __imr_try_fmt(ctx, f);
++ if (i < 0)
++ return -EINVAL;
++
++ /* ...format is supported; save current format in a queue-specific data */
++ q_data = &ctx->queue[V4L2_TYPE_IS_OUTPUT(f->type) ? 0 : 1];
++
++ /* ...processing is locked? tbd */
++ q_data->fmt = f->fmt.pix;
++ q_data->flags = imr_lx4_formats[i].flags;
++
++ /* ...set default crop factors */
++ if (V4L2_TYPE_IS_OUTPUT(f->type) == 0) {
++ ctx->crop[0] = 0;
++ ctx->crop[1] = f->fmt.pix.width - 1;
++ ctx->crop[2] = 0;
++ ctx->crop[3] = f->fmt.pix.height - 1;
++ }
++
++ return 0;
++}
++
++static int imr_reqbufs(struct file *file, void *priv, struct v4l2_requestbuffers *reqbufs)
++{
++ struct imr_ctx *ctx = fh_to_ctx(priv);
++
++ return v4l2_m2m_reqbufs(file, ctx->m2m_ctx, reqbufs);
++}
++
++static int imr_querybuf(struct file *file, void *priv, struct v4l2_buffer *buf)
++{
++ struct imr_ctx *ctx = fh_to_ctx(priv);
++
++ return v4l2_m2m_querybuf(file, ctx->m2m_ctx, buf);
++}
++
++static int imr_qbuf(struct file *file, void *priv, struct v4l2_buffer *buf)
++{
++ struct imr_ctx *ctx = fh_to_ctx(priv);
++
++ /* ...operation is protected with a queue lock */
++ WARN_ON(!mutex_is_locked(&ctx->imr->mutex));
++
++ /* ...verify the configuration is complete */
++ if (!V4L2_TYPE_IS_OUTPUT(buf->type) && !ctx->cfg) {
++ v4l2_err(&ctx->imr->v4l2_dev, "stream configuration is not complete\n");
++ return -EINVAL;
++ }
++
++ return v4l2_m2m_qbuf(file, ctx->m2m_ctx, buf);
++}
++
++static int imr_dqbuf(struct file *file, void *priv, struct v4l2_buffer *buf)
++{
++ struct imr_ctx *ctx = fh_to_ctx(priv);
++
++ return v4l2_m2m_dqbuf(file, ctx->m2m_ctx, buf);
++}
++
++static int imr_expbuf(struct file *file, void *priv, struct v4l2_exportbuffer *eb)
++{
++ struct imr_ctx *ctx = fh_to_ctx(priv);
++
++ return v4l2_m2m_expbuf(file, ctx->m2m_ctx, eb);
++}
++
++static int imr_streamon(struct file *file, void *priv, enum v4l2_buf_type type)
++{
++ struct imr_ctx *ctx = fh_to_ctx(priv);
++
++ /* ...context is prepared for a streaming */
++ return v4l2_m2m_streamon(file, ctx->m2m_ctx, type);
++}
++
++static int imr_streamoff(struct file *file, void *priv, enum v4l2_buf_type type)
++{
++ struct imr_ctx *ctx = fh_to_ctx(priv);
++
++ return v4l2_m2m_streamoff(file, ctx->m2m_ctx, type);
++}
++
++static int imr_g_crop(struct file *file, void *priv, struct v4l2_crop *cr)
++{
++ struct imr_ctx *ctx = fh_to_ctx(priv);
++
++ /* ...subpixel resolution of output buffer is not counted here */
++ cr->c.left = ctx->crop[0];
++ cr->c.top = ctx->crop[2];
++ cr->c.width = ctx->crop[1] - ctx->crop[0];
++ cr->c.height = ctx->crop[3] - ctx->crop[2];
++
++ return 0;
++}
++
++static int imr_s_crop(struct file *file, void *priv, const struct v4l2_crop *cr)
++{
++ struct imr_ctx *ctx = fh_to_ctx(priv);
++ int x0 = cr->c.left;
++ int y0 = cr->c.top;
++ int x1 = x0 + cr->c.width;
++ int y1 = y0 + cr->c.height;
++
++ if (x0 < 0 || x1 >= 2048 || y0 < 0 || y1 >= 2048) {
++ v4l2_err(&ctx->imr->v4l2_dev, "invalid cropping: %d/%d/%d/%d\n", x0, x1, y0, y1);
++ return -EINVAL;
++ }
++
++ /* ...subpixel resolution of output buffer is not counted here */
++ ctx->crop[0] = x0;
++ ctx->crop[1] = x1;
++ ctx->crop[2] = y0;
++ ctx->crop[3] = y1;
++
++ return 0;
++}
++
++/* ...customized I/O control processing */
++static long imr_default(struct file *file, void *fh, bool valid_prio, unsigned int cmd, void *arg)
++{
++ struct imr_ctx *ctx = fh_to_ctx(fh);
++
++ switch (cmd) {
++ case VIDIOC_IMR_MESH:
++ /* ...set mesh data */
++ return imr_ioctl_map(ctx, (struct imr_map_desc *)arg);
++
++ default:
++ return -ENOIOCTLCMD;
++ }
++}
++
++static const struct v4l2_ioctl_ops imr_ioctl_ops = {
++ .vidioc_querycap = imr_querycap,
++
++ .vidioc_enum_fmt_vid_cap = imr_enum_fmt,
++ .vidioc_enum_fmt_vid_out = imr_enum_fmt,
++ .vidioc_g_fmt_vid_cap = imr_g_fmt,
++ .vidioc_g_fmt_vid_out = imr_g_fmt,
++ .vidioc_try_fmt_vid_cap = imr_try_fmt,
++ .vidioc_try_fmt_vid_out = imr_try_fmt,
++ .vidioc_s_fmt_vid_cap = imr_s_fmt,
++ .vidioc_s_fmt_vid_out = imr_s_fmt,
++
++ .vidioc_reqbufs = imr_reqbufs,
++ .vidioc_querybuf = imr_querybuf,
++ .vidioc_qbuf = imr_qbuf,
++ .vidioc_dqbuf = imr_dqbuf,
++ .vidioc_expbuf = imr_expbuf,
++ .vidioc_streamon = imr_streamon,
++ .vidioc_streamoff = imr_streamoff,
++
++ .vidioc_g_crop = imr_g_crop,
++ .vidioc_s_crop = imr_s_crop,
++
++ .vidioc_default = imr_default,
++};
++
++/*******************************************************************************
++ * Generic device file operations
++ ******************************************************************************/
++
++static int imr_open(struct file *file)
++{
++ struct imr_device *imr = video_drvdata(file);
++ struct video_device *vfd = video_devdata(file);
++ struct imr_ctx *ctx;
++ int ret;
++
++ /* ...allocate processing context associated with given instance */
++ ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
++ if (!ctx)
++ return -ENOMEM;
++
++ /* ...initialize per-file-handle structure */
++ v4l2_fh_init(&ctx->fh, vfd);
++ //ctx->fh.ctrl_handler = &ctx->ctrl_handler;
++ file->private_data = &ctx->fh;
++ v4l2_fh_add(&ctx->fh);
++
++ /* ...set default source / destination formats - need that? */
++ ctx->imr = imr;
++ ctx->queue[0].fmt.pixelformat = 0;
++ ctx->queue[1].fmt.pixelformat = 0;
++
++ /* ...set default cropping parameters */
++ ctx->crop[1] = ctx->crop[3] = 0x3FF;
++
++ /* ...initialize M2M processing context */
++ ctx->m2m_ctx = v4l2_m2m_ctx_init(imr->m2m_dev, ctx, imr_queue_init);
++ if (IS_ERR(ctx->m2m_ctx)) {
++ ret = PTR_ERR(ctx->m2m_ctx);
++ goto v4l_prepare_rollback;
++ }
++
++#if 0
++ /* ...initialize controls and stuff */
++ ret = imr_controls_create(ctx);
++ if (ret < 0)
++ goto v4l_prepare_rollback;
++#endif
++
++ /* ...lock access to global device data */
++ if (mutex_lock_interruptible(&imr->mutex)) {
++ ret = -ERESTARTSYS;
++ goto v4l_prepare_rollback;
++ }
++
++ /* ...bring-up device as needed */
++ if (imr->refcount == 0) {
++ ret = clk_prepare_enable(imr->clock);
++ if (ret < 0)
++ goto device_prepare_rollback;
++ }
++
++ imr->refcount++;
++
++ mutex_unlock(&imr->mutex);
++
++ v4l2_dbg(1, debug, &imr->v4l2_dev, "IMR device opened (refcount=%u)\n", imr->refcount);
++
++ return 0;
++
++device_prepare_rollback:
++ /* ...unlock global device data */
++ mutex_unlock(&imr->mutex);
++
++v4l_prepare_rollback:
++ /* ...destroy context */
++ v4l2_fh_del(&ctx->fh);
++ v4l2_fh_exit(&ctx->fh);
++ kfree(ctx);
++
++ return ret;
++}
++
++static int imr_release(struct file *file)
++{
++ struct imr_device *imr = video_drvdata(file);
++ struct imr_ctx *ctx = fh_to_ctx(file->private_data);
++
++ /* ...I don't need to get a device-scope lock here really - tbd */
++ mutex_lock(&imr->mutex);
++
++ /* ...destroy M2M device processing context */
++ v4l2_m2m_ctx_release(ctx->m2m_ctx);
++ //v4l2_ctrl_handler_free(&ctx->ctrl_handler);
++ v4l2_fh_del(&ctx->fh);
++ v4l2_fh_exit(&ctx->fh);
++
++ /* ...drop active configuration as needed */
++ imr_cfg_unref(ctx, ctx->cfg);
++
++ /* ...make sure there are no more active configs */
++ WARN_ON(ctx->cfg_num);
++
++ /* ...destroy context data */
++ kfree(ctx);
++
++ /* ...disable hardware operation */
++ if (--imr->refcount == 0)
++ clk_disable_unprepare(imr->clock);
++
++ mutex_unlock(&imr->mutex);
++
++ v4l2_dbg(1, debug, &imr->v4l2_dev, "closed device instance\n");
++
++ return 0;
++}
++
++static unsigned int imr_poll(struct file *file, struct poll_table_struct *wait)
++{
++ struct imr_device *imr = video_drvdata(file);
++ struct imr_ctx *ctx = fh_to_ctx(file->private_data);
++ unsigned int res;
++
++ if (mutex_lock_interruptible(&imr->mutex))
++ return -ERESTARTSYS;
++
++ res = v4l2_m2m_poll(file, ctx->m2m_ctx, wait);
++ mutex_unlock(&imr->mutex);
++
++ return res;
++}
++
++static int imr_mmap(struct file *file, struct vm_area_struct *vma)
++{
++ struct imr_device *imr = video_drvdata(file);
++ struct imr_ctx *ctx = fh_to_ctx(file->private_data);
++ int ret;
++
++ /* ...should we protect all M2M operations with mutex? - tbd */
++ if (mutex_lock_interruptible(&imr->mutex))
++ return -ERESTARTSYS;
++
++ ret = v4l2_m2m_mmap(file, ctx->m2m_ctx, vma);
++
++ mutex_unlock(&imr->mutex);
++
++ return ret;
++}
++
++static const struct v4l2_file_operations imr_fops = {
++ .owner = THIS_MODULE,
++ .open = imr_open,
++ .release = imr_release,
++ .poll = imr_poll,
++ .mmap = imr_mmap,
++ .unlocked_ioctl = video_ioctl2,
++};
++
++/*******************************************************************************
++ * M2M device interface
++ ******************************************************************************/
++
++#if 0
++/* ...job cleanup function */
++static void imr_cleanup(struct imr_ctx *ctx)
++{
++ struct imr_device *imr = ctx->imr;
++ struct vb2_v4l2_buffer *src_buf, *dst_buf;
++ unsigned long flags;
++
++ /* ...interlock buffer handling with interrupt */
++ spin_lock_irqsave(&imr->lock, flags);
++
++ while ((src_buf = v4l2_m2m_src_buf_remove(ctx->m2m_ctx)) != NULL)
++ v4l2_m2m_buf_done(src_buf, VB2_BUF_STATE_ERROR);
++
++ while ((dst_buf = v4l2_m2m_dst_buf_remove(ctx->m2m_ctx)) != NULL)
++ v4l2_m2m_buf_done(dst_buf, VB2_BUF_STATE_ERROR);
++
++ /* ...release lock before we mark current job as finished */
++ spin_unlock_irqrestore(&imr->lock, flags);
++}
++#endif
++
++/* ...job execution function */
++static void imr_device_run(void *priv)
++{
++ struct imr_ctx *ctx = priv;
++ struct imr_device *imr = ctx->imr;
++ struct imr_cfg *cfg;
++ struct vb2_buffer *src_buf, *dst_buf;
++ u32 src_addr, dst_addr;
++ unsigned long flags;
++
++ v4l2_dbg(3, debug, &imr->v4l2_dev, "run next job...\n");
++
++ /* ...protect access to internal device state */
++ spin_lock_irqsave(&imr->lock, flags);
++
++ /* ...retrieve input/output buffers */
++ src_buf = v4l2_m2m_next_src_buf(ctx->m2m_ctx);
++ dst_buf = v4l2_m2m_next_dst_buf(ctx->m2m_ctx);
++
++ /* ...take configuration pointer associated with input buffer */
++ cfg = to_imr_buffer(to_vb2_v4l2_buffer(src_buf))->cfg;
++
++ /* ...cancel software reset state as needed */
++ iowrite32(0, imr->mmio + IMR_CR);
++
++ /* ...set cropping data with respect to destination sub-pixel mode */
++ iowrite32(ctx->crop[0] << cfg->dst_subpixel, imr->mmio + IMR_XMINR);
++ iowrite32(ctx->crop[1] << cfg->dst_subpixel, imr->mmio + IMR_XMAXR);
++ iowrite32(ctx->crop[2] << cfg->dst_subpixel, imr->mmio + IMR_YMINR);
++ iowrite32(ctx->crop[3] << cfg->dst_subpixel, imr->mmio + IMR_YMAXR);
++
++ /* ...adjust source/destination parameters of the program (interleaved / semiplanar) */
++ *cfg->src_pa_ptr[0] = src_addr = (u32)vb2_dma_contig_plane_dma_addr(src_buf, 0);
++ *cfg->dst_pa_ptr[0] = dst_addr = (u32)vb2_dma_contig_plane_dma_addr(dst_buf, 0);
++
++ /* ...adjust source/destination parameters of the UV-plane as needed */
++ if (cfg->src_pa_ptr[1] && cfg->dst_pa_ptr[1]) {
++ *cfg->src_pa_ptr[1] = src_addr + ctx->queue[0].fmt.width * ctx->queue[0].fmt.height;
++ *cfg->dst_pa_ptr[1] = dst_addr + ctx->queue[1].fmt.width * ctx->queue[1].fmt.height;
++ }
++
++ v4l2_dbg(3, debug, &imr->v4l2_dev, "process buffer-pair 0x%08x:0x%08x\n",
++ *cfg->src_pa_ptr[0], *cfg->dst_pa_ptr[0]);
++
++ /* ...force clearing of status register bits */
++ iowrite32(0x7, imr->mmio + IMR_SRCR);
++
++ /* ...unmask/enable interrupts */
++ iowrite32(ioread32(imr->mmio + IMR_ICR) | (IMR_ICR_TRAEN | IMR_ICR_IEREN | IMR_ICR_INTEN), imr->mmio + IMR_ICR);
++ iowrite32(ioread32(imr->mmio + IMR_IMR) & ~(IMR_ICR_TRAEN | IMR_ICR_IEREN | IMR_ICR_INTEN), imr->mmio + IMR_IMR);
++
++ /* ...set display list address */
++ iowrite32(cfg->dl_dma_addr + cfg->dl_start_offset, imr->mmio + IMR_DLSAR);
++
++ /* ...explicitly flush any pending write operations (don't need that, I guess) */
++ wmb();
++
++ /* ...start rendering operation */
++ iowrite32(IMR_CR_RS, imr->mmio + IMR_CR);
++
++ /* ...timestamp input buffer */
++ src_buf->timestamp = ktime_get_ns();
++
++ /* ...unlock device access */
++ spin_unlock_irqrestore(&imr->lock, flags);
++
++ v4l2_dbg(1, debug, &imr->v4l2_dev, "rendering started: status=%X, DLSAR=0x%08X, DLPR=0x%08X\n", ioread32(imr->mmio + IMR_SR), ioread32(imr->mmio + IMR_DLSAR), ioread32(imr->mmio + IMR_DLSR));
++}
++
++/* ...check whether a job is ready for execution */
++static int imr_job_ready(void *priv)
++{
++ /* ...no specific requirements on the job readiness */
++ return 1;
++}
++
++/* ...abort currently processed job */
++static void imr_job_abort(void *priv)
++{
++ struct imr_ctx *ctx = priv;
++ struct imr_device *imr = ctx->imr;
++ unsigned long flags;
++
++ /* ...protect access to internal device state */
++ spin_lock_irqsave(&imr->lock, flags);
++
++ /* ...make sure current job is still current (may get finished by interrupt already) */
++ if (v4l2_m2m_get_curr_priv(imr->m2m_dev) == ctx) {
++ v4l2_dbg(1, debug, &imr->v4l2_dev, "abort job: status=%X, DLSAR=0x%08X, DLPR=0x%08X\n",
++ ioread32(imr->mmio + IMR_SR), ioread32(imr->mmio + IMR_DLSAR), ioread32(imr->mmio + IMR_DLSR));
++
++ /* ...force device reset to stop processing of the buffers */
++ //iowrite32(IMR_CR_SWRST, imr->mmio + IMR_CR);
++
++ /* ...resetting the module while operation is active may lead to hw-stall */
++ spin_unlock_irqrestore(&imr->lock, flags);
++
++ /* ...finish current job as interrupt will probably not occur */
++ //v4l2_m2m_job_finish(imr->m2m_dev, ctx->m2m_ctx);
++ } else {
++ spin_unlock_irqrestore(&imr->lock, flags);
++ v4l2_dbg(1, debug, &imr->v4l2_dev, "job has completed already\n");
++ }
++}
++
++/* ...M2M interface definition */
++static struct v4l2_m2m_ops imr_m2m_ops = {
++ .device_run = imr_device_run,
++ .job_ready = imr_job_ready,
++ .job_abort = imr_job_abort,
++};
++
++/*******************************************************************************
++ * Interrupt handling
++ ******************************************************************************/
++
++static irqreturn_t imr_irq_handler(int irq, void *data)
++{
++ struct imr_device *imr = data;
++ struct imr_ctx *ctx;
++ struct vb2_v4l2_buffer *src_buf, *dst_buf;
++ u32 status;
++ irqreturn_t ret = IRQ_NONE;
++
++ /* ...check and ack interrupt status */
++ status = ioread32(imr->mmio + IMR_SR);
++ iowrite32(status, imr->mmio + IMR_SRCR);
++ if (!(status & (IMR_SR_INT | IMR_SR_IER | IMR_SR_TRA))) {
++ v4l2_err(&imr->v4l2_dev, "spurious interrupt: %x\n", status);
++ return ret;
++ }
++
++ /* ...protect access to current context */
++ spin_lock(&imr->lock);
++
++ /* ...get current job context (may have been cancelled already) */
++ ctx = v4l2_m2m_get_curr_priv(imr->m2m_dev);
++ if (!ctx) {
++ v4l2_dbg(3, debug, &imr->v4l2_dev, "no active job\n");
++ goto handled;
++ }
++
++ /* ...remove buffers (may have been removed already?) */
++ src_buf = v4l2_m2m_src_buf_remove(ctx->m2m_ctx);
++ dst_buf = v4l2_m2m_dst_buf_remove(ctx->m2m_ctx);
++ if (!src_buf || !dst_buf) {
++ v4l2_dbg(3, debug, &imr->v4l2_dev, "no buffers associated with current context\n");
++ goto handled;
++ }
++
++ /* ...check for a TRAP interrupt indicating completion of current DL */
++ if (status & IMR_SR_TRA) {
++ /* ...operation completed normally; timestamp output buffer */
++ dst_buf->vb2_buf.timestamp = ktime_get_ns();
++ if (src_buf->flags & V4L2_BUF_FLAG_TIMECODE)
++ dst_buf->timecode = src_buf->timecode;
++ dst_buf->flags = src_buf->flags & (V4L2_BUF_FLAG_TIMECODE | V4L2_BUF_FLAG_KEYFRAME |
++ V4L2_BUF_FLAG_PFRAME | V4L2_BUF_FLAG_BFRAME | V4L2_BUF_FLAG_TSTAMP_SRC_MASK);
++ dst_buf->sequence = src_buf->sequence = ctx->sequence++;
++ v4l2_m2m_buf_done(src_buf, VB2_BUF_STATE_DONE);
++ v4l2_m2m_buf_done(dst_buf, VB2_BUF_STATE_DONE);
++
++ v4l2_dbg(3, debug, &imr->v4l2_dev, "buffers <0x%08x,0x%08x> done\n",
++ (u32)vb2_dma_contig_plane_dma_addr(&src_buf->vb2_buf, 0),
++ (u32)vb2_dma_contig_plane_dma_addr(&dst_buf->vb2_buf, 0));
++ } else {
++ /* ...operation completed in error; no way to understand what exactly went wrong */
++ v4l2_m2m_buf_done(src_buf, VB2_BUF_STATE_ERROR);
++ v4l2_m2m_buf_done(dst_buf, VB2_BUF_STATE_ERROR);
++
++ v4l2_dbg(3, debug, &imr->v4l2_dev, "buffers <0x%08x,0x%08x> done in error\n",
++ (u32)vb2_dma_contig_plane_dma_addr(&src_buf->vb2_buf, 0),
++ (u32)vb2_dma_contig_plane_dma_addr(&dst_buf->vb2_buf, 0));
++ }
++
++ spin_unlock(&imr->lock);
++
++ /* ...finish current job (and start any pending) */
++ v4l2_m2m_job_finish(imr->m2m_dev, ctx->m2m_ctx);
++
++ return IRQ_HANDLED;
++
++handled:
++ /* ...again, what exactly is to be protected? */
++ spin_unlock(&imr->lock);
++
++ return IRQ_HANDLED;
++}
++
++/*******************************************************************************
++ * Device probing / removal interface
++ ******************************************************************************/
++
++static int imr_probe(struct platform_device *pdev)
++{
++ struct imr_device *imr;
++ struct resource *res;
++ int ret;
++
++ imr = devm_kzalloc(&pdev->dev, sizeof(*imr), GFP_KERNEL);
++ if (!imr)
++ return -ENOMEM;
++
++ mutex_init(&imr->mutex);
++ spin_lock_init(&imr->lock);
++ imr->dev = &pdev->dev;
++
++ /* ...memory-mapped registers */
++ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
++ if (!res) {
++ dev_err(&pdev->dev, "cannot get memory region\n");
++ return -EINVAL;
++ }
++
++ imr->mmio = devm_ioremap_resource(&pdev->dev, res);
++ if (IS_ERR(imr->mmio))
++ return PTR_ERR(imr->mmio);
++
++ /* ...interrupt service routine registration */
++ imr->irq = ret = platform_get_irq(pdev, 0);
++ if (ret < 0) {
++ dev_err(&pdev->dev, "cannot find IRQ\n");
++ return ret;
++ }
++
++ ret = devm_request_irq(&pdev->dev, imr->irq, imr_irq_handler, 0, dev_name(&pdev->dev), imr);
++ if (ret) {
++ dev_err(&pdev->dev, "cannot claim IRQ %d\n", imr->irq);
++ return ret;
++ }
++
++ imr->clock = devm_clk_get(&pdev->dev, NULL);
++ if (IS_ERR(imr->clock)) {
++ dev_err(&pdev->dev, "cannot get clock\n");
++ return PTR_ERR(imr->clock);
++ }
++
++ /* ...create v4l2 device */
++ ret = v4l2_device_register(&pdev->dev, &imr->v4l2_dev);
++ if (ret) {
++ dev_err(&pdev->dev, "Failed to register v4l2 device\n");
++ return ret;
++ }
++
++ /* ...create mem2mem device handle */
++ imr->m2m_dev = v4l2_m2m_init(&imr_m2m_ops);
++ if (IS_ERR(imr->m2m_dev)) {
++ v4l2_err(&imr->v4l2_dev, "Failed to init mem2mem device\n");
++ ret = PTR_ERR(imr->m2m_dev);
++ goto device_register_rollback;
++ }
++
++ strlcpy(imr->video_dev.name, dev_name(&pdev->dev), sizeof(imr->video_dev.name));
++ imr->video_dev.fops = &imr_fops;
++ imr->video_dev.ioctl_ops = &imr_ioctl_ops;
++ imr->video_dev.minor = -1;
++ imr->video_dev.release = video_device_release_empty;
++ imr->video_dev.lock = &imr->mutex;
++ imr->video_dev.v4l2_dev = &imr->v4l2_dev;
++ imr->video_dev.vfl_dir = VFL_DIR_M2M;
++
++ ret = video_register_device(&imr->video_dev, VFL_TYPE_GRABBER, -1);
++ if (ret) {
++ v4l2_err(&imr->v4l2_dev, "Failed to register video device\n");
++ goto m2m_init_rollback;
++ }
++
++ video_set_drvdata(&imr->video_dev, imr);
++ platform_set_drvdata(pdev, imr);
++ //pm_runtime_enable(&pdev->dev);
++
++ v4l2_info(&imr->v4l2_dev, "IMR device (pdev: %d) registered as /dev/video%d\n", pdev->id, imr->video_dev.num);
++
++ return 0;
++
++m2m_init_rollback:
++ v4l2_m2m_release(imr->m2m_dev);
++
++device_register_rollback:
++ v4l2_device_unregister(&imr->v4l2_dev);
++
++ return ret;
++}
++
++static int imr_remove(struct platform_device *pdev)
++{
++ struct imr_device *imr = platform_get_drvdata(pdev);
++
++ //pm_runtime_disable(imr->v4l2_dev.dev);
++ video_unregister_device(&imr->video_dev);
++ v4l2_m2m_release(imr->m2m_dev);
++ v4l2_device_unregister(&imr->v4l2_dev);
++
++ return 0;
++}
++
++/*******************************************************************************
++ * Power management
++ ******************************************************************************/
++
++#ifdef CONFIG_PM_SLEEP
++
++/* ...device suspend hook; clock control only - tbd */
++static int imr_pm_suspend(struct device *dev)
++{
++ struct imr_device *imr = dev_get_drvdata(dev);
++
++ WARN_ON(mutex_is_locked(&imr->mutex));
++
++ if (imr->refcount == 0)
++ return 0;
++
++ clk_disable_unprepare(imr->clock);
++
++ return 0;
++}
++
++/* ...device resume hook; clock control only */
++static int imr_pm_resume(struct device *dev)
++{
++ struct imr_device *imr = dev_get_drvdata(dev);
++
++ WARN_ON(mutex_is_locked(&imr->mutex));
++
++ if (imr->refcount == 0)
++ return 0;
++
++ clk_prepare_enable(imr->clock);
++
++ return 0;
++}
++
++#endif /* CONFIG_PM_SLEEP */
++
++/* ...power management callbacks */
++static const struct dev_pm_ops imr_pm_ops = {
++ SET_SYSTEM_SLEEP_PM_OPS(imr_pm_suspend, imr_pm_resume)
++};
++
++/* ...device table */
++static const struct of_device_id imr_of_match[] = {
++ { .compatible = "renesas,imr-lx4" },
++ { },
++};
++
++/* ...platform driver interface */
++static struct platform_driver imr_platform_driver = {
++ .probe = imr_probe,
++ .remove = imr_remove,
++ .driver = {
++ .owner = THIS_MODULE,
++ .name = "imr",
++ .pm = &imr_pm_ops,
++ .of_match_table = imr_of_match,
++ },
++};
++
++module_platform_driver(imr_platform_driver);
++
++MODULE_ALIAS("imr");
++MODULE_AUTHOR("Cogent Embedded Inc. <sources@cogentembedded.com>");
++MODULE_DESCRIPTION("Renesas IMR-LX4 Driver");
++MODULE_LICENSE("GPL");
+diff --git a/include/uapi/linux/rcar-imr.h b/include/uapi/linux/rcar-imr.h
+new file mode 100644
+index 0000000..d02082f
+--- /dev/null
++++ b/include/uapi/linux/rcar-imr.h
+@@ -0,0 +1,98 @@
++/*
++ * imr.h -- R-Car IMR-LX4 Driver UAPI
++ *
++ * Copyright (C) 2016 Cogent Embedded, Inc. <source@cogentembedded.com>
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ */
++
++#ifndef RCAR_IMR_USER_H
++#define RCAR_IMR_USER_H
++
++#include <linux/videodev2.h>
++
++/*******************************************************************************
++ * Mapping specification descriptor
++ ******************************************************************************/
++
++struct imr_map_desc {
++ /* ...mapping types */
++ u32 type;
++
++ /* ...total size of the mesh structure */
++ u32 size;
++
++ /* ...map-specific user-pointer */
++ void *data;
++
++} __attribute__((packed));
++
++/* ...regular mesh specification */
++#define IMR_MAP_MESH (1 << 0)
++
++/* ...auto-generated source coordinates */
++#define IMR_MAP_AUTODG (1 << 1)
++
++/* ...auto-generated destination coordinates */
++#define IMR_MAP_AUTOSG (1 << 2)
++
++/* ...luminance correction flag */
++#define IMR_MAP_LUCE (1 << 3)
++
++/* ...chromacity correction flag */
++#define IMR_MAP_CLCE (1 << 4)
++
++/* ...vertex clockwise-mode order */
++#define IMR_MAP_TCM (1 << 5)
++
++/* ...source coordinate decimal point position bit index */
++#define __IMR_MAP_UVDPOR_SHIFT 8
++#define __IMR_MAP_UVDPOR(v) (((v) >> __IMR_MAP_UVDPOR_SHIFT) & 0x7)
++#define IMR_MAP_UVDPOR(n) ((n & 0x7) << __IMR_MAP_UVDPOR_SHIFT)
++
++/* ...destination coordinate sub-pixel mode */
++#define IMR_MAP_DDP (1 << 11)
++
++/* ...luminance correction offset decimal point position */
++#define __IMR_MAP_YLDPO_SHIFT 12
++#define __IMR_MAP_YLDPO(v) (((v) >> __IMR_MAP_YLDPO_SHIFT) & 0x7)
++#define IMR_MAP_YLDPO(n) ((n & 0x7) << __IMR_MAP_YLDPO_SHIFT)
++
++/* ...chromacity (U) correction offset decimal point position */
++#define __IMR_MAP_UBDPO_SHIFT 15
++#define __IMR_MAP_UBDPO(v) (((v) >> __IMR_MAP_UBDPO_SHIFT) & 0x7)
++#define IMR_MAP_UBDPO(n) ((n & 0x7) << __IMR_MAP_UBDPO_SHIFT)
++
++/* ...chromacity (V) correction offset decimal point position */
++#define __IMR_MAP_VRDPO_SHIFT 18
++#define __IMR_MAP_VRDPO(v) (((v) >> __IMR_MAP_VRDPO_SHIFT) & 0x7)
++#define IMR_MAP_VRDPO(n) ((n & 0x7) << __IMR_MAP_VRDPO_SHIFT)
++
++/* ...regular mesh specification */
++struct imr_mesh {
++ /* ...rectangular mesh size */
++ u16 rows, columns;
++
++ /* ...mesh parameters */
++ u16 x0, y0, dx, dy;
++
++} __attribute__((packed));
++
++/* ...VBO descriptor */
++struct imr_vbo {
++ /* ...number of triangles */
++ u16 num;
++
++} __attribute__((packed));
++
++
++/*******************************************************************************
++ * Private IOCTL codes
++ ******************************************************************************/
++
++#define VIDIOC_IMR_MESH _IOW('V', BASE_VIDIOC_PRIVATE + 0, struct imr_map_desc)
++
++#endif /* RCAR_IMR_USER_H */
+--
+1.9.1
+
diff --git a/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0014-lib-swiotlb-reduce-verbosity.patch b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0014-lib-swiotlb-reduce-verbosity.patch
new file mode 100644
index 0000000..6cb5f65
--- /dev/null
+++ b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0014-lib-swiotlb-reduce-verbosity.patch
@@ -0,0 +1,40 @@
+From f52105d57c1ec04f8dac9b403232d8b1965a02ca Mon Sep 17 00:00:00 2001
+From: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+Date: Thu, 26 Jan 2017 16:37:50 +0300
+Subject: [PATCH] lib: swiotlb: reduce verbosity
+
+Signed-off-by: Nikita Yushchenko <nikita.yoush@cogentembedded.com>
+Signed-off-by: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+---
+ lib/swiotlb.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/lib/swiotlb.c b/lib/swiotlb.c
+index 771234d..b395abc 100644
+--- a/lib/swiotlb.c
++++ b/lib/swiotlb.c
+@@ -513,8 +513,10 @@ phys_addr_t swiotlb_tbl_map_single(struct device *hwdev,
+
+ not_found:
+ spin_unlock_irqrestore(&io_tlb_lock, flags);
++#if 0
+ if (printk_ratelimit())
+ dev_warn(hwdev, "swiotlb buffer is full (sz: %zd bytes)\n", size);
++#endif
+ return SWIOTLB_MAP_ERROR;
+ found:
+ spin_unlock_irqrestore(&io_tlb_lock, flags);
+@@ -714,8 +714,10 @@ swiotlb_full(struct device *dev, size_t size, enum dma_data_direction dir,
+ * When the mapping is small enough return a static buffer to limit
+ * the damage, or panic when the transfer is too big.
+ */
++#if 0
+ dev_err_ratelimited(dev, "DMA: Out of SW-IOMMU space for %zu bytes\n",
+ size);
++#endif
+
+ if (size <= io_tlb_overflow || !do_panic)
+ return;
+--
+1.9.1
+
diff --git a/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0015-gpio-max732x-fix-gpio-set.patch b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0015-gpio-max732x-fix-gpio-set.patch
new file mode 100644
index 0000000..c08c0ed
--- /dev/null
+++ b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0015-gpio-max732x-fix-gpio-set.patch
@@ -0,0 +1,29 @@
+From 75b9bdbafde96b6af222f96e47d7a4a260ed32df Mon Sep 17 00:00:00 2001
+From: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+Date: Tue, 11 Apr 2017 20:12:56 +0300
+Subject: [PATCH] gpio: max732x: fix gpio set
+
+gpio set value/direction must 0 or 1, but
+gpiolib sets it to not binary values
+
+Signed-off-by: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+---
+ drivers/gpio/gpio-max732x.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/gpio/gpio-max732x.c b/drivers/gpio/gpio-max732x.c
+index a9aaf9d..b6fc8c5 100644
+--- a/drivers/gpio/gpio-max732x.c
++++ b/drivers/gpio/gpio-max732x.c
+@@ -237,7 +237,7 @@ static void max732x_gpio_set_value(struct gpio_chip *gc, unsigned off, int val)
+ unsigned base = off & ~0x7;
+ uint8_t mask = 1u << (off & 0x7);
+
+- max732x_gpio_set_mask(gc, base, mask, val << (off & 0x7));
++ max732x_gpio_set_mask(gc, base, mask, (!!val) << (off & 0x7));
+ }
+
+ static void max732x_gpio_set_multiple(struct gpio_chip *gc,
+--
+1.9.1
+
diff --git a/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0016-gpio-gpiolib-suppress-gpiod-warning.patch b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0016-gpio-gpiolib-suppress-gpiod-warning.patch
new file mode 100644
index 0000000..9a6ae18
--- /dev/null
+++ b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0016-gpio-gpiolib-suppress-gpiod-warning.patch
@@ -0,0 +1,29 @@
+From d5f7b238ab2b458876a50521f9c92487f4ba3226 Mon Sep 17 00:00:00 2001
+From: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+Date: Thu, 13 Apr 2017 12:18:18 +0300
+Subject: [PATCH] gpio: gpiolib: suppress gpiod warning
+
+Suppress warning about use gpiod instead gpio deprecated callbacks
+
+Signed-off-by: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+---
+ drivers/gpio/gpiolib.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c
+index d407f904..06201ff 100644
+--- a/drivers/gpio/gpiolib.c
++++ b/drivers/gpio/gpiolib.c
+@@ -1945,7 +1945,9 @@ void gpiod_set_raw_value(struct gpio_desc *desc, int value)
+ {
+ VALIDATE_DESC_VOID(desc);
+ /* Should be using gpiod_set_value_cansleep() */
++#if 0
+ WARN_ON(desc->gdev->chip->can_sleep);
++#endif
+ _gpiod_set_raw_value(desc, value);
+ }
+ EXPORT_SYMBOL_GPL(gpiod_set_raw_value);
+--
+1.9.1
+
diff --git a/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0017-media-soc_camera-add-legacy-VIN-CSI2.patch b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0017-media-soc_camera-add-legacy-VIN-CSI2.patch
new file mode 100644
index 0000000..9a349a0
--- /dev/null
+++ b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0017-media-soc_camera-add-legacy-VIN-CSI2.patch
@@ -0,0 +1,5055 @@
+From fd6f489456137d148132010c9da3251ba80f7948 Mon Sep 17 00:00:00 2001
+From: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+Date: Sun, 14 May 2017 13:43:24 +0300
+Subject: [PATCH] media: soc_camera: add legacy VIN/CSI2
+
+Add legacy/old R-CAR VIN/CSI2 drivers
+
+Signed-off-by: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+---
+ arch/arm64/boot/dts/renesas/r8a7795-es1.dtsi | 348 ---
+ arch/arm64/boot/dts/renesas/r8a7795.dtsi | 271 ---
+ arch/arm64/boot/dts/renesas/r8a7796.dtsi | 258 ---
+ drivers/media/platform/soc_camera/Kconfig | 26 +
+ drivers/media/platform/soc_camera/Makefile | 2 +
+ drivers/media/platform/soc_camera/rcar_csi2.c | 708 ++++++
+ drivers/media/platform/soc_camera/rcar_vin.c | 3071 +++++++++++++++++++++++++
+ include/media/rcar_csi2.h | 66 +
+ 8 files changed, 3873 insertions(+), 877 deletions(-)
+ create mode 100644 drivers/media/platform/soc_camera/rcar_csi2.c
+ create mode 100644 drivers/media/platform/soc_camera/rcar_vin.c
+ create mode 100644 include/media/rcar_csi2.h
+
+diff --git a/arch/arm64/boot/dts/renesas/r8a7795-es1.dtsi b/arch/arm64/boot/dts/renesas/r8a7795-es1.dtsi
+index 2bf5911..09e1284 100644
+--- a/arch/arm64/boot/dts/renesas/r8a7795-es1.dtsi
++++ b/arch/arm64/boot/dts/renesas/r8a7795-es1.dtsi
+@@ -1927,31 +1927,6 @@
+ clocks = <&cpg CPG_MOD 811>;
+ power-domains = <&sysc R8A7795_PD_ALWAYS_ON>;
+ status = "disabled";
+-
+- ports {
+- #address-cells = <1>;
+- #size-cells = <0>;
+-
+- port@1 {
+- #address-cells = <1>;
+- #size-cells = <0>;
+-
+- reg = <1>;
+-
+- vin0csi20: endpoint@0 {
+- reg = <0>;
+- remote-endpoint= <&csi20vin0>;
+- };
+- vin0csi21: endpoint@1 {
+- reg = <1>;
+- remote-endpoint= <&csi21vin0>;
+- };
+- vin0csi40: endpoint@2 {
+- reg = <2>;
+- remote-endpoint= <&csi40vin0>;
+- };
+- };
+- };
+ };
+
+ vin1: video@e6ef1000 {
+@@ -1961,31 +1936,6 @@
+ clocks = <&cpg CPG_MOD 810>;
+ power-domains = <&sysc R8A7795_PD_ALWAYS_ON>;
+ status = "disabled";
+-
+- ports {
+- #address-cells = <1>;
+- #size-cells = <0>;
+-
+- port@1 {
+- #address-cells = <1>;
+- #size-cells = <0>;
+-
+- reg = <1>;
+-
+- vin1csi20: endpoint@0 {
+- reg = <0>;
+- remote-endpoint= <&csi20vin1>;
+- };
+- vin1csi21: endpoint@1 {
+- reg = <1>;
+- remote-endpoint= <&csi21vin1>;
+- };
+- vin1csi40: endpoint@2 {
+- reg = <2>;
+- remote-endpoint= <&csi40vin1>;
+- };
+- };
+- };
+ };
+
+ vin2: video@e6ef2000 {
+@@ -1995,31 +1945,6 @@
+ clocks = <&cpg CPG_MOD 809>;
+ power-domains = <&sysc R8A7795_PD_ALWAYS_ON>;
+ status = "disabled";
+-
+- ports {
+- #address-cells = <1>;
+- #size-cells = <0>;
+-
+- port@1 {
+- #address-cells = <1>;
+- #size-cells = <0>;
+-
+- reg = <1>;
+-
+- vin2csi20: endpoint@0 {
+- reg = <0>;
+- remote-endpoint= <&csi20vin2>;
+- };
+- vin2csi21: endpoint@1 {
+- reg = <1>;
+- remote-endpoint= <&csi21vin2>;
+- };
+- vin2csi40: endpoint@2 {
+- reg = <2>;
+- remote-endpoint= <&csi40vin2>;
+- };
+- };
+- };
+ };
+
+ vin3: video@e6ef3000 {
+@@ -2029,31 +1954,6 @@
+ clocks = <&cpg CPG_MOD 808>;
+ power-domains = <&sysc R8A7795_PD_ALWAYS_ON>;
+ status = "disabled";
+-
+- ports {
+- #address-cells = <1>;
+- #size-cells = <0>;
+-
+- port@1 {
+- #address-cells = <1>;
+- #size-cells = <0>;
+-
+- reg = <1>;
+-
+- vin3csi20: endpoint@0 {
+- reg = <0>;
+- remote-endpoint= <&csi20vin3>;
+- };
+- vin3csi21: endpoint@1 {
+- reg = <1>;
+- remote-endpoint= <&csi21vin3>;
+- };
+- vin3csi40: endpoint@2 {
+- reg = <2>;
+- remote-endpoint= <&csi40vin3>;
+- };
+- };
+- };
+ };
+
+ vin4: video@e6ef4000 {
+@@ -2063,31 +1963,6 @@
+ clocks = <&cpg CPG_MOD 807>;
+ power-domains = <&sysc R8A7795_PD_ALWAYS_ON>;
+ status = "disabled";
+-
+- ports {
+- #address-cells = <1>;
+- #size-cells = <0>;
+-
+- port@1 {
+- #address-cells = <1>;
+- #size-cells = <0>;
+-
+- reg = <1>;
+-
+- vin4csi20: endpoint@0 {
+- reg = <0>;
+- remote-endpoint= <&csi20vin4>;
+- };
+- vin4csi21: endpoint@1 {
+- reg = <1>;
+- remote-endpoint= <&csi21vin4>;
+- };
+- vin4csi41: endpoint@3 {
+- reg = <3>;
+- remote-endpoint= <&csi41vin4>;
+- };
+- };
+- };
+ };
+
+ vin5: video@e6ef5000 {
+@@ -2097,31 +1972,6 @@
+ clocks = <&cpg CPG_MOD 806>;
+ power-domains = <&sysc R8A7795_PD_ALWAYS_ON>;
+ status = "disabled";
+-
+- ports {
+- #address-cells = <1>;
+- #size-cells = <0>;
+-
+- port@1 {
+- #address-cells = <1>;
+- #size-cells = <0>;
+-
+- reg = <1>;
+-
+- vin5csi20: endpoint@0 {
+- reg = <0>;
+- remote-endpoint= <&csi20vin5>;
+- };
+- vin5csi21: endpoint@1 {
+- reg = <1>;
+- remote-endpoint= <&csi21vin5>;
+- };
+- vin5csi41: endpoint@3 {
+- reg = <3>;
+- remote-endpoint= <&csi41vin5>;
+- };
+- };
+- };
+ };
+
+ vin6: video@e6ef6000 {
+@@ -2131,31 +1981,6 @@
+ clocks = <&cpg CPG_MOD 805>;
+ power-domains = <&sysc R8A7795_PD_ALWAYS_ON>;
+ status = "disabled";
+-
+- ports {
+- #address-cells = <1>;
+- #size-cells = <0>;
+-
+- port@1 {
+- #address-cells = <1>;
+- #size-cells = <0>;
+-
+- reg = <1>;
+-
+- vin6csi20: endpoint@0 {
+- reg = <0>;
+- remote-endpoint= <&csi20vin6>;
+- };
+- vin6csi21: endpoint@1 {
+- reg = <1>;
+- remote-endpoint= <&csi21vin6>;
+- };
+- vin6csi41: endpoint@3 {
+- reg = <3>;
+- remote-endpoint= <&csi41vin6>;
+- };
+- };
+- };
+ };
+
+ vin7: video@e6ef7000 {
+@@ -2165,31 +1990,6 @@
+ clocks = <&cpg CPG_MOD 804>;
+ power-domains = <&sysc R8A7795_PD_ALWAYS_ON>;
+ status = "disabled";
+-
+- ports {
+- #address-cells = <1>;
+- #size-cells = <0>;
+-
+- port@1 {
+- #address-cells = <1>;
+- #size-cells = <0>;
+-
+- reg = <1>;
+-
+- vin7csi20: endpoint@0 {
+- reg = <0>;
+- remote-endpoint= <&csi20vin7>;
+- };
+- vin7csi21: endpoint@1 {
+- reg = <1>;
+- remote-endpoint= <&csi21vin7>;
+- };
+- vin7csi41: endpoint@3 {
+- reg = <3>;
+- remote-endpoint= <&csi41vin7>;
+- };
+- };
+- };
+ };
+
+ csi2_20: csi2@fea80000 {
+@@ -2199,51 +1999,6 @@
+ clocks = <&cpg CPG_MOD 714>;
+ power-domains = <&sysc R8A7795_PD_ALWAYS_ON>;
+ status = "disabled";
+-
+- ports {
+- #address-cells = <1>;
+- #size-cells = <0>;
+-
+- port@1 {
+- #address-cells = <1>;
+- #size-cells = <0>;
+-
+- reg = <1>;
+-
+- csi20vin0: endpoint@0 {
+- reg = <0>;
+- remote-endpoint = <&vin0csi20>;
+- };
+- csi20vin1: endpoint@1 {
+- reg = <1>;
+- remote-endpoint = <&vin1csi20>;
+- };
+- csi20vin2: endpoint@2 {
+- reg = <2>;
+- remote-endpoint = <&vin2csi20>;
+- };
+- csi20vin3: endpoint@3 {
+- reg = <3>;
+- remote-endpoint = <&vin3csi20>;
+- };
+- csi20vin4: endpoint@4 {
+- reg = <4>;
+- remote-endpoint = <&vin4csi20>;
+- };
+- csi20vin5: endpoint@5 {
+- reg = <5>;
+- remote-endpoint = <&vin5csi20>;
+- };
+- csi20vin6: endpoint@6 {
+- reg = <6>;
+- remote-endpoint = <&vin6csi20>;
+- };
+- csi20vin7: endpoint@7 {
+- reg = <7>;
+- remote-endpoint = <&vin7csi20>;
+- };
+- };
+- };
+ };
+
+ csi2_21: csi2@fea90000 {
+@@ -2253,51 +2008,6 @@
+ clocks = <&cpg CPG_MOD 713>;
+ power-domains = <&sysc R8A7795_PD_ALWAYS_ON>;
+ status = "disabled";
+-
+- ports {
+- #address-cells = <1>;
+- #size-cells = <0>;
+-
+- port@1 {
+- #address-cells = <1>;
+- #size-cells = <0>;
+-
+- reg = <1>;
+-
+- csi21vin0: endpoint@0 {
+- reg = <0>;
+- remote-endpoint = <&vin0csi21>;
+- };
+- csi21vin1: endpoint@1 {
+- reg = <1>;
+- remote-endpoint = <&vin1csi21>;
+- };
+- csi21vin2: endpoint@2 {
+- reg = <2>;
+- remote-endpoint = <&vin2csi21>;
+- };
+- csi21vin3: endpoint@3 {
+- reg = <3>;
+- remote-endpoint = <&vin3csi21>;
+- };
+- csi21vin4: endpoint@4 {
+- reg = <4>;
+- remote-endpoint = <&vin4csi21>;
+- };
+- csi21vin5: endpoint@5 {
+- reg = <5>;
+- remote-endpoint = <&vin5csi21>;
+- };
+- csi21vin6: endpoint@6 {
+- reg = <6>;
+- remote-endpoint = <&vin6csi21>;
+- };
+- csi21vin7: endpoint@7 {
+- reg = <7>;
+- remote-endpoint = <&vin7csi21>;
+- };
+- };
+- };
+ };
+
+ csi2_40: csi2@feaa0000 {
+@@ -2307,35 +2017,6 @@
+ clocks = <&cpg CPG_MOD 716>;
+ power-domains = <&sysc R8A7795_PD_ALWAYS_ON>;
+ status = "disabled";
+-
+- ports {
+- #address-cells = <1>;
+- #size-cells = <0>;
+-
+- port@1 {
+- #address-cells = <1>;
+- #size-cells = <0>;
+-
+- reg = <1>;
+-
+- csi40vin0: endpoint@0 {
+- reg = <0>;
+- remote-endpoint = <&vin0csi40>;
+- };
+- csi40vin1: endpoint@1 {
+- reg = <1>;
+- remote-endpoint = <&vin1csi40>;
+- };
+- csi40vin2: endpoint@2 {
+- reg = <2>;
+- remote-endpoint = <&vin2csi40>;
+- };
+- csi40vin3: endpoint@3 {
+- reg = <3>;
+- remote-endpoint = <&vin3csi40>;
+- };
+- };
+- };
+ };
+
+ csi2_41: csi2@feab0000 {
+@@ -2345,35 +2026,6 @@
+ clocks = <&cpg CPG_MOD 715>;
+ power-domains = <&sysc R8A7795_PD_ALWAYS_ON>;
+ status = "disabled";
+-
+- ports {
+- #address-cells = <1>;
+- #size-cells = <0>;
+-
+- port@1 {
+- #address-cells = <1>;
+- #size-cells = <0>;
+-
+- reg = <1>;
+-
+- csi41vin4: endpoint@4 {
+- reg = <4>;
+- remote-endpoint = <&vin4csi41>;
+- };
+- csi41vin5: endpoint@5 {
+- reg = <5>;
+- remote-endpoint = <&vin5csi41>;
+- };
+- csi41vin6: endpoint@6 {
+- reg = <6>;
+- remote-endpoint = <&vin6csi41>;
+- };
+- csi41vin7: endpoint@7 {
+- reg = <7>;
+- remote-endpoint = <&vin7csi41>;
+- };
+- };
+- };
+ };
+
+ sata: sata@ee300000 {
+diff --git a/arch/arm64/boot/dts/renesas/r8a7795.dtsi b/arch/arm64/boot/dts/renesas/r8a7795.dtsi
+index 94262a1..82ebfd4 100644
+--- a/arch/arm64/boot/dts/renesas/r8a7795.dtsi
++++ b/arch/arm64/boot/dts/renesas/r8a7795.dtsi
+@@ -1902,27 +1902,6 @@
+ clocks = <&cpg CPG_MOD 811>;
+ power-domains = <&sysc R8A7795_PD_ALWAYS_ON>;
+ status = "disabled";
+-
+- ports {
+- #address-cells = <1>;
+- #size-cells = <0>;
+-
+- port@1 {
+- #address-cells = <1>;
+- #size-cells = <0>;
+-
+- reg = <1>;
+-
+- vin0csi20: endpoint@0 {
+- reg = <0>;
+- remote-endpoint= <&csi20vin0>;
+- };
+- vin0csi40: endpoint@2 {
+- reg = <2>;
+- remote-endpoint= <&csi40vin0>;
+- };
+- };
+- };
+ };
+
+ vin1: video@e6ef1000 {
+@@ -1932,27 +1911,6 @@
+ clocks = <&cpg CPG_MOD 810>;
+ power-domains = <&sysc R8A7795_PD_ALWAYS_ON>;
+ status = "disabled";
+-
+- ports {
+- #address-cells = <1>;
+- #size-cells = <0>;
+-
+- port@1 {
+- #address-cells = <1>;
+- #size-cells = <0>;
+-
+- reg = <1>;
+-
+- vin1csi20: endpoint@0 {
+- reg = <0>;
+- remote-endpoint= <&csi20vin1>;
+- };
+- vin1csi40: endpoint@2 {
+- reg = <2>;
+- remote-endpoint= <&csi40vin1>;
+- };
+- };
+- };
+ };
+
+ vin2: video@e6ef2000 {
+@@ -1962,27 +1920,6 @@
+ clocks = <&cpg CPG_MOD 809>;
+ power-domains = <&sysc R8A7795_PD_ALWAYS_ON>;
+ status = "disabled";
+-
+- ports {
+- #address-cells = <1>;
+- #size-cells = <0>;
+-
+- port@1 {
+- #address-cells = <1>;
+- #size-cells = <0>;
+-
+- reg = <1>;
+-
+- vin2csi20: endpoint@0 {
+- reg = <0>;
+- remote-endpoint= <&csi20vin2>;
+- };
+- vin2csi40: endpoint@2 {
+- reg = <2>;
+- remote-endpoint= <&csi40vin2>;
+- };
+- };
+- };
+ };
+
+ vin3: video@e6ef3000 {
+@@ -1992,27 +1929,6 @@
+ clocks = <&cpg CPG_MOD 808>;
+ power-domains = <&sysc R8A7795_PD_ALWAYS_ON>;
+ status = "disabled";
+-
+- ports {
+- #address-cells = <1>;
+- #size-cells = <0>;
+-
+- port@1 {
+- #address-cells = <1>;
+- #size-cells = <0>;
+-
+- reg = <1>;
+-
+- vin3csi20: endpoint@0 {
+- reg = <0>;
+- remote-endpoint= <&csi20vin3>;
+- };
+- vin3csi40: endpoint@2 {
+- reg = <2>;
+- remote-endpoint= <&csi40vin3>;
+- };
+- };
+- };
+ };
+
+ vin4: video@e6ef4000 {
+@@ -2022,27 +1938,6 @@
+ clocks = <&cpg CPG_MOD 807>;
+ power-domains = <&sysc R8A7795_PD_ALWAYS_ON>;
+ status = "disabled";
+-
+- ports {
+- #address-cells = <1>;
+- #size-cells = <0>;
+-
+- port@1 {
+- #address-cells = <1>;
+- #size-cells = <0>;
+-
+- reg = <1>;
+-
+- vin4csi20: endpoint@0 {
+- reg = <0>;
+- remote-endpoint= <&csi20vin4>;
+- };
+- vin4csi41: endpoint@3 {
+- reg = <3>;
+- remote-endpoint= <&csi41vin4>;
+- };
+- };
+- };
+ };
+
+ vin5: video@e6ef5000 {
+@@ -2052,27 +1947,6 @@
+ clocks = <&cpg CPG_MOD 806>;
+ power-domains = <&sysc R8A7795_PD_ALWAYS_ON>;
+ status = "disabled";
+-
+- ports {
+- #address-cells = <1>;
+- #size-cells = <0>;
+-
+- port@1 {
+- #address-cells = <1>;
+- #size-cells = <0>;
+-
+- reg = <1>;
+-
+- vin5csi20: endpoint@0 {
+- reg = <0>;
+- remote-endpoint= <&csi20vin5>;
+- };
+- vin5csi41: endpoint@3 {
+- reg = <3>;
+- remote-endpoint= <&csi41vin5>;
+- };
+- };
+- };
+ };
+
+ vin6: video@e6ef6000 {
+@@ -2082,27 +1956,6 @@
+ clocks = <&cpg CPG_MOD 805>;
+ power-domains = <&sysc R8A7795_PD_ALWAYS_ON>;
+ status = "disabled";
+-
+- ports {
+- #address-cells = <1>;
+- #size-cells = <0>;
+-
+- port@1 {
+- #address-cells = <1>;
+- #size-cells = <0>;
+-
+- reg = <1>;
+-
+- vin6csi20: endpoint@0 {
+- reg = <0>;
+- remote-endpoint= <&csi20vin6>;
+- };
+- vin6csi41: endpoint@3 {
+- reg = <3>;
+- remote-endpoint= <&csi41vin6>;
+- };
+- };
+- };
+ };
+
+ vin7: video@e6ef7000 {
+@@ -2112,27 +1965,6 @@
+ clocks = <&cpg CPG_MOD 804>;
+ power-domains = <&sysc R8A7795_PD_ALWAYS_ON>;
+ status = "disabled";
+-
+- ports {
+- #address-cells = <1>;
+- #size-cells = <0>;
+-
+- port@1 {
+- #address-cells = <1>;
+- #size-cells = <0>;
+-
+- reg = <1>;
+-
+- vin7csi20: endpoint@0 {
+- reg = <0>;
+- remote-endpoint= <&csi20vin7>;
+- };
+- vin7csi41: endpoint@3 {
+- reg = <3>;
+- remote-endpoint= <&csi41vin7>;
+- };
+- };
+- };
+ };
+
+ csi2_20: csi2@fea80000 {
+@@ -2142,51 +1974,6 @@
+ clocks = <&cpg CPG_MOD 714>;
+ power-domains = <&sysc R8A7795_PD_ALWAYS_ON>;
+ status = "disabled";
+-
+- ports {
+- #address-cells = <1>;
+- #size-cells = <0>;
+-
+- port@1 {
+- #address-cells = <1>;
+- #size-cells = <0>;
+-
+- reg = <1>;
+-
+- csi20vin0: endpoint@0 {
+- reg = <0>;
+- remote-endpoint = <&vin0csi20>;
+- };
+- csi20vin1: endpoint@1 {
+- reg = <1>;
+- remote-endpoint = <&vin1csi20>;
+- };
+- csi20vin2: endpoint@2 {
+- reg = <2>;
+- remote-endpoint = <&vin2csi20>;
+- };
+- csi20vin3: endpoint@3 {
+- reg = <3>;
+- remote-endpoint = <&vin3csi20>;
+- };
+- csi20vin4: endpoint@4 {
+- reg = <4>;
+- remote-endpoint = <&vin4csi20>;
+- };
+- csi20vin5: endpoint@5 {
+- reg = <5>;
+- remote-endpoint = <&vin5csi20>;
+- };
+- csi20vin6: endpoint@6 {
+- reg = <6>;
+- remote-endpoint = <&vin6csi20>;
+- };
+- csi20vin7: endpoint@7 {
+- reg = <7>;
+- remote-endpoint = <&vin7csi20>;
+- };
+- };
+- };
+ };
+
+ csi2_40: csi2@feaa0000 {
+@@ -2196,35 +1983,6 @@
+ clocks = <&cpg CPG_MOD 716>;
+ power-domains = <&sysc R8A7795_PD_ALWAYS_ON>;
+ status = "disabled";
+-
+- ports {
+- #address-cells = <1>;
+- #size-cells = <0>;
+-
+- port@1 {
+- #address-cells = <1>;
+- #size-cells = <0>;
+-
+- reg = <1>;
+-
+- csi40vin0: endpoint@0 {
+- reg = <0>;
+- remote-endpoint = <&vin0csi40>;
+- };
+- csi40vin1: endpoint@1 {
+- reg = <1>;
+- remote-endpoint = <&vin1csi40>;
+- };
+- csi40vin2: endpoint@2 {
+- reg = <2>;
+- remote-endpoint = <&vin2csi40>;
+- };
+- csi40vin3: endpoint@3 {
+- reg = <3>;
+- remote-endpoint = <&vin3csi40>;
+- };
+- };
+- };
+ };
+
+ csi2_41: csi2@feab0000 {
+@@ -2234,35 +1992,6 @@
+ clocks = <&cpg CPG_MOD 715>;
+ power-domains = <&sysc R8A7795_PD_ALWAYS_ON>;
+ status = "disabled";
+-
+- ports {
+- #address-cells = <1>;
+- #size-cells = <0>;
+-
+- port@1 {
+- #address-cells = <1>;
+- #size-cells = <0>;
+-
+- reg = <1>;
+-
+- csi41vin4: endpoint@4 {
+- reg = <4>;
+- remote-endpoint = <&vin4csi41>;
+- };
+- csi41vin5: endpoint@5 {
+- reg = <5>;
+- remote-endpoint = <&vin5csi41>;
+- };
+- csi41vin6: endpoint@6 {
+- reg = <6>;
+- remote-endpoint = <&vin6csi41>;
+- };
+- csi41vin7: endpoint@7 {
+- reg = <7>;
+- remote-endpoint = <&vin7csi41>;
+- };
+- };
+- };
+ };
+
+ sata: sata@ee300000 {
+diff --git a/arch/arm64/boot/dts/renesas/r8a7796.dtsi b/arch/arm64/boot/dts/renesas/r8a7796.dtsi
+index afdd69d..e653814 100644
+--- a/arch/arm64/boot/dts/renesas/r8a7796.dtsi
++++ b/arch/arm64/boot/dts/renesas/r8a7796.dtsi
+@@ -1592,27 +1592,6 @@
+ clocks = <&cpg CPG_MOD 811>;
+ power-domains = <&sysc R8A7796_PD_ALWAYS_ON>;
+ status = "disabled";
+-
+- ports {
+- #address-cells = <1>;
+- #size-cells = <0>;
+-
+- port@1 {
+- #address-cells = <1>;
+- #size-cells = <0>;
+-
+- reg = <1>;
+-
+- vin0csi20: endpoint@0 {
+- reg = <0>;
+- remote-endpoint= <&csi20vin0>;
+- };
+- vin0csi40: endpoint@2 {
+- reg = <2>;
+- remote-endpoint= <&csi40vin0>;
+- };
+- };
+- };
+ };
+
+ vin1: video@e6ef1000 {
+@@ -1622,27 +1601,6 @@
+ clocks = <&cpg CPG_MOD 810>;
+ power-domains = <&sysc R8A7796_PD_ALWAYS_ON>;
+ status = "disabled";
+-
+- ports {
+- #address-cells = <1>;
+- #size-cells = <0>;
+-
+- port@1 {
+- #address-cells = <1>;
+- #size-cells = <0>;
+-
+- reg = <1>;
+-
+- vin1csi20: endpoint@0 {
+- reg = <0>;
+- remote-endpoint= <&csi20vin1>;
+- };
+- vin1csi40: endpoint@2 {
+- reg = <2>;
+- remote-endpoint= <&csi40vin1>;
+- };
+- };
+- };
+ };
+
+ vin2: video@e6ef2000 {
+@@ -1652,27 +1610,6 @@
+ clocks = <&cpg CPG_MOD 809>;
+ power-domains = <&sysc R8A7796_PD_ALWAYS_ON>;
+ status = "disabled";
+-
+- ports {
+- #address-cells = <1>;
+- #size-cells = <0>;
+-
+- port@1 {
+- #address-cells = <1>;
+- #size-cells = <0>;
+-
+- reg = <1>;
+-
+- vin2csi20: endpoint@0 {
+- reg = <0>;
+- remote-endpoint= <&csi20vin2>;
+- };
+- vin2csi40: endpoint@2 {
+- reg = <2>;
+- remote-endpoint= <&csi40vin2>;
+- };
+- };
+- };
+ };
+
+ vin3: video@e6ef3000 {
+@@ -1682,27 +1619,6 @@
+ clocks = <&cpg CPG_MOD 808>;
+ power-domains = <&sysc R8A7796_PD_ALWAYS_ON>;
+ status = "disabled";
+-
+- ports {
+- #address-cells = <1>;
+- #size-cells = <0>;
+-
+- port@1 {
+- #address-cells = <1>;
+- #size-cells = <0>;
+-
+- reg = <1>;
+-
+- vin3csi20: endpoint@0 {
+- reg = <0>;
+- remote-endpoint= <&csi20vin3>;
+- };
+- vin3csi40: endpoint@2 {
+- reg = <2>;
+- remote-endpoint= <&csi40vin3>;
+- };
+- };
+- };
+ };
+
+ vin4: video@e6ef4000 {
+@@ -1712,27 +1628,6 @@
+ clocks = <&cpg CPG_MOD 807>;
+ power-domains = <&sysc R8A7796_PD_ALWAYS_ON>;
+ status = "disabled";
+-
+- ports {
+- #address-cells = <1>;
+- #size-cells = <0>;
+-
+- port@1 {
+- #address-cells = <1>;
+- #size-cells = <0>;
+-
+- reg = <1>;
+-
+- vin4csi20: endpoint@0 {
+- reg = <0>;
+- remote-endpoint= <&csi20vin4>;
+- };
+- vin4csi40: endpoint@2 {
+- reg = <2>;
+- remote-endpoint= <&csi40vin4>;
+- };
+- };
+- };
+ };
+
+ vin5: video@e6ef5000 {
+@@ -1742,27 +1637,6 @@
+ clocks = <&cpg CPG_MOD 806>;
+ power-domains = <&sysc R8A7796_PD_ALWAYS_ON>;
+ status = "disabled";
+-
+- ports {
+- #address-cells = <1>;
+- #size-cells = <0>;
+-
+- port@1 {
+- #address-cells = <1>;
+- #size-cells = <0>;
+-
+- reg = <1>;
+-
+- vin5csi20: endpoint@0 {
+- reg = <0>;
+- remote-endpoint= <&csi20vin5>;
+- };
+- vin5csi40: endpoint@2 {
+- reg = <2>;
+- remote-endpoint= <&csi40vin5>;
+- };
+- };
+- };
+ };
+
+ vin6: video@e6ef6000 {
+@@ -1772,27 +1646,6 @@
+ clocks = <&cpg CPG_MOD 805>;
+ power-domains = <&sysc R8A7796_PD_ALWAYS_ON>;
+ status = "disabled";
+-
+- ports {
+- #address-cells = <1>;
+- #size-cells = <0>;
+-
+- port@1 {
+- #address-cells = <1>;
+- #size-cells = <0>;
+-
+- reg = <1>;
+-
+- vin6csi20: endpoint@0 {
+- reg = <0>;
+- remote-endpoint= <&csi20vin6>;
+- };
+- vin6csi40: endpoint@2 {
+- reg = <2>;
+- remote-endpoint= <&csi40vin6>;
+- };
+- };
+- };
+ };
+
+ vin7: video@e6ef7000 {
+@@ -1802,27 +1655,6 @@
+ clocks = <&cpg CPG_MOD 804>;
+ power-domains = <&sysc R8A7796_PD_ALWAYS_ON>;
+ status = "disabled";
+-
+- ports {
+- #address-cells = <1>;
+- #size-cells = <0>;
+-
+- port@1 {
+- #address-cells = <1>;
+- #size-cells = <0>;
+-
+- reg = <1>;
+-
+- vin7csi20: endpoint@0 {
+- reg = <0>;
+- remote-endpoint= <&csi20vin7>;
+- };
+- vin7csi40: endpoint@2 {
+- reg = <2>;
+- remote-endpoint= <&csi40vin7>;
+- };
+- };
+- };
+ };
+
+ csi2_20: csi2@fea80000 {
+@@ -1832,51 +1664,6 @@
+ clocks = <&cpg CPG_MOD 714>;
+ power-domains = <&sysc R8A7796_PD_ALWAYS_ON>;
+ status = "disabled";
+-
+- ports {
+- #address-cells = <1>;
+- #size-cells = <0>;
+-
+- port@1 {
+- #address-cells = <1>;
+- #size-cells = <0>;
+-
+- reg = <1>;
+-
+- csi20vin0: endpoint@0 {
+- reg = <0>;
+- remote-endpoint = <&vin0csi20>;
+- };
+- csi20vin1: endpoint@1 {
+- reg = <1>;
+- remote-endpoint = <&vin1csi20>;
+- };
+- csi20vin2: endpoint@2 {
+- reg = <2>;
+- remote-endpoint = <&vin2csi20>;
+- };
+- csi20vin3: endpoint@3 {
+- reg = <3>;
+- remote-endpoint = <&vin3csi20>;
+- };
+- csi20vin4: endpoint@4 {
+- reg = <4>;
+- remote-endpoint = <&vin4csi20>;
+- };
+- csi20vin5: endpoint@5 {
+- reg = <5>;
+- remote-endpoint = <&vin5csi20>;
+- };
+- csi20vin6: endpoint@6 {
+- reg = <6>;
+- remote-endpoint = <&vin6csi20>;
+- };
+- csi20vin7: endpoint@7 {
+- reg = <7>;
+- remote-endpoint = <&vin7csi20>;
+- };
+- };
+- };
+ };
+
+ csi2_40: csi2@feaa0000 {
+@@ -1886,51 +1673,6 @@
+ clocks = <&cpg CPG_MOD 716>;
+ power-domains = <&sysc R8A7796_PD_ALWAYS_ON>;
+ status = "disabled";
+-
+- ports {
+- #address-cells = <1>;
+- #size-cells = <0>;
+-
+- port@1 {
+- #address-cells = <1>;
+- #size-cells = <0>;
+-
+- reg = <1>;
+-
+- csi40vin0: endpoint@0 {
+- reg = <0>;
+- remote-endpoint = <&vin0csi40>;
+- };
+- csi40vin1: endpoint@1 {
+- reg = <1>;
+- remote-endpoint = <&vin1csi40>;
+- };
+- csi40vin2: endpoint@2 {
+- reg = <2>;
+- remote-endpoint = <&vin2csi40>;
+- };
+- csi40vin3: endpoint@3 {
+- reg = <3>;
+- remote-endpoint = <&vin3csi40>;
+- };
+- csi40vin4: endpoint@4 {
+- reg = <4>;
+- remote-endpoint = <&vin4csi40>;
+- };
+- csi40vin5: endpoint@5 {
+- reg = <5>;
+- remote-endpoint = <&vin5csi40>;
+- };
+- csi40vin6: endpoint@6 {
+- reg = <6>;
+- remote-endpoint = <&vin6csi40>;
+- };
+- csi40vin7: endpoint@7 {
+- reg = <7>;
+- remote-endpoint = <&vin7csi40>;
+- };
+- };
+- };
+ };
+
+ vcplf: vcp4@fe910000 {
+diff --git a/drivers/media/platform/soc_camera/Kconfig b/drivers/media/platform/soc_camera/Kconfig
+index 86d7478..17178ad 100644
+--- a/drivers/media/platform/soc_camera/Kconfig
++++ b/drivers/media/platform/soc_camera/Kconfig
+@@ -17,6 +17,32 @@ config SOC_CAMERA_PLATFORM
+ help
+ This is a generic SoC camera platform driver, useful for testing
+
++config VIDEO_RCAR_VIN_LEGACY
++ tristate "R-Car Video Input (VIN) support"
++ depends on VIDEO_DEV && SOC_CAMERA
++ depends on ARCH_RENESAS || COMPILE_TEST
++ depends on HAS_DMA
++ select VIDEOBUF2_DMA_CONTIG
++ select SOC_CAMERA_SCALE_CROP
++ ---help---
++ This is a v4l2 driver for the R-Car VIN Interface
++
++config VIDEO_RCAR_VIN_LEGACY_DEBUG
++ bool "Renesas VIN overflow debug messages"
++ depends on VIDEO_RCAR_VIN_LEGACY
++ ---help---
++ Enable debug overflow messages on R-Car Video
++ Input driver.
++ If you set to enable, When an overflow occurred,
++ a debug overflow message is output.
++
++config VIDEO_RCAR_CSI2_LEGACY
++ tristate "R-Car MIPI CSI-2 Interface driver"
++ depends on VIDEO_DEV && SOC_CAMERA && HAVE_CLK
++ depends on ARCH_R8A7795 || ARCH_R8A7796 || COMPILE_TEST
++ ---help---
++ This is a v4l2 driver for the R-Car CSI-2 Interface
++
+ config VIDEO_SH_MOBILE_CEU
+ tristate "SuperH Mobile CEU Interface driver"
+ depends on VIDEO_DEV && SOC_CAMERA && HAS_DMA && HAVE_CLK
+diff --git a/drivers/media/platform/soc_camera/Makefile b/drivers/media/platform/soc_camera/Makefile
+index 7633a0f..8c7ede6 100644
+--- a/drivers/media/platform/soc_camera/Makefile
++++ b/drivers/media/platform/soc_camera/Makefile
+@@ -8,3 +8,5 @@ obj-$(CONFIG_SOC_CAMERA_PLATFORM) += soc_camera_platform.o
+ # soc-camera host drivers have to be linked after camera drivers
+ obj-$(CONFIG_VIDEO_ATMEL_ISI) += atmel-isi.o
+ obj-$(CONFIG_VIDEO_SH_MOBILE_CEU) += sh_mobile_ceu_camera.o
++obj-$(CONFIG_VIDEO_RCAR_CSI2_LEGACY) += rcar_csi2.o
++obj-$(CONFIG_VIDEO_RCAR_VIN_LEGACY) += rcar_vin.o
+diff --git a/drivers/media/platform/soc_camera/rcar_csi2.c b/drivers/media/platform/soc_camera/rcar_csi2.c
+new file mode 100644
+index 0000000..05f623468
+--- /dev/null
++++ b/drivers/media/platform/soc_camera/rcar_csi2.c
+@@ -0,0 +1,708 @@
++/*
++ * drivers/media/platform/soc_camera/rcar_csi2.c
++ * This file is the driver for the R-Car MIPI CSI-2 unit.
++ *
++ * Copyright (C) 2015-2016 Renesas Electronics Corporation
++ *
++ * This file is based on the drivers/media/platform/soc_camera/sh_mobile_csi2.c
++ *
++ * Driver for the SH-Mobile MIPI CSI-2 unit
++ *
++ * Copyright (C) 2010, Guennadi Liakhovetski <g.liakhovetski@gmx.de>
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License version 2 as
++ * published by the Free Software Foundation.
++ */
++
++#include <linux/delay.h>
++#include <linux/interrupt.h>
++#include <linux/err.h>
++#include <linux/i2c.h>
++#include <linux/io.h>
++#include <linux/platform_device.h>
++#include <linux/pm_runtime.h>
++#include <linux/slab.h>
++#include <linux/videodev2.h>
++#include <linux/module.h>
++
++#include <media/rcar_csi2.h>
++#include <media/soc_camera.h>
++#include <media/v4l2-common.h>
++#include <media/v4l2-dev.h>
++#include <media/v4l2-device.h>
++#include <media/v4l2-mediabus.h>
++#include <media/v4l2-subdev.h>
++
++#include <media/v4l2-of.h>
++
++#define DRV_NAME "rcar_csi2"
++#define CONNECT_SLAVE_NAME "adv7482"
++#define VC_MAX_CHANNEL 4
++
++#define RCAR_CSI2_TREF 0x00
++#define RCAR_CSI2_SRST 0x04
++#define RCAR_CSI2_PHYCNT 0x08
++#define RCAR_CSI2_CHKSUM 0x0C
++#define RCAR_CSI2_VCDT 0x10
++
++#define RCAR_CSI2_VCDT2 0x14 /* Channel Data Type Select */
++#define RCAR_CSI2_FRDT 0x18 /* Frame Data Type Select */
++#define RCAR_CSI2_FLD 0x1C /* Field Detection Control */
++#define RCAR_CSI2_ASTBY 0x20 /* Automatic standby control */
++#define RCAR_CSI2_LNGDT0 0x28
++#define RCAR_CSI2_LNGDT1 0x2C
++#define RCAR_CSI2_INTEN 0x30
++#define RCAR_CSI2_INTCLOSE 0x34
++#define RCAR_CSI2_INTSTATE 0x38
++#define RCAR_CSI2_INTERRSTATE 0x3C
++
++#define RCAR_CSI2_SHPDAT 0x40
++#define RCAR_CSI2_SHPCNT 0x44
++
++#define RCAR_CSI2_LINKCNT 0x48
++#define RCAR_CSI2_LSWAP 0x4C
++#define RCAR_CSI2_PHTC 0x58
++#define RCAR_CSI2_PHYPLL 0x68
++
++#define RCAR_CSI2_PHEERM 0x74
++#define RCAR_CSI2_PHCLM 0x78
++#define RCAR_CSI2_PHDLM 0x7C
++
++#define RCAR_CSI2_PHYCNT_SHUTDOWNZ (1 << 17)
++#define RCAR_CSI2_PHYCNT_RSTZ (1 << 16)
++#define RCAR_CSI2_PHYCNT_ENABLECLK (1 << 4)
++#define RCAR_CSI2_PHYCNT_ENABLE_3 (1 << 3)
++#define RCAR_CSI2_PHYCNT_ENABLE_2 (1 << 2)
++#define RCAR_CSI2_PHYCNT_ENABLE_1 (1 << 1)
++#define RCAR_CSI2_PHYCNT_ENABLE_0 (1 << 0)
++
++#define RCAR_CSI2_VCDT_VCDTN_EN (1 << 15)
++#define RCAR_CSI2_VCDT_SEL_VCN (1 << 8)
++#define RCAR_CSI2_VCDT_SEL_DTN_ON (1 << 6)
++#define RCAR_CSI2_VCDT_SEL_DTN (1 << 0)
++
++#define RCAR_CSI2_LINKCNT_MONITOR_EN (1 << 31)
++#define RCAR_CSI2_LINKCNT_REG_MONI_PACT_EN (1 << 25)
++
++#define RCAR_CSI2_LSWAP_L3SEL_PLANE0 (0 << 6)
++#define RCAR_CSI2_LSWAP_L3SEL_PLANE1 (1 << 6)
++#define RCAR_CSI2_LSWAP_L3SEL_PLANE2 (2 << 6)
++#define RCAR_CSI2_LSWAP_L3SEL_PLANE3 (3 << 6)
++
++#define RCAR_CSI2_LSWAP_L2SEL_PLANE0 (0 << 4)
++#define RCAR_CSI2_LSWAP_L2SEL_PLANE1 (1 << 4)
++#define RCAR_CSI2_LSWAP_L2SEL_PLANE2 (2 << 4)
++#define RCAR_CSI2_LSWAP_L2SEL_PLANE3 (3 << 4)
++
++#define RCAR_CSI2_LSWAP_L1SEL_PLANE0 (0 << 2)
++#define RCAR_CSI2_LSWAP_L1SEL_PLANE1 (1 << 2)
++#define RCAR_CSI2_LSWAP_L1SEL_PLANE2 (2 << 2)
++#define RCAR_CSI2_LSWAP_L1SEL_PLANE3 (3 << 2)
++
++#define RCAR_CSI2_LSWAP_L0SEL_PLANE0 (0 << 0)
++#define RCAR_CSI2_LSWAP_L0SEL_PLANE1 (1 << 0)
++#define RCAR_CSI2_LSWAP_L0SEL_PLANE2 (2 << 0)
++#define RCAR_CSI2_LSWAP_L0SEL_PLANE3 (3 << 0)
++
++#define RCAR_CSI2_PHTC_TESTCLR (1 << 0)
++
++/* interrupt status registers */
++#define RCAR_CSI2_INTSTATE_EBD_CH1 (1 << 29)
++#define RCAR_CSI2_INTSTATE_LESS_THAN_WC (1 << 28)
++#define RCAR_CSI2_INTSTATE_AFIFO_OF (1 << 27)
++#define RCAR_CSI2_INTSTATE_VD4_START (1 << 26)
++#define RCAR_CSI2_INTSTATE_VD4_END (1 << 25)
++#define RCAR_CSI2_INTSTATE_VD3_START (1 << 24)
++#define RCAR_CSI2_INTSTATE_VD3_END (1 << 23)
++#define RCAR_CSI2_INTSTATE_VD2_START (1 << 22)
++#define RCAR_CSI2_INTSTATE_VD2_END (1 << 21)
++#define RCAR_CSI2_INTSTATE_VD1_START (1 << 20)
++#define RCAR_CSI2_INTSTATE_VD1_END (1 << 19)
++#define RCAR_CSI2_INTSTATE_SHP (1 << 18)
++#define RCAR_CSI2_INTSTATE_FSFE (1 << 17)
++#define RCAR_CSI2_INTSTATE_LNP (1 << 16)
++#define RCAR_CSI2_INTSTATE_CRC_ERR (1 << 15)
++#define RCAR_CSI2_INTSTATE_HD_WC_ZERO (1 << 14)
++#define RCAR_CSI2_INTSTATE_FRM_SEQ_ERR1 (1 << 13)
++#define RCAR_CSI2_INTSTATE_FRM_SEQ_ERR2 (1 << 12)
++#define RCAR_CSI2_INTSTATE_ECC_ERR (1 << 11)
++#define RCAR_CSI2_INTSTATE_ECC_CRCT_ERR (1 << 10)
++#define RCAR_CSI2_INTSTATE_LPDT_START (1 << 9)
++#define RCAR_CSI2_INTSTATE_LPDT_END (1 << 8)
++#define RCAR_CSI2_INTSTATE_ULPS_START (1 << 7)
++#define RCAR_CSI2_INTSTATE_ULPS_END (1 << 6)
++#define RCAR_CSI2_INTSTATE_RESERVED (1 << 5)
++#define RCAR_CSI2_INTSTATE_ERRSOTHS (1 << 4)
++#define RCAR_CSI2_INTSTATE_ERRSOTSYNCCHS (1 << 3)
++#define RCAR_CSI2_INTSTATE_ERRESC (1 << 2)
++#define RCAR_CSI2_INTSTATE_ERRSYNCESC (1 << 1)
++#define RCAR_CSI2_INTSTATE_ERRCONTROL (1 << 0)
++
++/* monitoring registers of interrupt error status */
++#define RCAR_CSI2_INTSTATE_ECC_ERR (1 << 11)
++#define RCAR_CSI2_INTSTATE_ECC_CRCT_ERR (1 << 10)
++#define RCAR_CSI2_INTSTATE_LPDT_START (1 << 9)
++#define RCAR_CSI2_INTSTATE_LPDT_END (1 << 8)
++#define RCAR_CSI2_INTSTATE_ULPS_START (1 << 7)
++#define RCAR_CSI2_INTSTATE_ULPS_END (1 << 6)
++#define RCAR_CSI2_INTSTATE_RESERVED (1 << 5)
++#define RCAR_CSI2_INTSTATE_ERRSOTHS (1 << 4)
++#define RCAR_CSI2_INTSTATE_ERRSOTSYNCCHS (1 << 3)
++#define RCAR_CSI2_INTSTATE_ERRESC (1 << 2)
++#define RCAR_CSI2_INTSTATE_ERRSYNCESC (1 << 1)
++#define RCAR_CSI2_INTSTATE_ERRCONTROL (1 << 0)
++
++enum chip_id {
++ RCAR_GEN3,
++ RCAR_GEN2,
++};
++
++enum decoder_input_interface {
++ DECODER_INPUT_INTERFACE_RGB888,
++ DECODER_INPUT_INTERFACE_YCBCR422,
++ DECODER_INPUT_INTERFACE_NONE,
++};
++
++/**
++ * struct rcar_csi2_link_config - Describes rcar_csi2 hardware configuration
++ * @input_colorspace: The input colorspace (RGB, YUV444, YUV422)
++ */
++struct rcar_csi2_link_config {
++ enum decoder_input_interface input_interface;
++ unsigned char lanes;
++ unsigned long vcdt;
++ unsigned long vcdt2;
++};
++
++#define INIT_RCAR_CSI2_LINK_CONFIG(m) \
++{ \
++ m.input_interface = DECODER_INPUT_INTERFACE_NONE; \
++ m.lanes = 0; \
++}
++
++struct rcar_csi_irq_counter_log {
++ unsigned long crc_err;
++};
++
++struct rcar_csi2 {
++ struct v4l2_subdev subdev;
++ struct v4l2_mbus_framefmt *mf;
++ unsigned int irq;
++ unsigned long mipi_flags;
++ void __iomem *base;
++ struct platform_device *pdev;
++ struct rcar_csi2_client_config *client;
++ unsigned long vcdt;
++ unsigned long vcdt2;
++
++ unsigned int field;
++ unsigned int code;
++ unsigned int lanes;
++ spinlock_t lock;
++};
++
++#define RCAR_CSI_80MBPS 0
++#define RCAR_CSI_90MBPS 1
++#define RCAR_CSI_100MBPS 2
++#define RCAR_CSI_110MBPS 3
++#define RCAR_CSI_120MBPS 4
++#define RCAR_CSI_130MBPS 5
++#define RCAR_CSI_140MBPS 6
++#define RCAR_CSI_150MBPS 7
++#define RCAR_CSI_160MBPS 8
++#define RCAR_CSI_170MBPS 9
++#define RCAR_CSI_180MBPS 10
++#define RCAR_CSI_190MBPS 11
++#define RCAR_CSI_205MBPS 12
++#define RCAR_CSI_220MBPS 13
++#define RCAR_CSI_235MBPS 14
++#define RCAR_CSI_250MBPS 15
++#define RCAR_CSI_275MBPS 16
++#define RCAR_CSI_300MBPS 17
++#define RCAR_CSI_325MBPS 18
++#define RCAR_CSI_350MBPS 19
++#define RCAR_CSI_400MBPS 20
++#define RCAR_CSI_450MBPS 21
++#define RCAR_CSI_500MBPS 22
++#define RCAR_CSI_550MBPS 23
++#define RCAR_CSI_600MBPS 24
++#define RCAR_CSI_650MBPS 25
++#define RCAR_CSI_700MBPS 26
++#define RCAR_CSI_750MBPS 27
++#define RCAR_CSI_800MBPS 28
++#define RCAR_CSI_850MBPS 29
++#define RCAR_CSI_900MBPS 30
++#define RCAR_CSI_950MBPS 31
++#define RCAR_CSI_1000MBPS 32
++#define RCAR_CSI_1050MBPS 33
++#define RCAR_CSI_1100MBPS 34
++#define RCAR_CSI_1150MBPS 35
++#define RCAR_CSI_1200MBPS 36
++#define RCAR_CSI_1250MBPS 37
++#define RCAR_CSI_1300MBPS 38
++#define RCAR_CSI_1350MBPS 39
++#define RCAR_CSI_1400MBPS 40
++#define RCAR_CSI_1450MBPS 41
++#define RCAR_CSI_1500MBPS 42
++
++static int rcar_csi2_set_phy_freq(struct rcar_csi2 *priv)
++{
++ const uint32_t const hs_freq_range[43] = {
++ 0x00, 0x10, 0x20, 0x30, 0x01, /* 0-4 */
++ 0x11, 0x21, 0x31, 0x02, 0x12, /* 5-9 */
++ 0x22, 0x32, 0x03, 0x13, 0x23, /* 10-14 */
++ 0x33, 0x04, 0x14, 0x05, 0x15, /* 15-19 */
++ 0x25, 0x06, 0x16, 0x07, 0x17, /* 20-24 */
++ 0x08, 0x18, 0x09, 0x19, 0x29, /* 25-29 */
++ 0x39, 0x0A, 0x1A, 0x2A, 0x3A, /* 30-34 */
++ 0x0B, 0x1B, 0x2B, 0x3B, 0x0C, /* 35-39 */
++ 0x1C, 0x2C, 0x3C /* 40-42 */
++ };
++ uint32_t bps_per_lane = RCAR_CSI_190MBPS;
++
++ dev_dbg(&priv->pdev->dev, "Input size (%dx%d%c)\n",
++ priv->mf->width, priv->mf->height,
++ (priv->mf->field == V4L2_FIELD_NONE) ? 'p' : 'i');
++
++ switch (priv->lanes) {
++ case 1:
++ bps_per_lane = RCAR_CSI_400MBPS;
++ break;
++ case 4:
++ if (priv->mf->field == V4L2_FIELD_NONE) {
++ if ((priv->mf->width == 1920) &&
++ (priv->mf->height == 1080))
++ bps_per_lane = RCAR_CSI_900MBPS;
++ else if ((priv->mf->width == 1280) &&
++ (priv->mf->height == 720))
++ bps_per_lane = RCAR_CSI_450MBPS;
++ else if ((priv->mf->width == 720) &&
++ (priv->mf->height == 480))
++ bps_per_lane = RCAR_CSI_190MBPS;
++ else if ((priv->mf->width == 720) &&
++ (priv->mf->height == 576))
++ bps_per_lane = RCAR_CSI_190MBPS;
++ else if ((priv->mf->width == 640) &&
++ (priv->mf->height == 480))
++ bps_per_lane = RCAR_CSI_100MBPS;
++ else
++ goto error;
++ } else {
++ if ((priv->mf->width == 1920) &&
++ (priv->mf->height == 1080))
++ bps_per_lane = RCAR_CSI_450MBPS;
++ else
++ goto error;
++ }
++ break;
++ default:
++ dev_err(&priv->pdev->dev, "ERROR: lanes is invalid (%d)\n",
++ priv->lanes);
++ return -EINVAL;
++ }
++
++ dev_dbg(&priv->pdev->dev, "bps_per_lane (%d)\n", bps_per_lane);
++
++ iowrite32((hs_freq_range[bps_per_lane] << 16),
++ priv->base + RCAR_CSI2_PHYPLL);
++ return 0;
++
++error:
++ dev_err(&priv->pdev->dev, "Not support resolution (%dx%d%c)\n",
++ priv->mf->width, priv->mf->height,
++ (priv->mf->field == V4L2_FIELD_NONE) ? 'p' : 'i');
++ return -EINVAL;
++}
++
++static irqreturn_t rcar_csi2_irq(int irq, void *data)
++{
++ struct rcar_csi2 *priv = data;
++ u32 int_status;
++ unsigned int handled = 0;
++
++ spin_lock(&priv->lock);
++
++ int_status = ioread32(priv->base + RCAR_CSI2_INTSTATE);
++ if (!int_status)
++ goto done;
++
++ /* ack interrupts */
++ iowrite32(int_status, priv->base + RCAR_CSI2_INTSTATE);
++ handled = 1;
++
++done:
++ spin_unlock(&priv->lock);
++
++ return IRQ_RETVAL(handled);
++
++}
++
++static void rcar_csi2_hwdeinit(struct rcar_csi2 *priv)
++{
++ iowrite32(0, priv->base + RCAR_CSI2_PHYCNT);
++
++ /* reset CSI2 hardware */
++ iowrite32(0x00000001, priv->base + RCAR_CSI2_SRST);
++ udelay(5);
++ iowrite32(0x00000000, priv->base + RCAR_CSI2_SRST);
++}
++
++static int rcar_csi2_hwinit(struct rcar_csi2 *priv)
++{
++ int ret;
++ __u32 tmp = 0x10; /* Enable MIPI CSI clock lane */
++
++ /* Reflect registers immediately */
++ iowrite32(0x00000001, priv->base + RCAR_CSI2_TREF);
++ /* reset CSI2 hardware */
++ iowrite32(0x00000001, priv->base + RCAR_CSI2_SRST);
++ udelay(5);
++ iowrite32(0x00000000, priv->base + RCAR_CSI2_SRST);
++
++ iowrite32(0x00000000, priv->base + RCAR_CSI2_PHTC);
++
++ /* setting HS reception frequency */
++ {
++ switch (priv->lanes) {
++ case 1:
++ /* First field number setting */
++ iowrite32(0x0001000f, priv->base + RCAR_CSI2_FLD);
++ tmp |= 0x1;
++ break;
++ case 4:
++ /* First field number setting */
++ iowrite32(0x0002000f, priv->base + RCAR_CSI2_FLD);
++ tmp |= 0xF;
++ break;
++ default:
++ dev_err(&priv->pdev->dev,
++ "ERROR: lanes is invalid (%d)\n",
++ priv->lanes);
++ return -EINVAL;
++ }
++
++ /* set PHY frequency */
++ ret = rcar_csi2_set_phy_freq(priv);
++ if (ret < 0)
++ return ret;
++
++ /* Enable lanes */
++ iowrite32(tmp, priv->base + RCAR_CSI2_PHYCNT);
++
++ iowrite32(tmp | RCAR_CSI2_PHYCNT_SHUTDOWNZ,
++ priv->base + RCAR_CSI2_PHYCNT);
++ iowrite32(tmp | (RCAR_CSI2_PHYCNT_SHUTDOWNZ |
++ RCAR_CSI2_PHYCNT_RSTZ),
++ priv->base + RCAR_CSI2_PHYCNT);
++ }
++
++ iowrite32(0x00000003, priv->base + RCAR_CSI2_CHKSUM);
++ iowrite32(priv->vcdt, priv->base + RCAR_CSI2_VCDT);
++ iowrite32(priv->vcdt2, priv->base + RCAR_CSI2_VCDT2);
++ iowrite32(0x00010000, priv->base + RCAR_CSI2_FRDT);
++ udelay(10);
++ iowrite32(0x83000000, priv->base + RCAR_CSI2_LINKCNT);
++ iowrite32(0x000000e4, priv->base + RCAR_CSI2_LSWAP);
++
++ dev_dbg(&priv->pdev->dev, "CSI2 VCDT: 0x%x\n",
++ ioread32(priv->base + RCAR_CSI2_VCDT));
++ dev_dbg(&priv->pdev->dev, "CSI2 VCDT2: 0x%x\n",
++ ioread32(priv->base + RCAR_CSI2_VCDT2));
++
++ /* wait until video decoder power off */
++ msleep(10);
++ {
++ int timeout = 100;
++
++ /* Read the PHY clock lane monitor register (PHCLM). */
++ while (!(ioread32(priv->base + RCAR_CSI2_PHCLM) & 0x01)
++ && timeout) {
++ timeout--;
++ }
++ if (timeout == 0)
++ dev_err(&priv->pdev->dev,
++ "Timeout of reading the PHY clock lane\n");
++ else
++ dev_dbg(&priv->pdev->dev,
++ "Detected the PHY clock lane\n");
++
++ timeout = 100;
++
++ /* Read the PHY data lane monitor register (PHDLM). */
++ while (!(ioread32(priv->base + RCAR_CSI2_PHDLM) & 0x01)
++ && timeout) {
++ timeout--;
++ }
++ if (timeout == 0)
++ dev_err(&priv->pdev->dev,
++ "Timeout of reading the PHY data lane\n");
++ else
++ dev_dbg(&priv->pdev->dev,
++ "Detected the PHY data lane\n");
++ }
++
++ return 0;
++}
++
++static int rcar_csi2_s_power(struct v4l2_subdev *sd, int on)
++{
++ struct rcar_csi2 *priv = container_of(sd, struct rcar_csi2, subdev);
++ struct v4l2_subdev *tmp_sd;
++ struct v4l2_subdev_format fmt = {
++ .which = V4L2_SUBDEV_FORMAT_ACTIVE,
++ };
++ struct v4l2_mbus_framefmt *mf = &fmt.format;
++ int ret = 0;
++
++ if (on) {
++ v4l2_device_for_each_subdev(tmp_sd, sd->v4l2_dev) {
++ if (strncmp(tmp_sd->name, CONNECT_SLAVE_NAME,
++ sizeof(CONNECT_SLAVE_NAME) - 1) == 0) {
++ v4l2_subdev_call(tmp_sd, pad, get_fmt,
++ NULL, &fmt);
++ if (ret < 0)
++ return ret;
++ }
++ }
++ priv->mf = mf;
++ pm_runtime_get_sync(&priv->pdev->dev);
++ ret = rcar_csi2_hwinit(priv);
++ if (ret < 0)
++ return ret;
++ } else {
++ rcar_csi2_hwdeinit(priv);
++ pm_runtime_put_sync(&priv->pdev->dev);
++ }
++
++ return ret;
++}
++
++static struct v4l2_subdev_core_ops rcar_csi2_subdev_core_ops = {
++ .s_power = rcar_csi2_s_power,
++};
++
++static struct v4l2_subdev_ops rcar_csi2_subdev_ops = {
++ .core = &rcar_csi2_subdev_core_ops,
++};
++
++#ifdef CONFIG_OF
++static const struct of_device_id rcar_csi2_of_table[] = {
++ { .compatible = "renesas,r8a7796-csi2", .data = (void *)RCAR_GEN3 },
++ { .compatible = "renesas,r8a7795-csi2", .data = (void *)RCAR_GEN3 },
++ { },
++};
++MODULE_DEVICE_TABLE(of, rcar_csi2_of_table);
++#endif
++
++static struct platform_device_id rcar_csi2_id_table[] = {
++ { "r8a7796-csi2", RCAR_GEN3 },
++ { "r8a7795-csi2", RCAR_GEN3 },
++ {},
++};
++MODULE_DEVICE_TABLE(platform, rcar_csi2_id_table);
++
++static int rcar_csi2_parse_dt(struct device_node *np,
++ struct rcar_csi2_link_config *config)
++{
++ struct v4l2_of_endpoint bus_cfg;
++ struct device_node *endpoint;
++ struct device_node *vc_np, *vc_ch;
++ const char *str;
++ char csi_name[9];
++ int ret;
++ int i, ch;
++
++ /* Parse the endpoint. */
++ endpoint = of_graph_get_next_endpoint(np, NULL);
++ if (!endpoint)
++ return -EINVAL;
++
++ v4l2_of_parse_endpoint(endpoint, &bus_cfg);
++ of_node_put(endpoint);
++
++ config->lanes = bus_cfg.bus.mipi_csi2.num_data_lanes;
++
++ ret = of_property_read_string(np, "adi,input-interface", &str);
++ if (ret < 0)
++ return ret;
++
++ vc_np = of_get_child_by_name(np, "virtual,channel");
++
++ config->vcdt = 0;
++ config->vcdt2 = 0;
++ for (i = 0; i < VC_MAX_CHANNEL; i++) {
++ sprintf(csi_name, "csi2_vc%d", i);
++
++ vc_ch = of_get_child_by_name(vc_np, csi_name);
++ if (!vc_ch)
++ continue;
++ ret = of_property_read_string(vc_ch, "data,type", &str);
++ if (ret < 0)
++ return ret;
++ ret = of_property_read_u32(vc_ch, "receive,vc", &ch);
++ if (ret < 0)
++ return ret;
++
++ if (i < 2) {
++ if (!strcmp(str, "rgb888"))
++ config->vcdt |= (0x24 << (i * 16));
++ else if (!strcmp(str, "ycbcr422"))
++ config->vcdt |= (0x1e << (i * 16));
++ else
++ config->vcdt |= 0;
++
++ config->vcdt |= (ch << (8 + (i * 16)));
++ config->vcdt |= (RCAR_CSI2_VCDT_VCDTN_EN << (i * 16)) |
++ (RCAR_CSI2_VCDT_SEL_DTN_ON << (i * 16));
++ }
++ if (i >= 2) {
++ int j = (i - 2);
++
++ if (!strcmp(str, "rgb888"))
++ config->vcdt2 |= (0x24 << (j * 16));
++ else if (!strcmp(str, "ycbcr422"))
++ config->vcdt2 |= (0x1e << (j * 16));
++ else
++ config->vcdt2 |= 0;
++
++ config->vcdt2 |= (ch << (8 + (j * 16)));
++ config->vcdt2 |= (RCAR_CSI2_VCDT_VCDTN_EN << (j * 16)) |
++ (RCAR_CSI2_VCDT_SEL_DTN_ON << (j * 16));
++ }
++ }
++
++ return 0;
++}
++
++static int rcar_csi2_probe(struct platform_device *pdev)
++{
++ struct resource *res;
++ unsigned int irq;
++ int ret;
++ struct rcar_csi2 *priv;
++ /* Platform data specify the PHY, lanes, ECC, CRC */
++ struct rcar_csi2_pdata *pdata;
++ struct rcar_csi2_link_config link_config;
++
++ dev_dbg(&pdev->dev, "CSI2 probed.\n");
++
++ INIT_RCAR_CSI2_LINK_CONFIG(link_config);
++
++ if (pdev->dev.of_node) {
++ ret = rcar_csi2_parse_dt(pdev->dev.of_node, &link_config);
++ if (ret)
++ return ret;
++
++ if (link_config.lanes == 4)
++ dev_info(&pdev->dev,
++ "Detected rgb888 in rcar_csi2_parse_dt\n");
++ else
++ dev_info(&pdev->dev,
++ "Detected YCbCr422 in rcar_csi2_parse_dt\n");
++ } else {
++ pdata = pdev->dev.platform_data;
++ if (!pdata)
++ return -EINVAL;
++ }
++
++ priv = devm_kzalloc(&pdev->dev, sizeof(struct rcar_csi2), GFP_KERNEL);
++ if (!priv)
++ return -ENOMEM;
++
++ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
++ /* Interrupt unused so far */
++ irq = platform_get_irq(pdev, 0);
++
++ if (!res || (int)irq <= 0) {
++ dev_err(&pdev->dev, "Not enough CSI2 platform resources.\n");
++ return -ENODEV;
++ }
++
++ priv->irq = irq;
++
++ priv->base = devm_ioremap_resource(&pdev->dev, res);
++ if (IS_ERR(priv->base))
++ return PTR_ERR(priv->base);
++
++ ret = devm_request_irq(&pdev->dev, irq, rcar_csi2_irq, IRQF_SHARED,
++ dev_name(&pdev->dev), priv);
++ if (ret)
++ return ret;
++
++ priv->pdev = pdev;
++ priv->subdev.owner = THIS_MODULE;
++ priv->subdev.dev = &pdev->dev;
++ priv->lanes = link_config.lanes;
++ priv->vcdt = link_config.vcdt;
++ priv->vcdt2 = link_config.vcdt2;
++
++ platform_set_drvdata(pdev, &priv->subdev);
++
++ v4l2_subdev_init(&priv->subdev, &rcar_csi2_subdev_ops);
++ v4l2_set_subdevdata(&priv->subdev, &pdev->dev);
++
++ snprintf(priv->subdev.name, V4L2_SUBDEV_NAME_SIZE, "rcar_csi2.%s",
++ dev_name(&pdev->dev));
++
++ ret = v4l2_async_register_subdev(&priv->subdev);
++ if (ret < 0)
++ return ret;
++
++ spin_lock_init(&priv->lock);
++
++ pm_runtime_enable(&pdev->dev);
++
++ dev_dbg(&pdev->dev, "CSI2 probed.\n");
++
++ return 0;
++}
++
++static int rcar_csi2_remove(struct platform_device *pdev)
++{
++ struct v4l2_subdev *subdev = platform_get_drvdata(pdev);
++ struct rcar_csi2 *priv = container_of(subdev, struct rcar_csi2, subdev);
++
++ v4l2_async_unregister_subdev(&priv->subdev);
++ pm_runtime_disable(&pdev->dev);
++
++ return 0;
++}
++
++#ifdef CONFIG_PM_SLEEP
++static int rcar_csi2_suspend(struct device *dev)
++{
++ /* Empty function for now */
++ return 0;
++}
++
++static int rcar_csi2_resume(struct device *dev)
++{
++ /* Empty function for now */
++ return 0;
++}
++
++static SIMPLE_DEV_PM_OPS(rcar_csi2_pm_ops,
++ rcar_csi2_suspend, rcar_csi2_resume);
++#define DEV_PM_OPS (&rcar_csi2_pm_ops)
++#else
++#define DEV_PM_OPS NULL
++#endif /* CONFIG_PM_SLEEP */
++
++static struct platform_driver __refdata rcar_csi2_pdrv = {
++ .remove = rcar_csi2_remove,
++ .probe = rcar_csi2_probe,
++ .driver = {
++ .name = DRV_NAME,
++ .pm = DEV_PM_OPS,
++ .of_match_table = of_match_ptr(rcar_csi2_of_table),
++ },
++ .id_table = rcar_csi2_id_table,
++};
++
++module_platform_driver(rcar_csi2_pdrv);
++
++MODULE_DESCRIPTION("Renesas R-Car MIPI CSI-2 driver");
++MODULE_AUTHOR("Koji Matsuoka <koji.matsuoka.xm@renesas.com>");
++MODULE_LICENSE("GPL v2");
++MODULE_ALIAS("platform:rcar-csi2");
+diff --git a/drivers/media/platform/soc_camera/rcar_vin.c b/drivers/media/platform/soc_camera/rcar_vin.c
+new file mode 100644
+index 0000000..400958b
+--- /dev/null
++++ b/drivers/media/platform/soc_camera/rcar_vin.c
+@@ -0,0 +1,3071 @@
++/*
++ * SoC-camera host driver for Renesas R-Car VIN unit
++ *
++ * Copyright (C) 2015-2016 Renesas Electronics Corporation
++ * Copyright (C) 2011-2013 Renesas Solutions Corp.
++ * Copyright (C) 2013 Cogent Embedded, Inc., <source@cogentembedded.com>
++ *
++ * Based on V4L2 Driver for SuperH Mobile CEU interface "sh_mobile_ceu_camera.c"
++ *
++ * Copyright (C) 2008 Magnus Damm
++ *
++ * This program is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License as published by the
++ * Free Software Foundation; either version 2 of the License, or (at your
++ * option) any later version.
++ */
++
++#ifdef CONFIG_VIDEO_RCAR_VIN_LEGACY_DEBUG
++#define DEBUG
++#endif
++
++#include <linux/delay.h>
++#include <linux/interrupt.h>
++#include <linux/io.h>
++#include <linux/kernel.h>
++#include <linux/module.h>
++#include <linux/of.h>
++#include <linux/of_device.h>
++#include <linux/platform_device.h>
++#include <linux/pm_runtime.h>
++#include <linux/slab.h>
++#include <linux/videodev2.h>
++#include <linux/list.h>
++
++#include <media/soc_camera.h>
++#include <media/drv-intf/soc_mediabus.h>
++#include <media/v4l2-common.h>
++#include <media/v4l2-dev.h>
++#include <media/v4l2-device.h>
++#include <media/v4l2-mediabus.h>
++#include <media/v4l2-of.h>
++#include <media/v4l2-subdev.h>
++#include <media/videobuf2-dma-contig.h>
++
++#include <media/rcar_csi2.h>
++
++#include "soc_scale_crop.h"
++
++#define DRV_NAME "rcar_vin"
++
++/* Register offsets for R-Car VIN */
++#define VNMC_REG 0x00 /* Video n Main Control Register */
++#define VNMS_REG 0x04 /* Video n Module Status Register */
++#define VNFC_REG 0x08 /* Video n Frame Capture Register */
++#define VNSLPRC_REG 0x0C /* Video n Start Line Pre-Clip Register */
++#define VNELPRC_REG 0x10 /* Video n End Line Pre-Clip Register */
++#define VNSPPRC_REG 0x14 /* Video n Start Pixel Pre-Clip Register */
++#define VNEPPRC_REG 0x18 /* Video n End Pixel Pre-Clip Register */
++#define VNSLPOC_REG 0x1C /* Video n Start Line Post-Clip Register */
++#define VNELPOC_REG 0x20 /* Video n End Line Post-Clip Register */
++#define VNSPPOC_REG 0x24 /* Video n Start Pixel Post-Clip Register */
++#define VNEPPOC_REG 0x28 /* Video n End Pixel Post-Clip Register */
++#define VNIS_REG 0x2C /* Video n Image Stride Register */
++#define VNMB_REG(m) (0x30 + ((m) << 2)) /* Video n Memory Base m Register */
++#define VNIE_REG 0x40 /* Video n Interrupt Enable Register */
++#define VNINTS_REG 0x44 /* Video n Interrupt Status Register */
++#define VNSI_REG 0x48 /* Video n Scanline Interrupt Register */
++#define VNMTC_REG 0x4C /* Video n Memory Transfer Control Register */
++#define VNYS_REG 0x50 /* Video n Y Scale Register */
++#define VNXS_REG 0x54 /* Video n X Scale Register */
++#define VNDMR_REG 0x58 /* Video n Data Mode Register */
++#define VNDMR2_REG 0x5C /* Video n Data Mode Register 2 */
++#define VNUVAOF_REG 0x60 /* Video n UV Address Offset Register */
++#define VNC1A_REG 0x80 /* Video n Coefficient Set C1A Register */
++#define VNC1B_REG 0x84 /* Video n Coefficient Set C1B Register */
++#define VNC1C_REG 0x88 /* Video n Coefficient Set C1C Register */
++#define VNC2A_REG 0x90 /* Video n Coefficient Set C2A Register */
++#define VNC2B_REG 0x94 /* Video n Coefficient Set C2B Register */
++#define VNC2C_REG 0x98 /* Video n Coefficient Set C2C Register */
++#define VNC3A_REG 0xA0 /* Video n Coefficient Set C3A Register */
++#define VNC3B_REG 0xA4 /* Video n Coefficient Set C3B Register */
++#define VNC3C_REG 0xA8 /* Video n Coefficient Set C3C Register */
++#define VNC4A_REG 0xB0 /* Video n Coefficient Set C4A Register */
++#define VNC4B_REG 0xB4 /* Video n Coefficient Set C4B Register */
++#define VNC4C_REG 0xB8 /* Video n Coefficient Set C4C Register */
++#define VNC5A_REG 0xC0 /* Video n Coefficient Set C5A Register */
++#define VNC5B_REG 0xC4 /* Video n Coefficient Set C5B Register */
++#define VNC5C_REG 0xC8 /* Video n Coefficient Set C5C Register */
++#define VNC6A_REG 0xD0 /* Video n Coefficient Set C6A Register */
++#define VNC6B_REG 0xD4 /* Video n Coefficient Set C6B Register */
++#define VNC6C_REG 0xD8 /* Video n Coefficient Set C6C Register */
++#define VNC7A_REG 0xE0 /* Video n Coefficient Set C7A Register */
++#define VNC7B_REG 0xE4 /* Video n Coefficient Set C7B Register */
++#define VNC7C_REG 0xE8 /* Video n Coefficient Set C7C Register */
++#define VNC8A_REG 0xF0 /* Video n Coefficient Set C8A Register */
++#define VNC8B_REG 0xF4 /* Video n Coefficient Set C8B Register */
++#define VNC8C_REG 0xF8 /* Video n Coefficient Set C8C Register */
++
++/* Register bit fields for R-Car VIN */
++/* Video n Main Control Register bits */
++#define VNMC_DPINE (1 << 27)
++#define VNMC_SCLE (1 << 26)
++#define VNMC_FOC (1 << 21)
++#define VNMC_YCAL (1 << 19)
++#define VNMC_INF_YUV8_BT656 (0 << 16)
++#define VNMC_INF_YUV8_BT601 (1 << 16)
++#define VNMC_INF_YUV10_BT656 (2 << 16)
++#define VNMC_INF_YUV10_BT601 (3 << 16)
++#define VNMC_INF_YUV16 (5 << 16)
++#define VNMC_INF_RGB888 (6 << 16)
++#define VNMC_INF_MASK (7 << 16)
++#define VNMC_VUP (1 << 10)
++#define VNMC_IM_ODD (0 << 3)
++#define VNMC_IM_ODD_EVEN (1 << 3)
++#define VNMC_IM_EVEN (2 << 3)
++#define VNMC_IM_FULL (3 << 3)
++#define VNMC_BPS (1 << 1)
++#define VNMC_ME (1 << 0)
++
++/* Video n Module Status Register bits */
++#define VNMS_FBS_MASK (3 << 3)
++#define VNMS_FBS_SHIFT 3
++#define VNMS_AV (1 << 1)
++#define VNMS_CA (1 << 0)
++
++/* Video n Frame Capture Register bits */
++#define VNFC_C_FRAME (1 << 1)
++#define VNFC_S_FRAME (1 << 0)
++
++/* Video n Interrupt Enable Register bits */
++#define VNIE_FIE (1 << 4)
++#define VNIE_EFE (1 << 1)
++#define VNIE_FOE (1 << 0)
++
++/* Video n Interrupt Status Register bits */
++#define VNINTS_FIS (1 << 4)
++#define VNINTS_EFS (1 << 1)
++#define VNINTS_FOS (1 << 0)
++
++/* Video n Data Mode Register bits */
++#define VNDMR_EXRGB (1 << 8)
++#define VNDMR_BPSM (1 << 4)
++#define VNDMR_DTMD_YCSEP (1 << 1)
++#define VNDMR_DTMD_ARGB (1 << 0)
++#define VNDMR_DTMD_YCSEP_YCBCR420 (3 << 0)
++
++/* Video n Data Mode Register 2 bits */
++#define VNDMR2_VPS (1 << 30)
++#define VNDMR2_HPS (1 << 29)
++#define VNDMR2_FTEV (1 << 17)
++#define VNDMR2_VLV(n) ((n & 0xf) << 12)
++
++/* setting CSI2 on R-Car Gen3*/
++#define VNCSI_IFMD_REG 0x20 /* Video n CSI2 Interface Mode Register */
++
++#define VNCSI_IFMD_DES1 (1 << 26) /* CSI20 */
++#define VNCSI_IFMD_DES0 (1 << 25) /* H3:CSI40/41, M3:CSI40 */
++
++#define VNCSI_IFMD_CSI_CHSEL(n) (n << 0)
++#define VNCSI_IFMD_SEL_NUMBER 5
++
++/* UDS */
++#define VNUDS_CTRL_REG 0x80 /* Scaling Control Registers */
++#define VNUDS_CTRL_AMD (1 << 30)
++#define VNUDS_CTRL_BC (1 << 20)
++#define VNUDS_CTRL_TDIPC (1 << 1)
++
++#define VNUDS_SCALE_REG 0x84 /* Scaling Factor Register */
++#define VNUDS_PASS_BWIDTH_REG 0x90 /* Passband Registers */
++#define VNUDS_IPC_REG 0x98 /* 2D IPC Setting Register */
++#define VNUDS_CLIP_SIZE_REG 0xA4 /* UDS Output Size Clipping Register */
++
++#define TIMEOUT_MS 100
++
++#define RCAR_VIN_HSYNC_ACTIVE_LOW (1 << 0)
++#define RCAR_VIN_VSYNC_ACTIVE_LOW (1 << 1)
++#define RCAR_VIN_BT601 (1 << 2)
++#define RCAR_VIN_BT656 (1 << 3)
++#define RCAR_VIN_CSI2 (1 << 4)
++
++static int ifmd0_reg_match[VNCSI_IFMD_SEL_NUMBER];
++static int ifmd4_reg_match[VNCSI_IFMD_SEL_NUMBER];
++static int ifmd0_init = true;
++static int ifmd4_init = true;
++
++enum chip_id {
++ RCAR_GEN3,
++ RCAR_M3,
++ RCAR_H3,
++ RCAR_GEN2,
++ RCAR_H1,
++ RCAR_M1,
++ RCAR_E1,
++};
++
++enum csi2_ch {
++ RCAR_CSI_CH_NONE = -1,
++ RCAR_CSI40,
++ RCAR_CSI20,
++ RCAR_CSI41,
++ RCAR_CSI21,
++ RCAR_CSI_MAX,
++};
++
++enum gen3_vin_ch {
++ RCAR_VIN_CH_NONE = -1,
++ RCAR_VIDEO_0,
++ RCAR_VIDEO_1,
++ RCAR_VIDEO_2,
++ RCAR_VIDEO_3,
++ RCAR_VIDEO_4,
++ RCAR_VIDEO_5,
++ RCAR_VIDEO_6,
++ RCAR_VIDEO_7,
++ RCAR_VIDEO_MAX,
++};
++
++enum virtual_ch {
++ RCAR_VIRTUAL_NONE = -1,
++ RCAR_VIRTUAL_CH0,
++ RCAR_VIRTUAL_CH1,
++ RCAR_VIRTUAL_CH2,
++ RCAR_VIRTUAL_CH3,
++ RCAR_VIRTUAL_MAX,
++};
++
++struct vin_gen3_virtual_sel {
++ enum csi2_ch csi2_ch;
++ enum virtual_ch vc;
++};
++
++struct vin_gen3_ifmd {
++ unsigned int set_reg;
++ struct vin_gen3_virtual_sel v_sel[8];
++};
++
++static const struct vin_gen3_ifmd vin_h3_vc_ifmd[] = {
++ { 0x0000,
++ {
++ {RCAR_CSI40, RCAR_VIRTUAL_CH0},
++ {RCAR_CSI20, RCAR_VIRTUAL_CH0},
++ {RCAR_CSI20, RCAR_VIRTUAL_CH1},
++ {RCAR_CSI40, RCAR_VIRTUAL_CH1},
++ {RCAR_CSI41, RCAR_VIRTUAL_CH0},
++ {RCAR_CSI20, RCAR_VIRTUAL_CH0},
++ {RCAR_CSI20, RCAR_VIRTUAL_CH1},
++ {RCAR_CSI41, RCAR_VIRTUAL_CH1},
++ }
++ },
++ { 0x0001,
++ {
++ {RCAR_CSI20, RCAR_VIRTUAL_CH0},
++ {RCAR_CSI40, RCAR_VIRTUAL_CH1},
++ {RCAR_CSI40, RCAR_VIRTUAL_CH0},
++ {RCAR_CSI20, RCAR_VIRTUAL_CH1},
++ {RCAR_CSI20, RCAR_VIRTUAL_CH0},
++ {RCAR_CSI41, RCAR_VIRTUAL_CH1},
++ {RCAR_CSI41, RCAR_VIRTUAL_CH0},
++ {RCAR_CSI20, RCAR_VIRTUAL_CH1},
++ }
++ },
++ { 0x0002,
++ {
++ {RCAR_CSI40, RCAR_VIRTUAL_CH1},
++ {RCAR_CSI40, RCAR_VIRTUAL_CH0},
++ {RCAR_CSI20, RCAR_VIRTUAL_CH0},
++ {RCAR_CSI20, RCAR_VIRTUAL_CH1},
++ {RCAR_CSI41, RCAR_VIRTUAL_CH1},
++ {RCAR_CSI41, RCAR_VIRTUAL_CH0},
++ {RCAR_CSI20, RCAR_VIRTUAL_CH0},
++ {RCAR_CSI20, RCAR_VIRTUAL_CH1},
++ }
++ },
++ { 0x0003,
++ {
++ {RCAR_CSI40, RCAR_VIRTUAL_CH0},
++ {RCAR_CSI40, RCAR_VIRTUAL_CH1},
++ {RCAR_CSI40, RCAR_VIRTUAL_CH2},
++ {RCAR_CSI40, RCAR_VIRTUAL_CH3},
++ {RCAR_CSI41, RCAR_VIRTUAL_CH0},
++ {RCAR_CSI41, RCAR_VIRTUAL_CH1},
++ {RCAR_CSI41, RCAR_VIRTUAL_CH2},
++ {RCAR_CSI41, RCAR_VIRTUAL_CH3},
++ }
++ },
++ { 0x0004,
++ {
++ {RCAR_CSI20, RCAR_VIRTUAL_CH0},
++ {RCAR_CSI20, RCAR_VIRTUAL_CH1},
++ {RCAR_CSI20, RCAR_VIRTUAL_CH2},
++ {RCAR_CSI20, RCAR_VIRTUAL_CH3},
++ {RCAR_CSI20, RCAR_VIRTUAL_CH0},
++ {RCAR_CSI20, RCAR_VIRTUAL_CH1},
++ {RCAR_CSI20, RCAR_VIRTUAL_CH2},
++ {RCAR_CSI20, RCAR_VIRTUAL_CH3},
++ }
++ },
++};
++
++static const struct vin_gen3_ifmd vin_m3_vc_ifmd[] = {
++ { 0x0000,
++ {
++ {RCAR_CSI40, RCAR_VIRTUAL_CH0},
++ {RCAR_CSI20, RCAR_VIRTUAL_CH0},
++ {RCAR_CSI_CH_NONE, RCAR_VIN_CH_NONE},
++ {RCAR_CSI40, RCAR_VIRTUAL_CH1},
++ {RCAR_CSI40, RCAR_VIRTUAL_CH0},
++ {RCAR_CSI20, RCAR_VIRTUAL_CH0},
++ {RCAR_CSI_CH_NONE, RCAR_VIN_CH_NONE},
++ {RCAR_CSI40, RCAR_VIRTUAL_CH1},
++ }
++ },
++ { 0x0001,
++ {
++ {RCAR_CSI20, RCAR_VIRTUAL_CH0},
++ {RCAR_CSI_CH_NONE, RCAR_VIN_CH_NONE},
++ {RCAR_CSI40, RCAR_VIRTUAL_CH0},
++ {RCAR_CSI20, RCAR_VIRTUAL_CH1},
++ {RCAR_CSI20, RCAR_VIRTUAL_CH0},
++ {RCAR_CSI_CH_NONE, RCAR_VIN_CH_NONE},
++ {RCAR_CSI40, RCAR_VIRTUAL_CH0},
++ {RCAR_CSI20, RCAR_VIRTUAL_CH1},
++ }
++ },
++ { 0x0002,
++ {
++ {RCAR_CSI_CH_NONE, RCAR_VIN_CH_NONE},
++ {RCAR_CSI40, RCAR_VIRTUAL_CH0},
++ {RCAR_CSI20, RCAR_VIRTUAL_CH0},
++ {RCAR_CSI_CH_NONE, RCAR_VIN_CH_NONE},
++ {RCAR_CSI_CH_NONE, RCAR_VIN_CH_NONE},
++ {RCAR_CSI40, RCAR_VIRTUAL_CH0},
++ {RCAR_CSI20, RCAR_VIRTUAL_CH0},
++ {RCAR_CSI_CH_NONE, RCAR_VIN_CH_NONE},
++ }
++ },
++ { 0x0003,
++ {
++ {RCAR_CSI40, RCAR_VIRTUAL_CH0},
++ {RCAR_CSI40, RCAR_VIRTUAL_CH1},
++ {RCAR_CSI40, RCAR_VIRTUAL_CH2},
++ {RCAR_CSI40, RCAR_VIRTUAL_CH3},
++ {RCAR_CSI40, RCAR_VIRTUAL_CH0},
++ {RCAR_CSI40, RCAR_VIRTUAL_CH1},
++ {RCAR_CSI40, RCAR_VIRTUAL_CH2},
++ {RCAR_CSI40, RCAR_VIRTUAL_CH3},
++ }
++ },
++ { 0x0004,
++ {
++ {RCAR_CSI20, RCAR_VIRTUAL_CH0},
++ {RCAR_CSI20, RCAR_VIRTUAL_CH1},
++ {RCAR_CSI20, RCAR_VIRTUAL_CH2},
++ {RCAR_CSI20, RCAR_VIRTUAL_CH3},
++ {RCAR_CSI20, RCAR_VIRTUAL_CH0},
++ {RCAR_CSI20, RCAR_VIRTUAL_CH1},
++ {RCAR_CSI20, RCAR_VIRTUAL_CH2},
++ {RCAR_CSI20, RCAR_VIRTUAL_CH3},
++ }
++ },
++};
++
++enum csi2_fmt {
++ RCAR_CSI_FMT_NONE = -1,
++ RCAR_CSI_RGB888,
++ RCAR_CSI_YCBCR422,
++};
++
++struct vin_coeff {
++ unsigned short xs_value;
++ u32 coeff_set[24];
++};
++
++static const struct vin_coeff vin_coeff_set[] = {
++ { 0x0000, {
++ 0x00000000, 0x00000000, 0x00000000,
++ 0x00000000, 0x00000000, 0x00000000,
++ 0x00000000, 0x00000000, 0x00000000,
++ 0x00000000, 0x00000000, 0x00000000,
++ 0x00000000, 0x00000000, 0x00000000,
++ 0x00000000, 0x00000000, 0x00000000,
++ 0x00000000, 0x00000000, 0x00000000,
++ 0x00000000, 0x00000000, 0x00000000 },
++ },
++ { 0x1000, {
++ 0x000fa400, 0x000fa400, 0x09625902,
++ 0x000003f8, 0x00000403, 0x3de0d9f0,
++ 0x001fffed, 0x00000804, 0x3cc1f9c3,
++ 0x001003de, 0x00000c01, 0x3cb34d7f,
++ 0x002003d2, 0x00000c00, 0x3d24a92d,
++ 0x00200bca, 0x00000bff, 0x3df600d2,
++ 0x002013cc, 0x000007ff, 0x3ed70c7e,
++ 0x00100fde, 0x00000000, 0x3f87c036 },
++ },
++ { 0x1200, {
++ 0x002ffff1, 0x002ffff1, 0x02a0a9c8,
++ 0x002003e7, 0x001ffffa, 0x000185bc,
++ 0x002007dc, 0x000003ff, 0x3e52859c,
++ 0x00200bd4, 0x00000002, 0x3d53996b,
++ 0x00100fd0, 0x00000403, 0x3d04ad2d,
++ 0x00000bd5, 0x00000403, 0x3d35ace7,
++ 0x3ff003e4, 0x00000801, 0x3dc674a1,
++ 0x3fffe800, 0x00000800, 0x3e76f461 },
++ },
++ { 0x1400, {
++ 0x00100be3, 0x00100be3, 0x04d1359a,
++ 0x00000fdb, 0x002003ed, 0x0211fd93,
++ 0x00000fd6, 0x002003f4, 0x0002d97b,
++ 0x000007d6, 0x002ffffb, 0x3e93b956,
++ 0x3ff003da, 0x001003ff, 0x3db49926,
++ 0x3fffefe9, 0x00100001, 0x3d655cee,
++ 0x3fffd400, 0x00000003, 0x3d65f4b6,
++ 0x000fb421, 0x00000402, 0x3dc6547e },
++ },
++ { 0x1600, {
++ 0x00000bdd, 0x00000bdd, 0x06519578,
++ 0x3ff007da, 0x00000be3, 0x03c24973,
++ 0x3ff003d9, 0x00000be9, 0x01b30d5f,
++ 0x3ffff7df, 0x001003f1, 0x0003c542,
++ 0x000fdfec, 0x001003f7, 0x3ec4711d,
++ 0x000fc400, 0x002ffffd, 0x3df504f1,
++ 0x001fa81a, 0x002ffc00, 0x3d957cc2,
++ 0x002f8c3c, 0x00100000, 0x3db5c891 },
++ },
++ { 0x1800, {
++ 0x3ff003dc, 0x3ff003dc, 0x0791e558,
++ 0x000ff7dd, 0x3ff007de, 0x05328554,
++ 0x000fe7e3, 0x3ff00be2, 0x03232546,
++ 0x000fd7ee, 0x000007e9, 0x0143bd30,
++ 0x001fb800, 0x000007ee, 0x00044511,
++ 0x002fa015, 0x000007f4, 0x3ef4bcee,
++ 0x002f8832, 0x001003f9, 0x3e4514c7,
++ 0x001f7853, 0x001003fd, 0x3de54c9f },
++ },
++ { 0x1a00, {
++ 0x000fefe0, 0x000fefe0, 0x08721d3c,
++ 0x001fdbe7, 0x000ffbde, 0x0652a139,
++ 0x001fcbf0, 0x000003df, 0x0463292e,
++ 0x002fb3ff, 0x3ff007e3, 0x0293a91d,
++ 0x002f9c12, 0x3ff00be7, 0x01241905,
++ 0x001f8c29, 0x000007ed, 0x3fe470eb,
++ 0x000f7c46, 0x000007f2, 0x3f04b8ca,
++ 0x3fef7865, 0x000007f6, 0x3e74e4a8 },
++ },
++ { 0x1c00, {
++ 0x001fd3e9, 0x001fd3e9, 0x08f23d26,
++ 0x002fbff3, 0x001fe3e4, 0x0712ad23,
++ 0x002fa800, 0x000ff3e0, 0x05631d1b,
++ 0x001f9810, 0x000ffbe1, 0x03b3890d,
++ 0x000f8c23, 0x000003e3, 0x0233e8fa,
++ 0x3fef843b, 0x000003e7, 0x00f430e4,
++ 0x3fbf8456, 0x3ff00bea, 0x00046cc8,
++ 0x3f8f8c72, 0x3ff00bef, 0x3f3490ac },
++ },
++ { 0x1e00, {
++ 0x001fbbf4, 0x001fbbf4, 0x09425112,
++ 0x001fa800, 0x002fc7ed, 0x0792b110,
++ 0x000f980e, 0x001fdbe6, 0x0613110a,
++ 0x3fff8c20, 0x001fe7e3, 0x04a368fd,
++ 0x3fcf8c33, 0x000ff7e2, 0x0343b8ed,
++ 0x3f9f8c4a, 0x000fffe3, 0x0203f8da,
++ 0x3f5f9c61, 0x000003e6, 0x00e428c5,
++ 0x3f1fb07b, 0x000003eb, 0x3fe440af },
++ },
++ { 0x2000, {
++ 0x000fa400, 0x000fa400, 0x09625902,
++ 0x3fff980c, 0x001fb7f5, 0x0812b0ff,
++ 0x3fdf901c, 0x001fc7ed, 0x06b2fcfa,
++ 0x3faf902d, 0x001fd3e8, 0x055348f1,
++ 0x3f7f983f, 0x001fe3e5, 0x04038ce3,
++ 0x3f3fa454, 0x001fefe3, 0x02e3c8d1,
++ 0x3f0fb86a, 0x001ff7e4, 0x01c3e8c0,
++ 0x3ecfd880, 0x000fffe6, 0x00c404ac },
++ },
++ { 0x2200, {
++ 0x3fdf9c0b, 0x3fdf9c0b, 0x09725cf4,
++ 0x3fbf9818, 0x3fffa400, 0x0842a8f1,
++ 0x3f8f9827, 0x000fb3f7, 0x0702f0ec,
++ 0x3f5fa037, 0x000fc3ef, 0x05d330e4,
++ 0x3f2fac49, 0x001fcfea, 0x04a364d9,
++ 0x3effc05c, 0x001fdbe7, 0x038394ca,
++ 0x3ecfdc6f, 0x001fe7e6, 0x0273b0bb,
++ 0x3ea00083, 0x001fefe6, 0x0183c0a9 },
++ },
++ { 0x2400, {
++ 0x3f9fa014, 0x3f9fa014, 0x098260e6,
++ 0x3f7f9c23, 0x3fcf9c0a, 0x08629ce5,
++ 0x3f4fa431, 0x3fefa400, 0x0742d8e1,
++ 0x3f1fb440, 0x3fffb3f8, 0x062310d9,
++ 0x3eefc850, 0x000fbbf2, 0x050340d0,
++ 0x3ecfe062, 0x000fcbec, 0x041364c2,
++ 0x3ea00073, 0x001fd3ea, 0x03037cb5,
++ 0x3e902086, 0x001fdfe8, 0x022388a5 },
++ },
++ { 0x2600, {
++ 0x3f5fa81e, 0x3f5fa81e, 0x096258da,
++ 0x3f3fac2b, 0x3f8fa412, 0x088290d8,
++ 0x3f0fbc38, 0x3fafa408, 0x0772c8d5,
++ 0x3eefcc47, 0x3fcfa800, 0x0672f4ce,
++ 0x3ecfe456, 0x3fefaffa, 0x05531cc6,
++ 0x3eb00066, 0x3fffbbf3, 0x047334bb,
++ 0x3ea01c77, 0x000fc7ee, 0x039348ae,
++ 0x3ea04486, 0x000fd3eb, 0x02b350a1 },
++ },
++ { 0x2800, {
++ 0x3f2fb426, 0x3f2fb426, 0x094250ce,
++ 0x3f0fc032, 0x3f4fac1b, 0x086284cd,
++ 0x3eefd040, 0x3f7fa811, 0x0782acc9,
++ 0x3ecfe84c, 0x3f9fa807, 0x06a2d8c4,
++ 0x3eb0005b, 0x3fbfac00, 0x05b2f4bc,
++ 0x3eb0186a, 0x3fdfb3fa, 0x04c308b4,
++ 0x3eb04077, 0x3fefbbf4, 0x03f31ca8,
++ 0x3ec06884, 0x000fbff2, 0x03031c9e },
++ },
++ { 0x2a00, {
++ 0x3f0fc42d, 0x3f0fc42d, 0x090240c4,
++ 0x3eefd439, 0x3f2fb822, 0x08526cc2,
++ 0x3edfe845, 0x3f4fb018, 0x078294bf,
++ 0x3ec00051, 0x3f6fac0f, 0x06b2b4bb,
++ 0x3ec0185f, 0x3f8fac07, 0x05e2ccb4,
++ 0x3ec0386b, 0x3fafac00, 0x0502e8ac,
++ 0x3ed05c77, 0x3fcfb3fb, 0x0432f0a3,
++ 0x3ef08482, 0x3fdfbbf6, 0x0372f898 },
++ },
++ { 0x2c00, {
++ 0x3eefdc31, 0x3eefdc31, 0x08e238b8,
++ 0x3edfec3d, 0x3f0fc828, 0x082258b9,
++ 0x3ed00049, 0x3f1fc01e, 0x077278b6,
++ 0x3ed01455, 0x3f3fb815, 0x06c294b2,
++ 0x3ed03460, 0x3f5fb40d, 0x0602acac,
++ 0x3ef0506c, 0x3f7fb006, 0x0542c0a4,
++ 0x3f107476, 0x3f9fb400, 0x0472c89d,
++ 0x3f309c80, 0x3fbfb7fc, 0x03b2cc94 },
++ },
++ { 0x2e00, {
++ 0x3eefec37, 0x3eefec37, 0x088220b0,
++ 0x3ee00041, 0x3effdc2d, 0x07f244ae,
++ 0x3ee0144c, 0x3f0fd023, 0x07625cad,
++ 0x3ef02c57, 0x3f1fc81a, 0x06c274a9,
++ 0x3f004861, 0x3f3fbc13, 0x060288a6,
++ 0x3f20686b, 0x3f5fb80c, 0x05529c9e,
++ 0x3f408c74, 0x3f6fb805, 0x04b2ac96,
++ 0x3f80ac7e, 0x3f8fb800, 0x0402ac8e },
++ },
++ { 0x3000, {
++ 0x3ef0003a, 0x3ef0003a, 0x084210a6,
++ 0x3ef01045, 0x3effec32, 0x07b228a7,
++ 0x3f00284e, 0x3f0fdc29, 0x073244a4,
++ 0x3f104058, 0x3f0fd420, 0x06a258a2,
++ 0x3f305c62, 0x3f2fc818, 0x0612689d,
++ 0x3f508069, 0x3f3fc011, 0x05728496,
++ 0x3f80a072, 0x3f4fc00a, 0x04d28c90,
++ 0x3fc0c07b, 0x3f6fbc04, 0x04429088 },
++ },
++ { 0x3200, {
++ 0x3f00103e, 0x3f00103e, 0x07f1fc9e,
++ 0x3f102447, 0x3f000035, 0x0782149d,
++ 0x3f203c4f, 0x3f0ff02c, 0x07122c9c,
++ 0x3f405458, 0x3f0fe424, 0x06924099,
++ 0x3f607061, 0x3f1fd41d, 0x06024c97,
++ 0x3f909068, 0x3f2fcc16, 0x05726490,
++ 0x3fc0b070, 0x3f3fc80f, 0x04f26c8a,
++ 0x0000d077, 0x3f4fc409, 0x04627484 },
++ },
++ { 0x3400, {
++ 0x3f202040, 0x3f202040, 0x07a1e898,
++ 0x3f303449, 0x3f100c38, 0x0741fc98,
++ 0x3f504c50, 0x3f10002f, 0x06e21495,
++ 0x3f706459, 0x3f1ff028, 0x06722492,
++ 0x3fa08060, 0x3f1fe421, 0x05f2348f,
++ 0x3fd09c67, 0x3f1fdc19, 0x05824c89,
++ 0x0000bc6e, 0x3f2fd014, 0x04f25086,
++ 0x0040dc74, 0x3f3fcc0d, 0x04825c7f },
++ },
++ { 0x3600, {
++ 0x3f403042, 0x3f403042, 0x0761d890,
++ 0x3f504848, 0x3f301c3b, 0x0701f090,
++ 0x3f805c50, 0x3f200c33, 0x06a2008f,
++ 0x3fa07458, 0x3f10002b, 0x06520c8d,
++ 0x3fd0905e, 0x3f1ff424, 0x05e22089,
++ 0x0000ac65, 0x3f1fe81d, 0x05823483,
++ 0x0030cc6a, 0x3f2fdc18, 0x04f23c81,
++ 0x0080e871, 0x3f2fd412, 0x0482407c },
++ },
++ { 0x3800, {
++ 0x3f604043, 0x3f604043, 0x0721c88a,
++ 0x3f80544a, 0x3f502c3c, 0x06d1d88a,
++ 0x3fb06851, 0x3f301c35, 0x0681e889,
++ 0x3fd08456, 0x3f30082f, 0x0611fc88,
++ 0x00009c5d, 0x3f200027, 0x05d20884,
++ 0x0030b863, 0x3f2ff421, 0x05621880,
++ 0x0070d468, 0x3f2fe81b, 0x0502247c,
++ 0x00c0ec6f, 0x3f2fe015, 0x04a22877 },
++ },
++ { 0x3a00, {
++ 0x3f904c44, 0x3f904c44, 0x06e1b884,
++ 0x3fb0604a, 0x3f70383e, 0x0691c885,
++ 0x3fe07451, 0x3f502c36, 0x0661d483,
++ 0x00009055, 0x3f401831, 0x0601ec81,
++ 0x0030a85b, 0x3f300c2a, 0x05b1f480,
++ 0x0070c061, 0x3f300024, 0x0562047a,
++ 0x00b0d867, 0x3f3ff41e, 0x05020c77,
++ 0x00f0f46b, 0x3f2fec19, 0x04a21474 },
++ },
++ { 0x3c00, {
++ 0x3fb05c43, 0x3fb05c43, 0x06c1b07e,
++ 0x3fe06c4b, 0x3f902c3f, 0x0681c081,
++ 0x0000844f, 0x3f703838, 0x0631cc7d,
++ 0x00309855, 0x3f602433, 0x05d1d47e,
++ 0x0060b459, 0x3f50142e, 0x0581e47b,
++ 0x00a0c85f, 0x3f400828, 0x0531f078,
++ 0x00e0e064, 0x3f300021, 0x0501fc73,
++ 0x00b0fc6a, 0x3f3ff41d, 0x04a20873 },
++ },
++ { 0x3e00, {
++ 0x3fe06444, 0x3fe06444, 0x0681a07a,
++ 0x00007849, 0x3fc0503f, 0x0641b07a,
++ 0x0020904d, 0x3fa0403a, 0x05f1c07a,
++ 0x0060a453, 0x3f803034, 0x05c1c878,
++ 0x0090b858, 0x3f70202f, 0x0571d477,
++ 0x00d0d05d, 0x3f501829, 0x0531e073,
++ 0x0110e462, 0x3f500825, 0x04e1e471,
++ 0x01510065, 0x3f40001f, 0x04a1f06d },
++ },
++ { 0x4000, {
++ 0x00007044, 0x00007044, 0x06519476,
++ 0x00208448, 0x3fe05c3f, 0x0621a476,
++ 0x0050984d, 0x3fc04c3a, 0x05e1b075,
++ 0x0080ac52, 0x3fa03c35, 0x05a1b875,
++ 0x00c0c056, 0x3f803030, 0x0561c473,
++ 0x0100d45b, 0x3f70202b, 0x0521d46f,
++ 0x0140e860, 0x3f601427, 0x04d1d46e,
++ 0x01810064, 0x3f500822, 0x0491dc6b },
++ },
++ { 0x5000, {
++ 0x0110a442, 0x0110a442, 0x0551545e,
++ 0x0140b045, 0x00e0983f, 0x0531585f,
++ 0x0160c047, 0x00c08c3c, 0x0511645e,
++ 0x0190cc4a, 0x00908039, 0x04f1685f,
++ 0x01c0dc4c, 0x00707436, 0x04d1705e,
++ 0x0200e850, 0x00506833, 0x04b1785b,
++ 0x0230f453, 0x00305c30, 0x0491805a,
++ 0x02710056, 0x0010542d, 0x04718059 },
++ },
++ { 0x6000, {
++ 0x01c0bc40, 0x01c0bc40, 0x04c13052,
++ 0x01e0c841, 0x01a0b43d, 0x04c13851,
++ 0x0210cc44, 0x0180a83c, 0x04a13453,
++ 0x0230d845, 0x0160a03a, 0x04913c52,
++ 0x0260e047, 0x01409838, 0x04714052,
++ 0x0280ec49, 0x01208c37, 0x04514c50,
++ 0x02b0f44b, 0x01008435, 0x04414c50,
++ 0x02d1004c, 0x00e07c33, 0x0431544f },
++ },
++ { 0x7000, {
++ 0x0230c83e, 0x0230c83e, 0x04711c4c,
++ 0x0250d03f, 0x0210c43c, 0x0471204b,
++ 0x0270d840, 0x0200b83c, 0x0451244b,
++ 0x0290dc42, 0x01e0b43a, 0x0441244c,
++ 0x02b0e443, 0x01c0b038, 0x0441284b,
++ 0x02d0ec44, 0x01b0a438, 0x0421304a,
++ 0x02f0f445, 0x0190a036, 0x04213449,
++ 0x0310f847, 0x01709c34, 0x04213848 },
++ },
++ { 0x8000, {
++ 0x0280d03d, 0x0280d03d, 0x04310c48,
++ 0x02a0d43e, 0x0270c83c, 0x04311047,
++ 0x02b0dc3e, 0x0250c83a, 0x04311447,
++ 0x02d0e040, 0x0240c03a, 0x04211446,
++ 0x02e0e840, 0x0220bc39, 0x04111847,
++ 0x0300e842, 0x0210b438, 0x04012445,
++ 0x0310f043, 0x0200b037, 0x04012045,
++ 0x0330f444, 0x01e0ac36, 0x03f12445 },
++ },
++ { 0xefff, {
++ 0x0340dc3a, 0x0340dc3a, 0x03b0ec40,
++ 0x0340e03a, 0x0330e039, 0x03c0f03e,
++ 0x0350e03b, 0x0330dc39, 0x03c0ec3e,
++ 0x0350e43a, 0x0320dc38, 0x03c0f43e,
++ 0x0360e43b, 0x0320d839, 0x03b0f03e,
++ 0x0360e83b, 0x0310d838, 0x03c0fc3b,
++ 0x0370e83b, 0x0310d439, 0x03a0f83d,
++ 0x0370e83c, 0x0300d438, 0x03b0fc3c },
++ }
++};
++
++enum rcar_vin_state {
++ STOPPED = 0,
++ RUNNING,
++ STOPPING,
++};
++
++struct rcar_vin_async_client {
++ struct v4l2_async_subdev *sensor;
++ struct v4l2_async_notifier notifier;
++ struct platform_device *pdev;
++ struct list_head list; /* needed for clean up */
++};
++
++struct soc_of_info {
++ struct soc_camera_async_subdev sasd;
++ struct rcar_vin_async_client sasc;
++ struct v4l2_async_subdev *subdev;
++};
++
++struct rcar_vin_priv {
++ void __iomem *base;
++ spinlock_t lock;
++ int sequence;
++ /* State of the VIN module in capturing mode */
++ enum rcar_vin_state state;
++ struct soc_camera_host ici;
++ struct list_head capture;
++#define MAX_BUFFER_NUM 3
++ struct vb2_v4l2_buffer *queue_buf[MAX_BUFFER_NUM];
++ enum v4l2_field field;
++ unsigned int pdata_flags;
++ unsigned int vb_count;
++ unsigned int nr_hw_slots;
++ bool request_to_stop;
++ struct completion capture_stop;
++ enum chip_id chip;
++ unsigned int max_width;
++ unsigned int max_height;
++ unsigned int ratio_h;
++ unsigned int ratio_v;
++ bool error_flag;
++ enum csi2_ch csi_ch;
++ enum csi2_fmt csi_fmt;
++ enum virtual_ch vc;
++ bool csi_sync;
++
++ struct rcar_vin_async_client *async_client;
++ /* Asynchronous CSI2 linking */
++ struct v4l2_subdev *csi2_sd;
++ /* Synchronous probing compatibility */
++ struct platform_device *csi2_pdev;
++
++ unsigned int index;
++};
++
++#define is_continuous_transfer(priv) (priv->vb_count > MAX_BUFFER_NUM)
++
++struct rcar_vin_buffer {
++ struct vb2_v4l2_buffer vb;
++ struct list_head list;
++};
++
++#define to_buf_list(vb2_buffer) (&container_of(vb2_buffer, \
++ struct rcar_vin_buffer, \
++ vb)->list)
++
++struct rcar_vin_cam {
++ /* VIN offsets within the camera output, before the VIN scaler */
++ unsigned int vin_left;
++ unsigned int vin_top;
++ /* Client output, as seen by the VIN */
++ unsigned int width;
++ unsigned int height;
++ /* User window from S_FMT */
++ unsigned int out_width;
++ unsigned int out_height;
++ /*
++ * User window from S_SELECTION / G_SELECTION, produced by client cropping and
++ * scaling, VIN scaling and VIN cropping, mapped back onto the client
++ * input window
++ */
++ struct v4l2_rect subrect;
++ /* Camera cropping rectangle */
++ struct v4l2_rect rect;
++ const struct soc_mbus_pixelfmt *extra_fmt;
++};
++
++#define VIN_UT_IRQ 0x01
++
++static unsigned int vin_debug;
++module_param_named(debug, vin_debug, int, 0600);
++static int overflow_video[RCAR_VIDEO_MAX];
++module_param_array(overflow_video, int, NULL, 0600);
++
++#ifdef CONFIG_VIDEO_RCAR_VIN_LEGACY_DEBUG
++#define VIN_IRQ_DEBUG(fmt, args...) \
++ do { \
++ if (unlikely(vin_debug & VIN_UT_IRQ)) \
++ vin_ut_debug_printk(__func__, fmt, ##args); \
++ } while (0)
++#else
++#define VIN_IRQ_DEBUG(fmt, args...)
++#endif
++
++void vin_ut_debug_printk(const char *function_name, const char *format, ...)
++{
++ struct va_format vaf;
++ va_list args;
++
++ va_start(args, format);
++ vaf.fmt = format;
++ vaf.va = &args;
++
++ pr_debug("[" DRV_NAME ":%s] %pV", function_name, &vaf);
++
++ va_end(args);
++}
++
++static void rcar_vin_cpg_enable_for_ifmd(unsigned int ch, bool enable)
++{
++ void __iomem *smstpcr8;
++
++ smstpcr8 = ioremap(0xE6150990, 0x04);
++
++ if (enable) {
++ if (ch < RCAR_VIDEO_4)
++ iowrite32((ioread32(smstpcr8) & 0xFFFFF7FF), smstpcr8);
++ else
++ iowrite32((ioread32(smstpcr8) & 0xFFFFFF7F), smstpcr8);
++ } else {
++ if (ch < RCAR_VIDEO_4)
++ iowrite32((ioread32(smstpcr8) | 0x00000800), smstpcr8);
++ else
++ iowrite32((ioread32(smstpcr8) | 0x00000080), smstpcr8);
++ }
++
++ iounmap(smstpcr8);
++}
++
++static inline int is_scaling(struct rcar_vin_cam *cam)
++{
++ struct v4l2_rect *cam_subrect = &cam->subrect;
++
++ if ((cam_subrect->width != cam->out_width) ||
++ (cam_subrect->height != cam->out_height))
++ return 1;
++
++ return 0;
++}
++
++/*
++ * .queue_setup() is called to check whether the driver can accept the requested
++ * number of buffers and to fill in plane sizes for the current frame format if
++ * required
++ */
++static int rcar_vin_videobuf_setup(struct vb2_queue *vq,
++ unsigned int *count,
++ unsigned int *num_planes,
++ unsigned int sizes[], struct device *alloc_devs[])
++{
++ struct soc_camera_device *icd = soc_camera_from_vb2q(vq);
++ struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
++ struct rcar_vin_priv *priv = ici->priv;
++ struct rcar_vin_cam *cam = icd->host_priv;
++
++ if (priv->chip == RCAR_H3 || priv->chip == RCAR_M3) {
++ if ((priv->ratio_h > 0x10000) || (priv->ratio_v > 0x10000)) {
++ dev_err(icd->parent, "Scaling rate parameter error\n");
++ return -EINVAL;
++ }
++ if (is_scaling(cam) && (cam->out_width % 32)) {
++ dev_err(icd->parent, "Scaling parameter error\n");
++ return -EINVAL;
++ }
++ if (!is_scaling(cam) && (cam->out_width % 16)) {
++ dev_err(icd->parent, "Image stride parameter error\n");
++ return -EINVAL;
++ }
++ }
++
++ if (!vq->num_buffers)
++ priv->sequence = 0;
++
++ if (!*count)
++ *count = 2;
++ priv->vb_count = *count;
++
++ /* Number of hardware slots */
++ if (is_continuous_transfer(priv))
++ priv->nr_hw_slots = MAX_BUFFER_NUM;
++ else
++ priv->nr_hw_slots = 1;
++
++ if (*num_planes)
++ return sizes[0] < icd->sizeimage ? -EINVAL : 0;
++
++ sizes[0] = icd->sizeimage;
++ *num_planes = 1;
++
++ dev_dbg(icd->parent, "count=%d, size=%u\n", *count, sizes[0]);
++
++ return 0;
++}
++
++static int rcar_vin_setup(struct rcar_vin_priv *priv)
++{
++ struct soc_camera_device *icd = priv->ici.icd;
++ struct rcar_vin_cam *cam = icd->host_priv;
++ u32 vnmc, dmr, interrupts;
++ bool progressive = false, output_is_yuv = false, input_is_yuv = false;
++
++ switch (priv->field) {
++ case V4L2_FIELD_TOP:
++ vnmc = VNMC_IM_ODD;
++ break;
++ case V4L2_FIELD_BOTTOM:
++ vnmc = VNMC_IM_EVEN;
++ break;
++ case V4L2_FIELD_INTERLACED:
++ case V4L2_FIELD_INTERLACED_TB:
++ vnmc = VNMC_IM_FULL;
++ break;
++ case V4L2_FIELD_INTERLACED_BT:
++ vnmc = VNMC_IM_FULL | VNMC_FOC;
++ break;
++ case V4L2_FIELD_NONE:
++ if (is_continuous_transfer(priv)) {
++ vnmc = VNMC_IM_ODD_EVEN;
++ progressive = true;
++ } else {
++ vnmc = VNMC_IM_ODD;
++ }
++ break;
++ default:
++ vnmc = VNMC_IM_ODD;
++ break;
++ }
++
++ /* input interface */
++ switch (icd->current_fmt->code) {
++ case MEDIA_BUS_FMT_YUYV8_1X16:
++ /* BT.601/BT.1358 16bit YCbCr422 */
++ vnmc |= VNMC_INF_YUV16;
++ input_is_yuv = true;
++ break;
++ case MEDIA_BUS_FMT_YUYV8_2X8:
++ /* BT.656 8bit YCbCr422 or BT.601 8bit YCbCr422 */
++ vnmc |= priv->pdata_flags & RCAR_VIN_BT656 ?
++ VNMC_INF_YUV8_BT656 : VNMC_INF_YUV8_BT601;
++ input_is_yuv = true;
++ break;
++ case MEDIA_BUS_FMT_RGB888_1X24:
++ vnmc |= VNMC_INF_RGB888;
++ break;
++ case MEDIA_BUS_FMT_YUYV10_2X10:
++ /* BT.656 10bit YCbCr422 or BT.601 10bit YCbCr422 */
++ vnmc |= priv->pdata_flags & RCAR_VIN_BT656 ?
++ VNMC_INF_YUV10_BT656 : VNMC_INF_YUV10_BT601;
++ input_is_yuv = true;
++ break;
++ default:
++ break;
++ }
++
++ /* output format */
++ switch (icd->current_fmt->host_fmt->fourcc) {
++ case V4L2_PIX_FMT_NV12:
++ if (priv->chip == RCAR_H3 || priv->chip == RCAR_M3) {
++ iowrite32(ALIGN((cam->out_width * cam->out_height),
++ 0x80), priv->base + VNUVAOF_REG);
++ dmr = VNDMR_DTMD_YCSEP_YCBCR420;
++ output_is_yuv = true;
++ } else {
++ dev_warn(icd->parent, "Not support format\n");
++ return -EINVAL;
++ }
++ break;
++ case V4L2_PIX_FMT_NV16:
++ iowrite32(ALIGN((cam->out_width * cam->out_height), 0x80),
++ priv->base + VNUVAOF_REG);
++ dmr = VNDMR_DTMD_YCSEP;
++ output_is_yuv = true;
++ break;
++ case V4L2_PIX_FMT_YUYV:
++ dmr = VNDMR_BPSM;
++ output_is_yuv = true;
++ break;
++ case V4L2_PIX_FMT_UYVY:
++ dmr = 0;
++ output_is_yuv = true;
++ break;
++ case V4L2_PIX_FMT_ARGB555:
++ dmr = VNDMR_DTMD_ARGB;
++ break;
++ case V4L2_PIX_FMT_RGB565:
++ dmr = 0;
++ break;
++ case V4L2_PIX_FMT_XBGR32:
++ if (priv->chip != RCAR_H3 && priv->chip != RCAR_M3 &&
++ priv->chip != RCAR_GEN2 && priv->chip != RCAR_H1 &&
++ priv->chip != RCAR_E1)
++ goto e_format;
++
++ dmr = VNDMR_EXRGB;
++ break;
++ case V4L2_PIX_FMT_ABGR32:
++ if (priv->chip != RCAR_H3 && priv->chip != RCAR_M3)
++ goto e_format;
++
++ dmr = VNDMR_EXRGB | VNDMR_DTMD_ARGB;
++ break;
++ default:
++ goto e_format;
++ }
++
++ /* Always update on field change */
++ vnmc |= VNMC_VUP;
++
++ /* If input and output use the same colorspace, use bypass mode */
++ if (input_is_yuv == output_is_yuv)
++ vnmc |= VNMC_BPS;
++
++ if (priv->chip == RCAR_H3 || priv->chip == RCAR_M3) {
++ if (priv->pdata_flags & RCAR_VIN_CSI2)
++ vnmc &= ~VNMC_DPINE;
++ else
++ vnmc |= VNMC_DPINE;
++
++ if ((icd->current_fmt->host_fmt->fourcc != V4L2_PIX_FMT_NV12)
++ && is_scaling(cam))
++ vnmc |= VNMC_SCLE;
++ }
++
++ /* progressive or interlaced mode */
++ interrupts = progressive ? VNIE_FIE : VNIE_EFE;
++
++ /* Enable Overflow */
++ if (vin_debug)
++ interrupts |= VNIE_FOE;
++
++ /* ack interrupts */
++ iowrite32(interrupts, priv->base + VNINTS_REG);
++ /* enable interrupts */
++ iowrite32(interrupts, priv->base + VNIE_REG);
++ /* start capturing */
++ iowrite32(dmr, priv->base + VNDMR_REG);
++ iowrite32(vnmc | VNMC_ME, priv->base + VNMC_REG);
++
++ return 0;
++
++e_format:
++ dev_warn(icd->parent, "Invalid fourcc format (0x%x)\n",
++ icd->current_fmt->host_fmt->fourcc);
++ return -EINVAL;
++}
++
++static void rcar_vin_capture(struct rcar_vin_priv *priv)
++{
++ if (is_continuous_transfer(priv))
++ /* Continuous Frame Capture Mode */
++ iowrite32(VNFC_C_FRAME, priv->base + VNFC_REG);
++ else
++ /* Single Frame Capture Mode */
++ iowrite32(VNFC_S_FRAME, priv->base + VNFC_REG);
++}
++
++static void rcar_vin_request_capture_stop(struct rcar_vin_priv *priv)
++{
++ priv->state = STOPPING;
++
++ /* set continuous & single transfer off */
++ iowrite32(0, priv->base + VNFC_REG);
++ /* disable capture (release DMA buffer), reset */
++ iowrite32(ioread32(priv->base + VNMC_REG) & ~VNMC_ME,
++ priv->base + VNMC_REG);
++
++ /* update the status if stopped already */
++ if (!(ioread32(priv->base + VNMS_REG) & VNMS_CA))
++ priv->state = STOPPED;
++}
++
++static int rcar_vin_get_free_hw_slot(struct rcar_vin_priv *priv)
++{
++ int slot;
++
++ for (slot = 0; slot < priv->nr_hw_slots; slot++)
++ if (priv->queue_buf[slot] == NULL)
++ return slot;
++
++ return -1;
++}
++
++static int rcar_vin_hw_ready(struct rcar_vin_priv *priv)
++{
++ /* Ensure all HW slots are filled */
++ return rcar_vin_get_free_hw_slot(priv) < 0 ? 1 : 0;
++}
++
++/* Moves a buffer from the queue to the HW slots */
++static int rcar_vin_fill_hw_slot(struct rcar_vin_priv *priv)
++{
++ struct vb2_v4l2_buffer *vbuf;
++ dma_addr_t phys_addr_top;
++ int slot;
++
++ if (list_empty(&priv->capture))
++ return 0;
++
++ /* Find a free HW slot */
++ slot = rcar_vin_get_free_hw_slot(priv);
++ if (slot < 0)
++ return 0;
++
++ vbuf = &list_entry(priv->capture.next,
++ struct rcar_vin_buffer, list)->vb;
++ list_del_init(to_buf_list(vbuf));
++ priv->queue_buf[slot] = vbuf;
++ phys_addr_top = vb2_dma_contig_plane_dma_addr(&vbuf->vb2_buf, 0);
++ iowrite32(phys_addr_top, priv->base + VNMB_REG(slot));
++
++ return 1;
++}
++
++static void rcar_vin_videobuf_queue(struct vb2_buffer *vb)
++{
++ struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
++ struct soc_camera_device *icd = soc_camera_from_vb2q(vb->vb2_queue);
++ struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
++ struct rcar_vin_priv *priv = ici->priv;
++ unsigned long size;
++
++ size = icd->sizeimage;
++
++ if (vb2_plane_size(vb, 0) < size) {
++ dev_err(icd->parent, "Buffer #%d too small (%lu < %lu)\n",
++ vb->index, vb2_plane_size(vb, 0), size);
++ goto error;
++ }
++
++ vb2_set_plane_payload(vb, 0, size);
++
++ dev_dbg(icd->parent, "%s (vb=0x%p) 0x%p %lu\n", __func__,
++ vb, vb2_plane_vaddr(vb, 0), vb2_get_plane_payload(vb, 0));
++
++ spin_lock_irq(&priv->lock);
++
++ list_add_tail(to_buf_list(vbuf), &priv->capture);
++ rcar_vin_fill_hw_slot(priv);
++
++ /* If we weren't running, and have enough buffers, start capturing! */
++ if (priv->state != RUNNING && rcar_vin_hw_ready(priv)) {
++ if (rcar_vin_setup(priv)) {
++ /* Submit error */
++ list_del_init(to_buf_list(vbuf));
++ spin_unlock_irq(&priv->lock);
++ goto error;
++ }
++ priv->request_to_stop = false;
++ init_completion(&priv->capture_stop);
++ priv->state = RUNNING;
++ rcar_vin_capture(priv);
++ }
++
++ spin_unlock_irq(&priv->lock);
++
++ return;
++
++error:
++ vb2_buffer_done(vb, VB2_BUF_STATE_ERROR);
++}
++
++/*
++ * Wait for capture to stop and all in-flight buffers to be finished with by
++ * the video hardware. This must be called under &priv->lock
++ *
++ */
++static void rcar_vin_wait_stop_streaming(struct rcar_vin_priv *priv)
++{
++ while (priv->state != STOPPED) {
++ /* issue stop if running */
++ if (priv->state == RUNNING)
++ rcar_vin_request_capture_stop(priv);
++
++ /* wait until capturing has been stopped */
++ if (priv->state == STOPPING) {
++ priv->request_to_stop = true;
++ spin_unlock_irq(&priv->lock);
++ if (!wait_for_completion_timeout(
++ &priv->capture_stop,
++ msecs_to_jiffies(TIMEOUT_MS)))
++ priv->state = STOPPED;
++ spin_lock_irq(&priv->lock);
++ }
++ }
++}
++
++static void rcar_vin_stop_streaming(struct vb2_queue *vq)
++{
++ struct soc_camera_device *icd = soc_camera_from_vb2q(vq);
++ struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
++ struct rcar_vin_priv *priv = ici->priv;
++ struct list_head *buf_head, *tmp;
++ int i;
++
++ spin_lock_irq(&priv->lock);
++ rcar_vin_wait_stop_streaming(priv);
++
++ for (i = 0; i < MAX_BUFFER_NUM; i++) {
++ if (priv->queue_buf[i]) {
++ vb2_buffer_done(&priv->queue_buf[i]->vb2_buf,
++ VB2_BUF_STATE_ERROR);
++ priv->queue_buf[i] = NULL;
++ }
++ }
++
++ list_for_each_safe(buf_head, tmp, &priv->capture) {
++ vb2_buffer_done(&list_entry(buf_head,
++ struct rcar_vin_buffer, list)->vb.vb2_buf,
++ VB2_BUF_STATE_ERROR);
++ list_del_init(buf_head);
++ }
++ spin_unlock_irq(&priv->lock);
++}
++
++static const struct vb2_ops rcar_vin_vb2_ops = {
++ .queue_setup = rcar_vin_videobuf_setup,
++ .buf_queue = rcar_vin_videobuf_queue,
++ .stop_streaming = rcar_vin_stop_streaming,
++ .wait_prepare = vb2_ops_wait_prepare,
++ .wait_finish = vb2_ops_wait_finish,
++};
++
++static irqreturn_t rcar_vin_irq(int irq, void *data)
++{
++ struct rcar_vin_priv *priv = data;
++ u32 int_status;
++ bool can_run = false, hw_stopped;
++ int slot;
++ unsigned int handled = 0;
++ int vin_ovr_cnt = 0;
++
++ spin_lock(&priv->lock);
++
++ int_status = ioread32(priv->base + VNINTS_REG);
++ if (!int_status)
++ goto done;
++
++ /* ack interrupts */
++ iowrite32(int_status, priv->base + VNINTS_REG);
++ handled = 1;
++
++ /* overflow occurs */
++ if (vin_debug && (int_status & VNINTS_FOS)) {
++ vin_ovr_cnt = ++overflow_video[priv->index];
++ VIN_IRQ_DEBUG("overflow occurrs num[%d] at VIN (%s)\n",
++ vin_ovr_cnt, dev_name(priv->ici.v4l2_dev.dev));
++ }
++
++ /* nothing to do if capture status is 'STOPPED' */
++ if (priv->state == STOPPED)
++ goto done;
++
++ hw_stopped = !(ioread32(priv->base + VNMS_REG) & VNMS_CA);
++
++ if (!priv->request_to_stop) {
++ if (is_continuous_transfer(priv))
++ slot = (ioread32(priv->base + VNMS_REG) &
++ VNMS_FBS_MASK) >> VNMS_FBS_SHIFT;
++ else
++ slot = 0;
++
++ if (!is_continuous_transfer(priv) || ((priv->state == RUNNING)
++ && !list_empty(&priv->capture))) {
++ priv->queue_buf[slot]->field = priv->field;
++ priv->queue_buf[slot]->sequence = priv->sequence++;
++ priv->queue_buf[slot]->vb2_buf.timestamp =
++ ktime_get_ns();
++ vb2_buffer_done(&priv->queue_buf[slot]->vb2_buf,
++ VB2_BUF_STATE_DONE);
++ priv->queue_buf[slot] = NULL;
++
++ can_run = rcar_vin_fill_hw_slot(priv);
++ }
++
++ if (is_continuous_transfer(priv)) {
++ if (hw_stopped)
++ priv->state = STOPPED;
++ else if (list_empty(&priv->capture) &&
++ priv->state == RUNNING)
++ /*
++ * The continuous capturing requires an
++ * explicit stop operation when there is no
++ * buffer to be set into the VnMBm registers.
++ */
++ rcar_vin_request_capture_stop(priv);
++ } else {
++ if (can_run)
++ rcar_vin_capture(priv);
++ else
++ priv->state = STOPPED;
++ }
++ } else if (hw_stopped) {
++ priv->state = STOPPED;
++ priv->request_to_stop = false;
++ complete(&priv->capture_stop);
++ }
++
++done:
++ spin_unlock(&priv->lock);
++
++ return IRQ_RETVAL(handled);
++}
++
++static struct v4l2_subdev *find_csi2(struct rcar_vin_priv *pcdev)
++{
++ struct v4l2_subdev *sd;
++ char name[] = "rcar_csi2";
++
++ v4l2_device_for_each_subdev(sd, &pcdev->ici.v4l2_dev) {
++ if (!strncmp(name, sd->name, sizeof(name) - 1)) {
++ pcdev->csi2_sd = sd;
++ return sd;
++ }
++ }
++
++ return NULL;
++}
++
++static int rcar_vin_add_device(struct soc_camera_device *icd)
++{
++ struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
++ struct rcar_vin_priv *priv = ici->priv;
++ int i;
++
++ for (i = 0; i < MAX_BUFFER_NUM; i++)
++ priv->queue_buf[i] = NULL;
++
++ pm_runtime_get_sync(ici->v4l2_dev.dev);
++
++ if (priv->chip == RCAR_H3 || priv->chip == RCAR_M3) {
++ struct v4l2_subdev *csi2_sd = find_csi2(priv);
++ int ret;
++
++ if (csi2_sd) {
++ csi2_sd->grp_id = soc_camera_grp_id(icd);
++ v4l2_set_subdev_hostdata(csi2_sd, icd);
++
++ ret = v4l2_subdev_call(csi2_sd, core, s_power, 1);
++ priv->csi_sync = true;
++
++ if (ret < 0 && ret != -EINVAL)
++ priv->csi_sync = false;
++
++ if (ret < 0 && ret != -ENOIOCTLCMD && ret != -ENODEV)
++ return ret;
++ }
++ /*
++ * -ENODEV is special:
++ * either csi2_sd == NULL or the CSI-2 driver
++ * has not found this soc-camera device among its clients
++ */
++ if (csi2_sd && ret == -ENODEV)
++ csi2_sd->grp_id = 0;
++
++ dev_dbg(icd->parent,
++ "R-Car VIN/CSI-2 driver attached to camera %d\n",
++ icd->devnum);
++
++ } else
++ dev_dbg(icd->parent, "R-Car VIN driver attached to camera %d\n",
++ icd->devnum);
++
++ priv->error_flag = false;
++
++ return 0;
++}
++
++static void rcar_vin_remove_device(struct soc_camera_device *icd)
++{
++ struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
++ struct rcar_vin_priv *priv = ici->priv;
++ struct vb2_v4l2_buffer *vbuf;
++ struct v4l2_subdev *csi2_sd = find_csi2(priv);
++ int i;
++
++ /* disable capture, disable interrupts */
++ iowrite32(ioread32(priv->base + VNMC_REG) & ~VNMC_ME,
++ priv->base + VNMC_REG);
++ iowrite32(0, priv->base + VNIE_REG);
++
++ priv->state = STOPPED;
++ priv->request_to_stop = false;
++ priv->error_flag = false;
++
++ /* make sure active buffer is cancelled */
++ spin_lock_irq(&priv->lock);
++ for (i = 0; i < MAX_BUFFER_NUM; i++) {
++ vbuf = priv->queue_buf[i];
++ if (vbuf) {
++ list_del_init(to_buf_list(vbuf));
++ vb2_buffer_done(&vbuf->vb2_buf, VB2_BUF_STATE_ERROR);
++ }
++ }
++ spin_unlock_irq(&priv->lock);
++
++ pm_runtime_put(ici->v4l2_dev.dev);
++
++ if ((csi2_sd) && (priv->csi_sync))
++ v4l2_subdev_call(csi2_sd, core, s_power, 0);
++
++ dev_dbg(icd->parent, "R-Car VIN driver detached from camera %d\n",
++ icd->devnum);
++}
++
++struct rcar_vin_uds_regs {
++ unsigned long ctrl;
++ unsigned long scale;
++ unsigned long pass_bwidth;
++ unsigned long clip_size;
++};
++
++static unsigned long rcar_vin_get_bwidth(unsigned long ratio)
++{
++ unsigned long bwidth;
++ unsigned long mant, frac;
++
++ mant = (ratio & 0xF000) >> 12;
++ frac = ratio & 0x0FFF;
++ if (mant)
++ bwidth = 64 * 4096 * mant / (4096 * mant + frac);
++ else
++ bwidth = 64;
++
++ return bwidth;
++}
++
++static unsigned long rcar_vin_compute_ratio(unsigned int input,
++ unsigned int output)
++{
++ return ((input * 4096 / output) == 0x10000) ?
++ 0xFFFF : (input * 4096 / output);
++}
++
++int rcar_vin_uds_set(struct rcar_vin_priv *priv, struct rcar_vin_cam *cam)
++{
++ struct rcar_vin_uds_regs regs;
++ unsigned long ratio_h, ratio_v;
++ unsigned long bwidth_h, bwidth_v;
++ unsigned long ctrl;
++ unsigned long clip_size;
++ struct v4l2_rect *cam_subrect = &cam->subrect;
++ u32 vnmc;
++
++ ratio_h = rcar_vin_compute_ratio(cam_subrect->width, cam->out_width);
++ ratio_v = rcar_vin_compute_ratio(cam_subrect->height, cam->out_height);
++
++ priv->ratio_h = ratio_h;
++ priv->ratio_v = ratio_v;
++
++ bwidth_h = rcar_vin_get_bwidth(ratio_h);
++ bwidth_v = rcar_vin_get_bwidth(ratio_v);
++
++ ctrl = VNUDS_CTRL_AMD;
++
++ if (priv->field == V4L2_FIELD_NONE)
++ clip_size = (cam->out_width << 16) | (cam->out_height);
++ else
++ clip_size = (cam->out_width << 16) | (cam->out_height / 2);
++
++ regs.ctrl = ctrl;
++ regs.scale = (ratio_h << 16) | ratio_v;
++ regs.pass_bwidth = (bwidth_h << 16) | bwidth_v;
++ regs.clip_size = clip_size;
++
++ vnmc = ioread32(priv->base + VNMC_REG);
++ iowrite32(vnmc | VNMC_SCLE, priv->base + VNMC_REG);
++ iowrite32(regs.ctrl, priv->base + VNUDS_CTRL_REG);
++ iowrite32(regs.scale, priv->base + VNUDS_SCALE_REG);
++ iowrite32(regs.pass_bwidth, priv->base + VNUDS_PASS_BWIDTH_REG);
++ iowrite32(regs.clip_size, priv->base + VNUDS_CLIP_SIZE_REG);
++
++ return 0;
++}
++
++static void set_coeff(struct rcar_vin_priv *priv, unsigned short xs)
++{
++ int i;
++ const struct vin_coeff *p_prev_set = NULL;
++ const struct vin_coeff *p_set = NULL;
++
++ /* Look for suitable coefficient values */
++ for (i = 0; i < ARRAY_SIZE(vin_coeff_set); i++) {
++ p_prev_set = p_set;
++ p_set = &vin_coeff_set[i];
++
++ if (xs < p_set->xs_value)
++ break;
++ }
++
++ /* Use previous value if its XS value is closer */
++ if (p_prev_set && p_set &&
++ xs - p_prev_set->xs_value < p_set->xs_value - xs)
++ p_set = p_prev_set;
++
++ /* Set coefficient registers */
++ iowrite32(p_set->coeff_set[0], priv->base + VNC1A_REG);
++ iowrite32(p_set->coeff_set[1], priv->base + VNC1B_REG);
++ iowrite32(p_set->coeff_set[2], priv->base + VNC1C_REG);
++
++ iowrite32(p_set->coeff_set[3], priv->base + VNC2A_REG);
++ iowrite32(p_set->coeff_set[4], priv->base + VNC2B_REG);
++ iowrite32(p_set->coeff_set[5], priv->base + VNC2C_REG);
++
++ iowrite32(p_set->coeff_set[6], priv->base + VNC3A_REG);
++ iowrite32(p_set->coeff_set[7], priv->base + VNC3B_REG);
++ iowrite32(p_set->coeff_set[8], priv->base + VNC3C_REG);
++
++ iowrite32(p_set->coeff_set[9], priv->base + VNC4A_REG);
++ iowrite32(p_set->coeff_set[10], priv->base + VNC4B_REG);
++ iowrite32(p_set->coeff_set[11], priv->base + VNC4C_REG);
++
++ iowrite32(p_set->coeff_set[12], priv->base + VNC5A_REG);
++ iowrite32(p_set->coeff_set[13], priv->base + VNC5B_REG);
++ iowrite32(p_set->coeff_set[14], priv->base + VNC5C_REG);
++
++ iowrite32(p_set->coeff_set[15], priv->base + VNC6A_REG);
++ iowrite32(p_set->coeff_set[16], priv->base + VNC6B_REG);
++ iowrite32(p_set->coeff_set[17], priv->base + VNC6C_REG);
++
++ iowrite32(p_set->coeff_set[18], priv->base + VNC7A_REG);
++ iowrite32(p_set->coeff_set[19], priv->base + VNC7B_REG);
++ iowrite32(p_set->coeff_set[20], priv->base + VNC7C_REG);
++
++ iowrite32(p_set->coeff_set[21], priv->base + VNC8A_REG);
++ iowrite32(p_set->coeff_set[22], priv->base + VNC8B_REG);
++ iowrite32(p_set->coeff_set[23], priv->base + VNC8C_REG);
++}
++
++/* rect is guaranteed to not exceed the scaled camera rectangle */
++static int rcar_vin_set_rect(struct soc_camera_device *icd)
++{
++ struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
++ struct rcar_vin_cam *cam = icd->host_priv;
++ struct rcar_vin_priv *priv = ici->priv;
++ unsigned int left_offset, top_offset;
++ unsigned char dsize = 0;
++ struct v4l2_rect *cam_subrect = &cam->subrect;
++ u32 value;
++ int ret = 0;
++
++ dev_dbg(icd->parent, "Crop %ux%u@%u:%u\n",
++ icd->user_width, icd->user_height, cam->vin_left, cam->vin_top);
++
++ left_offset = cam->vin_left;
++ top_offset = cam->vin_top;
++
++ if (icd->current_fmt->host_fmt->fourcc == V4L2_PIX_FMT_XBGR32 &&
++ priv->chip == RCAR_E1)
++ dsize = 1;
++
++ dev_dbg(icd->parent, "Cam %ux%u@%u:%u\n",
++ cam->width, cam->height, cam->vin_left, cam->vin_top);
++ dev_dbg(icd->parent, "Cam subrect %ux%u@%u:%u\n",
++ cam_subrect->width, cam_subrect->height,
++ cam_subrect->left, cam_subrect->top);
++
++ /* Set Start/End Pixel/Line Pre-Clip */
++ iowrite32(left_offset << dsize, priv->base + VNSPPRC_REG);
++ iowrite32((left_offset + cam_subrect->width - 1) << dsize,
++ priv->base + VNEPPRC_REG);
++ switch (priv->field) {
++ case V4L2_FIELD_INTERLACED:
++ case V4L2_FIELD_INTERLACED_TB:
++ case V4L2_FIELD_INTERLACED_BT:
++ iowrite32(top_offset / 2, priv->base + VNSLPRC_REG);
++ iowrite32((top_offset + cam_subrect->height) / 2 - 1,
++ priv->base + VNELPRC_REG);
++ break;
++ default:
++ iowrite32(top_offset, priv->base + VNSLPRC_REG);
++ iowrite32(top_offset + cam_subrect->height - 1,
++ priv->base + VNELPRC_REG);
++ break;
++ }
++
++ if (priv->chip == RCAR_H3 || priv->chip == RCAR_M3) {
++ if ((icd->current_fmt->host_fmt->fourcc != V4L2_PIX_FMT_NV12)
++ && is_scaling(cam)) {
++ ret = rcar_vin_uds_set(priv, cam);
++ if (ret < 0)
++ return ret;
++ }
++ if (is_scaling(cam) ||
++ (icd->current_fmt->host_fmt->fourcc == V4L2_PIX_FMT_NV16) ||
++ (icd->current_fmt->host_fmt->fourcc == V4L2_PIX_FMT_NV12))
++ iowrite32(ALIGN(cam->out_width, 0x20),
++ priv->base + VNIS_REG);
++ else
++ iowrite32(ALIGN(cam->out_width, 0x10),
++ priv->base + VNIS_REG);
++ } else {
++ /* Set scaling coefficient */
++ value = 0;
++ if (cam_subrect->height != cam->out_height)
++ value = (4096 * cam_subrect->height) / cam->out_height;
++ dev_dbg(icd->parent, "YS Value: %x\n", value);
++ iowrite32(value, priv->base + VNYS_REG);
++
++ value = 0;
++ if (cam_subrect->width != cam->out_width)
++ value = (4096 * cam_subrect->width) / cam->out_width;
++
++ /* Horizontal upscaling is up to double size */
++ if (value < 2048)
++ value = 2048;
++
++ dev_dbg(icd->parent, "XS Value: %x\n", value);
++ iowrite32(value, priv->base + VNXS_REG);
++
++ /* Horizontal upscaling is carried out */
++ /* by scaling down from double size */
++ if (value < 4096)
++ value *= 2;
++
++ set_coeff(priv, value);
++
++ /* Set Start/End Pixel/Line Post-Clip */
++ iowrite32(0, priv->base + VNSPPOC_REG);
++ iowrite32(0, priv->base + VNSLPOC_REG);
++ iowrite32((cam->out_width - 1) << dsize,
++ priv->base + VNEPPOC_REG);
++ switch (priv->field) {
++ case V4L2_FIELD_INTERLACED:
++ case V4L2_FIELD_INTERLACED_TB:
++ case V4L2_FIELD_INTERLACED_BT:
++ iowrite32(cam->out_height / 2 - 1,
++ priv->base + VNELPOC_REG);
++ break;
++ default:
++ iowrite32(cam->out_height - 1,
++ priv->base + VNELPOC_REG);
++ break;
++ }
++
++ iowrite32(ALIGN(cam->out_width, 0x10), priv->base + VNIS_REG);
++ }
++
++ return ret;
++}
++
++static void capture_stop_preserve(struct rcar_vin_priv *priv, u32 *vnmc)
++{
++ *vnmc = ioread32(priv->base + VNMC_REG);
++ /* module disable */
++ iowrite32(*vnmc & ~VNMC_ME, priv->base + VNMC_REG);
++}
++
++static void capture_restore(struct rcar_vin_priv *priv, u32 vnmc)
++{
++ unsigned long timeout = jiffies + 10 * HZ;
++
++ /*
++ * Wait until the end of the current frame. It can take a long time,
++ * but if it has been aborted by a MRST1 reset, it should exit sooner.
++ */
++ while ((ioread32(priv->base + VNMS_REG) & VNMS_AV) &&
++ time_before(jiffies, timeout))
++ msleep(1);
++
++ if (time_after(jiffies, timeout)) {
++ dev_err(priv->ici.v4l2_dev.dev,
++ "Timeout waiting for frame end! Interface problem?\n");
++ return;
++ }
++
++ iowrite32(vnmc, priv->base + VNMC_REG);
++}
++
++#define VIN_MBUS_FLAGS (V4L2_MBUS_MASTER | \
++ V4L2_MBUS_PCLK_SAMPLE_RISING | \
++ V4L2_MBUS_HSYNC_ACTIVE_HIGH | \
++ V4L2_MBUS_HSYNC_ACTIVE_LOW | \
++ V4L2_MBUS_VSYNC_ACTIVE_HIGH | \
++ V4L2_MBUS_VSYNC_ACTIVE_LOW | \
++ V4L2_MBUS_DATA_ACTIVE_HIGH)
++
++static int rcar_vin_set_bus_param(struct soc_camera_device *icd)
++{
++ struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
++ struct rcar_vin_priv *priv = ici->priv;
++ struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
++ struct v4l2_mbus_config cfg;
++ unsigned long common_flags;
++ u32 vnmc;
++ u32 val;
++ int ret;
++
++ capture_stop_preserve(priv, &vnmc);
++
++ ret = v4l2_subdev_call(sd, video, g_mbus_config, &cfg);
++ if (!ret) {
++ common_flags = soc_mbus_config_compatible(&cfg, VIN_MBUS_FLAGS);
++ if (!common_flags) {
++ dev_warn(icd->parent,
++ "MBUS flags incompatible: camera 0x%x, host 0x%x\n",
++ cfg.flags, VIN_MBUS_FLAGS);
++ return -EINVAL;
++ }
++ } else if (ret != -ENOIOCTLCMD) {
++ return ret;
++ } else {
++ common_flags = VIN_MBUS_FLAGS;
++ }
++
++ /* Make choises, based on platform preferences */
++ if ((common_flags & V4L2_MBUS_HSYNC_ACTIVE_HIGH) &&
++ (common_flags & V4L2_MBUS_HSYNC_ACTIVE_LOW)) {
++ if (priv->pdata_flags & RCAR_VIN_HSYNC_ACTIVE_LOW)
++ common_flags &= ~V4L2_MBUS_HSYNC_ACTIVE_HIGH;
++ else
++ common_flags &= ~V4L2_MBUS_HSYNC_ACTIVE_LOW;
++ }
++
++ if ((common_flags & V4L2_MBUS_VSYNC_ACTIVE_HIGH) &&
++ (common_flags & V4L2_MBUS_VSYNC_ACTIVE_LOW)) {
++ if (priv->pdata_flags & RCAR_VIN_VSYNC_ACTIVE_LOW)
++ common_flags &= ~V4L2_MBUS_VSYNC_ACTIVE_HIGH;
++ else
++ common_flags &= ~V4L2_MBUS_VSYNC_ACTIVE_LOW;
++ }
++
++ cfg.flags = common_flags;
++ ret = v4l2_subdev_call(sd, video, s_mbus_config, &cfg);
++ if (ret < 0 && ret != -ENOIOCTLCMD)
++ return ret;
++
++ if (priv->chip == RCAR_H3 || priv->chip == RCAR_M3) {
++ if (cfg.type == V4L2_MBUS_CSI2)
++ vnmc &= ~VNMC_DPINE;
++ else
++ vnmc |= VNMC_DPINE;
++ }
++
++ if (priv->chip == RCAR_H3 || priv->chip == RCAR_M3)
++ val = VNDMR2_FTEV;
++ else
++ val = VNDMR2_FTEV | VNDMR2_VLV(1);
++ if (!(common_flags & V4L2_MBUS_VSYNC_ACTIVE_LOW))
++ val |= VNDMR2_VPS;
++ if (!(common_flags & V4L2_MBUS_HSYNC_ACTIVE_LOW))
++ val |= VNDMR2_HPS;
++ iowrite32(val, priv->base + VNDMR2_REG);
++
++ ret = rcar_vin_set_rect(icd);
++ if (ret < 0)
++ return ret;
++
++ capture_restore(priv, vnmc);
++
++ return 0;
++}
++
++static int rcar_vin_try_bus_param(struct soc_camera_device *icd,
++ unsigned char buswidth)
++{
++ struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
++ struct v4l2_mbus_config cfg;
++ int ret;
++
++ ret = v4l2_subdev_call(sd, video, g_mbus_config, &cfg);
++ if (ret == -ENOIOCTLCMD)
++ return 0;
++ else if (ret)
++ return ret;
++
++ if (buswidth > 24)
++ return -EINVAL;
++
++ /* check is there common mbus flags */
++ ret = soc_mbus_config_compatible(&cfg, VIN_MBUS_FLAGS);
++ if (ret)
++ return 0;
++
++ dev_warn(icd->parent,
++ "MBUS flags incompatible: camera 0x%x, host 0x%x\n",
++ cfg.flags, VIN_MBUS_FLAGS);
++
++ return -EINVAL;
++}
++
++static bool rcar_vin_packing_supported(const struct soc_mbus_pixelfmt *fmt)
++{
++ return fmt->packing == SOC_MBUS_PACKING_NONE ||
++ (fmt->bits_per_sample > 8 &&
++ fmt->packing == SOC_MBUS_PACKING_EXTEND16);
++}
++
++static const struct soc_mbus_pixelfmt rcar_vin_formats[] = {
++ {
++ .fourcc = V4L2_PIX_FMT_NV12,
++ .name = "NV12",
++ .bits_per_sample = 8,
++ .packing = SOC_MBUS_PACKING_1_5X8,
++ .order = SOC_MBUS_ORDER_LE,
++ .layout = SOC_MBUS_LAYOUT_PLANAR_2Y_C,
++ },
++ {
++ .fourcc = V4L2_PIX_FMT_NV16,
++ .name = "NV16",
++ .bits_per_sample = 8,
++ .packing = SOC_MBUS_PACKING_2X8_PADHI,
++ .order = SOC_MBUS_ORDER_LE,
++ .layout = SOC_MBUS_LAYOUT_PLANAR_Y_C,
++ },
++ {
++ .fourcc = V4L2_PIX_FMT_YUYV,
++ .name = "YUYV",
++ .bits_per_sample = 16,
++ .packing = SOC_MBUS_PACKING_NONE,
++ .order = SOC_MBUS_ORDER_LE,
++ .layout = SOC_MBUS_LAYOUT_PACKED,
++ },
++ {
++ .fourcc = V4L2_PIX_FMT_UYVY,
++ .name = "UYVY",
++ .bits_per_sample = 16,
++ .packing = SOC_MBUS_PACKING_NONE,
++ .order = SOC_MBUS_ORDER_LE,
++ .layout = SOC_MBUS_LAYOUT_PACKED,
++ },
++ {
++ .fourcc = V4L2_PIX_FMT_RGB565,
++ .name = "RGB565",
++ .bits_per_sample = 16,
++ .packing = SOC_MBUS_PACKING_NONE,
++ .order = SOC_MBUS_ORDER_LE,
++ .layout = SOC_MBUS_LAYOUT_PACKED,
++ },
++ {
++ .fourcc = V4L2_PIX_FMT_ARGB555,
++ .name = "ARGB1555",
++ .bits_per_sample = 16,
++ .packing = SOC_MBUS_PACKING_NONE,
++ .order = SOC_MBUS_ORDER_LE,
++ .layout = SOC_MBUS_LAYOUT_PACKED,
++ },
++ {
++ .fourcc = V4L2_PIX_FMT_XBGR32,
++ .name = "RGB888",
++ .bits_per_sample = 32,
++ .packing = SOC_MBUS_PACKING_NONE,
++ .order = SOC_MBUS_ORDER_LE,
++ .layout = SOC_MBUS_LAYOUT_PACKED,
++ },
++ {
++ .fourcc = V4L2_PIX_FMT_ABGR32,
++ .name = "ARGB8888",
++ .bits_per_sample = 32,
++ .packing = SOC_MBUS_PACKING_NONE,
++ .order = SOC_MBUS_ORDER_LE,
++ .layout = SOC_MBUS_LAYOUT_PACKED,
++ },
++};
++
++static int rcar_vin_get_formats(struct soc_camera_device *icd, unsigned int idx,
++ struct soc_camera_format_xlate *xlate)
++{
++ struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
++ struct device *dev = icd->parent;
++ int ret, k, n;
++ int formats = 0;
++ struct rcar_vin_cam *cam;
++ struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
++ struct rcar_vin_priv *priv = ici->priv;
++ struct v4l2_subdev_mbus_code_enum code = {
++ .which = V4L2_SUBDEV_FORMAT_ACTIVE,
++ .index = idx,
++ };
++ const struct soc_mbus_pixelfmt *fmt;
++
++ ret = v4l2_subdev_call(sd, pad, enum_mbus_code, NULL, &code);
++ if (ret < 0)
++ return 0;
++
++ fmt = soc_mbus_get_fmtdesc(code.code);
++ if (!fmt) {
++ dev_warn(dev, "unsupported format code #%u: %d\n", idx, code.code);
++ return 0;
++ }
++
++ ret = rcar_vin_try_bus_param(icd, fmt->bits_per_sample);
++ if (ret < 0)
++ return 0;
++
++ if (!icd->host_priv) {
++ struct v4l2_subdev_format fmt = {
++ .which = V4L2_SUBDEV_FORMAT_ACTIVE,
++ };
++ struct v4l2_mbus_framefmt *mf = &fmt.format;
++ struct v4l2_rect rect;
++ struct device *dev = icd->parent;
++ int shift;
++
++ ret = v4l2_subdev_call(sd, pad, get_fmt, NULL, &fmt);
++ if (ret < 0)
++ return ret;
++
++ /* Cache current client geometry */
++ ret = soc_camera_client_g_rect(sd, &rect);
++ if (ret == -ENOIOCTLCMD) {
++ /* Sensor driver doesn't support cropping */
++ rect.left = 0;
++ rect.top = 0;
++ rect.width = mf->width;
++ rect.height = mf->height;
++ } else if (ret < 0) {
++ return ret;
++ }
++
++ /*
++ * If sensor proposes too large format then try smaller ones:
++ * 1280x960, 640x480, 320x240
++ */
++ for (shift = 0; shift < 3; shift++) {
++ if (mf->width <= priv->max_width &&
++ mf->height <= priv->max_height)
++ break;
++
++ mf->width = 1280 >> shift;
++ mf->height = 960 >> shift;
++ ret = v4l2_device_call_until_err(sd->v4l2_dev,
++ soc_camera_grp_id(icd),
++ pad, set_fmt, NULL,
++ &fmt);
++ if (ret < 0)
++ return ret;
++ }
++
++ if (shift == 3) {
++ dev_err(dev,
++ "Failed to configure the client below %ux%u\n",
++ mf->width, mf->height);
++ return -EIO;
++ }
++
++ dev_dbg(dev, "camera fmt %ux%u\n", mf->width, mf->height);
++
++ cam = kzalloc(sizeof(*cam), GFP_KERNEL);
++ if (!cam)
++ return -ENOMEM;
++ /*
++ * We are called with current camera crop,
++ * initialise subrect with it
++ */
++ cam->rect = rect;
++ cam->subrect = rect;
++ cam->width = mf->width;
++ cam->height = mf->height;
++ cam->out_width = mf->width;
++ cam->out_height = mf->height;
++
++ icd->host_priv = cam;
++ } else {
++ cam = icd->host_priv;
++ }
++
++ /* Beginning of a pass */
++ if (!idx)
++ cam->extra_fmt = NULL;
++
++ switch (code.code) {
++ case MEDIA_BUS_FMT_YUYV8_1X16:
++ case MEDIA_BUS_FMT_YUYV8_2X8:
++ case MEDIA_BUS_FMT_YUYV10_2X10:
++ case MEDIA_BUS_FMT_RGB888_1X24:
++ if (cam->extra_fmt)
++ break;
++
++ /* Add all our formats that can be generated by VIN */
++ cam->extra_fmt = rcar_vin_formats;
++
++ n = ARRAY_SIZE(rcar_vin_formats);
++ formats += n;
++ for (k = 0; xlate && k < n; k++, xlate++) {
++ xlate->host_fmt = &rcar_vin_formats[k];
++ xlate->code = code.code;
++ dev_dbg(dev, "Providing format %s using code %d\n",
++ rcar_vin_formats[k].name, code.code);
++ }
++ break;
++ default:
++ if (!rcar_vin_packing_supported(fmt))
++ return 0;
++
++ dev_dbg(dev, "Providing format %s in pass-through mode\n",
++ fmt->name);
++ break;
++ }
++
++ /* Generic pass-through */
++ formats++;
++ if (xlate) {
++ xlate->host_fmt = fmt;
++ xlate->code = code.code;
++ xlate++;
++ }
++
++ return formats;
++}
++
++static void rcar_vin_put_formats(struct soc_camera_device *icd)
++{
++ kfree(icd->host_priv);
++ icd->host_priv = NULL;
++}
++
++static int rcar_vin_set_selection(struct soc_camera_device *icd,
++ struct v4l2_selection *sel)
++{
++ const struct v4l2_rect *rect = &sel->r;
++ struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
++ struct rcar_vin_priv *priv = ici->priv;
++ struct v4l2_selection cam_sel;
++ struct rcar_vin_cam *cam = icd->host_priv;
++ struct v4l2_rect *cam_rect = &cam_sel.r;
++ struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
++ struct device *dev = icd->parent;
++ struct v4l2_subdev_format fmt = {
++ .which = V4L2_SUBDEV_FORMAT_ACTIVE,
++ };
++ struct v4l2_mbus_framefmt *mf = &fmt.format;
++ u32 vnmc;
++ int ret, i;
++
++ dev_dbg(dev, "S_SELECTION(%ux%u@%u:%u)\n", rect->width, rect->height,
++ rect->left, rect->top);
++
++ /* During camera cropping its output window can change too, stop VIN */
++ capture_stop_preserve(priv, &vnmc);
++ dev_dbg(dev, "VNMC_REG 0x%x\n", vnmc);
++
++ /* Apply iterative camera S_SELECTION for new input window. */
++ ret = soc_camera_client_s_selection(sd, sel, &cam_sel,
++ &cam->rect, &cam->subrect);
++ if (ret < 0)
++ return ret;
++
++ dev_dbg(dev, "camera cropped to %ux%u@%u:%u\n",
++ cam_rect->width, cam_rect->height,
++ cam_rect->left, cam_rect->top);
++
++ /* On success cam_crop contains current camera crop */
++
++ /* Retrieve camera output window */
++ ret = v4l2_subdev_call(sd, pad, get_fmt, NULL, &fmt);
++ if (ret < 0)
++ return ret;
++
++ if (mf->width > priv->max_width || mf->height > priv->max_height)
++ return -EINVAL;
++
++ /* Cache camera output window */
++ cam->width = mf->width;
++ cam->height = mf->height;
++
++ cam->vin_left = rect->left;
++ cam->vin_top = rect->top;
++
++ /* Use VIN cropping to crop to the new window. */
++ ret = rcar_vin_set_rect(icd);
++ if (ret < 0)
++ return ret;
++
++ dev_dbg(dev, "VIN cropped to %ux%u@%u:%u\n",
++ icd->user_width, icd->user_height,
++ cam->vin_left, cam->vin_top);
++
++ /* Restore capture */
++ for (i = 0; i < MAX_BUFFER_NUM; i++) {
++ if (priv->queue_buf[i] && priv->state == STOPPED) {
++ vnmc |= VNMC_ME;
++ break;
++ }
++ }
++ capture_restore(priv, vnmc);
++
++ /* Even if only camera cropping succeeded */
++ return ret;
++}
++
++static int rcar_vin_get_selection(struct soc_camera_device *icd,
++ struct v4l2_selection *sel)
++{
++ struct rcar_vin_cam *cam = icd->host_priv;
++
++ sel->r = cam->subrect;
++
++ return 0;
++}
++
++/* Similar to set_crop multistage iterative algorithm */
++static int rcar_vin_set_fmt(struct soc_camera_device *icd,
++ struct v4l2_format *f)
++{
++ struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
++ struct rcar_vin_priv *priv = ici->priv;
++ struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
++ struct rcar_vin_cam *cam = icd->host_priv;
++ struct v4l2_pix_format *pix = &f->fmt.pix;
++ struct v4l2_mbus_framefmt mf;
++ struct device *dev = icd->parent;
++ __u32 pixfmt = pix->pixelformat;
++ const struct soc_camera_format_xlate *xlate;
++ unsigned int vin_sub_width = 0, vin_sub_height = 0;
++ int ret;
++ bool can_scale;
++ enum v4l2_field field;
++ v4l2_std_id std;
++
++ dev_dbg(dev, "S_FMT(pix=0x%x, %ux%u)\n",
++ pixfmt, pix->width, pix->height);
++
++ /* At the time of NV16 capture format, the user has to specify */
++ /* the width of the multiple of 32 for H/W specification. */
++ if (priv->error_flag == false)
++ priv->error_flag = true;
++ else {
++ if (((pixfmt == V4L2_PIX_FMT_NV16) ||
++ (pixfmt == V4L2_PIX_FMT_NV12)) &&
++ (pix->width & 0x1F)) {
++ dev_dbg(icd->parent,
++ "specify width of 32 multiple in separate format.\n");
++ return -EINVAL;
++ }
++ }
++
++ switch (pix->field) {
++ default:
++ pix->field = V4L2_FIELD_NONE;
++ /* fall-through */
++ case V4L2_FIELD_NONE:
++ case V4L2_FIELD_TOP:
++ case V4L2_FIELD_BOTTOM:
++ case V4L2_FIELD_INTERLACED_TB:
++ case V4L2_FIELD_INTERLACED_BT:
++ field = pix->field;
++ break;
++ case V4L2_FIELD_INTERLACED:
++ /* Query for standard if not explicitly mentioned _TB/_BT */
++ ret = v4l2_subdev_call(sd, video, querystd, &std);
++ if (ret == -ENOIOCTLCMD) {
++ field = V4L2_FIELD_NONE;
++ } else if (ret < 0) {
++ return ret;
++ } else {
++ field = std & V4L2_STD_625_50 ?
++ V4L2_FIELD_INTERLACED_TB :
++ V4L2_FIELD_INTERLACED_BT;
++ }
++ break;
++ }
++
++ xlate = soc_camera_xlate_by_fourcc(icd, pixfmt);
++ if (!xlate) {
++ dev_warn(dev, "Format %x not found\n", pixfmt);
++ return -EINVAL;
++ }
++ /* Calculate client output geometry */
++ soc_camera_calc_client_output(icd, &cam->rect, &cam->subrect, pix, &mf,
++ 12);
++ mf.field = pix->field;
++ mf.colorspace = pix->colorspace;
++ mf.code = xlate->code;
++
++ switch (pixfmt) {
++ case V4L2_PIX_FMT_XBGR32:
++ can_scale = priv->chip != RCAR_E1;
++ break;
++ case V4L2_PIX_FMT_ABGR32:
++ case V4L2_PIX_FMT_UYVY:
++ case V4L2_PIX_FMT_YUYV:
++ case V4L2_PIX_FMT_RGB565:
++ case V4L2_PIX_FMT_ARGB555:
++ case V4L2_PIX_FMT_NV16:
++ can_scale = true;
++ break;
++ case V4L2_PIX_FMT_NV12:
++ default:
++ can_scale = false;
++ break;
++ }
++
++ dev_dbg(dev, "request camera output %ux%u\n", mf.width, mf.height);
++
++ ret = soc_camera_client_scale(icd, &cam->rect, &cam->subrect,
++ &mf, &vin_sub_width, &vin_sub_height,
++ can_scale, 12);
++
++ /* Done with the camera. Now see if we can improve the result */
++ dev_dbg(dev, "Camera %d fmt %ux%u, requested %ux%u\n",
++ ret, mf.width, mf.height, pix->width, pix->height);
++
++ if (ret == -ENOIOCTLCMD)
++ dev_dbg(dev, "Sensor doesn't support scaling\n");
++ else if (ret < 0)
++ return ret;
++
++ if (mf.code != xlate->code)
++ return -EINVAL;
++
++ /* Prepare VIN crop */
++ cam->width = mf.width;
++ cam->height = mf.height;
++
++ /* Use VIN scaling to scale to the requested user window. */
++
++ /* We cannot scale up */
++ if (pix->width > vin_sub_width)
++ vin_sub_width = pix->width;
++
++ if (pix->height > vin_sub_height)
++ vin_sub_height = pix->height;
++
++ pix->colorspace = mf.colorspace;
++
++ if (!can_scale) {
++ pix->width = vin_sub_width;
++ pix->height = vin_sub_height;
++ }
++
++ /*
++ * We have calculated CFLCR, the actual configuration will be performed
++ * in rcar_vin_set_bus_param()
++ */
++
++ dev_dbg(dev, "W: %u : %u, H: %u : %u\n",
++ vin_sub_width, pix->width, vin_sub_height, pix->height);
++
++ cam->out_width = pix->width;
++ cam->out_height = pix->height;
++
++ icd->current_fmt = xlate;
++
++ priv->field = field;
++
++ return 0;
++}
++
++static int rcar_vin_try_fmt(struct soc_camera_device *icd,
++ struct v4l2_format *f)
++{
++ const struct soc_camera_format_xlate *xlate;
++ struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
++ struct rcar_vin_priv *priv = ici->priv;
++ struct v4l2_pix_format *pix = &f->fmt.pix;
++ struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
++ struct v4l2_subdev_pad_config pad_cfg;
++ struct v4l2_subdev_format format = {
++ .which = V4L2_SUBDEV_FORMAT_TRY,
++ };
++ struct v4l2_mbus_framefmt *mf = &format.format;
++ __u32 pixfmt = pix->pixelformat;
++ int width, height;
++ int ret;
++
++ xlate = soc_camera_xlate_by_fourcc(icd, pixfmt);
++ if (!xlate) {
++ xlate = icd->current_fmt;
++ dev_dbg(icd->parent, "Format %x not found, keeping %x\n",
++ pixfmt, xlate->host_fmt->fourcc);
++ pixfmt = xlate->host_fmt->fourcc;
++ pix->pixelformat = pixfmt;
++ pix->colorspace = icd->colorspace;
++ }
++
++ /* When performing a YCbCr-422 format output, even if it performs */
++ /* odd number clipping by pixel post clip processing, */
++ /* it is outputted to a memory per even pixels. */
++ if ((pixfmt == V4L2_PIX_FMT_NV16) || (pixfmt == V4L2_PIX_FMT_NV12) ||
++ (pixfmt == V4L2_PIX_FMT_YUYV) || (pixfmt == V4L2_PIX_FMT_UYVY))
++ v4l_bound_align_image(&pix->width, 5, priv->max_width, 1,
++ &pix->height, 2, priv->max_height, 0, 0);
++ else
++ v4l_bound_align_image(&pix->width, 5, priv->max_width, 0,
++ &pix->height, 2, priv->max_height, 0, 0);
++
++ width = pix->width;
++ height = pix->height;
++
++ /* let soc-camera calculate these values */
++ pix->bytesperline = 0;
++ pix->sizeimage = 0;
++
++ /* limit to sensor capabilities */
++ mf->width = pix->width;
++ mf->height = pix->height;
++ mf->field = pix->field;
++ mf->code = xlate->code;
++ mf->colorspace = pix->colorspace;
++
++ ret = v4l2_device_call_until_err(sd->v4l2_dev, soc_camera_grp_id(icd),
++ pad, set_fmt, &pad_cfg, &format);
++ if (ret < 0)
++ return ret;
++
++ if (priv->chip == RCAR_H3 || priv->chip == RCAR_M3) {
++ /* Adjust max scaling size for Gen3 */
++ if (pix->width > 4096)
++ pix->width = priv->max_width;
++ if (pix->height > 4096)
++ pix->height = priv->max_height;
++ } else {
++ /* Adjust only if VIN cannot scale */
++ if (pix->width > mf->width * 2)
++ pix->width = mf->width * 2;
++ if (pix->height > mf->height * 3)
++ pix->height = mf->height * 3;
++ }
++
++ pix->field = mf->field;
++ pix->colorspace = mf->colorspace;
++
++ if (pixfmt == V4L2_PIX_FMT_NV16) {
++ /* FIXME: check against rect_max after converting soc-camera */
++ /* We can scale precisely, need a bigger image from camera */
++ if (pix->width < width || pix->height < height) {
++ /*
++ * We presume, the sensor behaves sanely, i.e. if
++ * requested a bigger rectangle, it will not return a
++ * smaller one.
++ */
++ mf->width = priv->max_width;
++ mf->height = priv->max_height;
++ ret = v4l2_device_call_until_err(sd->v4l2_dev,
++ soc_camera_grp_id(icd),
++ pad, set_fmt, &pad_cfg,
++ &format);
++ if (ret < 0) {
++ dev_err(icd->parent,
++ "client try_fmt() = %d\n", ret);
++ return ret;
++ }
++ }
++ /* We will scale exactly */
++ if (mf->width > width)
++ pix->width = width;
++ if (mf->height > height)
++ pix->height = height;
++ }
++
++ return ret;
++}
++
++static unsigned int rcar_vin_poll(struct file *file, poll_table *pt)
++{
++ struct soc_camera_device *icd = file->private_data;
++
++ return vb2_poll(&icd->vb2_vidq, file, pt);
++}
++
++static int rcar_vin_querycap(struct soc_camera_host *ici,
++ struct v4l2_capability *cap)
++{
++ strlcpy(cap->card, "R_Car_VIN", sizeof(cap->card));
++ cap->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING;
++ cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS;
++ snprintf(cap->bus_info, sizeof(cap->bus_info), "platform:%s%d", DRV_NAME, ici->nr);
++
++ return 0;
++}
++
++static int rcar_vin_init_videobuf2(struct vb2_queue *vq,
++ struct soc_camera_device *icd)
++{
++ struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
++
++ vq->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
++ vq->io_modes = VB2_MMAP | VB2_USERPTR | VB2_DMABUF;
++ vq->drv_priv = icd;
++ vq->ops = &rcar_vin_vb2_ops;
++ vq->mem_ops = &vb2_dma_contig_memops;
++ vq->buf_struct_size = sizeof(struct rcar_vin_buffer);
++ vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
++ vq->lock = &ici->host_lock;
++ vq->dev = ici->v4l2_dev.dev;
++
++ return vb2_queue_init(vq);
++}
++
++#if 0
++static int rcar_vin_get_selection(struct soc_camera_device *icd,
++ struct v4l2_selection *sel)
++{
++ struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
++ struct v4l2_subdev_format fmt = {
++ .which = V4L2_SUBDEV_FORMAT_ACTIVE,
++ };
++ struct v4l2_mbus_framefmt *mf = &fmt.format;
++ int ret;
++
++ ret = v4l2_subdev_call(sd, pad, get_fmt, NULL, &fmt);
++ if (ret < 0)
++ return ret;
++
++ if (sel->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
++ return -EINVAL;
++
++ switch (sel->target) {
++ case V4L2_SEL_TGT_CROP_BOUNDS:
++ case V4L2_SEL_TGT_CROP_DEFAULT:
++ sel->r.left = sel->r.top = 0;
++ sel->r.width = mf->width;
++ sel->r.height = mf->height;
++ break;
++ default:
++ return -EINVAL;
++ }
++
++ return 0;
++}
++
++static int rcar_vin_cropcap(struct soc_camera_device *icd,
++ struct v4l2_cropcap *crop)
++{
++ struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
++ struct v4l2_subdev_format fmt = {
++ .which = V4L2_SUBDEV_FORMAT_ACTIVE,
++ };
++ struct v4l2_mbus_framefmt *mf = &fmt.format;
++ int ret;
++
++ ret = v4l2_subdev_call(sd, pad, get_fmt, NULL, &fmt);
++ if (ret < 0)
++ return ret;
++
++ crop->bounds.left = 0;
++ crop->bounds.top = 0;
++ crop->bounds.width = mf->width;
++ crop->bounds.height = mf->height;
++
++ /* default cropping rectangle */
++ crop->defrect = crop->bounds;
++ crop->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
++
++ return 0;
++}
++#endif
++
++static struct soc_camera_host_ops rcar_vin_host_ops = {
++ .owner = THIS_MODULE,
++ .add = rcar_vin_add_device,
++ .remove = rcar_vin_remove_device,
++ .get_formats = rcar_vin_get_formats,
++ .put_formats = rcar_vin_put_formats,
++ .get_selection = rcar_vin_get_selection,
++ .set_selection = rcar_vin_set_selection,
++ .try_fmt = rcar_vin_try_fmt,
++ .set_fmt = rcar_vin_set_fmt,
++ .poll = rcar_vin_poll,
++ .querycap = rcar_vin_querycap,
++ .set_bus_param = rcar_vin_set_bus_param,
++ .init_videobuf2 = rcar_vin_init_videobuf2,
++#if 0
++ .get_selection = rcar_vin_get_selection,
++ .cropcap = rcar_vin_cropcap,
++#endif
++};
++
++#ifdef CONFIG_OF
++static const struct of_device_id rcar_vin_of_table[] = {
++ { .compatible = "renesas,vin-r8a7796", .data = (void *)RCAR_M3 },
++ { .compatible = "renesas,vin-r8a7795", .data = (void *)RCAR_H3 },
++ { .compatible = "renesas,vin-r8a7794", .data = (void *)RCAR_GEN2 },
++ { .compatible = "renesas,vin-r8a7793", .data = (void *)RCAR_GEN2 },
++ { .compatible = "renesas,vin-r8a7791", .data = (void *)RCAR_GEN2 },
++ { .compatible = "renesas,vin-r8a7790", .data = (void *)RCAR_GEN2 },
++ { .compatible = "renesas,vin-r8a7779", .data = (void *)RCAR_H1 },
++ { .compatible = "renesas,vin-r8a7778", .data = (void *)RCAR_M1 },
++ { .compatible = "renesas,rcar-gen3-vin", .data = (void *)RCAR_GEN3 },
++ { .compatible = "renesas,rcar-gen2-vin", .data = (void *)RCAR_GEN2 },
++ { },
++};
++MODULE_DEVICE_TABLE(of, rcar_vin_of_table);
++#endif
++
++#define MAP_MAX_NUM 32
++static DECLARE_BITMAP(device_map, MAP_MAX_NUM);
++static DEFINE_MUTEX(list_lock);
++
++static int rcar_vin_dyn_pdev(struct soc_camera_desc *sdesc,
++ struct rcar_vin_async_client *sasc)
++{
++ struct platform_device *pdev;
++ int ret, i;
++
++ mutex_lock(&list_lock);
++ i = find_first_zero_bit(device_map, MAP_MAX_NUM);
++ if (i < MAP_MAX_NUM)
++ set_bit(i, device_map);
++ mutex_unlock(&list_lock);
++ if (i >= MAP_MAX_NUM)
++ return -ENOMEM;
++
++ pdev = platform_device_alloc("soc-camera-pdrv", ((2 * i) + 1));
++ if (!pdev)
++ return -ENOMEM;
++
++ ret = platform_device_add_data(pdev, sdesc, sizeof(*sdesc));
++ if (ret < 0) {
++ platform_device_put(pdev);
++ return ret;
++ }
++
++ sasc->pdev = pdev;
++
++ return 0;
++}
++
++static int rcar_vin_async_bound(struct v4l2_async_notifier *notifier,
++ struct v4l2_subdev *sd,
++ struct v4l2_async_subdev *asd)
++{
++ /* None. */
++ return 0;
++}
++
++static void rcar_vin_async_unbind(struct v4l2_async_notifier *notifier,
++ struct v4l2_subdev *sd,
++ struct v4l2_async_subdev *asd)
++{
++ /* None. */
++}
++
++static int rcar_vin_async_probe(struct soc_camera_host *ici,
++ struct soc_camera_device *icd)
++{
++ struct soc_camera_desc *sdesc = to_soc_camera_desc(icd);
++ struct soc_camera_host_desc *shd = &sdesc->host_desc;
++ struct device *control = NULL;
++ int ret;
++
++ ret = v4l2_ctrl_handler_init(&icd->ctrl_handler, 16);
++ if (ret < 0)
++ return ret;
++
++ if (shd->module_name)
++ ret = request_module(shd->module_name);
++
++ ret = shd->add_device(icd);
++
++ control = to_soc_camera_control(icd);
++ if (!control || !control->driver || !dev_get_drvdata(control) ||
++ !try_module_get(control->driver->owner)) {
++ shd->del_device(icd);
++ ret = -ENODEV;
++ }
++
++ return ret;
++}
++
++static int rcar_vin_async_complete(struct v4l2_async_notifier *notifier)
++{
++ struct rcar_vin_async_client *sasc = container_of(notifier,
++ struct rcar_vin_async_client, notifier);
++ struct soc_camera_device *icd = platform_get_drvdata(sasc->pdev);
++
++ if (to_soc_camera_control(icd)) {
++ struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
++ int ret;
++
++ mutex_lock(&list_lock);
++ ret = rcar_vin_async_probe(ici, icd);
++ mutex_unlock(&list_lock);
++ if (ret < 0)
++ return ret;
++ }
++
++ return 0;
++}
++
++static struct soc_camera_device *rcar_vin_add_pdev(
++ struct rcar_vin_async_client *sasc)
++{
++ struct platform_device *pdev = sasc->pdev;
++ int ret;
++
++ ret = platform_device_add(pdev);
++
++ if (ret < 0 || !pdev->dev.driver)
++ return NULL;
++
++ return platform_get_drvdata(pdev);
++}
++
++static int rcar_vin_soc_of_bind(struct rcar_vin_priv *priv,
++ struct soc_camera_host *ici,
++ struct device_node *ep,
++ struct device_node *remote)
++{
++ struct soc_camera_device *icd;
++ struct soc_camera_desc sdesc = {.host_desc.bus_id = ici->nr,};
++ struct rcar_vin_async_client *sasc;
++ struct soc_of_info *info;
++ struct i2c_client *client;
++ char clk_name[V4L2_SUBDEV_NAME_SIZE];
++ int ret;
++
++ /* allocate a new subdev and add match info to it */
++ info = devm_kzalloc(ici->v4l2_dev.dev, sizeof(struct soc_of_info),
++ GFP_KERNEL);
++ if (!info)
++ return -ENOMEM;
++
++ info->sasd.asd.match.of.node = remote;
++ info->sasd.asd.match_type = V4L2_ASYNC_MATCH_OF;
++ info->subdev = &info->sasd.asd;
++
++ /* Or shall this be managed by the soc-camera device? */
++ sasc = &info->sasc;
++
++ ret = rcar_vin_dyn_pdev(&sdesc, sasc);
++ if (ret < 0)
++ goto eallocpdev;
++
++ sasc->sensor = &info->sasd.asd;
++
++ icd = rcar_vin_add_pdev(sasc);
++ if (!icd) {
++ ret = -ENOMEM;
++ goto eaddpdev;
++ }
++
++ sasc->notifier.subdevs = &info->subdev;
++ sasc->notifier.num_subdevs = 1;
++ sasc->notifier.bound = rcar_vin_async_bound;
++ sasc->notifier.unbind = rcar_vin_async_unbind;
++ sasc->notifier.complete = rcar_vin_async_complete;
++
++ priv->async_client = sasc;
++
++ client = of_find_i2c_device_by_node(remote);
++
++ if (client)
++ snprintf(clk_name, sizeof(clk_name), "%d-%04x",
++ client->adapter->nr, client->addr);
++ else
++ snprintf(clk_name, sizeof(clk_name), "of-%s",
++ of_node_full_name(remote));
++
++ ret = v4l2_async_notifier_register(&ici->v4l2_dev, &sasc->notifier);
++ if (!ret)
++ return 0;
++
++ platform_device_del(sasc->pdev);
++eaddpdev:
++ platform_device_put(sasc->pdev);
++eallocpdev:
++ devm_kfree(ici->v4l2_dev.dev, info);
++ dev_err(ici->v4l2_dev.dev, "group probe failed: %d\n", ret);
++
++ return ret;
++}
++
++static int rcar_vin_probe(struct platform_device *pdev)
++{
++ const struct of_device_id *match = NULL;
++ struct rcar_vin_priv *priv;
++ struct v4l2_of_endpoint ep;
++ struct device_node *np;
++ struct resource *mem;
++ unsigned int pdata_flags;
++ int irq, ret;
++ const char *str;
++ unsigned int i;
++ struct device_node *epn = NULL, *ren = NULL;
++ bool csi_use = false;
++
++ match = of_match_device(of_match_ptr(rcar_vin_of_table), &pdev->dev);
++
++ np = of_graph_get_next_endpoint(pdev->dev.of_node, NULL);
++ if (!np) {
++ dev_err(&pdev->dev, "could not find endpoint\n");
++ return -EINVAL;
++ }
++
++ for (i = 0; ; i++) {
++ epn = of_graph_get_next_endpoint(pdev->dev.of_node,
++ epn);
++ if (!epn)
++ break;
++
++ ren = of_graph_get_remote_port(epn);
++ if (!ren) {
++ dev_notice(&pdev->dev, "no remote for %s\n",
++ of_node_full_name(epn));
++ continue;
++ }
++
++ /* so we now have a remote node to connect */
++ dev_dbg(&pdev->dev, "node name:%s\n",
++ of_node_full_name(ren->parent));
++
++ if (strcmp(ren->parent->name, "csi2") == 0)
++ csi_use = true;
++
++ of_node_put(ren);
++
++ if (i)
++ break;
++ }
++
++ ret = v4l2_of_parse_endpoint(np, &ep);
++ if (ret) {
++ dev_err(&pdev->dev, "could not parse endpoint\n");
++ return ret;
++ }
++
++ if (ep.bus_type == V4L2_MBUS_BT656)
++ pdata_flags = RCAR_VIN_BT656;
++ else if (ep.bus_type == V4L2_MBUS_CSI2)
++ pdata_flags = RCAR_VIN_BT656 | RCAR_VIN_CSI2;
++ else {
++ pdata_flags = 0;
++ if (ep.bus.parallel.flags & V4L2_MBUS_HSYNC_ACTIVE_LOW)
++ pdata_flags |= RCAR_VIN_HSYNC_ACTIVE_LOW;
++ if (ep.bus.parallel.flags & V4L2_MBUS_VSYNC_ACTIVE_LOW)
++ pdata_flags |= RCAR_VIN_VSYNC_ACTIVE_LOW;
++ }
++
++ of_node_put(np);
++
++ dev_dbg(&pdev->dev, "pdata_flags = %08x\n", pdata_flags);
++
++ mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
++ if (mem == NULL)
++ return -EINVAL;
++
++ irq = platform_get_irq(pdev, 0);
++ if (irq <= 0)
++ return -EINVAL;
++
++ priv = devm_kzalloc(&pdev->dev, sizeof(struct rcar_vin_priv),
++ GFP_KERNEL);
++ if (!priv)
++ return -ENOMEM;
++
++ priv->base = devm_ioremap_resource(&pdev->dev, mem);
++ if (IS_ERR(priv->base))
++ return PTR_ERR(priv->base);
++
++ ret = devm_request_irq(&pdev->dev, irq, rcar_vin_irq, IRQF_SHARED,
++ dev_name(&pdev->dev), priv);
++ if (ret)
++ return ret;
++
++ priv->ici.priv = priv;
++ priv->ici.v4l2_dev.dev = &pdev->dev;
++ priv->ici.drv_name = dev_name(&pdev->dev);
++ priv->ici.ops = &rcar_vin_host_ops;
++ priv->csi_sync = false;
++
++ priv->pdata_flags = pdata_flags;
++ if (!match) {
++ priv->ici.nr = pdev->id;
++ priv->chip = pdev->id_entry->driver_data;
++ } else {
++ priv->ici.nr = of_alias_get_id(pdev->dev.of_node, "vin");
++ priv->chip = (enum chip_id)match->data;
++ }
++
++ if (priv->chip == RCAR_H3 || priv->chip == RCAR_M3) {
++ priv->max_width = 4096;
++ priv->max_height = 4096;
++ } else {
++ priv->max_width = 2048;
++ priv->max_height = 2048;
++ }
++
++ if (priv->chip == RCAR_H3 || priv->chip == RCAR_M3) {
++ u32 ifmd = 0;
++ bool match_flag = false;
++ const struct vin_gen3_ifmd *gen3_ifmd_table = NULL;
++ int vc, num;
++
++ num = VNCSI_IFMD_SEL_NUMBER;
++
++ if (strcmp(dev_name(priv->ici.v4l2_dev.dev),
++ "e6ef0000.video") == 0)
++ priv->index = RCAR_VIDEO_0;
++ else if (strcmp(dev_name(priv->ici.v4l2_dev.dev),
++ "e6ef1000.video") == 0)
++ priv->index = RCAR_VIDEO_1;
++ else if (strcmp(dev_name(priv->ici.v4l2_dev.dev),
++ "e6ef2000.video") == 0)
++ priv->index = RCAR_VIDEO_2;
++ else if (strcmp(dev_name(priv->ici.v4l2_dev.dev),
++ "e6ef3000.video") == 0)
++ priv->index = RCAR_VIDEO_3;
++ else if (strcmp(dev_name(priv->ici.v4l2_dev.dev),
++ "e6ef4000.video") == 0)
++ priv->index = RCAR_VIDEO_4;
++ else if (strcmp(dev_name(priv->ici.v4l2_dev.dev),
++ "e6ef5000.video") == 0)
++ priv->index = RCAR_VIDEO_5;
++ else if (strcmp(dev_name(priv->ici.v4l2_dev.dev),
++ "e6ef6000.video") == 0)
++ priv->index = RCAR_VIDEO_6;
++ else if (strcmp(dev_name(priv->ici.v4l2_dev.dev),
++ "e6ef7000.video") == 0)
++ priv->index = RCAR_VIDEO_7;
++ else
++ priv->index = RCAR_VIN_CH_NONE;
++
++ ret = of_property_read_string(np, "csi,select", &str);
++ if (ret) {
++ dev_err(&pdev->dev, "could not parse csi,select\n");
++ return ret;
++ }
++
++ if (strcmp(str, "csi40") == 0)
++ priv->csi_ch = RCAR_CSI40;
++ else if (strcmp(str, "csi20") == 0)
++ priv->csi_ch = RCAR_CSI20;
++ else if (strcmp(str, "csi41") == 0)
++ priv->csi_ch = RCAR_CSI41;
++ else if (strcmp(str, "csi21") == 0)
++ priv->csi_ch = RCAR_CSI21;
++ else
++ priv->csi_ch = RCAR_CSI_CH_NONE;
++
++ ret = of_property_read_u32(np, "virtual,channel", &vc);
++ if (ret) {
++ dev_err(&pdev->dev,
++ "could not parse virtual,channel\n");
++ return ret;
++ }
++
++ if (vc == 0)
++ priv->vc = RCAR_VIRTUAL_CH0;
++ else if (vc == 1)
++ priv->vc = RCAR_VIRTUAL_CH1;
++ else if (vc == 2)
++ priv->vc = RCAR_VIRTUAL_CH2;
++ else if (vc == 3)
++ priv->vc = RCAR_VIRTUAL_CH3;
++ else
++ priv->vc = RCAR_VIRTUAL_NONE;
++
++ dev_dbg(&pdev->dev, "csi_ch:%d, vc:%d\n",
++ priv->csi_ch, priv->vc);
++
++ ifmd = VNCSI_IFMD_DES1 | VNCSI_IFMD_DES0;
++
++ if (priv->chip == RCAR_H3)
++ gen3_ifmd_table = vin_h3_vc_ifmd;
++ else if (priv->chip == RCAR_M3)
++ gen3_ifmd_table = vin_m3_vc_ifmd;
++
++ for (i = 0; i < num; i++) {
++ if ((gen3_ifmd_table[i].v_sel[priv->index].csi2_ch
++ == priv->csi_ch) &&
++ (gen3_ifmd_table[i].v_sel[priv->index].vc
++ == priv->vc)) {
++ if (priv->index < RCAR_VIDEO_4) {
++ if (ifmd0_init) {
++ ifmd0_reg_match[i] = true;
++ match_flag = true;
++ } else if (ifmd0_reg_match[i])
++ match_flag = true;
++ } else {
++ if (ifmd4_init) {
++ ifmd4_reg_match[i] = true;
++ match_flag = true;
++ } else if (ifmd4_reg_match[i])
++ match_flag = true;
++ }
++ } else {
++ if (priv->index < RCAR_VIDEO_4)
++ ifmd0_reg_match[i] = false;
++ else
++ ifmd4_reg_match[i] = false;
++ }
++ }
++ if (priv->index < RCAR_VIDEO_4)
++ ifmd0_init = false;
++ else
++ ifmd4_init = false;
++
++ if (!match_flag) {
++ dev_err(&pdev->dev,
++ "Not match, virtual channel pattern error.\n");
++ return -EINVAL;
++ }
++
++ rcar_vin_cpg_enable_for_ifmd(priv->index, true);
++
++ if (priv->index < RCAR_VIDEO_4) {
++ void __iomem *ifmd0_mem;
++
++ for (i = 0; i < num; i++) {
++ if (ifmd0_reg_match[i]) {
++ ifmd |= gen3_ifmd_table[i].set_reg;
++ break;
++ }
++ }
++
++ ifmd0_mem = ioremap(0xe6ef0000 + VNCSI_IFMD_REG, 0x04);
++ iowrite32(ifmd, ifmd0_mem);
++ iounmap(ifmd0_mem);
++ } else {
++ void __iomem *ifmd4_mem;
++
++ for (i = 0; i < num; i++) {
++ if (ifmd4_reg_match[i]) {
++ ifmd |= gen3_ifmd_table[i].set_reg;
++ break;
++ }
++ }
++
++ ifmd4_mem = ioremap(0xe6ef4000 + VNCSI_IFMD_REG, 0x04);
++ iowrite32(ifmd, ifmd4_mem);
++ iounmap(ifmd4_mem);
++ }
++
++ rcar_vin_cpg_enable_for_ifmd(priv->index, false);
++ }
++
++ spin_lock_init(&priv->lock);
++ INIT_LIST_HEAD(&priv->capture);
++
++ priv->state = STOPPED;
++
++ pm_suspend_ignore_children(&pdev->dev, true);
++ pm_runtime_enable(&pdev->dev);
++
++ ret = soc_camera_host_register(&priv->ici);
++ if (ret)
++ goto cleanup;
++
++ if (csi_use) {
++ ret = rcar_vin_soc_of_bind(priv, &priv->ici, epn, ren->parent);
++ if (ret)
++ goto cleanup;
++ }
++
++ vin_debug = 0;
++
++ return 0;
++
++cleanup:
++ pm_runtime_disable(&pdev->dev);
++
++ return ret;
++}
++
++static int rcar_vin_remove(struct platform_device *pdev)
++{
++ struct soc_camera_host *soc_host = to_soc_camera_host(&pdev->dev);
++ struct rcar_vin_priv *priv = container_of(soc_host,
++ struct rcar_vin_priv, ici);
++
++ platform_device_del(priv->async_client->pdev);
++ platform_device_put(priv->async_client->pdev);
++
++ v4l2_async_notifier_unregister(&priv->async_client->notifier);
++
++ soc_camera_host_unregister(soc_host);
++ pm_runtime_disable(&pdev->dev);
++
++ return 0;
++}
++
++#ifdef CONFIG_PM_SLEEP
++static int rcar_vin_suspend(struct device *dev)
++{
++ /* Empty function for now */
++ return 0;
++}
++
++static int rcar_vin_resume(struct device *dev)
++{
++ u32 ifmd = 0;
++ bool match_flag = false;
++ const struct vin_gen3_ifmd *gen3_ifmd_table = NULL;
++ int num;
++ unsigned int i;
++ struct soc_camera_host *soc_host = to_soc_camera_host(dev);
++ struct rcar_vin_priv *priv = container_of(soc_host,
++ struct rcar_vin_priv, ici);
++ num = VNCSI_IFMD_SEL_NUMBER;
++ ifmd0_init = true;
++ ifmd4_init = true;
++
++ if (priv->chip == RCAR_H3) {
++ ifmd = VNCSI_IFMD_DES1 | VNCSI_IFMD_DES0;
++ gen3_ifmd_table = vin_h3_vc_ifmd;
++ } else if (priv->chip == RCAR_M3) {
++ ifmd = VNCSI_IFMD_DES1;
++ gen3_ifmd_table = vin_m3_vc_ifmd;
++ }
++
++ for (i = 0; i < num; i++) {
++ if ((gen3_ifmd_table[i].v_sel[priv->index].csi2_ch
++ == priv->csi_ch) &&
++ (gen3_ifmd_table[i].v_sel[priv->index].vc
++ == priv->vc)) {
++ if (priv->index < RCAR_VIDEO_4) {
++ if (ifmd0_init) {
++ ifmd0_reg_match[i] = true;
++ match_flag = true;
++ } else if (ifmd0_reg_match[i])
++ match_flag = true;
++ } else {
++ if (ifmd4_init) {
++ ifmd4_reg_match[i] = true;
++ match_flag = true;
++ } else if (ifmd4_reg_match[i])
++ match_flag = true;
++ }
++ } else {
++ if (priv->index < RCAR_VIDEO_4)
++ ifmd0_reg_match[i] = false;
++ else
++ ifmd4_reg_match[i] = false;
++ }
++ }
++ if (priv->index < RCAR_VIDEO_4)
++ ifmd0_init = false;
++ else
++ ifmd4_init = false;
++
++ if (priv->index < RCAR_VIDEO_4) {
++ void __iomem *ifmd0_mem;
++
++ for (i = 0; i < num; i++) {
++ if (ifmd0_reg_match[i]) {
++ ifmd |= gen3_ifmd_table[i].set_reg;
++ break;
++ }
++ }
++
++ ifmd0_mem = ioremap(0xe6ef0000 + VNCSI_IFMD_REG, 0x04);
++ iowrite32(ifmd, ifmd0_mem);
++ iounmap(ifmd0_mem);
++ } else {
++ void __iomem *ifmd4_mem;
++
++ for (i = 0; i < num; i++) {
++ if (ifmd4_reg_match[i]) {
++ ifmd |= gen3_ifmd_table[i].set_reg;
++ break;
++ }
++ }
++
++ ifmd4_mem = ioremap(0xe6ef4000 + VNCSI_IFMD_REG, 0x04);
++ iowrite32(ifmd, ifmd4_mem);
++ iounmap(ifmd4_mem);
++ }
++
++ return 0;
++}
++
++static SIMPLE_DEV_PM_OPS(rcar_vin_pm_ops,
++ rcar_vin_suspend, rcar_vin_resume);
++#define DEV_PM_OPS (&rcar_vin_pm_ops)
++#else
++#define DEV_PM_OPS NULL
++#endif /* CONFIG_PM_SLEEP */
++
++static struct platform_driver rcar_vin_driver = {
++ .probe = rcar_vin_probe,
++ .remove = rcar_vin_remove,
++ .driver = {
++ .name = DRV_NAME,
++ .pm = DEV_PM_OPS,
++ .of_match_table = of_match_ptr(rcar_vin_of_table),
++ },
++};
++
++module_platform_driver(rcar_vin_driver);
++
++MODULE_LICENSE("GPL");
++MODULE_ALIAS("platform:rcar_vin");
++MODULE_DESCRIPTION("Renesas R-Car VIN camera host driver");
++MODULE_AUTHOR("Koji Matsuoka <koji.matsuoka.xm@renesas.com>");
+diff --git a/include/media/rcar_csi2.h b/include/media/rcar_csi2.h
+new file mode 100644
+index 0000000..1a040fa
+--- /dev/null
++++ b/include/media/rcar_csi2.h
+@@ -0,0 +1,66 @@
++/*
++ * include/media/rcar_csi2.h
++ * This file is the driver header
++ * for the Renesas R-Car MIPI CSI-2 unit.
++ *
++ * Copyright (C) 2015 Renesas Electronics Corporation
++ *
++ * This file is based on the include/media/sh_mobile_csi2.h
++ *
++ * Driver header for the SH-Mobile MIPI CSI-2 unit
++ *
++ * Copyright (C) 2010, Guennadi Liakhovetski <g.liakhovetski@gmx.de>
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License version 2 as
++ * published by the Free Software Foundation.
++ */
++
++#ifndef RCAR_MIPI_CSI
++#define RCAR_MIPI_CSI
++
++#include <linux/list.h>
++
++enum rcar_csi2_phy {
++ RCAR_CSI2_PHY_CSI40, /* CSI0 */
++ RCAR_CSI2_PHY_CSI20, /* CSI1 */
++ RCAR_CSI2_PHY_CSI41, /* CSI2 */
++ RCAR_CSI2_PHY_CSI21, /* CSI3 */
++};
++
++enum rcar_csi2_link {
++ RCAR_CSI2_LINK_CSI40,
++ RCAR_CSI2_LINK_CSI20,
++ RCAR_CSI2_LINK_CSI41,
++ RCAR_CSI2_LINK_CSI21,
++};
++
++enum rcar_csi2_type {
++ RCAR_CSI2_CSI4X,
++ RCAR_CSI2_CSI2X,
++};
++
++#define RCAR_CSI2_CRC (1 << 0)
++#define RCAR_CSI2_ECC (1 << 1)
++
++struct platform_device;
++
++struct rcar_csi2_client_config {
++ enum rcar_csi2_phy phy;
++ enum rcar_csi2_link link;
++ unsigned char lanes; /* bitmask[3:0] */
++ unsigned char channel; /* 0..3 */
++ struct platform_device *pdev; /* client platform device */
++ const char *name; /* async matching: client name */
++};
++
++struct v4l2_device;
++
++struct rcar_csi2_pdata {
++ enum rcar_csi2_type type;
++ unsigned int flags;
++ struct rcar_csi2_client_config *clients;
++ int num_clients;
++};
++
++#endif
+--
+1.9.1
+
diff --git a/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0018-arm64-renesas-r8a7797-Add-Renesas-R8A7797-SoC-suppor.patch b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0018-arm64-renesas-r8a7797-Add-Renesas-R8A7797-SoC-suppor.patch
new file mode 100644
index 0000000..f1a2cd6
--- /dev/null
+++ b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0018-arm64-renesas-r8a7797-Add-Renesas-R8A7797-SoC-suppor.patch
@@ -0,0 +1,5139 @@
+From e8fd03e53c50c67a2aebf19f39a9f14b583f0e2d Mon Sep 17 00:00:00 2001
+From: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+Date: Sun, 14 May 2017 14:48:08 +0300
+Subject: [PATCH] arm64: renesas: r8a7797: Add Renesas R8A7797 SoC support
+
+This adds Renesas R8A7797 SoC support
+
+Signed-off-by: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+---
+ arch/arm64/Kconfig.platforms | 6 +
+ arch/arm64/boot/dts/renesas/r8a7797.dtsi | 992 ++++++++++
+ drivers/clk/renesas/Kconfig | 1 +
+ drivers/clk/renesas/Makefile | 1 +
+ drivers/clk/renesas/r8a7797-cpg-mssr.c | 218 +++
+ drivers/clk/renesas/rcar-gen3-cpg.c | 41 +-
+ drivers/clk/renesas/rcar-gen3-cpg.h | 6 +
+ drivers/clk/renesas/renesas-cpg-mssr.c | 6 +
+ drivers/clk/renesas/renesas-cpg-mssr.h | 1 +
+ drivers/cpufreq/cpufreq-dt-platdev.c | 1 +
+ drivers/gpio/gpio-rcar.c | 6 +-
+ drivers/gpu/drm/rcar-du/rcar_du_drv.c | 25 +
+ drivers/gpu/drm/rcar-du/rcar_du_group.c | 12 +-
+ drivers/gpu/drm/rcar-du/rcar_du_lvdsenc.c | 38 +-
+ drivers/hwspinlock/rcar_hwspinlock.c | 8 +-
+ drivers/i2c/busses/i2c-rcar.c | 1 +
+ drivers/iommu/ipmmu-vmsa.c | 7 +-
+ drivers/media/platform/soc_camera/Kconfig | 2 +-
+ drivers/media/platform/soc_camera/rcar_csi2.c | 26 +-
+ drivers/media/platform/soc_camera/rcar_vin.c | 86 +-
+ drivers/media/platform/vsp1/vsp1_drv.c | 9 +
+ drivers/media/platform/vsp1/vsp1_lif.c | 12 +-
+ drivers/media/platform/vsp1/vsp1_regs.h | 7 +
+ drivers/mmc/host/sh_mobile_sdhi.c | 2 +
+ drivers/net/ethernet/renesas/ravb_main.c | 1 +
+ drivers/pinctrl/sh-pfc/Kconfig | 5 +
+ drivers/pinctrl/sh-pfc/Makefile | 1 +
+ drivers/pinctrl/sh-pfc/core.c | 7 +
+ drivers/pinctrl/sh-pfc/pfc-r8a7797.c | 2586 +++++++++++++++++++++++++
+ drivers/pinctrl/sh-pfc/sh_pfc.h | 12 +
+ drivers/soc/renesas/Makefile | 4 +
+ drivers/soc/renesas/r8a7797-sysc.c | 39 +
+ drivers/soc/renesas/rcar-rst.c | 1 +
+ drivers/soc/renesas/rcar-sysc.c | 3 +
+ drivers/soc/renesas/rcar-sysc.h | 1 +
+ drivers/soc/renesas/rcar_ems_ctrl.c | 10 +
+ drivers/soc/renesas/renesas-soc.c | 8 +
+ drivers/spi/spi-sh-msiof.c | 4 +-
+ drivers/thermal/rcar_gen3_thermal.c | 29 +
+ include/dt-bindings/clock/r8a7797-cpg-mssr.h | 48 +
+ include/dt-bindings/power/r8a7797-sysc.h | 32 +
+ 41 files changed, 4275 insertions(+), 30 deletions(-)
+ create mode 100644 arch/arm64/boot/dts/renesas/r8a7797.dtsi
+ create mode 100644 drivers/clk/renesas/r8a7797-cpg-mssr.c
+ create mode 100644 drivers/pinctrl/sh-pfc/pfc-r8a7797.c
+ create mode 100644 drivers/soc/renesas/r8a7797-sysc.c
+ create mode 100644 include/dt-bindings/clock/r8a7797-cpg-mssr.h
+ create mode 100644 include/dt-bindings/power/r8a7797-sysc.h
+
+diff --git a/arch/arm64/Kconfig.platforms b/arch/arm64/Kconfig.platforms
+index 7c104ca..9380fc6 100644
+--- a/arch/arm64/Kconfig.platforms
++++ b/arch/arm64/Kconfig.platforms
+@@ -160,6 +160,12 @@ config ARCH_R8A7796
+ help
+ This enables support for the Renesas R-Car M3-W SoC.
+
++config ARCH_R8A7797
++ bool "Renesas R-Car V3M SoC Platform"
++ depends on ARCH_RENESAS
++ help
++ This enables support for the Renesas R-Car V3M SoC.
++
+ config ARCH_STRATIX10
+ bool "Altera's Stratix 10 SoCFPGA Family"
+ help
+diff --git a/arch/arm64/boot/dts/renesas/r8a7797.dtsi b/arch/arm64/boot/dts/renesas/r8a7797.dtsi
+new file mode 100644
+index 0000000..5bd447a
+--- /dev/null
++++ b/arch/arm64/boot/dts/renesas/r8a7797.dtsi
+@@ -0,0 +1,992 @@
++/*
++ * Device Tree Source for the r8a7797 SoC
++ *
++ * Copyright (C) 2016 - 2017 Renesas Electronics Corp.
++ *
++ * This file is licensed under the terms of the GNU General Public License
++ * version 2. This program is licensed "as is" without any warranty of any
++ * kind, whether express or implied.
++ */
++
++#include <dt-bindings/clock/r8a7797-cpg-mssr.h>
++#include <dt-bindings/interrupt-controller/arm-gic.h>
++#include <dt-bindings/power/r8a7797-sysc.h>
++
++/ {
++ compatible = "renesas,r8a7797";
++ #address-cells = <2>;
++ #size-cells = <2>;
++
++ aliases {
++ csi2_40 = &csi2_40;
++ i2c0 = &i2c0;
++ i2c1 = &i2c1;
++ i2c2 = &i2c2;
++ i2c3 = &i2c3;
++ i2c4 = &i2c4;
++ spi1 = &msiof0;
++ spi2 = &msiof1;
++ spi3 = &msiof2;
++ spi4 = &msiof3;
++ vin0 = &vin0;
++ vin1 = &vin1;
++ vin2 = &vin2;
++ vin3 = &vin3;
++ tsc0 = &tsc1;
++ };
++
++ psci {
++ compatible = "arm,psci-1.0";
++ method = "smc";
++ };
++
++ cpus {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ a53_0: cpu@0 {
++ compatible = "arm,cortex-a53", "arm,armv8";
++ reg = <0x0>;
++ device_type = "cpu";
++ power-domains = <&sysc R8A7797_PD_CA53_CPU0>;
++ next-level-cache = <&L2_CA53>;
++ enable-method = "psci";
++ cpu-idle-states = <&CPU_SLEEP_0>;
++ #cooling-cells = <2>;
++ dynamic-power-coefficient = <277>;
++ cooling-min-level = <0>;
++ cooling-max-level = <2>;
++ clocks =<&cpg CPG_CORE R8A7797_CLK_Z2>;
++ operating-points-v2 = <&cluster0_opp_tb0>;
++ /*cpu-supply = <&vdd_dvfs>;*/
++ };
++
++ a53_1: cpu@1 {
++ compatible = "arm,cortex-a53","arm,armv8";
++ reg = <0x1>;
++ device_type = "cpu";
++ power-domains = <&sysc R8A7797_PD_CA53_CPU1>;
++ next-level-cache = <&L2_CA53>;
++ enable-method = "psci";
++ cpu-idle-states = <&CPU_SLEEP_0>;
++ operating-points-v2 = <&cluster0_opp_tb0>;
++ };
++
++ idle-states {
++ entry-method = "psci";
++
++ CPU_SLEEP_0: cpu-sleep-0 {
++ compatible = "arm,idle-state";
++ arm,psci-suspend-param = <0x0010000>;
++ local-timer-stop;
++ entry-latency-us = <639>;
++ exit-latency-us = <680>;
++ min-residency-us = <1088>;
++ status = "disabled";
++ };
++ };
++ };
++
++ L2_CA53: cache-controller@1 {
++ compatible = "cache";
++ power-domains = <&sysc R8A7797_PD_CA53_SCU>;
++ cache-unified;
++ cache-level = <2>;
++ };
++
++ cluster0_opp_tb0: opp_table0 {
++ compatible = "operating-points-v2";
++ opp-shared;
++
++ opp@800000000 {
++ opp-hz = /bits/ 64 <800000000>;
++ opp-microvolt = <850000>;
++ clock-latency-ns = <300000>;
++ };
++ };
++
++ extal_clk: extal {
++ compatible = "fixed-clock";
++ #clock-cells = <0>;
++ /* This value must be overridden by the board */
++ clock-frequency = <0>;
++ };
++
++ extalr_clk: extalr {
++ compatible = "fixed-clock";
++ #clock-cells = <0>;
++ /* This value must be overridden by the board */
++ clock-frequency = <0>;
++ };
++
++ /* External CAN clock - to be overridden by boards that provide it */
++ can_clk: can {
++ compatible = "fixed-clock";
++ #clock-cells = <0>;
++ clock-frequency = <0>;
++ };
++
++ /* External SCIF clock - to be overridden by boards that provide it */
++ scif_clk: scif {
++ compatible = "fixed-clock";
++ #clock-cells = <0>;
++ clock-frequency = <0>;
++ };
++
++ /* DU input dot clock - tob be overriden by boards that probide it */
++ du_dotclkin0: dclkin-0 {
++ compatible = "fixed-clock";
++ #clock-cells = <0>;
++ clock-frequency = <148500000>;
++ };
++
++ soc {
++ compatible = "simple-bus";
++ interrupt-parent = <&gic>;
++
++ #address-cells = <2>;
++ #size-cells = <2>;
++ ranges;
++
++ gic: interrupt-controller@0xf1010000 {
++ compatible = "arm,gic-400";
++ #interrupt-cells = <3>;
++ #address-cells = <0>;
++ interrupt-controller;
++ reg = <0x0 0xf1010000 0 0x1000>,
++ <0x0 0xf1020000 0 0x20000>,
++ <0x0 0xf1040000 0 0x20000>,
++ <0x0 0xf1060000 0 0x20000>;
++ interrupts = <GIC_PPI 9
++ (GIC_CPU_MASK_SIMPLE(8) | IRQ_TYPE_LEVEL_HIGH)>; /* PPI9:Virtual maintenance interrupt */
++/* clocks = <&cpg CPG_MOD 408>;
++ clock-names = "clk";
++ power-domains = <&sysc R8A7797_PD_ALWAYS_ON>; */
++ };
++
++ gpio0: gpio@e6050000 {
++ compatible = "renesas,gpio-r8a7797",
++ "renesas,gpio-rcar";
++ reg = <0 0xe6050000 0 0x50>;
++ interrupts = <GIC_SPI 4 IRQ_TYPE_LEVEL_HIGH>; /* SPI4:GPIO.ch0 */
++ #gpio-cells = <2>;
++ gpio-controller;
++ gpio-ranges = <&pfc 0 0 22>;
++ #interrupt-cells = <2>;
++ interrupt-controller;
++ clocks = <&cpg CPG_MOD 912>; /* RMSTPCR9/bit12:GPIO0 */
++ power-domains = <&sysc R8A7797_PD_ALWAYS_ON>;
++ };
++
++ gpio1: gpio@e6051000 {
++ compatible = "renesas,gpio-r8a7797",
++ "renesas,gpio-rcar";
++ reg = <0 0xe6051000 0 0x50>;
++ interrupts = <GIC_SPI 5 IRQ_TYPE_LEVEL_HIGH>; /* SPI5:GPIO.ch1 */
++ #gpio-cells = <2>;
++ gpio-controller;
++ gpio-ranges = <&pfc 0 32 28>;
++ #interrupt-cells = <2>;
++ interrupt-controller;
++ clocks = <&cpg CPG_MOD 911>; /* RMSTPCR9/bit11:GPIO1 */
++ power-domains = <&sysc R8A7797_PD_ALWAYS_ON>;
++ };
++
++ gpio2: gpio@e6052000 {
++ compatible = "renesas,gpio-r8a7797",
++ "renesas,gpio-rcar";
++ reg = <0 0xe6052000 0 0x50>;
++ interrupts = <GIC_SPI 6 IRQ_TYPE_LEVEL_HIGH>; /* SPI6:GPIO.ch2 */
++ #gpio-cells = <2>;
++ gpio-controller;
++ gpio-ranges = <&pfc 0 64 17>;
++ #interrupt-cells = <2>;
++ interrupt-controller;
++ clocks = <&cpg CPG_MOD 910>; /* RMSTPCR9/bit10:GPIO2 */
++ power-domains = <&sysc R8A7797_PD_ALWAYS_ON>;
++ };
++
++ gpio3: gpio@e6053000 {
++ compatible = "renesas,gpio-r8a7797",
++ "renesas,gpio-rcar";
++ reg = <0 0xe6053000 0 0x50>;
++ interrupts = <GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH>; /* SPI7:GPIO.ch3 */
++ #gpio-cells = <2>;
++ gpio-controller;
++ gpio-ranges = <&pfc 0 96 17>;
++ #interrupt-cells = <2>;
++ interrupt-controller;
++ clocks = <&cpg CPG_MOD 909>; /* RMSTPCR9/bit9:GPIO3 */
++ power-domains = <&sysc R8A7797_PD_ALWAYS_ON>;
++ };
++
++ gpio4: gpio@e6054000 {
++ compatible = "renesas,gpio-r8a7797",
++ "renesas,gpio-rcar";
++ reg = <0 0xe6054000 0 0x50>;
++ interrupts = <GIC_SPI 8 IRQ_TYPE_LEVEL_HIGH>; /* SPI8:GPIO.ch4 */
++ #gpio-cells = <2>;
++ gpio-controller;
++ gpio-ranges = <&pfc 0 128 6>;
++ #interrupt-cells = <2>;
++ interrupt-controller;
++ clocks = <&cpg CPG_MOD 908>; /* RMSTPCR9/bit8:GPIO4 */
++ power-domains = <&sysc R8A7797_PD_ALWAYS_ON>;
++ };
++
++ gpio5: gpio@e6055000 {
++ compatible = "renesas,gpio-r8a7797",
++ "renesas,gpio-rcar";
++ reg = <0 0xe6055000 0 0x50>;
++ interrupts = <GIC_SPI 9 IRQ_TYPE_LEVEL_HIGH>; /* SPI9:GPIO.ch5 */
++ #gpio-cells = <2>;
++ gpio-controller;
++ gpio-ranges = <&pfc 0 160 15>;
++ #interrupt-cells = <2>;
++ interrupt-controller;
++ clocks = <&cpg CPG_MOD 907>; /* RMSTPCR9/bit7:GPIO5 */
++ power-domains = <&sysc R8A7797_PD_ALWAYS_ON>;
++ };
++
++ pmu_a53 {
++ compatible = "arm,cortex-a53-pmu";
++ interrupts = <GIC_SPI 84 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 85 IRQ_TYPE_LEVEL_HIGH>; /* SPI84:AP-System Core.CA53core0 pmu, SPI85:AP-System Core.CA53core1 pmu */
++ interrupt-affinity = <&a53_0>,
++ <&a53_1>;
++ };
++
++ timer {
++ compatible = "arm,armv8-timer";
++ interrupts = <GIC_PPI 13
++ (GIC_CPU_MASK_SIMPLE(8) | IRQ_TYPE_LEVEL_LOW)>,
++ <GIC_PPI 14
++ (GIC_CPU_MASK_SIMPLE(8) | IRQ_TYPE_LEVEL_LOW)>,
++ <GIC_PPI 11
++ (GIC_CPU_MASK_SIMPLE(8) | IRQ_TYPE_LEVEL_LOW)>,
++ <GIC_PPI 10
++ (GIC_CPU_MASK_SIMPLE(8) | IRQ_TYPE_LEVEL_LOW)>; /* PPI13:Secure physical timer, PPI14:Non-secure physical timer,
++ PPI11:Virtual timer, PPI10:Hypervisor timer */
++ };
++
++ wdt0: wdt@e6020000 {
++ compatible = "renesas,r8a7797-wdt", "renesas,rcar-gen3-wdt";
++ reg = <0 0xe6020000 0 0x0c>;
++ clocks = <&cpg CPG_MOD 402>; /* RMSTPCR4/bit2:RWDT */
++ power-domains = <&sysc R8A7797_PD_ALWAYS_ON>;
++ status = "disabled";
++ };
++
++ cpg: clock-controller@e6150000 {
++ compatible = "renesas,r8a7797-cpg-mssr";
++ reg = <0 0xe6150000 0 0x1000>;
++ clocks = <&extal_clk>, <&extalr_clk>;
++ clock-names = "extal", "extalr";
++ #clock-cells = <2>;
++ #power-domain-cells = <0>;
++ };
++
++ csi2_40: csi2@feaa0000 {
++ compatible = "renesas,r8a7797-csi2";
++ reg = <0 0xfeaa0000 0 0x10000>;
++ interrupts = <GIC_SPI 246 IRQ_TYPE_LEVEL_HIGH>; /* SPI246:CSI2.ch2 */
++ clocks = <&cpg CPG_MOD 716>; /* RMSTPCR7/bit16:CSI40 */
++ power-domains = <&sysc R8A7797_PD_ALWAYS_ON>;
++ status = "disabled";
++ };
++
++ prr: chipid@fff00044 {
++ compatible = "renesas,prr";
++ reg = <0 0xfff00044 0 4>;
++ };
++
++ rst: reset-controller@e6160000 {
++ compatible = "renesas,r8a7797-rst";
++ reg = <0 0xe6160000 0 0x0200>;
++ };
++
++ sysc: system-controller@e6180000 {
++ compatible = "renesas,r8a7797-sysc";
++ reg = <0 0xe6180000 0 0x0440>;
++ #power-domain-cells = <1>;
++ };
++
++ pfc: pfc@e6060000 {
++ compatible = "renesas,pfc-r8a7797";
++ reg = <0 0xe6060000 0 0x50c>;
++ };
++
++ intc_ex: interrupt-controller@e61c0000 {
++ compatible = "renesas,intc-ex-r8a7797", "renesas,irqc";
++ #interrupt-cells = <2>;
++ interrupt-controller;
++ reg = <0 0xe61c0000 0 0x200>;
++ interrupts = <GIC_SPI 0 IRQ_TYPE_LEVEL_HIGH
++ GIC_SPI 1 IRQ_TYPE_LEVEL_HIGH
++ GIC_SPI 2 IRQ_TYPE_LEVEL_HIGH
++ GIC_SPI 3 IRQ_TYPE_LEVEL_HIGH
++ GIC_SPI 18 IRQ_TYPE_LEVEL_HIGH
++ GIC_SPI 161 IRQ_TYPE_LEVEL_HIGH>; /* SPI1:IRQ1, SPI2:IRQ2, SPI3:IRQ3, SPI18:IRQ4, SPI161:IRQ5 */
++ clocks = <&cpg CPG_MOD 407>; /* RMSTPCR4/bit7:INTC-EX */
++ power-domains = <&sysc R8A7797_PD_ALWAYS_ON>;
++ };
++
++ ipmmu_vi: mmu@febd0000 {
++ compatible = "renesas,ipmmu-r8a7797";
++ reg = <0 0xfebd0000 0 0x1000>; /* IPMMU-VI */
++ renesas,ipmmu-main = <&ipmmu_mm 11>;
++ #iommu-cells = <1>;
++ status = "disabled";
++ };
++
++ ipmmu_ir: mmu@ff8b0000 {
++ compatible = "renesas,ipmmu-r8a7797";
++ reg = <0 0xff8b0000 0 0x1000>; /* IPMMU-IR */
++ renesas,ipmmu-main = <&ipmmu_mm 3>;
++ #iommu-cells = <1>;
++ status = "disabled";
++ };
++
++ ipmmu_rt: mmu@ffc80000 {
++ compatible = "renesas,ipmmu-r8a7797";
++ reg = <0 0xffc80000 0 0x1000>; /* IPMMU-RT */
++ renesas,ipmmu-main = <&ipmmu_mm 7>;
++ #iommu-cells = <1>;
++ status = "disabled";
++ };
++
++ ipmmu_ds0: mmu@e6740000 {
++ compatible = "renesas,ipmmu-r8a7797";
++ reg = <0 0xe6740000 0 0x1000>; /* IPMMU-DS0 */
++ renesas,ipmmu-main = <&ipmmu_mm 0>;
++ #iommu-cells = <1>;
++ status = "disabled";
++ };
++
++ ipmmu_mm: mmu@e67b0000 {
++ compatible = "renesas,ipmmu-r8a7797";
++ reg = <0 0xe67b0000 0 0x1000>; /* IPMMU-MM */
++ interrupts = <GIC_SPI 196 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 197 IRQ_TYPE_LEVEL_HIGH>; /* SPI196:IPMMU, SPI197:IPMMU sec */
++ #iommu-cells = <1>;
++ status = "disabled";
++ };
++
++ dmac1: dma-controller@e7300000 {
++ compatible = "renesas,dmac-r8a7797",
++ "renesas,rcar-dmac";
++ reg = <0 0xe7300000 0 0x10000>;
++ interrupts = <GIC_SPI 220 IRQ_TYPE_LEVEL_HIGH
++ GIC_SPI 216 IRQ_TYPE_LEVEL_HIGH
++ GIC_SPI 217 IRQ_TYPE_LEVEL_HIGH
++ GIC_SPI 218 IRQ_TYPE_LEVEL_HIGH
++ GIC_SPI 219 IRQ_TYPE_LEVEL_HIGH
++ GIC_SPI 308 IRQ_TYPE_LEVEL_HIGH
++ GIC_SPI 309 IRQ_TYPE_LEVEL_HIGH
++ GIC_SPI 310 IRQ_TYPE_LEVEL_HIGH
++ GIC_SPI 311 IRQ_TYPE_LEVEL_HIGH>; /* SPI220::SYS-DMAC1 err,
++ SPI216~219:SYS-DMAC1.ch0~SYS-DMAC1.ch3,
++ SPI308~311:SYS-DMAC1.ch4~SYS-DMAC1.ch7 */
++ interrupt-names = "error",
++ "ch0", "ch1", "ch2", "ch3",
++ "ch4", "ch5", "ch6", "ch7";
++ clocks = <&cpg CPG_MOD 218>; /* RMSTPCR2/bit18:SYS-DMAC1 */
++ clock-names = "fck";
++ power-domains = <&sysc R8A7797_PD_ALWAYS_ON>;
++ #dma-cells = <1>;
++ dma-channels = <8>;
++ iommus = <&ipmmu_ds0 0>, <&ipmmu_ds0 1>,
++ <&ipmmu_ds0 2>, <&ipmmu_ds0 3>,
++ <&ipmmu_ds0 4>, <&ipmmu_ds0 5>,
++ <&ipmmu_ds0 6>, <&ipmmu_ds0 7>; /* @@ */
++ };
++
++ dmac2: dma-controller@e7310000 {
++ compatible = "renesas,dmac-r8a7797",
++ "renesas,rcar-dmac";
++ reg = <0 0xe7310000 0 0x10000>;
++ interrupts = <GIC_SPI 307 IRQ_TYPE_LEVEL_HIGH
++ GIC_SPI 312 IRQ_TYPE_LEVEL_HIGH
++ GIC_SPI 313 IRQ_TYPE_LEVEL_HIGH
++ GIC_SPI 314 IRQ_TYPE_LEVEL_HIGH
++ GIC_SPI 315 IRQ_TYPE_LEVEL_HIGH
++ GIC_SPI 316 IRQ_TYPE_LEVEL_HIGH
++ GIC_SPI 317 IRQ_TYPE_LEVEL_HIGH
++ GIC_SPI 318 IRQ_TYPE_LEVEL_HIGH
++ GIC_SPI 319 IRQ_TYPE_LEVEL_HIGH>; /* SPI307::SYS-DMAC2 err,
++ SPI312~319:SYS-DMAC2.ch0~SYS-DMAC1.ch7 */
++ interrupt-names = "error",
++ "ch0", "ch1", "ch2", "ch3",
++ "ch4", "ch5", "ch6", "ch7";
++ clocks = <&cpg CPG_MOD 217>; /* RMSTPCR2/bit17:SYS-DMAC2 */
++ clock-names = "fck";
++ power-domains = <&sysc R8A7797_PD_ALWAYS_ON>;
++ #dma-cells = <1>;
++ dma-channels = <8>;
++ iommus = <&ipmmu_ds0 16>, <&ipmmu_ds0 17>,
++ <&ipmmu_ds0 18>, <&ipmmu_ds0 19>,
++ <&ipmmu_ds0 20>, <&ipmmu_ds0 21>,
++ <&ipmmu_ds0 22>, <&ipmmu_ds0 23>; /* @@ */
++ };
++
++ avb: ethernet@e6800000 {
++ compatible = "renesas,etheravb-r8a7797",
++ "renesas,etheravb-rcar-gen3";
++ reg = <0 0xe6800000 0 0x800>, <0 0xe6a00000 0 0x10000>;
++ interrupts = <GIC_SPI 39 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 40 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 41 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 42 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 43 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 44 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 45 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 46 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 47 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 48 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 49 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 50 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 51 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 52 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 53 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 54 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 55 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 56 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 57 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 58 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 59 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 60 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 61 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 62 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 63 IRQ_TYPE_LEVEL_HIGH>; /* SPI39~63:Ethernet AVB.ch0~24 */
++ /* @@ errreq_avb_p[0]~[3] add (T.B.D) */
++ interrupt-names = "ch0", "ch1", "ch2", "ch3",
++ "ch4", "ch5", "ch6", "ch7",
++ "ch8", "ch9", "ch10", "ch11",
++ "ch12", "ch13", "ch14", "ch15",
++ "ch16", "ch17", "ch18", "ch19",
++ "ch20", "ch21", "ch22", "ch23",
++ "ch24";
++ clocks = <&cpg CPG_MOD 812>; /* RMSTPCR8/bit12:EAVB-IF */
++ power-domains = <&sysc R8A7797_PD_ALWAYS_ON>;
++ phy-mode = "rgmii-id";
++ #address-cells = <1>;
++ #size-cells = <0>;
++ };
++
++ /* Future
++ canfd: canfd@e66c0000 {
++ compatible = "renesas,r8a7797-canfd",
++ "renesas,rcar-gen3-canfd";
++ reg = <0 0xe66c0000 0 0x8000>;
++ interrupts = <GIC_SPI 29 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 30 IRQ_TYPE_LEVEL_HIGH>; ** SPI29:CAN-FD channel, SPI30:CAN-FD global **
++ clocks = <&cpg CPG_MOD 914>,
++ <&cpg CPG_CORE R8A7797_CLK_CANFD>,
++ <&can_clk>; ** RMSTPCR9/bit14:CAN-FD **
++ clock-names = "fck", "canfd", "can_clk";
++ assigned-clocks = <&cpg CPG_CORE R8A7797_CLK_CANFD>;
++ assigned-clock-rates = <40000000>;
++ power-domains = <&cpg>;
++ status = "disabled";
++
++ channel0 {
++ status = "disabled";
++ };
++
++ channel1 {
++ status = "disabled";
++ };
++ }; */
++
++ pwm0: pwm@e6e30000 {
++ compatible = "renesas,pwm-r8a7797", "renesas,pwm-rcar";
++ reg = <0 0xe6e30000 0 0x10>;
++ #pwm-cells = <2>;
++ clocks = <&cpg CPG_MOD 523>; /* RMSTPCR5/bit23:PWM */
++ power-domains = <&sysc R8A7797_PD_ALWAYS_ON>;
++ status = "disabled";
++ };
++
++ pwm1: pwm@e6e31000 {
++ compatible = "renesas,pwm-r8a7797", "renesas,pwm-rcar";
++ reg = <0 0xe6e31000 0 0x10>;
++ #pwm-cells = <2>;
++ clocks = <&cpg CPG_MOD 523>; /* RMSTPCR5/bit23:PWM */
++ power-domains = <&sysc R8A7797_PD_ALWAYS_ON>;
++ status = "disabled";
++ };
++
++ pwm2: pwm@e6e32000 {
++ compatible = "renesas,pwm-r8a7797", "renesas,pwm-rcar";
++ reg = <0 0xe6e32000 0 0x10>;
++ #pwm-cells = <2>;
++ clocks = <&cpg CPG_MOD 523>; /* RMSTPCR5/bit23:PWM */
++ power-domains = <&sysc R8A7797_PD_ALWAYS_ON>;
++ status = "disabled";
++ };
++
++ pwm3: pwm@e6e33000 {
++ compatible = "renesas,pwm-r8a7797", "renesas,pwm-rcar";
++ reg = <0 0xe6e33000 0 0x10>;
++ #pwm-cells = <2>;
++ clocks = <&cpg CPG_MOD 523>; /* RMSTPCR5/bit23:PWM */
++ power-domains = <&sysc R8A7797_PD_ALWAYS_ON>;
++ status = "disabled";
++ };
++
++ pwm4: pwm@e6e34000 {
++ compatible = "renesas,pwm-r8a7797", "renesas,pwm-rcar";
++ reg = <0 0xe6e34000 0 0x10>;
++ #pwm-cells = <2>;
++ clocks = <&cpg CPG_MOD 523>; /* RMSTPCR5/bit23:PWM */
++ power-domains = <&sysc R8A7797_PD_ALWAYS_ON>;
++ status = "disabled";
++ };
++
++ hscif0: serial@e6540000 {
++ compatible = "renesas,hscif-r8a7797",
++ "renesas,rcar-gen3-hscif",
++ "renesas,hscif";
++ reg = <0 0xe6540000 0 96>;
++ interrupts = <GIC_SPI 154 IRQ_TYPE_LEVEL_HIGH>; /* SPI154:HSCIF.ch0 */
++ clocks = <&cpg CPG_MOD 520>,
++ <&cpg CPG_CORE R8A7797_CLK_S2D1>,
++ <&scif_clk>; /* RMSTPCR5/bit20:HSCIF0 */
++ clock-names = "fck", "brg_int", "scif_clk";
++ dmas = <&dmac1 0x31>, <&dmac1 0x30>;
++ dma-names = "tx", "rx";
++ power-domains = <&sysc R8A7797_PD_ALWAYS_ON>;
++ status = "disabled";
++ };
++
++ hscif1: serial@e6550000 {
++ compatible = "renesas,hscif-r8a7797",
++ "renesas,rcar-gen3-hscif",
++ "renesas,hscif";
++ reg = <0 0xe6550000 0 96>;
++ interrupts = <GIC_SPI 155 IRQ_TYPE_LEVEL_HIGH>; /* SPI155:HSCIF.ch1 */
++ clocks = <&cpg CPG_MOD 519>,
++ <&cpg CPG_CORE R8A7797_CLK_S2D1>,
++ <&scif_clk>; /* RMSTPCR5/bit19:HSCIF1 */
++ clock-names = "fck", "brg_int", "scif_clk";
++ dmas = <&dmac1 0x33>, <&dmac1 0x32>;
++ dma-names = "tx", "rx";
++ power-domains = <&sysc R8A7797_PD_ALWAYS_ON>;
++ status = "disabled";
++ };
++
++ hscif2: serial@e6560000 {
++ compatible = "renesas,hscif-r8a7797",
++ "renesas,rcar-gen3-hscif",
++ "renesas,hscif";
++ reg = <0 0xe6560000 0 96>;
++ interrupts = <GIC_SPI 144 IRQ_TYPE_LEVEL_HIGH>; /* SPI144:HSCIF.ch2 */
++ clocks = <&cpg CPG_MOD 518>,
++ <&cpg CPG_CORE R8A7797_CLK_S2D1>,
++ <&scif_clk>; /* RMSTPCR5/bit18:HSCIF2 */
++ clock-names = "fck", "brg_int", "scif_clk";
++ dmas = <&dmac1 0x35>, <&dmac1 0x34>;
++ dma-names = "tx", "rx";
++ power-domains = <&sysc R8A7797_PD_ALWAYS_ON>;
++ status = "disabled";
++ };
++
++ hscif3: serial@e66a0000 {
++ compatible = "renesas,hscif-r8a7797",
++ "renesas,rcar-gen3-hscif",
++ "renesas,hscif";
++ reg = <0 0xe66a0000 0 96>;
++ interrupts = <GIC_SPI 145 IRQ_TYPE_LEVEL_HIGH>; /* SPI145:HSCIF.ch3 */
++ clocks = <&cpg CPG_MOD 517>,
++ <&cpg CPG_CORE R8A7797_CLK_S2D1>,
++ <&scif_clk>; /* RMSTPCR5/bit17:HSCIF3 */
++ clock-names = "fck", "brg_int", "scif_clk";
++ dmas = <&dmac1 0x37>, <&dmac1 0x36>;
++ dma-names = "tx", "rx";
++ power-domains = <&sysc R8A7797_PD_ALWAYS_ON>;
++ status = "disabled";
++ };
++
++ scif0: serial@e6e60000 {
++ compatible = "renesas,scif-r8a7797",
++ "renesas,rcar-gen3-scif", "renesas,scif";
++ reg = <0 0xe6e60000 0 64>;
++ interrupts = <GIC_SPI 152 IRQ_TYPE_LEVEL_HIGH>; /* SPI152:SCIF.ch0 */
++ clocks = <&cpg CPG_MOD 207>,
++ <&cpg CPG_CORE R8A7797_CLK_S2D1>,
++ <&scif_clk>; /* RMSTPCR2/bit7:SCIF0 */
++ /*clock-names = "fck", "sck", "brg_int", "scif_clk"; */
++ clock-names = "fck";
++ dmas = <&dmac1 0x51>, <&dmac1 0x50>;
++ dma-names = "tx", "rx";
++ power-domains = <&sysc R8A7797_PD_ALWAYS_ON>;
++ status = "disabled";
++ };
++
++ scif1: serial@e6e68000 {
++ compatible = "renesas,scif-r8a7797",
++ "renesas,rcar-gen3-scif", "renesas,scif";
++ reg = <0 0xe6e68000 0 64>;
++ interrupts = <GIC_SPI 153 IRQ_TYPE_LEVEL_HIGH>; /* SPI153:SCIF.ch1 */
++ clocks = <&cpg CPG_MOD 206>,
++ <&cpg CPG_CORE R8A7797_CLK_S2D1>,
++ <&scif_clk>; /* RMSTPCR2/bit6:SCIF1 */
++ clock-names = "fck", "brg_int", "scif_clk";
++ dmas = <&dmac1 0x53>, <&dmac1 0x52>;
++ dma-names = "tx", "rx";
++ power-domains = <&sysc R8A7797_PD_ALWAYS_ON>;
++ status = "disabled";
++ };
++
++ scif3: serial@e6c50000 {
++ compatible = "renesas,scif-r8a7797",
++ "renesas,rcar-gen3-scif", "renesas,scif";
++ reg = <0 0xe6c50000 0 64>;
++ interrupts = <GIC_SPI 23 IRQ_TYPE_LEVEL_HIGH>; /* SPI23:SCIF.ch3 */
++ clocks = <&cpg CPG_MOD 204>,
++ <&cpg CPG_CORE R8A7797_CLK_S2D1>,
++ <&scif_clk>; /* RMSTPCR2/bit4:SCIF3 */
++ clock-names = "fck", "brg_int", "scif_clk";
++ dmas = <&dmac1 0x57>, <&dmac1 0x56>;
++ dma-names = "tx", "rx";
++ power-domains = <&sysc R8A7797_PD_ALWAYS_ON>;
++ status = "disabled";
++ };
++
++ scif4: serial@e6c40000 {
++ compatible = "renesas,scif-r8a7797",
++ "renesas,rcar-gen3-scif", "renesas,scif";
++ reg = <0 0xe6c40000 0 64>;
++ interrupts = <GIC_SPI 16 IRQ_TYPE_LEVEL_HIGH>; /* SPI16:SCIF.ch4 */
++ clocks = <&cpg CPG_MOD 203>,
++ <&cpg CPG_CORE R8A7797_CLK_S2D1>,
++ <&scif_clk>; /* RMSTPCR2/bit3:SCIF4 */
++ clock-names = "fck", "brg_int", "scif_clk";
++ dmas = <&dmac1 0x59>, <&dmac1 0x58>;
++ dma-names = "tx", "rx";
++ power-domains = <&sysc R8A7797_PD_ALWAYS_ON>;
++ status = "disabled";
++ };
++
++ i2c0: i2c@e6500000 {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ compatible = "renesas,i2c-r8a7797";
++ reg = <0 0xe6500000 0 0x40>;
++ interrupts = <GIC_SPI 287 IRQ_TYPE_LEVEL_HIGH>; /* SPI287:I2C.ch0 */
++ clocks = <&cpg CPG_MOD 931>; /* RMSTPCR9/bit31:I2C-IF0 */
++ power-domains = <&sysc R8A7797_PD_ALWAYS_ON>;
++ dmas = <&dmac1 0x91>, <&dmac1 0x90>;
++ dma-names = "tx", "rx";
++ i2c-scl-internal-delay-ns = <6>;
++ status = "disabled";
++ };
++
++ i2c1: i2c@e6508000 {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ compatible = "renesas,i2c-r8a7797";
++ reg = <0 0xe6508000 0 0x40>;
++ interrupts = <GIC_SPI 288 IRQ_TYPE_LEVEL_HIGH>; /* SPI288:I2C.ch1 */
++ clocks = <&cpg CPG_MOD 930>; /* RMSTPCR9/bit30:I2C-IF1 */
++ power-domains = <&sysc R8A7797_PD_ALWAYS_ON>;
++ dmas = <&dmac1 0x93>, <&dmac1 0x92>;
++ dma-names = "tx", "rx";
++ i2c-scl-internal-delay-ns = <6>;
++ status = "disabled";
++ };
++
++ i2c2: i2c@e6510000 {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ compatible = "renesas,i2c-r8a7797";
++ reg = <0 0xe6510000 0 0x40>;
++ interrupts = <GIC_SPI 286 IRQ_TYPE_LEVEL_HIGH>; /* SPI286:I2C.ch2 */
++ clocks = <&cpg CPG_MOD 929>; /* RMSTPCR9/bit29:I2C-IF2 */
++ power-domains = <&sysc R8A7797_PD_ALWAYS_ON>;
++ dmas = <&dmac1 0x95>, <&dmac1 0x94>;
++ dma-names = "tx", "rx";
++ i2c-scl-internal-delay-ns = <6>;
++ status = "disabled";
++ };
++
++ i2c3: i2c@e66d0000 {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ compatible = "renesas,i2c-r8a7797";
++ reg = <0 0xe66d0000 0 0x40>;
++ interrupts = <GIC_SPI 290 IRQ_TYPE_LEVEL_HIGH>; /* SPI290:I2C.ch3 */
++ clocks = <&cpg CPG_MOD 928>; /* RMSTPCR9/bit28:I2C-IF3 */
++ power-domains = <&sysc R8A7797_PD_ALWAYS_ON>;
++ dmas = <&dmac1 0x97>, <&dmac1 0x96>;
++ dma-names = "tx", "rx";
++ i2c-scl-internal-delay-ns = <6>;
++ status = "disabled";
++ };
++
++ i2c4: i2c@e66d8000 {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ compatible = "renesas,i2c-r8a7797";
++ reg = <0 0xe66d8000 0 0x40>;
++ interrupts = <GIC_SPI 19 IRQ_TYPE_LEVEL_HIGH>; /* SPI19:I2C.ch4 */
++ clocks = <&cpg CPG_MOD 927>; /* RMSTPCR9/bit27:I2C-IF4 */
++ power-domains = <&sysc R8A7797_PD_ALWAYS_ON>;
++ dmas = <&dmac1 0x99>, <&dmac1 0x98>;
++ dma-names = "tx", "rx";
++ i2c-scl-internal-delay-ns = <6>;
++ status = "disabled";
++ };
++
++ msiof0: spi@e6e90000 {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ compatible = "renesas,msiof-r8a7797";
++ reg = <0 0xe6e90000 0 0x64>;
++ interrupts = <GIC_SPI 156 IRQ_TYPE_LEVEL_HIGH>; /* SPI156:MSIOF.ch0 */
++ clocks = <&cpg CPG_MOD 211>, <&msiof_ref_clk>; /* RMSTPCR2/bit11:MSIOF0, @@ msiof_ref_clk->Eagle.dts */
++ clock-names = "msiof_clk", "msiof_ref_clk";
++ dmas = <&dmac1 0x41>, <&dmac1 0x40>;
++ dma-names = "tx", "rx";
++ power-domains = <&sysc R8A7797_PD_ALWAYS_ON>;
++ status = "disabled";
++ };
++
++ msiof1: spi@e6ea0000 {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ compatible = "renesas,msiof-r8a7797";
++ reg = <0 0xe6ea0000 0 0x0064>;
++ interrupts = <GIC_SPI 157 IRQ_TYPE_LEVEL_HIGH>; /* SPI157:MSIOF.ch1 */
++ clocks = <&cpg CPG_MOD 210>, <&msiof_ref_clk>; /* RMSTPCR2/bit10:MSIOF1, @@ msiof_ref_clk->Eagle.dts */
++ clock-names = "msiof_clk", "msiof_ref_clk";
++ dmas = <&dmac1 0x43>, <&dmac1 0x42>;
++ dma-names = "tx", "rx";
++ power-domains = <&sysc R8A7797_PD_ALWAYS_ON>;
++ status = "disabled";
++ };
++
++ msiof2: spi@e6c00000 {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ compatible = "renesas,msiof-r8a7797";
++ reg = <0 0xe6c00000 0 0x0064>;
++ interrupts = <GIC_SPI 158 IRQ_TYPE_LEVEL_HIGH>; /* SPI158:MSIOF.ch2 */
++ clocks = <&cpg CPG_MOD 209>, <&msiof_ref_clk>; /* RMSTPCR2/bit9:MSIOF2, @@ msiof_ref_clk->Eagle.dts */
++ clock-names = "msiof_clk", "msiof_ref_clk";
++ dmas = <&dmac1 0x45>, <&dmac1 0x44>;
++ dma-names = "tx", "rx";
++ power-domains = <&sysc R8A7797_PD_ALWAYS_ON>;
++ status = "disabled";
++ };
++
++ msiof3: spi@e6c10000 {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ compatible = "renesas,msiof-r8a7797";
++ reg = <0 0xe6c10000 0 0x0064>;
++ interrupts = <GIC_SPI 159 IRQ_TYPE_LEVEL_HIGH>; /* SPI159:MSIOF.ch3 */
++ clocks = <&cpg CPG_MOD 208>, <&msiof_ref_clk>; /* RMSTPCR2/bit8:MSIOF3, @@ msiof_ref_clk->Eagle.dts */
++ clock-names = "msiof_clk", "msiof_ref_clk";
++ dmas = <&dmac1 0x47>, <&dmac1 0x46>;
++ dma-names = "tx", "rx";
++ power-domains = <&sysc R8A7797_PD_ALWAYS_ON>;
++ status = "disabled";
++ };
++
++ vin0: video@e6ef0000 {
++ compatible = "renesas,vin-r8a7797";
++ reg = <0 0xe6ef0000 0 0x1000>;
++ interrupts = <GIC_SPI 188 IRQ_TYPE_LEVEL_HIGH>; /* SPI188:VIN.ch0 */
++ clocks = <&cpg CPG_MOD 811>; /* RMSTPCR8/bit11:VIN0 */
++ power-domains = <&sysc R8A7797_PD_ALWAYS_ON>;
++ status = "disabled";
++ };
++
++ vin1: video@e6ef1000 {
++ compatible = "renesas,vin-r8a7797";
++ reg = <0 0xe6ef1000 0 0x1000>;
++ interrupts = <GIC_SPI 189 IRQ_TYPE_LEVEL_HIGH>; /* SPI189:VIN.ch1 */
++ clocks = <&cpg CPG_MOD 810>; /* RMSTPCR8/bit10:VIN1 */
++ power-domains = <&sysc R8A7797_PD_ALWAYS_ON>;
++ status = "disabled";
++ };
++
++ vin2: video@e6ef2000 {
++ compatible = "renesas,vin-r8a7797";
++ reg = <0 0xe6ef2000 0 0x1000>;
++ interrupts = <GIC_SPI 190 IRQ_TYPE_LEVEL_HIGH>; /* SPI190:VIN.ch2 */
++ clocks = <&cpg CPG_MOD 809>; /* RMSTPCR8/bit9:VIN2 */
++ power-domains = <&sysc R8A7797_PD_ALWAYS_ON>;
++ status = "disabled";
++ };
++
++ vin3: video@e6ef3000 {
++ compatible = "renesas,vin-r8a7797";
++ reg = <0 0xe6ef3000 0 0x1000>;
++ interrupts = <GIC_SPI 191 IRQ_TYPE_LEVEL_HIGH>; /* SPI191:VIN.ch3 */
++ clocks = <&cpg CPG_MOD 808>; /* RMSTPCR8/bit8:VIN3 */
++ power-domains = <&sysc R8A7797_PD_ALWAYS_ON>;
++ status = "disabled";
++ };
++
++
++ sdhi2: sd@ee140000 {
++ compatible = "renesas,sdhi-r8a7797";
++ reg = <0 0xee140000 0 0x2000>;
++ interrupts = <GIC_SPI 165 IRQ_TYPE_LEVEL_HIGH>; /* SPI165:SDHI.ch0 */
++ clocks = <&cpg CPG_MOD 314>; /* RMSTPCR3/bit14:SDIF */
++ power-domains = <&sysc R8A7797_PD_ALWAYS_ON>;
++ renesas,clk-rate = <200000000>;
++ cap-sd-highspeed;
++ sd-uhs-sdr50;
++ sd-uhs-sdr104;
++ renesas,mmc-scc-tapnum = <8>;
++ status = "disabled";
++ };
++
++ mmc0: mmc@ee140000 {
++ compatible = "renesas,mmc-r8a7797";
++ reg = <0 0xee140000 0 0x2000>;
++ interrupts = <GIC_SPI 165 IRQ_TYPE_LEVEL_HIGH>; /* SPI165:SDHI.ch0 */
++ clocks = <&cpg CPG_MOD 314>; /* RMSTPCR3/bit14:SDIF */
++ power-domains = <&sysc R8A7797_PD_ALWAYS_ON>;
++ renesas,clk-rate = <200000000>;
++ cap-mmc-highspeed;
++ mmc-hs200-1_8v;
++ renesas,mmc-scc-tapnum = <8>;
++ status = "disabled";
++ };
++
++ qos@e67e0000 {
++ compatible = "renesas,qos";
++ };
++
++ vspd0: vsp@fea20000 {
++ compatible = "renesas,vsp2";
++ reg = <0 0xfea20000 0 0x4000>;
++
++ interrupts = <GIC_SPI 169 IRQ_TYPE_LEVEL_HIGH>;
++ clocks = <&cpg CPG_MOD 623>; /* RMSTPCR6/bit23:VSP(VSPD0) */
++ power-domains = <&sysc R8A7797_PD_ALWAYS_ON>;
++
++ renesas,fcp = <&fcpvd0>;
++ };
++
++ fcpvd0: fcp@fea27000 {
++ compatible = "renesas,r8a7797-fcpv", "renesas,fcpv";
++ reg = <0 0xfea27000 0 0x200>;
++ clocks = <&cpg CPG_MOD 603>; /* RMSTPCR6/bit3:FCPVD0 */
++ power-domains = <&sysc R8A7797_PD_ALWAYS_ON>;
++ };
++
++ du: display@feb00000 {
++ compatible = "renesas,du-r8a7797";
++ reg = <0 0xfeb00000 0 0x80000>,
++ <0 0xfeb90000 0 0x14>; /* LDVS */
++ reg-names = "du", "lvds.0";
++ interrupts = <GIC_SPI 256 IRQ_TYPE_LEVEL_HIGH>; /* SPI256:DU.ch0 */
++ clocks = <&cpg CPG_MOD 724>,
++ <&cpg CPG_MOD 727>,
++ <&dclkin_p0>;
++ clock-names = "du.0", "lvds.0", "dclkin.0";
++ status = "disabled";
++
++ vsps = <&vspd0>;
++
++ interlaced = <1>;
++
++ ports {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ port@0 {
++ reg = <0>;
++ du_out_lvds0: endpoint {
++ };
++ };
++ };
++ };
++
++ tsc1: thermal@0xe6190000 {
++ compatible = "renesas,thermal-r8a7797";
++ reg = <0 0xe6190000 0 0x5c>;
++ interrupts = <GIC_SPI 67 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 68 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 69 IRQ_TYPE_LEVEL_HIGH>; /* SPI67~69:Thermal Sensor.ch0~2 */
++ clocks = <&cpg CPG_MOD 522>; /* RMSTPCR5/bit22:THS/TSC */
++ power-domains = <&sysc R8A7797_PD_ALWAYS_ON>;
++ #thermal-sensor-cells = <0>;
++ status = "okay";
++ };
++
++ thermal-zones {
++ emergency {
++ polling-delay = <1000>;
++ on-temperature = <110000>;
++ off-temperature = <95000>;
++ target_cpus = <&a53_1>;
++ status = "disabled";
++ };
++
++ sensor_thermal1: sensor-thermal1 {
++ polling-delay-passive = <250>;
++ polling-delay = <0>;
++ sustainable-power = <6313>;
++
++ /* sensor ID */
++ thermal-sensors = <&tsc1>;
++
++ trips {
++ threshold: trip-point@0 {
++ /* miliCelsius */
++ temperature = <90000>;
++ hysteresis = <2000>;
++ type = "passive";
++ };
++
++ target: trip-point@1 {
++ /* miliCelsius */
++ temperature = <100000>;
++ hysteresis = <2000>;
++ type = "passive";
++ };
++
++ sensor1_crit: sensor1-crit {
++ temperature = <120000>;
++ hysteresis = <2000>;
++ type = "critical";
++ };
++ };
++
++ cooling-maps {
++ map0 {
++ trip = <&target>;
++ cooling-device = <&a53_0 0 2>;
++ contribution = <1024>;
++ };
++ };
++ };
++ };
++
++ mfis: mfis@e6260000 {
++ compatible = "renesas,mfis-r8a7797", "renesas,mfis";
++ reg = <0 0xe6260000 0 0x0200>;
++ interrupts = <GIC_SPI 180 IRQ_TYPE_LEVEL_HIGH>; /* SPI180:MFIS eicr0 */
++ interrupt-names = "eicr0";
++ clocks = <&cpg CPG_MOD 213>; /* RMSTPCR2/bit13:MFIS */
++ clock-names = "mfis";
++ power-domains = <&sysc R8A7797_PD_ALWAYS_ON>;
++ status = "okay";
++ };
++
++ mfis_lock: mfis-lock {
++ compatible = "renesas,mfis-lock-r8a7797",
++ "renesas,mfis-lock";
++ reg = <0 0xe62600c0 0 0x0750>; /* @@ transitional 0x20->0x750 */
++ clocks = <&cpg CPG_MOD 213>; /* RMSTPCR2/bit13:MFIS */
++ power-domains = <&sysc R8A7797_PD_ALWAYS_ON>;
++ status = "okay";
++ };
++ };
++};
+diff --git a/drivers/clk/renesas/Kconfig b/drivers/clk/renesas/Kconfig
+index 2586dfa..f86f2bf 100644
+--- a/drivers/clk/renesas/Kconfig
++++ b/drivers/clk/renesas/Kconfig
+@@ -4,6 +4,7 @@ config CLK_RENESAS_CPG_MSSR
+ default y if ARCH_R8A7745
+ default y if ARCH_R8A7795
+ default y if ARCH_R8A7796
++ default y if ARCH_R8A7797
+
+ config CLK_RENESAS_CPG_MSTP
+ bool
+diff --git a/drivers/clk/renesas/Makefile b/drivers/clk/renesas/Makefile
+index 1072f76..c6f0abb 100644
+--- a/drivers/clk/renesas/Makefile
++++ b/drivers/clk/renesas/Makefile
+@@ -13,6 +13,7 @@ obj-$(CONFIG_ARCH_R8A7793) += clk-rcar-gen2.o clk-div6.o
+ obj-$(CONFIG_ARCH_R8A7794) += clk-rcar-gen2.o clk-div6.o
+ obj-$(CONFIG_ARCH_R8A7795) += r8a7795-cpg-mssr.o rcar-gen3-cpg.o
+ obj-$(CONFIG_ARCH_R8A7796) += r8a7796-cpg-mssr.o rcar-gen3-cpg.o
++obj-$(CONFIG_ARCH_R8A7797) += r8a7797-cpg-mssr.o rcar-gen3-cpg.o
+ obj-$(CONFIG_ARCH_SH73A0) += clk-sh73a0.o clk-div6.o
+
+ obj-$(CONFIG_CLK_RENESAS_CPG_MSSR) += renesas-cpg-mssr.o clk-div6.o
+diff --git a/drivers/clk/renesas/r8a7797-cpg-mssr.c b/drivers/clk/renesas/r8a7797-cpg-mssr.c
+new file mode 100644
+index 0000000..c69bf31
+--- /dev/null
++++ b/drivers/clk/renesas/r8a7797-cpg-mssr.c
+@@ -0,0 +1,218 @@
++/*
++ * r8a7797 Clock Pulse Generator / Module Standby and Software Reset
++ *
++ * Copyright (C) 2016 Glider bvba
++ *
++ * Based on r8a7795-cpg-mssr.c
++ *
++ * Copyright (C) 2016 Renesas Electronics Corp.
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; version 2 of the License.
++ */
++
++#include <linux/device.h>
++#include <linux/init.h>
++#include <linux/kernel.h>
++#include <linux/soc/renesas/rcar-rst.h>
++#include <linux/sys_soc.h>
++
++#include <dt-bindings/clock/r8a7797-cpg-mssr.h>
++
++#include "renesas-cpg-mssr.h"
++#include "rcar-gen3-cpg.h"
++
++enum clk_ids {
++ /* Core Clock Outputs exported to DT */
++ LAST_DT_CORE_CLK = R8A7797_CLK_OSC,
++
++ /* External Input Clocks */
++ CLK_EXTAL,
++ CLK_EXTALR,
++
++ /* Internal Core Clocks */
++ CLK_MAIN,
++ CLK_PLL0,
++ CLK_PLL1,
++ CLK_PLL3,
++ CLK_PLL1_DIV2,
++ CLK_PLL1_DIV4,
++ CLK_S1,
++ CLK_S2,
++ CLK_RINT,
++
++ /* Module Clocks */
++ MOD_CLK_BASE
++};
++
++static const struct cpg_core_clk r8a7797_core_clks[] __initconst = {
++ /* External Clock Inputs */
++ DEF_INPUT("extal", CLK_EXTAL),
++ DEF_INPUT("extalr", CLK_EXTALR),
++
++ /* Internal Core Clocks */
++ DEF_BASE(".main", CLK_MAIN, CLK_TYPE_GEN3_MAIN, CLK_EXTAL),
++ DEF_BASE(".pll0", CLK_PLL0, CLK_TYPE_GEN3_PLL0, CLK_MAIN),
++ DEF_BASE(".pll1", CLK_PLL1, CLK_TYPE_GEN3_PLL1, CLK_MAIN),
++ DEF_BASE(".pll3", CLK_PLL3, CLK_TYPE_GEN3_PLL3, CLK_MAIN),
++
++ DEF_FIXED(".pll1_div2", CLK_PLL1_DIV2, CLK_PLL1, 2, 1),
++ DEF_FIXED(".pll1_div4", CLK_PLL1_DIV4, CLK_PLL1_DIV2, 2, 1),
++ DEF_FIXED(".s1", CLK_S1, CLK_PLL1_DIV2, 4, 1),
++ DEF_FIXED(".s2", CLK_S2, CLK_PLL1_DIV2, 6, 1),
++
++ /* Core Clock Outputs */
++ DEF_BASE("z2", R8A7797_CLK_Z2, CLK_TYPE_GEN3_Z2, CLK_PLL1_DIV4),
++ DEF_FIXED("ztr", R8A7797_CLK_ZTR, CLK_PLL1_DIV2, 6, 1),
++ DEF_FIXED("ztrd2", R8A7797_CLK_ZTRD2, CLK_PLL1_DIV2, 12, 1),
++ DEF_FIXED("zt", R8A7797_CLK_ZT, CLK_PLL1_DIV2, 4, 1),
++ DEF_FIXED("zx", R8A7797_CLK_ZX, CLK_PLL1_DIV2, 3, 1),
++ DEF_FIXED("s1d1", R8A7797_CLK_S1D1, CLK_S1, 1, 1),
++ DEF_FIXED("s1d2", R8A7797_CLK_S1D2, CLK_S1, 2, 1),
++ DEF_FIXED("s1d4", R8A7797_CLK_S1D4, CLK_S1, 4, 1),
++ DEF_FIXED("s2d1", R8A7797_CLK_S2D1, CLK_S2, 1, 1),
++ DEF_FIXED("s2d2", R8A7797_CLK_S2D2, CLK_S2, 2, 1),
++ DEF_FIXED("s2d4", R8A7797_CLK_S2D4, CLK_S2, 4, 1),
++
++ DEF_GEN3_SD0H("sd0h", R8A7797_CLK_SD0H, CLK_PLL1_DIV4, 0x0074),
++ DEF_GEN3_SD0("sd0", R8A7797_CLK_SD0, CLK_PLL1_DIV4, 0x0074),
++
++ DEF_FIXED("cl", R8A7797_CLK_CL, CLK_PLL1_DIV2, 48, 1),
++ DEF_FIXED("cp", R8A7797_CLK_CP, CLK_EXTAL, 2, 1),
++
++ DEF_DIV6P1("mso", R8A7797_CLK_MSO, CLK_PLL1_DIV4, 0x014),
++ DEF_DIV6P1("canfd", R8A7797_CLK_CANFD, CLK_PLL1_DIV4, 0x244),
++ DEF_DIV6P1("csi0", R8A7797_CLK_CSI0, CLK_PLL1_DIV4, 0x00c),
++
++ DEF_FIXED("osc", R8A7797_CLK_OSC, CLK_PLL1_DIV2, (12*1024), 1),
++ DEF_BASE("r_int", CLK_RINT, CLK_TYPE_GEN3_RINT, CLK_EXTAL),
++
++ DEF_BASE("r", R8A7797_CLK_R, CLK_TYPE_GEN3_R, CLK_RINT),
++};
++
++static const struct mssr_mod_clk r8a7797_mod_clks[] __initconst = {
++ DEF_MOD("ivcp1e", 127, R8A7797_CLK_S2D1),
++ DEF_MOD("scif4", 203, R8A7797_CLK_S2D4), /* @@ H3=S3D4 */
++ DEF_MOD("scif3", 204, R8A7797_CLK_S2D4), /* @@ H3=S3D4 */
++ DEF_MOD("scif1", 206, R8A7797_CLK_S2D4), /* @@ H3=S3D4 */
++ DEF_MOD("scif0", 207, R8A7797_CLK_S2D4), /* @@ H3=S3D4 */
++ DEF_MOD("msiof3", 208, R8A7797_CLK_MSO),
++ DEF_MOD("msiof2", 209, R8A7797_CLK_MSO),
++ DEF_MOD("msiof1", 210, R8A7797_CLK_MSO),
++ DEF_MOD("msiof0", 211, R8A7797_CLK_MSO),
++ DEF_MOD("mfis", 213, R8A7797_CLK_S2D2), /* @@ H3=S3D2 */
++ DEF_MOD("sys-dmac2", 217, R8A7797_CLK_S2D1), /* @@ H3=S3D1 */
++ DEF_MOD("sys-dmac1", 218, R8A7797_CLK_S2D1), /* @@ H3=S3D1 */
++ DEF_MOD("sdif", 314, R8A7797_CLK_SD0),
++ DEF_MOD("rwdt0", 402, R8A7797_CLK_R),
++ DEF_MOD("intc-ex", 407, R8A7797_CLK_CP),
++ DEF_MOD("intc-ap", 408, R8A7797_CLK_S2D1), /* @@ H3=S3D1 */
++ DEF_MOD("hscif3", 517, R8A7797_CLK_S2D1), /* @@ H3=S3D1 */
++ DEF_MOD("hscif2", 518, R8A7797_CLK_S2D1), /* @@ H3=S3D1 */
++ DEF_MOD("hscif1", 519, R8A7797_CLK_S2D1), /* @@ H3=S3D1 */
++ DEF_MOD("hscif0", 520, R8A7797_CLK_S2D1), /* @@ H3=S3D1 */
++ DEF_MOD("thermal", 522, R8A7797_CLK_CP),
++ DEF_MOD("pwm", 523, R8A7797_CLK_S2D4),
++ DEF_MOD("fcpvd0", 603, R8A7797_CLK_S2D1),
++ DEF_MOD("vspd0", 623, R8A7797_CLK_S2D1),
++ DEF_MOD("csi40", 716, R8A7797_CLK_CSI0),
++ DEF_MOD("du0", 724, R8A7797_CLK_S2D1),
++ DEF_MOD("lvds", 727, R8A7797_CLK_S2D1),
++ DEF_MOD("vin3", 808, R8A7797_CLK_S2D1),
++ DEF_MOD("vin2", 809, R8A7797_CLK_S2D1),
++ DEF_MOD("vin1", 810, R8A7797_CLK_S2D1),
++ DEF_MOD("vin0", 811, R8A7797_CLK_S2D1),
++ DEF_MOD("etheravb", 812, R8A7797_CLK_S2D2),
++ DEF_MOD("isp", 817, R8A7797_CLK_S2D1), /* @@ Unknown Module Clock */
++ DEF_MOD("gpio5", 907, R8A7797_CLK_CP),
++ DEF_MOD("gpio4", 908, R8A7797_CLK_CP),
++ DEF_MOD("gpio3", 909, R8A7797_CLK_CP),
++ DEF_MOD("gpio2", 910, R8A7797_CLK_CP),
++ DEF_MOD("gpio1", 911, R8A7797_CLK_CP),
++ DEF_MOD("gpio0", 912, R8A7797_CLK_CP),
++ DEF_MOD("can-fd", 914, R8A7797_CLK_S2D2), /* @@ H3=S3D2 */
++ DEF_MOD("i2c4", 927, R8A7797_CLK_S2D2),
++ DEF_MOD("i2c3", 928, R8A7797_CLK_S2D2),
++ DEF_MOD("i2c2", 929, R8A7797_CLK_S2D2),
++ DEF_MOD("i2c1", 930, R8A7797_CLK_S2D2),
++ DEF_MOD("i2c0", 931, R8A7797_CLK_S2D2),
++};
++
++static const unsigned int r8a7797_crit_mod_clks[] __initconst = {
++ MOD_CLK_ID(408), /* INTC-AP (GIC) */
++};
++
++
++/*
++ * CPG Clock Data
++ */
++
++/*
++ * MD EXTAL PLL0 PLL1 PLL3
++ * 14 13 19 (MHz)
++ *-------------------------------------------------
++ * 0 0 0 16.66 x 1 x192 x192 x96
++ * 0 0 1 16.66 x 1 x192 x192 x80
++ * 0 1 0 20 x 1 x160 x160 x80
++ * 0 1 1 20 x 1 x160 x160 x66
++ * 1 0 0 27 / 2 x236 x236 x118
++ * 1 0 1 27 / 2 x236 x236 x98
++ * 1 1 0 33.33 / 2 x192 x192 x96
++ * 1 1 1 33.33 / 2 x192 x192 x80
++ */
++#define CPG_PLL_CONFIG_INDEX(md) ((((md) & BIT(14)) >> 12) | \
++ (((md) & BIT(13)) >> 12) | \
++ (((md) & BIT(19)) >> 19))
++
++static const struct rcar_gen3_cpg_pll_config cpg_pll_configs[8] __initconst = {
++ /* EXTAL div PLL1 mult PLL3 mult */
++ { 1, 192, 96, },
++ { 1, 192, 80, },
++ { 1, 160, 80, },
++ { 1, 160, 66, },
++ { 2, 236, 118, },
++ { 2, 236, 98, },
++ { 2, 192, 96, },
++ { 2, 192, 80, },
++};
++
++static int __init r8a7797_cpg_mssr_init(struct device *dev)
++{
++ const struct rcar_gen3_cpg_pll_config *cpg_pll_config;
++ u32 cpg_mode;
++ int error;
++
++ error = rcar_rst_read_mode_pins(&cpg_mode);
++ if (error)
++ return error;
++
++ cpg_pll_config = &cpg_pll_configs[CPG_PLL_CONFIG_INDEX(cpg_mode)];
++ if (!cpg_pll_config->extal_div) {
++ dev_err(dev, "Prohibited setting (cpg_mode=0x%x)\n", cpg_mode);
++ return -EINVAL;
++ }
++
++ return rcar_gen3_cpg_init(cpg_pll_config, CLK_EXTALR, cpg_mode);
++}
++
++const struct cpg_mssr_info r8a7797_cpg_mssr_info __initconst = {
++ /* Core Clocks */
++ .core_clks = r8a7797_core_clks,
++ .num_core_clks = ARRAY_SIZE(r8a7797_core_clks),
++ .last_dt_core_clk = LAST_DT_CORE_CLK,
++ .num_total_core_clks = MOD_CLK_BASE,
++
++ /* Module Clocks */
++ .mod_clks = r8a7797_mod_clks,
++ .num_mod_clks = ARRAY_SIZE(r8a7797_mod_clks),
++ .num_hw_mod_clks = 12 * 32,
++
++ /* Critical Module Clocks */
++ .crit_mod_clks = r8a7797_crit_mod_clks,
++ .num_crit_mod_clks = ARRAY_SIZE(r8a7797_crit_mod_clks),
++
++ /* Callbacks */
++ .init = r8a7797_cpg_mssr_init,
++ .cpg_clk_register = rcar_gen3_cpg_clk_register,
++};
+diff --git a/drivers/clk/renesas/rcar-gen3-cpg.c b/drivers/clk/renesas/rcar-gen3-cpg.c
+index f9d1763..96de154 100644
+--- a/drivers/clk/renesas/rcar-gen3-cpg.c
++++ b/drivers/clk/renesas/rcar-gen3-cpg.c
+@@ -26,6 +26,13 @@
+ #include "renesas-cpg-mssr.h"
+ #include "rcar-gen3-cpg.h"
+
++static spinlock_t cpg_lock;
++
++static const struct soc_device_attribute r8a7797[] = {
++ { .soc_id = "r8a7797" },
++ { /* sentinel */ }
++};
++
+ #define CPG_PLL0CR 0x00d8
+ #define CPG_PLL2CR 0x002c
+ #define CPG_PLL4CR 0x01f4
+@@ -227,7 +234,10 @@ static unsigned long cpg_z2_clk_recalc_rate(struct clk_hw *hw,
+ unsigned int val;
+ unsigned long rate;
+
+- val = (clk_readl(zclk->reg) & CPG_FRQCRC_Z2FC_MASK);
++ if (!soc_device_match(r8a7797))
++ val = (clk_readl(zclk->reg) & CPG_FRQCRC_Z2FC_MASK);
++ else
++ val = 0;
+ mult = 32 - val;
+
+ rate = div_u64((u64)parent_rate * mult + 16, 32);
+@@ -339,6 +349,11 @@ static int cpg_z2_clk_set_rate(struct clk_hw *hw, unsigned long rate,
+ u32 val, kick;
+ unsigned int i;
+
++ if (soc_device_match(r8a7797)){
++ pr_info("Do not support V3M's Z2 clock changing\n");
++ return 0;
++ }
++
+ mult = div_u64((u64)rate * 32 + parent_rate/2, parent_rate);
+ mult = clamp(mult, 1U, 32U);
+
+@@ -451,6 +466,19 @@ static struct clk * __init cpg_z2_clk_register(const char *name,
+ /*
+ * SDn Clock
+ */
++/* SDHI divisors */
++static const struct clk_div_table cpg_sdh_div_table[] = {
++ { 0, 2 }, { 1, 3 }, { 2, 4 }, { 3, 6 },
++ { 4, 8 }, { 5, 12 }, { 6, 16 }, { 7, 18 },
++ { 8, 24 }, { 10, 36 }, { 11, 48 }, { 0, 0 },
++};
++
++static const struct clk_div_table cpg_sd01_div_table[] = {
++ { 4, 8 },
++ { 5, 12 }, { 6, 16 }, { 7, 18 }, { 8, 24 },
++ { 10, 36 }, { 11, 48 }, { 12, 10 }, { 0, 0 },
++};
++
+ #define CPG_SD_STP_HCK BIT(9)
+ #define CPG_SD_STP_CK BIT(8)
+
+@@ -749,6 +777,14 @@ struct clk * __init rcar_gen3_cpg_clk_register(struct device *dev,
+ case CLK_TYPE_GEN3_SD:
+ return cpg_sd_clk_register(core, base, __clk_get_name(parent));
+
++ case CLK_TYPE_GEN3_SD0:
++ return clk_register_divider_table(NULL, core->name, __clk_get_name(parent), 0, base + 0x0074,
++ 4, 4,0, cpg_sd01_div_table, &cpg_lock);
++
++ case CLK_TYPE_GEN3_SD0H:
++ return clk_register_divider_table(NULL, core->name, __clk_get_name(parent), 0, base + 0x0074,
++ 8, 4,0, cpg_sdh_div_table, &cpg_lock);
++
+ case CLK_TYPE_GEN3_RINT:
+ div = cpg_pll_config->rint;
+ break;
+@@ -799,5 +835,8 @@ int __init rcar_gen3_cpg_init(const struct rcar_gen3_cpg_pll_config *config,
+ if (attr)
+ cpg_quirks = (uintptr_t)attr->data;
+ pr_debug("%s: mode = 0x%x quirks = 0x%x\n", __func__, mode, cpg_quirks);
++
++ spin_lock_init(&cpg_lock);
++
+ return 0;
+ }
+diff --git a/drivers/clk/renesas/rcar-gen3-cpg.h b/drivers/clk/renesas/rcar-gen3-cpg.h
+index 4155023..f0c0a92 100644
+--- a/drivers/clk/renesas/rcar-gen3-cpg.h
++++ b/drivers/clk/renesas/rcar-gen3-cpg.h
+@@ -19,6 +19,8 @@ enum rcar_gen3_clk_types {
+ CLK_TYPE_GEN3_PLL3,
+ CLK_TYPE_GEN3_PLL4,
+ CLK_TYPE_GEN3_SD,
++ CLK_TYPE_GEN3_SD0,
++ CLK_TYPE_GEN3_SD0H,
+ CLK_TYPE_GEN3_R,
+ CLK_TYPE_GEN3_Z,
+ CLK_TYPE_GEN3_Z2,
+@@ -26,6 +28,10 @@ enum rcar_gen3_clk_types {
+
+ #define DEF_GEN3_SD(_name, _id, _parent, _offset) \
+ DEF_BASE(_name, _id, CLK_TYPE_GEN3_SD, _parent, .offset = _offset)
++#define DEF_GEN3_SD0(_name, _id, _parent, _offset) \
++ DEF_BASE(_name, _id, CLK_TYPE_GEN3_SD0, _parent, .offset = _offset)
++#define DEF_GEN3_SD0H(_name, _id, _parent, _offset) \
++ DEF_BASE(_name, _id, CLK_TYPE_GEN3_SD0H, _parent, .offset = _offset)
+
+ struct rcar_gen3_cpg_pll_config {
+ unsigned int extal_div;
+diff --git a/drivers/clk/renesas/renesas-cpg-mssr.c b/drivers/clk/renesas/renesas-cpg-mssr.c
+index 494e4e8..e523ab7 100644
+--- a/drivers/clk/renesas/renesas-cpg-mssr.c
++++ b/drivers/clk/renesas/renesas-cpg-mssr.c
+@@ -588,6 +588,12 @@ static int __init cpg_mssr_add_clk_domain(struct device *dev,
+ .data = &r8a7796_cpg_mssr_info,
+ },
+ #endif
++#ifdef CONFIG_ARCH_R8A7797
++ {
++ .compatible = "renesas,r8a7797-cpg-mssr",
++ .data = &r8a7797_cpg_mssr_info,
++ },
++#endif
+ { /* sentinel */ }
+ };
+
+diff --git a/drivers/clk/renesas/renesas-cpg-mssr.h b/drivers/clk/renesas/renesas-cpg-mssr.h
+index 148f4f0a..77c27d8 100644
+--- a/drivers/clk/renesas/renesas-cpg-mssr.h
++++ b/drivers/clk/renesas/renesas-cpg-mssr.h
+@@ -134,6 +134,7 @@ struct cpg_mssr_info {
+ extern const struct cpg_mssr_info r8a7745_cpg_mssr_info;
+ extern const struct cpg_mssr_info r8a7795_cpg_mssr_info;
+ extern const struct cpg_mssr_info r8a7796_cpg_mssr_info;
++extern const struct cpg_mssr_info r8a7797_cpg_mssr_info;
+
+
+ /*
+diff --git a/drivers/cpufreq/cpufreq-dt-platdev.c b/drivers/cpufreq/cpufreq-dt-platdev.c
+index 29f76a4..809a6e1 100644
+--- a/drivers/cpufreq/cpufreq-dt-platdev.c
++++ b/drivers/cpufreq/cpufreq-dt-platdev.c
+@@ -59,6 +59,7 @@
+ { .compatible = "renesas,r8a7794", },
+ { .compatible = "renesas,r8a7795", },
+ { .compatible = "renesas,r8a7796", },
++ { .compatible = "renesas,r8a7797", },
+ { .compatible = "renesas,sh73a0", },
+
+ { .compatible = "rockchip,rk2928", },
+diff --git a/drivers/gpio/gpio-rcar.c b/drivers/gpio/gpio-rcar.c
+index f721a89..118e579 100644
+--- a/drivers/gpio/gpio-rcar.c
++++ b/drivers/gpio/gpio-rcar.c
+@@ -1,7 +1,7 @@
+ /*
+ * Renesas R-Car GPIO Support
+ *
+- * Copyright (C) 2014 Renesas Electronics Corporation
++ * Copyright (C) 2014-2016 Renesas Electronics Corporation
+ * Copyright (C) 2013 Magnus Damm
+ *
+ * This program is free software; you can redistribute it and/or modify
+@@ -579,6 +579,10 @@ struct gpio_rcar_info {
+ /* Gen3 GPIO is identical to Gen2. */
+ .data = &gpio_rcar_info_gen2,
+ }, {
++ .compatible = "renesas,gpio-r8a7797",
++ /* Gen3 GPIO is identical to Gen2. */
++ .data = &gpio_rcar_info_gen2,
++ }, {
+ .compatible = "renesas,gpio-rcar",
+ .data = &gpio_rcar_info_gen1,
+ }, {
+diff --git a/drivers/gpu/drm/rcar-du/rcar_du_drv.c b/drivers/gpu/drm/rcar-du/rcar_du_drv.c
+index 6295c73..ac9cf2a 100644
+--- a/drivers/gpu/drm/rcar-du/rcar_du_drv.c
++++ b/drivers/gpu/drm/rcar-du/rcar_du_drv.c
+@@ -289,6 +289,30 @@
+ {/*sentinel*/}
+ };
+
++static const struct rcar_du_device_info rcar_du_r8a7797_info = {
++ .gen = 3,
++ .features = RCAR_DU_FEATURE_CRTC_IRQ_CLOCK
++ | RCAR_DU_FEATURE_EXT_CTRL_REGS
++ | RCAR_DU_FEATURE_VSP1_SOURCE
++ | RCAR_DU_FEATURE_GEN3_REGS,
++ .num_crtcs = 1,
++ .routes = {
++ /* R8A7797 has one RGB output, one LVDS output. */
++ [RCAR_DU_OUTPUT_DPAD0] = {
++ .possible_crtcs = BIT(0),
++ .encoder_type = DRM_MODE_ENCODER_NONE,
++ .port = 1,
++ },
++ [RCAR_DU_OUTPUT_LVDS0] = {
++ .possible_crtcs = BIT(0),
++ .encoder_type = DRM_MODE_ENCODER_LVDS,
++ .port = 0,
++ },
++ },
++ .num_lvds = 1,
++ .dpll_ch = BIT(1),
++};
++
+ static const struct of_device_id rcar_du_of_table[] = {
+ { .compatible = "renesas,du-r8a7779", .data = &rcar_du_r8a7779_info },
+ { .compatible = "renesas,du-r8a7790", .data = &rcar_du_r8a7790_info },
+@@ -298,6 +322,7 @@
+ { .compatible = "renesas,du-r8a7794", .data = &rcar_du_r8a7794_info },
+ { .compatible = "renesas,du-r8a7795", .data = &rcar_du_r8a7795_info },
+ { .compatible = "renesas,du-r8a7796", .data = &rcar_du_r8a7796_info },
++ { .compatible = "renesas,du-r8a7797", .data = &rcar_du_r8a7797_info },
+ { }
+ };
+
+diff --git a/drivers/gpu/drm/rcar-du/rcar_du_group.c b/drivers/gpu/drm/rcar-du/rcar_du_group.c
+index c15611c..95023bd 100644
+--- a/drivers/gpu/drm/rcar-du/rcar_du_group.c
++++ b/drivers/gpu/drm/rcar-du/rcar_du_group.c
+@@ -29,11 +29,17 @@
+
+ #include <linux/clk.h>
+ #include <linux/io.h>
++#include <linux/sys_soc.h>
+
+ #include "rcar_du_drv.h"
+ #include "rcar_du_group.h"
+ #include "rcar_du_regs.h"
+
++static const struct soc_device_attribute r8a7797[] = {
++ { .soc_id = "r8a7797" },
++ { }
++};
++
+ u32 rcar_du_group_read(struct rcar_du_group *rgrp, u32 reg)
+ {
+ return rcar_du_read(rgrp->dev, rgrp->mmio_offset + reg);
+@@ -147,8 +153,10 @@ static void rcar_du_group_setup(struct rcar_du_group *rgrp)
+
+ /* Apply planes to CRTCs association. */
+ mutex_lock(&rgrp->lock);
+- rcar_du_group_write(rgrp, DPTSR, (rgrp->dptsr_planes << 16) |
+- rgrp->dptsr_planes);
++ if (!soc_device_match(r8a7797))
++ rcar_du_group_write(rgrp, DPTSR, (rgrp->dptsr_planes << 16) |
++ rgrp->dptsr_planes);
++
+ mutex_unlock(&rgrp->lock);
+ }
+
+diff --git a/drivers/gpu/drm/rcar-du/rcar_du_lvdsenc.c b/drivers/gpu/drm/rcar-du/rcar_du_lvdsenc.c
+index ecae864..42eb45c 100644
+--- a/drivers/gpu/drm/rcar-du/rcar_du_lvdsenc.c
++++ b/drivers/gpu/drm/rcar-du/rcar_du_lvdsenc.c
+@@ -17,12 +17,18 @@
+ #include <linux/of_gpio.h>
+ #include <linux/platform_device.h>
+ #include <linux/slab.h>
++#include <linux/sys_soc.h>
+
+ #include "rcar_du_drv.h"
+ #include "rcar_du_encoder.h"
+ #include "rcar_du_lvdsenc.h"
+ #include "rcar_lvds_regs.h"
+
++static const struct soc_device_attribute r8a7797[] = {
++ { .soc_id = "r8a7797" },
++ { }
++};
++
+ struct rcar_du_lvdsenc {
+ struct rcar_du_device *dev;
+
+@@ -96,14 +102,25 @@ static void rcar_du_lvdsenc_start_gen3(struct rcar_du_lvdsenc *lvds,
+ u32 pllcr;
+
+ /* PLL clock configuration */
+- if (freq < 42000)
+- pllcr = LVDPLLCR_PLLDIVCNT_42M;
+- else if (freq < 85000)
+- pllcr = LVDPLLCR_PLLDIVCNT_85M;
+- else if (freq < 128000)
+- pllcr = LVDPLLCR_PLLDIVCNT_128M;
+- else
+- pllcr = LVDPLLCR_PLLDIVCNT_148M;
++ if (soc_device_match(r8a7797)) {
++ if (freq < 39000)
++ pllcr = LVDPLLCR_CEEN | LVDPLLCR_COSEL | LVDPLLCR_PLLDLYCNT_38M;
++ else if (freq < 61000)
++ pllcr = LVDPLLCR_CEEN | LVDPLLCR_COSEL | LVDPLLCR_PLLDLYCNT_60M;
++ else if (freq < 121000)
++ pllcr = LVDPLLCR_CEEN | LVDPLLCR_COSEL | LVDPLLCR_PLLDLYCNT_121M;
++ else
++ pllcr = LVDPLLCR_PLLDLYCNT_150M;
++ } else {
++ if (freq < 42000)
++ pllcr = LVDPLLCR_PLLDIVCNT_42M;
++ else if (freq < 85000)
++ pllcr = LVDPLLCR_PLLDIVCNT_85M;
++ else if (freq < 128000)
++ pllcr = LVDPLLCR_PLLDIVCNT_128M;
++ else
++ pllcr = LVDPLLCR_PLLDIVCNT_148M;
++ }
+
+ rcar_lvds_write(lvds, LVDPLLCR, pllcr);
+
+@@ -123,6 +140,11 @@ static void rcar_du_lvdsenc_start_gen3(struct rcar_du_lvdsenc *lvds,
+ lvdcr0 |= LVDCR0_PWD;
+ rcar_lvds_write(lvds, LVDCR0, lvdcr0);
+
++ if (soc_device_match(r8a7797)) {
++ lvdcr0 |= LVDCR0_LVEN;
++ rcar_lvds_write(lvds, LVDCR0, lvdcr0);
++ }
++
+ usleep_range(100, 150);
+
+ lvdcr0 |= LVDCR0_LVRES;
+diff --git a/drivers/hwspinlock/rcar_hwspinlock.c b/drivers/hwspinlock/rcar_hwspinlock.c
+index b92db1b..a656c0a 100644
+--- a/drivers/hwspinlock/rcar_hwspinlock.c
++++ b/drivers/hwspinlock/rcar_hwspinlock.c
+@@ -21,10 +21,16 @@
+ #include <linux/of_address.h>
+ #include <linux/platform_device.h>
+ #include <linux/io.h>
++#include <linux/sys_soc.h>
+
+ #include "hwspinlock_internal.h"
+
+-#define RCAR_HWSPINLOCK_NUM (8)
++static const struct soc_device_attribute r8a7797[] = {
++ { .soc_id = "r8a7797" },
++ { }
++};
++
++#define RCAR_HWSPINLOCK_NUM (soc_device_match(r8a7797) ? 64 : 8)
+
+ static int rcar_hwspinlock_trylock(struct hwspinlock *lock)
+ {
+diff --git a/drivers/i2c/busses/i2c-rcar.c b/drivers/i2c/busses/i2c-rcar.c
+index 73ff520..306ba97 100644
+--- a/drivers/i2c/busses/i2c-rcar.c
++++ b/drivers/i2c/busses/i2c-rcar.c
+@@ -807,6 +807,7 @@ static u32 rcar_i2c_func(struct i2c_adapter *adap)
+ { .compatible = "renesas,i2c-r8a7794", .data = (void *)I2C_RCAR_GEN2 },
+ { .compatible = "renesas,i2c-r8a7795", .data = (void *)I2C_RCAR_GEN3 },
+ { .compatible = "renesas,i2c-r8a7796", .data = (void *)I2C_RCAR_GEN3 },
++ { .compatible = "renesas,i2c-r8a7797", .data = (void *)I2C_RCAR_GEN3 },
+ {},
+ };
+ MODULE_DEVICE_TABLE(of, rcar_i2c_dt_ids);
+diff --git a/drivers/iommu/ipmmu-vmsa.c b/drivers/iommu/ipmmu-vmsa.c
+index 2b380ff..b9ef21a 100644
+--- a/drivers/iommu/ipmmu-vmsa.c
++++ b/drivers/iommu/ipmmu-vmsa.c
+@@ -1,7 +1,7 @@
+ /*
+ * IPMMU VMSA
+ *
+- * Copyright (C) 2014 Renesas Electronics Corporation
++ * Copyright (C) 2014-2016 Renesas Electronics Corporation
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+@@ -1274,6 +1274,9 @@ static void ipmmu_device_reset(struct ipmmu_vmsa_device *mmu)
+ .compatible = "renesas,ipmmu-r8a7796",
+ .data = &ipmmu_features_rcar_gen3,
+ }, {
++ .compatible = "renesas,ipmmu-r8a7797",
++ .data = &ipmmu_features_rcar_gen3,
++ }, {
+ /* Terminator */
+ },
+ };
+@@ -1640,6 +1643,8 @@ static int __init ipmmu_vmsa_iommu_of_setup(struct device_node *np)
+ ipmmu_vmsa_iommu_of_setup);
+ IOMMU_OF_DECLARE(ipmmu_r8a7796_iommu_of, "renesas,ipmmu-r8a7796",
+ ipmmu_vmsa_iommu_of_setup);
++IOMMU_OF_DECLARE(ipmmu_r8a7797_iommu_of, "renesas,ipmmu-r8a7797",
++ ipmmu_vmsa_iommu_of_setup);
+ #endif
+
+ MODULE_DESCRIPTION("IOMMU API for Renesas VMSA-compatible IPMMU");
+diff --git a/drivers/media/platform/soc_camera/Kconfig b/drivers/media/platform/soc_camera/Kconfig
+index 17178ad..5539c5d 100644
+--- a/drivers/media/platform/soc_camera/Kconfig
++++ b/drivers/media/platform/soc_camera/Kconfig
+@@ -39,7 +39,7 @@ config VIDEO_RCAR_VIN_LEGACY_DEBUG
+ config VIDEO_RCAR_CSI2_LEGACY
+ tristate "R-Car MIPI CSI-2 Interface driver"
+ depends on VIDEO_DEV && SOC_CAMERA && HAVE_CLK
+- depends on ARCH_R8A7795 || ARCH_R8A7796 || COMPILE_TEST
++ depends on ARCH_R8A7795 || ARCH_R8A7796 || ARCH_R8A7797 || COMPILE_TEST
+ ---help---
+ This is a v4l2 driver for the R-Car CSI-2 Interface
+
+diff --git a/drivers/media/platform/soc_camera/rcar_csi2.c b/drivers/media/platform/soc_camera/rcar_csi2.c
+index 05f623468..5faac64 100644
+--- a/drivers/media/platform/soc_camera/rcar_csi2.c
++++ b/drivers/media/platform/soc_camera/rcar_csi2.c
+@@ -25,6 +25,7 @@
+ #include <linux/slab.h>
+ #include <linux/videodev2.h>
+ #include <linux/module.h>
++#include <linux/sys_soc.h>
+
+ #include <media/rcar_csi2.h>
+ #include <media/soc_camera.h>
+@@ -153,6 +154,11 @@
+ #define RCAR_CSI2_INTSTATE_ERRSYNCESC (1 << 1)
+ #define RCAR_CSI2_INTSTATE_ERRCONTROL (1 << 0)
+
++static const struct soc_device_attribute r8a7797[] = {
++ { .soc_id = "r8a7797" },
++ { }
++};
++
+ enum chip_id {
+ RCAR_GEN3,
+ RCAR_GEN2,
+@@ -248,6 +254,17 @@ struct rcar_csi2 {
+
+ static int rcar_csi2_set_phy_freq(struct rcar_csi2 *priv)
+ {
++ const uint32_t const hs_freq_range_v3m[43] = {
++ 0x00, 0x00, 0x20, 0x40, 0x02, /* 80M, 90M, 100M, 110M, 120M */
++ 0x02, 0x22, 0x42, 0x04, 0x04, /* 130M, 140M, 150M, 160M, 170M */
++ 0x24, 0x44, 0x44, 0x06, 0x26, /* 180M, 190M, 205M, 220M, 235M */
++ 0x46, 0x08, 0x28, 0x0a, 0x2a, /* 250M, 270M, 300M, 325M, 350M */
++ 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, /* 400M, 450M, 500M, 550M, 600M */
++ 0x10, 0x30, 0x12, 0x32, 0x52, /* 650M, 700M, 750M, 800M, 950M */
++ 0x72, 0x14, 0x34, 0x52, 0x74, /* 900M, 950M, 1000M, 1050M, 1100M */
++ 0x16, 0x36, 0x56, 0x76, 0x18, /* 1150M, 1200M, 1250M, 1300M, 1350M */
++ 0x38, 0x58, 0x78 /* 1400M, 1450M, 1500M */
++ };
+ const uint32_t const hs_freq_range[43] = {
+ 0x00, 0x10, 0x20, 0x30, 0x01, /* 0-4 */
+ 0x11, 0x21, 0x31, 0x02, 0x12, /* 5-9 */
+@@ -304,7 +321,12 @@ static int rcar_csi2_set_phy_freq(struct rcar_csi2 *priv)
+
+ dev_dbg(&priv->pdev->dev, "bps_per_lane (%d)\n", bps_per_lane);
+
+- iowrite32((hs_freq_range[bps_per_lane] << 16),
++ if (soc_device_match(r8a7797))
++ iowrite32((hs_freq_range_v3m[bps_per_lane] << 16) |
++ RCAR_CSI2_PHTW_DWEN | RCAR_CSI2_PHTW_CWEN | 0x44,
++ priv->base + RCAR_CSI2_PHTW);
++ else
++ iowrite32(hs_freq_range[bps_per_lane] << 16,
+ priv->base + RCAR_CSI2_PHYPLL);
+ return 0;
+
+@@ -488,6 +510,7 @@ static int rcar_csi2_s_power(struct v4l2_subdev *sd, int on)
+
+ #ifdef CONFIG_OF
+ static const struct of_device_id rcar_csi2_of_table[] = {
++ { .compatible = "renesas,r8a7797-csi2", .data = (void *)RCAR_GEN3 },
+ { .compatible = "renesas,r8a7796-csi2", .data = (void *)RCAR_GEN3 },
+ { .compatible = "renesas,r8a7795-csi2", .data = (void *)RCAR_GEN3 },
+ { },
+@@ -496,6 +519,7 @@ static int rcar_csi2_s_power(struct v4l2_subdev *sd, int on)
+ #endif
+
+ static struct platform_device_id rcar_csi2_id_table[] = {
++ { "r8a7797-csi2", RCAR_GEN3 },
+ { "r8a7796-csi2", RCAR_GEN3 },
+ { "r8a7795-csi2", RCAR_GEN3 },
+ {},
+diff --git a/drivers/media/platform/soc_camera/rcar_vin.c b/drivers/media/platform/soc_camera/rcar_vin.c
+index 400958b..74fb005 100644
+--- a/drivers/media/platform/soc_camera/rcar_vin.c
++++ b/drivers/media/platform/soc_camera/rcar_vin.c
+@@ -154,7 +154,7 @@
+ #define VNCSI_IFMD_REG 0x20 /* Video n CSI2 Interface Mode Register */
+
+ #define VNCSI_IFMD_DES1 (1 << 26) /* CSI20 */
+-#define VNCSI_IFMD_DES0 (1 << 25) /* H3:CSI40/41, M3:CSI40 */
++#define VNCSI_IFMD_DES0 (1 << 25) /* H3:CSI40/41, M3:CSI40, V3M:CSI40 */
+
+ #define VNCSI_IFMD_CSI_CHSEL(n) (n << 0)
+ #define VNCSI_IFMD_SEL_NUMBER 5
+@@ -185,6 +185,7 @@
+
+ enum chip_id {
+ RCAR_GEN3,
++ RCAR_V3M,
+ RCAR_M3,
+ RCAR_H3,
+ RCAR_GEN2,
+@@ -360,6 +361,49 @@ struct vin_gen3_ifmd {
+ },
+ };
+
++static const struct vin_gen3_ifmd vin_v3_vc_ifmd[] = {
++ { 0x0000,
++ {
++ {RCAR_CSI40, RCAR_VIRTUAL_CH0},
++ {RCAR_CSI_CH_NONE, RCAR_VIN_CH_NONE},
++ {RCAR_CSI_CH_NONE, RCAR_VIN_CH_NONE},
++ {RCAR_CSI40, RCAR_VIRTUAL_CH1},
++ }
++ },
++ { 0x0001,
++ {
++ {RCAR_CSI_CH_NONE, RCAR_VIN_CH_NONE},
++ {RCAR_CSI_CH_NONE, RCAR_VIN_CH_NONE},
++ {RCAR_CSI40, RCAR_VIRTUAL_CH0},
++ {RCAR_CSI_CH_NONE, RCAR_VIN_CH_NONE},
++ }
++ },
++ { 0x0002,
++ {
++ {RCAR_CSI_CH_NONE, RCAR_VIN_CH_NONE},
++ {RCAR_CSI40, RCAR_VIRTUAL_CH0},
++ {RCAR_CSI_CH_NONE, RCAR_VIN_CH_NONE},
++ {RCAR_CSI_CH_NONE, RCAR_VIN_CH_NONE},
++ }
++ },
++ { 0x0003,
++ {
++ {RCAR_CSI40, RCAR_VIRTUAL_CH0},
++ {RCAR_CSI40, RCAR_VIRTUAL_CH1},
++ {RCAR_CSI40, RCAR_VIRTUAL_CH2},
++ {RCAR_CSI40, RCAR_VIRTUAL_CH3},
++ }
++ },
++ { 0x0004,
++ {
++ {RCAR_CSI_CH_NONE, RCAR_VIN_CH_NONE},
++ {RCAR_CSI_CH_NONE, RCAR_VIN_CH_NONE},
++ {RCAR_CSI_CH_NONE, RCAR_VIN_CH_NONE},
++ {RCAR_CSI_CH_NONE, RCAR_VIN_CH_NONE},
++ }
++ },
++};
++
+ enum csi2_fmt {
+ RCAR_CSI_FMT_NONE = -1,
+ RCAR_CSI_RGB888,
+@@ -849,7 +893,8 @@ static int rcar_vin_videobuf_setup(struct vb2_queue *vq,
+ struct rcar_vin_priv *priv = ici->priv;
+ struct rcar_vin_cam *cam = icd->host_priv;
+
+- if (priv->chip == RCAR_H3 || priv->chip == RCAR_M3) {
++ if (priv->chip == RCAR_H3 || priv->chip == RCAR_M3 ||
++ priv->chip == RCAR_V3M) {
+ if ((priv->ratio_h > 0x10000) || (priv->ratio_v > 0x10000)) {
+ dev_err(icd->parent, "Scaling rate parameter error\n");
+ return -EINVAL;
+@@ -951,7 +996,8 @@ static int rcar_vin_setup(struct rcar_vin_priv *priv)
+ /* output format */
+ switch (icd->current_fmt->host_fmt->fourcc) {
+ case V4L2_PIX_FMT_NV12:
+- if (priv->chip == RCAR_H3 || priv->chip == RCAR_M3) {
++ if (priv->chip == RCAR_H3 || priv->chip == RCAR_M3 ||
++ priv->chip == RCAR_V3M) {
+ iowrite32(ALIGN((cam->out_width * cam->out_height),
+ 0x80), priv->base + VNUVAOF_REG);
+ dmr = VNDMR_DTMD_YCSEP_YCBCR420;
+@@ -983,6 +1029,7 @@ static int rcar_vin_setup(struct rcar_vin_priv *priv)
+ break;
+ case V4L2_PIX_FMT_XBGR32:
+ if (priv->chip != RCAR_H3 && priv->chip != RCAR_M3 &&
++ priv->chip != RCAR_V3M &&
+ priv->chip != RCAR_GEN2 && priv->chip != RCAR_H1 &&
+ priv->chip != RCAR_E1)
+ goto e_format;
+@@ -990,7 +1037,8 @@ static int rcar_vin_setup(struct rcar_vin_priv *priv)
+ dmr = VNDMR_EXRGB;
+ break;
+ case V4L2_PIX_FMT_ABGR32:
+- if (priv->chip != RCAR_H3 && priv->chip != RCAR_M3)
++ if (priv->chip != RCAR_H3 && priv->chip != RCAR_M3 &&
++ priv->chip != RCAR_V3M)
+ goto e_format;
+
+ dmr = VNDMR_EXRGB | VNDMR_DTMD_ARGB;
+@@ -1006,7 +1054,8 @@ static int rcar_vin_setup(struct rcar_vin_priv *priv)
+ if (input_is_yuv == output_is_yuv)
+ vnmc |= VNMC_BPS;
+
+- if (priv->chip == RCAR_H3 || priv->chip == RCAR_M3) {
++ if (priv->chip == RCAR_H3 || priv->chip == RCAR_M3 ||
++ priv->chip == RCAR_V3M) {
+ if (priv->pdata_flags & RCAR_VIN_CSI2)
+ vnmc &= ~VNMC_DPINE;
+ else
+@@ -1323,7 +1372,8 @@ static int rcar_vin_add_device(struct soc_camera_device *icd)
+
+ pm_runtime_get_sync(ici->v4l2_dev.dev);
+
+- if (priv->chip == RCAR_H3 || priv->chip == RCAR_M3) {
++ if (priv->chip == RCAR_H3 || priv->chip == RCAR_M3 ||
++ priv->chip == RCAR_V3M) {
+ struct v4l2_subdev *csi2_sd = find_csi2(priv);
+ int ret;
+
+@@ -1569,7 +1619,8 @@ static int rcar_vin_set_rect(struct soc_camera_device *icd)
+ break;
+ }
+
+- if (priv->chip == RCAR_H3 || priv->chip == RCAR_M3) {
++ if (priv->chip == RCAR_H3 || priv->chip == RCAR_M3 ||
++ priv->chip == RCAR_V3M) {
+ if ((icd->current_fmt->host_fmt->fourcc != V4L2_PIX_FMT_NV12)
+ && is_scaling(cam)) {
+ ret = rcar_vin_uds_set(priv, cam);
+@@ -1720,14 +1771,16 @@ static int rcar_vin_set_bus_param(struct soc_camera_device *icd)
+ if (ret < 0 && ret != -ENOIOCTLCMD)
+ return ret;
+
+- if (priv->chip == RCAR_H3 || priv->chip == RCAR_M3) {
++ if (priv->chip == RCAR_H3 || priv->chip == RCAR_M3 ||
++ priv->chip == RCAR_V3M) {
+ if (cfg.type == V4L2_MBUS_CSI2)
+ vnmc &= ~VNMC_DPINE;
+ else
+ vnmc |= VNMC_DPINE;
+ }
+
+- if (priv->chip == RCAR_H3 || priv->chip == RCAR_M3)
++ if (priv->chip == RCAR_H3 || priv->chip == RCAR_M3 ||
++ priv->chip == RCAR_V3M)
+ val = VNDMR2_FTEV;
+ else
+ val = VNDMR2_FTEV | VNDMR2_VLV(1);
+@@ -2289,7 +2342,8 @@ static int rcar_vin_try_fmt(struct soc_camera_device *icd,
+ if (ret < 0)
+ return ret;
+
+- if (priv->chip == RCAR_H3 || priv->chip == RCAR_M3) {
++ if (priv->chip == RCAR_H3 || priv->chip == RCAR_M3 ||
++ priv->chip == RCAR_V3M) {
+ /* Adjust max scaling size for Gen3 */
+ if (pix->width > 4096)
+ pix->width = priv->max_width;
+@@ -2454,6 +2508,7 @@ static int rcar_vin_cropcap(struct soc_camera_device *icd,
+
+ #ifdef CONFIG_OF
+ static const struct of_device_id rcar_vin_of_table[] = {
++ { .compatible = "renesas,vin-r8a7797", .data = (void *)RCAR_V3M },
+ { .compatible = "renesas,vin-r8a7796", .data = (void *)RCAR_M3 },
+ { .compatible = "renesas,vin-r8a7795", .data = (void *)RCAR_H3 },
+ { .compatible = "renesas,vin-r8a7794", .data = (void *)RCAR_GEN2 },
+@@ -2754,7 +2809,8 @@ static int rcar_vin_probe(struct platform_device *pdev)
+ priv->chip = (enum chip_id)match->data;
+ }
+
+- if (priv->chip == RCAR_H3 || priv->chip == RCAR_M3) {
++ if (priv->chip == RCAR_H3 || priv->chip == RCAR_M3 ||
++ priv->chip == RCAR_V3M) {
+ priv->max_width = 4096;
+ priv->max_height = 4096;
+ } else {
+@@ -2762,7 +2818,8 @@ static int rcar_vin_probe(struct platform_device *pdev)
+ priv->max_height = 2048;
+ }
+
+- if (priv->chip == RCAR_H3 || priv->chip == RCAR_M3) {
++ if (priv->chip == RCAR_H3 || priv->chip == RCAR_M3 ||
++ priv->chip == RCAR_V3M) {
+ u32 ifmd = 0;
+ bool match_flag = false;
+ const struct vin_gen3_ifmd *gen3_ifmd_table = NULL;
+@@ -2841,6 +2898,8 @@ static int rcar_vin_probe(struct platform_device *pdev)
+ gen3_ifmd_table = vin_h3_vc_ifmd;
+ else if (priv->chip == RCAR_M3)
+ gen3_ifmd_table = vin_m3_vc_ifmd;
++ else if (priv->chip == RCAR_V3M)
++ gen3_ifmd_table = vin_v3_vc_ifmd;
+
+ for (i = 0; i < num; i++) {
+ if ((gen3_ifmd_table[i].v_sel[priv->index].csi2_ch
+@@ -2983,6 +3042,9 @@ static int rcar_vin_resume(struct device *dev)
+ } else if (priv->chip == RCAR_M3) {
+ ifmd = VNCSI_IFMD_DES1;
+ gen3_ifmd_table = vin_m3_vc_ifmd;
++ } else if (priv->chip == RCAR_V3M) {
++ ifmd = VNCSI_IFMD_DES1;
++ gen3_ifmd_table = vin_v3_vc_ifmd;
+ }
+
+ for (i = 0; i < num; i++) {
+diff --git a/drivers/media/platform/vsp1/vsp1_drv.c b/drivers/media/platform/vsp1/vsp1_drv.c
+index 45bd0f3..90f7109 100644
+--- a/drivers/media/platform/vsp1/vsp1_drv.c
++++ b/drivers/media/platform/vsp1/vsp1_drv.c
+@@ -888,6 +888,15 @@ void vsp1_device_put(struct vsp1_device *vsp1)
+ .wpf_count = 2,
+ .num_bru_inputs = 5,
+ .header_mode = true,
++ }, {
++ .version = VI6_IP_VERSION_MODEL_VSPD_V3M,
++ .model = "VSP2-D",
++ .gen = 3,
++ .features = VSP1_HAS_BRU | VSP1_HAS_LIF,
++ .rpf_count = 5,
++ .wpf_count = 1,
++ .num_bru_inputs = 5,
++ .header_mode = true,
+ },
+ };
+
+diff --git a/drivers/media/platform/vsp1/vsp1_lif.c b/drivers/media/platform/vsp1/vsp1_lif.c
+index b442d14..e79f9e6 100644
+--- a/drivers/media/platform/vsp1/vsp1_lif.c
++++ b/drivers/media/platform/vsp1/vsp1_lif.c
+@@ -13,6 +13,7 @@
+
+ #include <linux/device.h>
+ #include <linux/gfp.h>
++#include <linux/sys_soc.h>
+
+ #include <media/v4l2-subdev.h>
+
+@@ -23,6 +24,11 @@
+ #define LIF_MIN_SIZE 2U
+ #define LIF_MAX_SIZE 8190U
+
++static const struct soc_device_attribute r8a7797[] = {
++ { .soc_id = "r8a7797" },
++ { }
++};
++
+ /* -----------------------------------------------------------------------------
+ * Device Access
+ */
+@@ -145,7 +151,7 @@ static void lif_configure(struct vsp1_entity *entity,
+ format = vsp1_entity_get_pad_format(&lif->entity, lif->entity.config,
+ LIF_PAD_SOURCE);
+
+- if (vsp1_gen3_vspdl_check(vsp1))
++ if (vsp1_gen3_vspdl_check(vsp1) || soc_device_match(r8a7797))
+ obth = 1500;
+ else
+ obth = 3000;
+@@ -158,6 +164,10 @@ static void lif_configure(struct vsp1_entity *entity,
+ (obth << VI6_LIF_CTRL_OBTH_SHIFT) |
+ (format->code == 0 ? VI6_LIF_CTRL_CFMT : 0) |
+ VI6_LIF_CTRL_REQSEL | VI6_LIF_CTRL_LIF_EN);
++
++ if (soc_device_match(r8a7797))
++ vsp1_lif_write(lif, dl, VI6_LIF_LBA, VI6_LIF_LBA_LBA0 |
++ VI6_LIF_LBA_LBA1);
+ }
+
+ static const struct vsp1_entity_operations lif_entity_ops = {
+diff --git a/drivers/media/platform/vsp1/vsp1_regs.h b/drivers/media/platform/vsp1/vsp1_regs.h
+index 885f60b..2d863a7 100644
+--- a/drivers/media/platform/vsp1/vsp1_regs.h
++++ b/drivers/media/platform/vsp1/vsp1_regs.h
+@@ -788,6 +788,12 @@
+ #define VI6_LIF_CSBTH_LBTH_MASK (0x7ff << 0)
+ #define VI6_LIF_CSBTH_LBTH_SHIFT 0
+
++
++#define VI6_LIF_LBA 0x3b0c
++#define VI6_LIF_LBA_LBA0 (1 << 31)
++#define VI6_LIF_LBA_LBA1 (0x600 << 16)
++
++
+ /* -----------------------------------------------------------------------------
+ * Security Control Registers
+ */
+@@ -811,6 +817,7 @@
+ #define VI6_IP_VERSION_MODEL_VSPBD_GEN3 (0x15 << 8)
+ #define VI6_IP_VERSION_MODEL_VSPBC_GEN3 (0x16 << 8)
+ #define VI6_IP_VERSION_MODEL_VSPD_GEN3 (0x17 << 8)
++#define VI6_IP_VERSION_MODEL_VSPD_V3M (0x18 << 8)
+ #define VI6_IP_VERSION_MODEL_VSPDL_H3 (0x19 << 8)
+ #define VI6_IP_VERSION_SOC_MASK (0xff << 0)
+ #define VI6_IP_VERSION_SOC_H (0x01 << 0)
+diff --git a/drivers/mmc/host/sh_mobile_sdhi.c b/drivers/mmc/host/sh_mobile_sdhi.c
+index 136ebac..fe4e022 100644
+--- a/drivers/mmc/host/sh_mobile_sdhi.c
++++ b/drivers/mmc/host/sh_mobile_sdhi.c
+@@ -150,6 +150,8 @@ struct sh_mobile_sdhi_of_data {
+ { .compatible = "renesas,sdhi-r8a7794", .data = &of_rcar_gen2_compatible, },
+ { .compatible = "renesas,sdhi-r8a7795", .data = &of_rcar_gen3_compatible, },
+ { .compatible = "renesas,sdhi-r8a7796", .data = &of_rcar_gen3_compatible, },
++ { .compatible = "renesas,sdhi-r8a7797", .data = &of_rcar_gen3_compatible, },
++ { .compatible = "renesas,mmc-r8a7797", .data = &of_rcar_gen3_compatible, },
+ {},
+ };
+ MODULE_DEVICE_TABLE(of, sh_mobile_sdhi_of_match);
+diff --git a/drivers/net/ethernet/renesas/ravb_main.c b/drivers/net/ethernet/renesas/ravb_main.c
+index 6c65426..97c52dd 100644
+--- a/drivers/net/ethernet/renesas/ravb_main.c
++++ b/drivers/net/ethernet/renesas/ravb_main.c
+@@ -1922,6 +1922,7 @@ static int ravb_mdio_release(struct ravb_private *priv)
+ { .compatible = "renesas,etheravb-rcar-gen2", .data = (void *)RCAR_GEN2 },
+ { .compatible = "renesas,etheravb-r8a7795", .data = (void *)RCAR_GEN3 },
+ { .compatible = "renesas,etheravb-r8a7796", .data = (void *)RCAR_GEN3 },
++ { .compatible = "renesas,etheravb-r8a7797", .data = (void *)RCAR_GEN3 },
+ { .compatible = "renesas,etheravb-rcar-gen3", .data = (void *)RCAR_GEN3 },
+ { }
+ };
+diff --git a/drivers/pinctrl/sh-pfc/Kconfig b/drivers/pinctrl/sh-pfc/Kconfig
+index 07eca54..002541f 100644
+--- a/drivers/pinctrl/sh-pfc/Kconfig
++++ b/drivers/pinctrl/sh-pfc/Kconfig
+@@ -79,6 +79,11 @@ config PINCTRL_PFC_R8A7796
+ depends on ARCH_R8A7796
+ select PINCTRL_SH_PFC
+
++config PINCTRL_PFC_R8A7797
++ def_bool y
++ depends on ARCH_R8A7797
++ select PINCTRL_SH_PFC
++
+ config PINCTRL_PFC_SH7203
+ def_bool y
+ depends on CPU_SUBTYPE_SH7203
+diff --git a/drivers/pinctrl/sh-pfc/Makefile b/drivers/pinctrl/sh-pfc/Makefile
+index 8e08684..10adc18 100644
+--- a/drivers/pinctrl/sh-pfc/Makefile
++++ b/drivers/pinctrl/sh-pfc/Makefile
+@@ -13,6 +13,7 @@ obj-$(CONFIG_PINCTRL_PFC_R8A7794) += pfc-r8a7794.o
+ obj-$(CONFIG_PINCTRL_PFC_R8A7795) += pfc-r8a7795.o
+ obj-$(CONFIG_PINCTRL_PFC_R8A7795) += pfc-r8a7795-es1.o
+ obj-$(CONFIG_PINCTRL_PFC_R8A7796) += pfc-r8a7796.o
++obj-$(CONFIG_PINCTRL_PFC_R8A7797) += pfc-r8a7797.o
+ obj-$(CONFIG_PINCTRL_PFC_SH7203) += pfc-sh7203.o
+ obj-$(CONFIG_PINCTRL_PFC_SH7264) += pfc-sh7264.o
+ obj-$(CONFIG_PINCTRL_PFC_SH7269) += pfc-sh7269.o
+diff --git a/drivers/pinctrl/sh-pfc/core.c b/drivers/pinctrl/sh-pfc/core.c
+index 6399eb1..9bb3665 100644
+--- a/drivers/pinctrl/sh-pfc/core.c
++++ b/drivers/pinctrl/sh-pfc/core.c
+@@ -5,6 +5,7 @@
+ *
+ * Copyright (C) 2008 Magnus Damm
+ * Copyright (C) 2009 - 2012 Paul Mundt
++ * Copyright (C) 2016 Renesas Electronics Corp.
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+@@ -622,6 +623,12 @@ static int sh_pfc_init_ranges(struct sh_pfc *pfc)
+ .data = &r8a7796_pinmux_info,
+ },
+ #endif
++#ifdef CONFIG_PINCTRL_PFC_R8A7797
++ {
++ .compatible = "renesas,pfc-r8a7797",
++ .data = &r8a7797_pinmux_info,
++ },
++#endif
+ #ifdef CONFIG_PINCTRL_PFC_SH73A0
+ {
+ .compatible = "renesas,pfc-sh73a0",
+diff --git a/drivers/pinctrl/sh-pfc/pfc-r8a7797.c b/drivers/pinctrl/sh-pfc/pfc-r8a7797.c
+new file mode 100644
+index 0000000..d58ccb3
+--- /dev/null
++++ b/drivers/pinctrl/sh-pfc/pfc-r8a7797.c
+@@ -0,0 +1,2586 @@
++/*
++ * R8A7797 processor support - PFC hardware block.
++ *
++ * Copyright (C) 2016 Renesas Electronics Corp.
++ *
++ * This file is based on the drivers/pinctrl/sh-pfc/pfc-r8a7795.c
++ *
++ * R-Car Gen3 processor support - PFC hardware block.
++ *
++ * Copyright (C) 2015 Renesas Electronics Corporation
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; version 2 of the License.
++ */
++
++#include <linux/io.h>
++#include <linux/kernel.h>
++#include <linux/sys_soc.h>
++
++#include "core.h"
++#include "sh_pfc.h"
++
++#define CPU_ALL_PORT(fn, sfx) \
++ PORT_GP_CFG_22(0, fn, sfx, SH_PFC_PIN_CFG_DRIVE_STRENGTH), \
++ PORT_GP_CFG_28(1, fn, sfx, SH_PFC_PIN_CFG_DRIVE_STRENGTH), \
++ PORT_GP_CFG_17(2, fn, sfx, SH_PFC_PIN_CFG_DRIVE_STRENGTH), \
++ PORT_GP_CFG_17(3, fn, sfx, SH_PFC_PIN_CFG_DRIVE_STRENGTH | \
++ SH_PFC_PIN_CFG_IO_VOLTAGE), \
++ PORT_GP_CFG_6(4, fn, sfx, SH_PFC_PIN_CFG_DRIVE_STRENGTH), \
++ PORT_GP_CFG_15(5, fn, sfx, SH_PFC_PIN_CFG_DRIVE_STRENGTH)
++/*
++ * F_() : just information
++ * FM() : macro for FN_xxx / xxx_MARK
++ */
++
++/* GPSR0 */
++#define GPSR0_21 F_(DU_EXODDF_DU_ODDF_DISP_CDE, IP2_23_20)
++#define GPSR0_20 F_(DU_EXVSYNC_DU_VSYNC, IP2_19_16)
++#define GPSR0_19 F_(DU_EXHSYNC_DU_HSYNC, IP2_15_12)
++#define GPSR0_18 F_(DU_DOTCLKOUT, IP2_11_8)
++#define GPSR0_17 F_(DU_DB7, IP2_7_4)
++#define GPSR0_16 F_(DU_DB6, IP2_3_0)
++#define GPSR0_15 F_(DU_DB5, IP1_31_28)
++#define GPSR0_14 F_(DU_DB4, IP1_27_24)
++#define GPSR0_13 F_(DU_DB3, IP1_23_20)
++#define GPSR0_12 F_(DU_DB2, IP1_19_16)
++#define GPSR0_11 F_(DU_DG7, IP1_15_12)
++#define GPSR0_10 F_(DU_DG6, IP1_11_8)
++#define GPSR0_9 F_(DU_DG5, IP1_7_4)
++#define GPSR0_8 F_(DU_DG4, IP1_3_0)
++#define GPSR0_7 F_(DU_DG3, IP0_31_28)
++#define GPSR0_6 F_(DU_DG2, IP0_27_24)
++#define GPSR0_5 F_(DU_DR7, IP0_23_20)
++#define GPSR0_4 F_(DU_DR6, IP0_19_16)
++#define GPSR0_3 F_(DU_DR5, IP0_15_12)
++#define GPSR0_2 F_(DU_DR4, IP0_11_8)
++#define GPSR0_1 F_(DU_DR3, IP0_7_4)
++#define GPSR0_0 F_(DU_DR2, IP0_3_0)
++
++/* GPSR1 */
++#define GPSR1_27 F_(DIGRF_CLKOUT, IP8_27_24)
++#define GPSR1_26 F_(DIGRF_CLKIN, IP8_23_20)
++#define GPSR1_25 F_(CANFD_CLK_A, IP8_19_16)
++#define GPSR1_24 F_(CANFD1_RX, IP8_15_12)
++#define GPSR1_23 F_(CANFD1_TX, IP8_11_8)
++#define GPSR1_22 F_(CANFD0_RX_A, IP8_7_4)
++#define GPSR1_21 F_(CANFD0_TX_A, IP8_3_0)
++#define GPSR1_20 F_(AVB0_AVTP_CAPTURE, IP7_31_28)
++#define GPSR1_19 FM(AVB0_AVTP_MATCH)
++#define GPSR1_18 FM(AVB0_LINK)
++#define GPSR1_17 FM(AVB0_PHY_INT)
++#define GPSR1_16 FM(AVB0_MAGIC)
++#define GPSR1_15 FM(AVB0_MDC)
++#define GPSR1_14 FM(AVB0_MDIO)
++#define GPSR1_13 FM(AVB0_TXCREFCLK)
++#define GPSR1_12 FM(AVB0_TD3)
++#define GPSR1_11 FM(AVB0_TD2)
++#define GPSR1_10 FM(AVB0_TD1)
++#define GPSR1_9 FM(AVB0_TD0)
++#define GPSR1_8 FM(AVB0_TXC)
++#define GPSR1_7 FM(AVB0_TX_CTL)
++#define GPSR1_6 FM(AVB0_RD3)
++#define GPSR1_5 FM(AVB0_RD2)
++#define GPSR1_4 FM(AVB0_RD1)
++#define GPSR1_3 FM(AVB0_RD0)
++#define GPSR1_2 FM(AVB0_RXC)
++#define GPSR1_1 FM(AVB0_RX_CTL)
++#define GPSR1_0 F_(IRQ0, IP2_27_24)
++
++/* GPSR2 */
++#define GPSR2_16 F_(VI0_FIELD, IP4_31_28)
++#define GPSR2_15 F_(VI0_DATA11, IP4_27_24)
++#define GPSR2_14 F_(VI0_DATA10, IP4_23_20)
++#define GPSR2_13 F_(VI0_DATA9, IP4_19_16)
++#define GPSR2_12 F_(VI0_DATA8, IP4_15_12)
++#define GPSR2_11 F_(VI0_DATA7, IP4_11_8)
++#define GPSR2_10 F_(VI0_DATA6, IP4_7_4)
++#define GPSR2_9 F_(VI0_DATA5, IP4_3_0)
++#define GPSR2_8 F_(VI0_DATA4, IP3_31_28)
++#define GPSR2_7 F_(VI0_DATA3, IP3_27_24)
++#define GPSR2_6 F_(VI0_DATA2, IP3_23_20)
++#define GPSR2_5 F_(VI0_DATA1, IP3_19_16)
++#define GPSR2_4 F_(VI0_DATA0, IP3_15_12)
++#define GPSR2_3 F_(VI0_VSYNC_N, IP3_11_8)
++#define GPSR2_2 F_(VI0_HSYNC_N, IP3_7_4)
++#define GPSR2_1 F_(VI0_CLKENB, IP3_3_0)
++#define GPSR2_0 F_(VI0_CLK, IP2_31_28)
++
++/* GPSR3 */
++#define GPSR3_16 F_(VI1_FIELD, IP7_3_0)
++#define GPSR3_15 F_(VI1_DATA11, IP6_31_28)
++#define GPSR3_14 F_(VI1_DATA10, IP6_27_24)
++#define GPSR3_13 F_(VI1_DATA9, IP6_23_20)
++#define GPSR3_12 F_(VI1_DATA8, IP6_19_16)
++#define GPSR3_11 F_(VI1_DATA7, IP6_15_12)
++#define GPSR3_10 F_(VI1_DATA6, IP6_11_8)
++#define GPSR3_9 F_(VI1_DATA5, IP6_7_4)
++#define GPSR3_8 F_(VI1_DATA4, IP6_3_0)
++#define GPSR3_7 F_(VI1_DATA3, IP5_31_28)
++#define GPSR3_6 F_(VI1_DATA2, IP5_27_24)
++#define GPSR3_5 F_(VI1_DATA1, IP5_23_20)
++#define GPSR3_4 F_(VI1_DATA0, IP5_19_16)
++#define GPSR3_3 F_(VI1_VSYNC_N, IP5_15_12)
++#define GPSR3_2 F_(VI1_HSYNC_N, IP5_11_8)
++#define GPSR3_1 F_(VI1_CLKENB, IP5_7_4)
++#define GPSR3_0 F_(VI1_CLK, IP5_3_0)
++
++/* GPSR4 */
++#define GPSR4_5 F_(SDA2, IP7_27_24)
++#define GPSR4_4 F_(SCL2, IP7_23_20)
++#define GPSR4_3 F_(SDA1, IP7_19_16)
++#define GPSR4_2 F_(SCL1, IP7_15_12)
++#define GPSR4_1 F_(SDA0, IP7_11_8)
++#define GPSR4_0 F_(SCL0, IP7_7_4)
++
++/* GPSR5 */
++#define GPSR5_14 FM(RPC_INT_N)
++#define GPSR5_13 FM(RPC_WP_N)
++#define GPSR5_12 FM(RPC_RESET_N)
++#define GPSR5_11 FM(QSPI1_SSL)
++#define GPSR5_10 FM(QSPI1_IO3)
++#define GPSR5_9 FM(QSPI1_IO2)
++#define GPSR5_8 FM(QSPI1_MISO_IO1)
++#define GPSR5_7 FM(QSPI1_MOSI_IO0)
++#define GPSR5_6 FM(QSPI1_SPCLK)
++#define GPSR5_5 FM(QSPI0_SSL)
++#define GPSR5_4 FM(QSPI0_IO3)
++#define GPSR5_3 FM(QSPI0_IO2)
++#define GPSR5_2 FM(QSPI0_MISO_IO1)
++#define GPSR5_1 FM(QSPI0_MOSI_IO0)
++#define GPSR5_0 FM(QSPI0_SPCLK)
++
++
++/* IPSRx */ /* 0 */ /* 1 */ /* 2 */ /* 3 */ /* 4 */ /* 5 */ /* 6 */ /* 7 */ /* 8 */ /* 9 */ /* A */ /* B */ /* C */ /* D */ /* E */ /* F */
++#define IP0_3_0 FM(DU_DR2) FM(HSCK0) F_(0, 0) FM(A0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP0_7_4 FM(DU_DR3) FM(HRTS0_N) F_(0, 0) FM(A1) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP0_11_8 FM(DU_DR4) FM(HCTS0_N) F_(0, 0) FM(A2) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP0_15_12 FM(DU_DR5) FM(HTX0) F_(0, 0) FM(A3) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP0_19_16 FM(DU_DR6) FM(MSIOF3_RXD) F_(0, 0) FM(A4) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP0_23_20 FM(DU_DR7) FM(MSIOF3_TXD) F_(0, 0) FM(A5) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP0_27_24 FM(DU_DG2) FM(MSIOF3_SS1) F_(0, 0) FM(A6) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP0_31_28 FM(DU_DG3) FM(MSIOF3_SS2) F_(0, 0) FM(A7) FM(PWMFSW0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP1_3_0 FM(DU_DG4) F_(0, 0) F_(0, 0) FM(A8) FM(FSO_CFE_0_N_A) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP1_7_4 FM(DU_DG5) F_(0, 0) F_(0, 0) FM(A9) FM(FSO_CFE_1_N_A) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP1_11_8 FM(DU_DG6) F_(0, 0) F_(0, 0) FM(A10) FM(FSO_TOE_N_A) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP1_15_12 FM(DU_DG7) F_(0, 0) F_(0, 0) FM(A11) FM(IRQ1) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP1_19_16 FM(DU_DB2) F_(0, 0) F_(0, 0) FM(A12) FM(IRQ2) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP1_23_20 FM(DU_DB3) F_(0, 0) F_(0, 0) FM(A13) FM(FXR_CLKOUT1) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP1_27_24 FM(DU_DB4) F_(0, 0) F_(0, 0) FM(A14) FM(FXR_CLKOUT2) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP1_31_28 FM(DU_DB5) F_(0, 0) F_(0, 0) FM(A15) FM(FXR_TXENA_N) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP2_3_0 FM(DU_DB6) F_(0, 0) F_(0, 0) FM(A16) FM(FXR_TXENB_N) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP2_7_4 FM(DU_DB7) F_(0, 0) F_(0, 0) FM(A17) FM(STPWT_EXTFXR) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP2_11_8 FM(DU_DOTCLKOUT) FM(SCIF_CLK_A) F_(0, 0) FM(A18) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP2_15_12 FM(DU_EXHSYNC_DU_HSYNC) FM(HRX0) F_(0, 0) FM(A19) FM(IRQ3) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP2_19_16 FM(DU_EXVSYNC_DU_VSYNC) FM(MSIOF3_SCK) F_(0, 0) FM(A20) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP2_23_20 FM(DU_EXODDF_DU_ODDF_DISP_CDE) FM(MSIOF3_SYNC) F_(0, 0) FM(A21) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP2_27_24 FM(IRQ0) FM(CC5_OSCOUT) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP2_31_28 FM(VI0_CLK) FM(MSIOF2_SCK) FM(SCK3) F_(0, 0) FM(HSCK3) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP3_3_0 FM(VI0_CLKENB) FM(MSIOF2_RXD) FM(RX3) FM(RD_WR_N) FM(HCTS3_N) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP3_7_4 FM(VI0_HSYNC_N) FM(MSIOF2_TXD) FM(TX3) F_(0, 0) FM(HRTS3_N) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP3_11_8 FM(VI0_VSYNC_N) FM(MSIOF2_SYNC) FM(CTS3_N) F_(0, 0) FM(HTX3) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP3_15_12 FM(VI0_DATA0) FM(MSIOF2_SS1) FM(RTS3_N_TANS) F_(0, 0) FM(HRX3) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP3_19_16 FM(VI0_DATA1) FM(MSIOF2_SS2) FM(SCK1) F_(0, 0) FM(SPEEDIN_A) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP3_23_20 FM(VI0_DATA2) FM(AVB0_AVTP_PPS) FM(SDA3_A) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP3_27_24 FM(VI0_DATA3) FM(HSCK1) FM(SCL3_A) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP3_31_28 FM(VI0_DATA4) FM(HRTS1_N) FM(RX1_A) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP4_3_0 FM(VI0_DATA5) FM(HCTS1_N) FM(TX1_A) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP4_7_4 FM(VI0_DATA6) FM(HTX1) FM(CTS1_N) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP4_11_8 FM(VI0_DATA7) FM(HRX1) FM(RTS1_N_TANS) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP4_15_12 FM(VI0_DATA8) FM(HSCK2) FM(PWM0_A) FM(A22) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP4_19_16 FM(VI0_DATA9) FM(HCTS2_N) FM(PWM1_A) FM(A23) FM(FSO_CFE_0_N_B) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP4_23_20 FM(VI0_DATA10) FM(HRTS2_N) FM(PWM2_A) FM(A24) FM(FSO_CFE_1_N_B) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP4_27_24 FM(VI0_DATA11) FM(HTX2) FM(PWM3_A) FM(A25) FM(FSO_TOE_N_B) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP4_31_28 FM(VI0_FIELD) FM(HRX2) FM(PWM4_A) FM(CS1_N_A26) FM(FSCLKST2_N_A) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP5_3_0 FM(VI1_CLK) FM(MSIOF1_RXD) F_(0, 0) FM(CS0_N) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP5_7_4 FM(VI1_CLKENB) FM(MSIOF1_TXD) F_(0, 0) FM(D0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP5_11_8 FM(VI1_HSYNC_N) FM(MSIOF1_SCK) F_(0, 0) FM(D1) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP5_15_12 FM(VI1_VSYNC_N) FM(MSIOF1_SYNC) F_(0, 0) FM(D2) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP5_19_16 FM(VI1_DATA0) FM(MSIOF1_SS1) F_(0, 0) FM(D3) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP5_23_20 FM(VI1_DATA1) FM(MSIOF1_SS2) F_(0, 0) FM(D4) FM(MMC_CMD) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP5_27_24 FM(VI1_DATA2) FM(CANFD0_TX_B) F_(0, 0) FM(D5) FM(MMC_D0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP5_31_28 FM(VI1_DATA3) FM(CANFD0_RX_B) F_(0, 0) FM(D6) FM(MMC_D1) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP6_3_0 FM(VI1_DATA4) FM(CANFD_CLK_B) F_(0, 0) FM(D7) FM(MMC_D2) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP6_7_4 FM(VI1_DATA5) F_(0,0) FM(SCK4) FM(D8) FM(MMC_D3) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP6_11_8 FM(VI1_DATA6) F_(0,0) FM(RX4) FM(D9) FM(MMC_CLK) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP6_15_12 FM(VI1_DATA7) F_(0,0) FM(TX4) FM(D10) FM(MMC_D4) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP6_19_16 FM(VI1_DATA8) F_(0,0) FM(CTS4_N) FM(D11) FM(MMC_D5) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP6_23_20 FM(VI1_DATA9) F_(0,0) FM(RTS4_N_TANS) FM(D12) FM(MMC_D6) FM(SCL3_B) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP6_27_24 FM(VI1_DATA10) F_(0,0) F_(0, 0) FM(D13) FM(MMC_D7) FM(SDA3_B) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP6_31_28 FM(VI1_DATA11) FM(SCL4) FM(IRQ4) FM(D14) FM(MMC_WP) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP7_3_0 FM(VI1_FIELD) FM(SDA4) FM(IRQ5) FM(D15) FM(MMC_CD) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP7_7_4 FM(SCL0) FM(DU_DR0) FM(TPU0TO0) FM(CLKOUT) F_(0, 0) FM(MSIOF0_RXD) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP7_11_8 FM(SDA0) FM(DU_DR1) FM(TPU0TO1) FM(BS_N) FM(SCK0) FM(MSIOF0_TXD) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP7_15_12 FM(SCL1) FM(DU_DG0) FM(TPU0TO2) FM(RD_N) FM(CTS0_N) FM(MSIOF0_SCK) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP7_19_16 FM(SDA1) FM(DU_DG1) FM(TPU0TO3) FM(WE0_N) FM(RTS0_N_TANS) FM(MSIOF0_SYNC) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP7_23_20 FM(SCL2) FM(DU_DB0) FM(TCLK1_A) FM(WE1_N) FM(RX0) FM(MSIOF0_SS1) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP7_27_24 FM(SDA2) FM(DU_DB1) FM(TCLK2_A) FM(EX_WAIT0) FM(TX0) FM(MSIOF0_SS2) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP7_31_28 FM(AVB0_AVTP_CAPTURE) F_(0, 0) F_(0, 0) F_(0, 0) FM(FSCLKST2_N_B) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP8_3_0 FM(CANFD0_TX_A) FM(FXR_TXDA) FM(PWM0_B) FM(DU_DISP) FM(FSCLKST2_N_C) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP8_7_4 FM(CANFD0_RX_A) FM(RXDA_EXTFXR) FM(PWM1_B) FM(DU_CDE) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP8_11_8 FM(CANFD1_TX) FM(FXR_TXDB) FM(PWM2_B) FM(TCLK1_B) FM(TX1_B) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP8_15_12 FM(CANFD1_RX) FM(RXDB_EXTFXR) FM(PWM3_B) FM(TCLK2_B) FM(RX1_B) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP8_19_16 FM(CANFD_CLK_A) FM(CLK_EXTFXR) FM(PWM4_B) FM(SPEEDIN_B) FM(SCIF_CLK_B) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP8_23_20 FM(DIGRF_CLKIN) FM(DIGRF_CLKEN_IN) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP8_27_24 FM(DIGRF_CLKOUT) FM(DIGRF_CLKEN_OUT) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP8_31_28 F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++
++#define PINMUX_GPSR \
++\
++ GPSR1_27 \
++ GPSR1_26 \
++ GPSR1_25 \
++ GPSR1_24 \
++ GPSR1_23 \
++ GPSR1_22 \
++GPSR0_21 GPSR1_21 \
++GPSR0_20 GPSR1_20 \
++GPSR0_19 GPSR1_19 \
++GPSR0_18 GPSR1_18 \
++GPSR0_17 GPSR1_17 \
++GPSR0_16 GPSR1_16 GPSR2_16 GPSR3_16 \
++GPSR0_15 GPSR1_15 GPSR2_15 GPSR3_15 \
++GPSR0_14 GPSR1_14 GPSR2_14 GPSR3_14 GPSR5_14 \
++GPSR0_13 GPSR1_13 GPSR2_13 GPSR3_13 GPSR5_13 \
++GPSR0_12 GPSR1_12 GPSR2_12 GPSR3_12 GPSR5_12 \
++GPSR0_11 GPSR1_11 GPSR2_11 GPSR3_11 GPSR5_11 \
++GPSR0_10 GPSR1_10 GPSR2_10 GPSR3_10 GPSR5_10 \
++GPSR0_9 GPSR1_9 GPSR2_9 GPSR3_9 GPSR5_9 \
++GPSR0_8 GPSR1_8 GPSR2_8 GPSR3_8 GPSR5_8 \
++GPSR0_7 GPSR1_7 GPSR2_7 GPSR3_7 GPSR5_7 \
++GPSR0_6 GPSR1_6 GPSR2_6 GPSR3_6 GPSR5_6 \
++GPSR0_5 GPSR1_5 GPSR2_5 GPSR3_5 GPSR4_5 GPSR5_5 \
++GPSR0_4 GPSR1_4 GPSR2_4 GPSR3_4 GPSR4_4 GPSR5_4 \
++GPSR0_3 GPSR1_3 GPSR2_3 GPSR3_3 GPSR4_3 GPSR5_3 \
++GPSR0_2 GPSR1_2 GPSR2_2 GPSR3_2 GPSR4_2 GPSR5_2 \
++GPSR0_1 GPSR1_1 GPSR2_1 GPSR3_1 GPSR4_1 GPSR5_1 \
++GPSR0_0 GPSR1_0 GPSR2_0 GPSR3_0 GPSR4_0 GPSR5_0
++
++#define PINMUX_IPSR \
++\
++FM(IP0_3_0) IP0_3_0 FM(IP1_3_0) IP1_3_0 FM(IP2_3_0) IP2_3_0 FM(IP3_3_0) IP3_3_0 \
++FM(IP0_7_4) IP0_7_4 FM(IP1_7_4) IP1_7_4 FM(IP2_7_4) IP2_7_4 FM(IP3_7_4) IP3_7_4 \
++FM(IP0_11_8) IP0_11_8 FM(IP1_11_8) IP1_11_8 FM(IP2_11_8) IP2_11_8 FM(IP3_11_8) IP3_11_8 \
++FM(IP0_15_12) IP0_15_12 FM(IP1_15_12) IP1_15_12 FM(IP2_15_12) IP2_15_12 FM(IP3_15_12) IP3_15_12 \
++FM(IP0_19_16) IP0_19_16 FM(IP1_19_16) IP1_19_16 FM(IP2_19_16) IP2_19_16 FM(IP3_19_16) IP3_19_16 \
++FM(IP0_23_20) IP0_23_20 FM(IP1_23_20) IP1_23_20 FM(IP2_23_20) IP2_23_20 FM(IP3_23_20) IP3_23_20 \
++FM(IP0_27_24) IP0_27_24 FM(IP1_27_24) IP1_27_24 FM(IP2_27_24) IP2_27_24 FM(IP3_27_24) IP3_27_24 \
++FM(IP0_31_28) IP0_31_28 FM(IP1_31_28) IP1_31_28 FM(IP2_31_28) IP2_31_28 FM(IP3_31_28) IP3_31_28 \
++\
++FM(IP4_3_0) IP4_3_0 FM(IP5_3_0) IP5_3_0 FM(IP6_3_0) IP6_3_0 FM(IP7_3_0) IP7_3_0 \
++FM(IP4_7_4) IP4_7_4 FM(IP5_7_4) IP5_7_4 FM(IP6_7_4) IP6_7_4 FM(IP7_7_4) IP7_7_4 \
++FM(IP4_11_8) IP4_11_8 FM(IP5_11_8) IP5_11_8 FM(IP6_11_8) IP6_11_8 FM(IP7_11_8) IP7_11_8 \
++FM(IP4_15_12) IP4_15_12 FM(IP5_15_12) IP5_15_12 FM(IP6_15_12) IP6_15_12 FM(IP7_15_12) IP7_15_12 \
++FM(IP4_19_16) IP4_19_16 FM(IP5_19_16) IP5_19_16 FM(IP6_19_16) IP6_19_16 FM(IP7_19_16) IP7_19_16 \
++FM(IP4_23_20) IP4_23_20 FM(IP5_23_20) IP5_23_20 FM(IP6_23_20) IP6_23_20 FM(IP7_23_20) IP7_23_20 \
++FM(IP4_27_24) IP4_27_24 FM(IP5_27_24) IP5_27_24 FM(IP6_27_24) IP6_27_24 FM(IP7_27_24) IP7_27_24 \
++FM(IP4_31_28) IP4_31_28 FM(IP5_31_28) IP5_31_28 FM(IP6_31_28) IP6_31_28 FM(IP7_31_28) IP7_31_28 \
++\
++FM(IP8_3_0) IP8_3_0 \
++FM(IP8_7_4) IP8_7_4 \
++FM(IP8_11_8) IP8_11_8 \
++FM(IP8_15_12) IP8_15_12 \
++FM(IP8_19_16) IP8_19_16 \
++FM(IP8_23_20) IP8_23_20 \
++FM(IP8_27_24) IP8_27_24 \
++FM(IP8_31_28) IP8_31_28
++
++/*
++ Set Value = H'0 Set Value = H'1
++Register Function Pin Function Pin
++------------------------------------------------------------
++sel_i2c3 SDA3_A VI0_DATA2 SDA3_B VI1_DATA10
++ SCL3_A VI0_DATA3 SCL3_B VI1_DATA9
++sel_hscif0 HSCIF0_A SCIF_CLK HSCIF0_B SCIF_CLK
++sel_scif1 SCIF1_A RX1 SCIF1_B TX1
++ SCIF1_A TX1 SCIF1_B RX1
++sel_canfd0 CANFD0_A CANFD0_TX CANFD0_B CANFD0_TX
++ CANFD0_A CANFD0_RX CANFD0_B CANFD0_RX
++ CANFD0_A CANFD_CLK CANFD0_B CANFD_CLK
++sel_pwm4 PWM4_A PWM4 PWM4_B PWM4
++sel_pwm3 PWM3_A PWM3 PWM3_B PWM3
++sel_pwm2 PWM2_A PWM2 PWM2_B PWM2
++sel_pwm1 PWM1_A PWM1 PWM1_B PWM1
++sel_pwm0 PWM0_A PWM0 PWM0_B PWM0
++sel_rfso RFSO_A FSO_CFE_0_N RFSO_B FSO_CFE_0_N
++ RFSO_A FSO_CFE_1_N RFSO_B FSO_CFE_1_N
++ RFSO_A FSO_TOE_N RFSO_B FSO_TOE_N
++sel_rsp RSP_A SPEEDIN RSP_B SPEEDIN
++sel_tmu TMU_A TCLK1 TMU_B TCLK1
++ TMU_A TCLK2 TMU_B TCLK2
++*/
++/* MOD_SEL0 */ /* 0 */ /* 1 */ /* 2 */ /* 3 */ /* 4 */ /* 5 */ /* 6 */ /* 7 */
++#define MOD_SEL0_11 FM(SEL_I2C3_0) FM(SEL_I2C3_1)
++#define MOD_SEL0_10 FM(SEL_HSCIF0_0) FM(SEL_HSCIF0_1)
++#define MOD_SEL0_9 FM(SEL_SCIF1_0) FM(SEL_SCIF1_1)
++#define MOD_SEL0_8 FM(SEL_CANFD0_0) FM(SEL_CANFD0_1)
++#define MOD_SEL0_7 FM(SEL_PWM4_0) FM(SEL_PWM4_1)
++#define MOD_SEL0_6 FM(SEL_PWM3_0) FM(SEL_PWM3_1)
++#define MOD_SEL0_5 FM(SEL_PWM2_0) FM(SEL_PWM2_1)
++#define MOD_SEL0_4 FM(SEL_PWM1_0) FM(SEL_PWM1_1)
++#define MOD_SEL0_3 FM(SEL_PWM0_0) FM(SEL_PWM0_1)
++#define MOD_SEL0_2 FM(SEL_RFSO_0) FM(SEL_RFSO_1)
++#define MOD_SEL0_1 FM(SEL_RSP_0) FM(SEL_RSP_1)
++#define MOD_SEL0_0 FM(SEL_TMU_0) FM(SEL_TMU_1)
++
++#define PINMUX_MOD_SELS \
++\
++MOD_SEL0_11 \
++MOD_SEL0_10 \
++MOD_SEL0_9 \
++MOD_SEL0_8 \
++MOD_SEL0_7 \
++MOD_SEL0_6 \
++MOD_SEL0_5 \
++MOD_SEL0_4 \
++MOD_SEL0_3 \
++MOD_SEL0_2 \
++MOD_SEL0_1 \
++MOD_SEL0_0
++
++enum {
++ PINMUX_RESERVED = 0,
++
++ PINMUX_DATA_BEGIN,
++ GP_ALL(DATA),
++ PINMUX_DATA_END,
++
++#define F_(x, y)
++#define FM(x) FN_##x,
++ PINMUX_FUNCTION_BEGIN,
++ GP_ALL(FN),
++ PINMUX_GPSR
++ PINMUX_IPSR
++ PINMUX_MOD_SELS
++ PINMUX_FUNCTION_END,
++#undef F_
++#undef FM
++
++#define F_(x, y)
++#define FM(x) x##_MARK,
++ PINMUX_MARK_BEGIN,
++ PINMUX_GPSR
++ PINMUX_IPSR
++ PINMUX_MOD_SELS
++ PINMUX_MARK_END,
++#undef F_
++#undef FM
++};
++
++static const u16 pinmux_data[] = {
++ PINMUX_DATA_GP_ALL(),
++
++ PINMUX_SINGLE(AVB0_RX_CTL),
++ PINMUX_SINGLE(AVB0_RXC),
++ PINMUX_SINGLE(AVB0_RD0),
++ PINMUX_SINGLE(AVB0_RD1),
++ PINMUX_SINGLE(AVB0_RD2),
++ PINMUX_SINGLE(AVB0_RD3),
++ PINMUX_SINGLE(AVB0_TX_CTL),
++ PINMUX_SINGLE(AVB0_TXC),
++ PINMUX_SINGLE(AVB0_TD0),
++ PINMUX_SINGLE(AVB0_TD1),
++ PINMUX_SINGLE(AVB0_TD2),
++ PINMUX_SINGLE(AVB0_TD3),
++ PINMUX_SINGLE(AVB0_TXCREFCLK),
++ PINMUX_SINGLE(AVB0_MDIO),
++ PINMUX_SINGLE(AVB0_MDC),
++ PINMUX_SINGLE(AVB0_MAGIC),
++ PINMUX_SINGLE(AVB0_PHY_INT),
++ PINMUX_SINGLE(AVB0_LINK),
++ PINMUX_SINGLE(AVB0_AVTP_MATCH),
++
++ PINMUX_SINGLE(QSPI0_SPCLK),
++ PINMUX_SINGLE(QSPI0_MOSI_IO0),
++ PINMUX_SINGLE(QSPI0_MISO_IO1),
++ PINMUX_SINGLE(QSPI0_IO2),
++ PINMUX_SINGLE(QSPI0_IO3),
++ PINMUX_SINGLE(QSPI0_SSL),
++ PINMUX_SINGLE(QSPI1_SPCLK),
++ PINMUX_SINGLE(QSPI1_MOSI_IO0),
++ PINMUX_SINGLE(QSPI1_MISO_IO1),
++ PINMUX_SINGLE(QSPI1_IO2),
++ PINMUX_SINGLE(QSPI1_IO3),
++ PINMUX_SINGLE(QSPI1_SSL),
++ PINMUX_SINGLE(RPC_RESET_N),
++ PINMUX_SINGLE(RPC_WP_N),
++ PINMUX_SINGLE(RPC_INT_N),
++
++ /* IPSR0 */
++ PINMUX_IPSR_GPSR(IP0_3_0, DU_DR2),
++ PINMUX_IPSR_GPSR(IP0_3_0, HSCK0),
++ PINMUX_IPSR_GPSR(IP0_3_0, A0),
++
++ PINMUX_IPSR_GPSR(IP0_7_4, DU_DR3),
++ PINMUX_IPSR_GPSR(IP0_7_4, HRTS0_N),
++ PINMUX_IPSR_GPSR(IP0_7_4, A1),
++
++ PINMUX_IPSR_GPSR(IP0_11_8, DU_DR4),
++ PINMUX_IPSR_GPSR(IP0_11_8, HCTS0_N),
++ PINMUX_IPSR_GPSR(IP0_11_8, A2),
++
++ PINMUX_IPSR_GPSR(IP0_15_12, DU_DR5),
++ PINMUX_IPSR_GPSR(IP0_15_12, HTX0),
++ PINMUX_IPSR_GPSR(IP0_15_12, A3),
++
++ PINMUX_IPSR_GPSR(IP0_19_16, DU_DR6),
++ PINMUX_IPSR_GPSR(IP0_19_16, MSIOF3_RXD),
++ PINMUX_IPSR_GPSR(IP0_19_16, A4),
++
++ PINMUX_IPSR_GPSR(IP0_23_20, DU_DR7),
++ PINMUX_IPSR_GPSR(IP0_23_20, MSIOF3_TXD),
++ PINMUX_IPSR_GPSR(IP0_23_20, A5),
++
++ PINMUX_IPSR_GPSR(IP0_27_24, DU_DG2),
++ PINMUX_IPSR_GPSR(IP0_27_24, MSIOF3_SS1),
++ PINMUX_IPSR_GPSR(IP0_27_24, A6),
++
++ PINMUX_IPSR_GPSR(IP0_31_28, DU_DG3),
++ PINMUX_IPSR_GPSR(IP0_31_28, MSIOF3_SS2),
++ PINMUX_IPSR_GPSR(IP0_31_28, A7),
++ PINMUX_IPSR_GPSR(IP0_31_28, PWMFSW0),
++
++ /* IPSR1 */
++ PINMUX_IPSR_GPSR(IP1_3_0, DU_DG4),
++ PINMUX_IPSR_GPSR(IP1_3_0, A8),
++ PINMUX_IPSR_MSEL(IP1_3_0, FSO_CFE_0_N_A, SEL_RFSO_0),
++
++ PINMUX_IPSR_GPSR(IP1_7_4, DU_DG5),
++ PINMUX_IPSR_GPSR(IP1_7_4, A9),
++ PINMUX_IPSR_MSEL(IP1_7_4, FSO_CFE_1_N_A, SEL_RFSO_0),
++
++ PINMUX_IPSR_GPSR(IP1_11_8, DU_DG6),
++ PINMUX_IPSR_GPSR(IP1_11_8, A10),
++ PINMUX_IPSR_MSEL(IP1_11_8, FSO_TOE_N_A, SEL_RFSO_0),
++
++ PINMUX_IPSR_GPSR(IP1_15_12, DU_DG7),
++ PINMUX_IPSR_GPSR(IP1_15_12, A11),
++ PINMUX_IPSR_GPSR(IP1_15_12, IRQ1),
++
++ PINMUX_IPSR_GPSR(IP1_19_16, DU_DB2),
++ PINMUX_IPSR_GPSR(IP1_19_16, A12),
++ PINMUX_IPSR_GPSR(IP1_19_16, IRQ2),
++
++ PINMUX_IPSR_GPSR(IP1_23_20, DU_DB3),
++ PINMUX_IPSR_GPSR(IP1_23_20, A13),
++ PINMUX_IPSR_GPSR(IP1_23_20, FXR_CLKOUT1),
++
++ PINMUX_IPSR_GPSR(IP1_27_24, DU_DB4),
++ PINMUX_IPSR_GPSR(IP1_27_24, A14),
++ PINMUX_IPSR_GPSR(IP1_27_24, FXR_CLKOUT2),
++
++ PINMUX_IPSR_GPSR(IP1_31_28, DU_DB5),
++ PINMUX_IPSR_GPSR(IP1_31_28, A15),
++ PINMUX_IPSR_GPSR(IP1_31_28, FXR_TXENA_N),
++
++ /* IPSR2 */
++ PINMUX_IPSR_GPSR(IP2_3_0, DU_DB6),
++ PINMUX_IPSR_GPSR(IP2_3_0, A16),
++ PINMUX_IPSR_GPSR(IP2_3_0, FXR_TXENB_N),
++
++ PINMUX_IPSR_GPSR(IP2_7_4, DU_DB7),
++ PINMUX_IPSR_GPSR(IP2_7_4, A17),
++ PINMUX_IPSR_GPSR(IP2_7_4, STPWT_EXTFXR),
++
++ PINMUX_IPSR_GPSR(IP2_11_8, DU_DOTCLKOUT),
++ PINMUX_IPSR_MSEL(IP2_11_8, SCIF_CLK_A, SEL_HSCIF0_0),
++ PINMUX_IPSR_GPSR(IP2_11_8, A18),
++
++ PINMUX_IPSR_GPSR(IP2_15_12, DU_EXHSYNC_DU_HSYNC),
++ PINMUX_IPSR_GPSR(IP2_15_12, HRX0),
++ PINMUX_IPSR_GPSR(IP2_15_12, A19),
++ PINMUX_IPSR_GPSR(IP2_15_12, IRQ3),
++
++ PINMUX_IPSR_GPSR(IP2_19_16, DU_EXVSYNC_DU_VSYNC),
++ PINMUX_IPSR_GPSR(IP2_19_16, MSIOF3_SCK),
++ PINMUX_IPSR_GPSR(IP2_19_16, A20),
++
++ PINMUX_IPSR_GPSR(IP2_23_20, DU_EXODDF_DU_ODDF_DISP_CDE),
++ PINMUX_IPSR_GPSR(IP2_23_20, MSIOF3_SYNC),
++ PINMUX_IPSR_GPSR(IP2_23_20, A21),
++
++ PINMUX_IPSR_GPSR(IP2_27_24, IRQ0),
++ PINMUX_IPSR_GPSR(IP2_27_24, CC5_OSCOUT),
++
++ PINMUX_IPSR_GPSR(IP2_31_28, VI0_CLK),
++ PINMUX_IPSR_GPSR(IP2_31_28, MSIOF2_SCK),
++ PINMUX_IPSR_GPSR(IP2_31_28, SCK3),
++ PINMUX_IPSR_GPSR(IP2_31_28, HSCK3),
++
++ /* IPSR3 */
++ PINMUX_IPSR_GPSR(IP3_3_0, VI0_CLKENB),
++ PINMUX_IPSR_GPSR(IP3_3_0, MSIOF2_RXD),
++ PINMUX_IPSR_GPSR(IP3_3_0, RX3),
++ PINMUX_IPSR_GPSR(IP3_3_0, RD_WR_N),
++ PINMUX_IPSR_GPSR(IP3_3_0, HCTS3_N),
++
++ PINMUX_IPSR_GPSR(IP3_7_4, VI0_HSYNC_N),
++ PINMUX_IPSR_GPSR(IP3_7_4, MSIOF2_TXD),
++ PINMUX_IPSR_GPSR(IP3_7_4, TX3),
++ PINMUX_IPSR_GPSR(IP3_7_4, HRTS3_N),
++
++ PINMUX_IPSR_GPSR(IP3_11_8, VI0_VSYNC_N),
++ PINMUX_IPSR_GPSR(IP3_11_8, MSIOF2_SYNC),
++ PINMUX_IPSR_GPSR(IP3_11_8, CTS3_N),
++ PINMUX_IPSR_GPSR(IP3_11_8, HTX3),
++
++ PINMUX_IPSR_GPSR(IP3_15_12, VI0_DATA0),
++ PINMUX_IPSR_GPSR(IP3_15_12, MSIOF2_SS1),
++ PINMUX_IPSR_GPSR(IP3_15_12, RTS3_N_TANS),
++ PINMUX_IPSR_GPSR(IP3_15_12, HRX3),
++
++ PINMUX_IPSR_GPSR(IP3_19_16, VI0_DATA1),
++ PINMUX_IPSR_GPSR(IP3_19_16, MSIOF2_SS2),
++ PINMUX_IPSR_GPSR(IP3_19_16, SCK1),
++ PINMUX_IPSR_MSEL(IP3_19_16, SPEEDIN_A, SEL_RSP_1),
++
++ PINMUX_IPSR_GPSR(IP3_23_20, VI0_DATA2),
++ PINMUX_IPSR_GPSR(IP3_23_20, AVB0_AVTP_PPS),
++ PINMUX_IPSR_GPSR(IP3_23_20, SDA3_A),
++
++ PINMUX_IPSR_GPSR(IP3_27_24, VI0_DATA3),
++ PINMUX_IPSR_GPSR(IP3_27_24, HSCK1),
++ PINMUX_IPSR_GPSR(IP3_27_24, SCL3_A),
++
++ PINMUX_IPSR_GPSR(IP3_31_28, VI0_DATA4),
++ PINMUX_IPSR_GPSR(IP3_31_28, HRTS1_N),
++ PINMUX_IPSR_MSEL(IP3_31_28, RX1_A, SEL_SCIF1_0),
++
++ /* IPSR4 */
++ PINMUX_IPSR_GPSR(IP4_3_0, VI0_DATA5),
++ PINMUX_IPSR_GPSR(IP4_3_0, HCTS1_N),
++ PINMUX_IPSR_MSEL(IP4_3_0, TX1_A, SEL_SCIF1_0),
++
++ PINMUX_IPSR_GPSR(IP4_7_4, VI0_DATA6),
++ PINMUX_IPSR_GPSR(IP4_7_4, HTX1),
++ PINMUX_IPSR_GPSR(IP4_7_4, CTS1_N),
++
++ PINMUX_IPSR_GPSR(IP4_11_8, VI0_DATA7),
++ PINMUX_IPSR_GPSR(IP4_11_8, HRX1),
++ PINMUX_IPSR_GPSR(IP4_11_8, RTS1_N_TANS),
++
++ PINMUX_IPSR_GPSR(IP4_15_12, VI0_DATA8),
++ PINMUX_IPSR_GPSR(IP4_15_12, HSCK2),
++ PINMUX_IPSR_MSEL(IP4_15_12, PWM0_A, SEL_PWM0_0),
++ PINMUX_IPSR_GPSR(IP4_15_12, A22),
++
++ PINMUX_IPSR_GPSR(IP4_19_16, VI0_DATA9),
++ PINMUX_IPSR_GPSR(IP4_19_16, HCTS2_N),
++ PINMUX_IPSR_MSEL(IP4_19_16, PWM1_A, SEL_PWM1_0),
++ PINMUX_IPSR_GPSR(IP4_19_16, A23),
++ PINMUX_IPSR_MSEL(IP4_19_16, FSO_CFE_0_N_B, SEL_RFSO_1),
++
++ PINMUX_IPSR_GPSR(IP4_23_20, VI0_DATA10),
++ PINMUX_IPSR_GPSR(IP4_23_20, HRTS2_N),
++ PINMUX_IPSR_MSEL(IP4_23_20, PWM2_A, SEL_PWM2_0),
++ PINMUX_IPSR_GPSR(IP4_23_20, A24),
++ PINMUX_IPSR_MSEL(IP4_23_20, FSO_CFE_1_N_B, SEL_RFSO_1),
++
++ PINMUX_IPSR_GPSR(IP4_27_24, VI0_DATA11),
++ PINMUX_IPSR_GPSR(IP4_27_24, HTX2),
++ PINMUX_IPSR_MSEL(IP4_27_24, PWM3_A, SEL_PWM3_0),
++ PINMUX_IPSR_GPSR(IP4_27_24, A25),
++ PINMUX_IPSR_MSEL(IP4_27_24, FSO_TOE_N_B, SEL_RFSO_1),
++
++ PINMUX_IPSR_GPSR(IP4_31_28, VI0_FIELD),
++ PINMUX_IPSR_GPSR(IP4_31_28, HRX2),
++ PINMUX_IPSR_MSEL(IP4_31_28, PWM4_A, SEL_PWM4_0),
++ PINMUX_IPSR_GPSR(IP4_31_28, CS1_N_A26),
++ PINMUX_IPSR_GPSR(IP4_31_28, FSCLKST2_N_A),
++
++ /* IPSR5 */
++ PINMUX_IPSR_GPSR(IP5_3_0, VI1_CLK),
++ PINMUX_IPSR_GPSR(IP5_3_0, MSIOF1_RXD),
++ PINMUX_IPSR_GPSR(IP5_3_0, CS0_N),
++
++ PINMUX_IPSR_GPSR(IP5_7_4, VI1_CLKENB),
++ PINMUX_IPSR_GPSR(IP5_7_4, MSIOF1_TXD),
++ PINMUX_IPSR_GPSR(IP5_7_4, D0),
++
++ PINMUX_IPSR_GPSR(IP5_11_8, VI1_HSYNC_N),
++ PINMUX_IPSR_GPSR(IP5_11_8, MSIOF1_SCK),
++ PINMUX_IPSR_GPSR(IP5_11_8, D1),
++
++ PINMUX_IPSR_GPSR(IP5_15_12, VI1_VSYNC_N),
++ PINMUX_IPSR_GPSR(IP5_15_12, MSIOF1_SYNC),
++ PINMUX_IPSR_GPSR(IP5_15_12, D2),
++
++ PINMUX_IPSR_GPSR(IP5_19_16, VI1_DATA0),
++ PINMUX_IPSR_GPSR(IP5_19_16, MSIOF1_SS1),
++ PINMUX_IPSR_GPSR(IP5_19_16, D3),
++
++ PINMUX_IPSR_GPSR(IP5_23_20, VI1_DATA1),
++ PINMUX_IPSR_GPSR(IP5_23_20, MSIOF1_SS2),
++ PINMUX_IPSR_GPSR(IP5_23_20, D4),
++ PINMUX_IPSR_GPSR(IP5_23_20, MMC_CMD),
++
++ PINMUX_IPSR_GPSR(IP5_27_24, VI1_DATA2),
++ PINMUX_IPSR_MSEL(IP5_27_24, CANFD0_TX_B, SEL_CANFD0_1),
++ PINMUX_IPSR_GPSR(IP5_27_24, D5),
++ PINMUX_IPSR_GPSR(IP5_27_24, MMC_D0),
++
++ PINMUX_IPSR_GPSR(IP5_31_28, VI1_DATA3),
++ PINMUX_IPSR_MSEL(IP5_31_28, CANFD0_RX_B, SEL_CANFD0_1),
++ PINMUX_IPSR_GPSR(IP5_31_28, D6),
++ PINMUX_IPSR_GPSR(IP5_31_28, MMC_D1),
++
++ /* IPSR6 */
++ PINMUX_IPSR_GPSR(IP6_3_0, VI1_DATA4),
++ PINMUX_IPSR_MSEL(IP6_3_0, CANFD_CLK_B, SEL_CANFD0_1),
++ PINMUX_IPSR_GPSR(IP6_3_0, D7),
++ PINMUX_IPSR_GPSR(IP6_3_0, MMC_D2),
++
++ PINMUX_IPSR_GPSR(IP6_7_4, VI1_DATA5),
++ PINMUX_IPSR_GPSR(IP6_7_4, SCK4),
++ PINMUX_IPSR_GPSR(IP6_7_4, D8),
++ PINMUX_IPSR_GPSR(IP6_7_4, MMC_D3),
++
++ PINMUX_IPSR_GPSR(IP6_11_8, VI1_DATA6),
++ PINMUX_IPSR_GPSR(IP6_11_8, RX4),
++ PINMUX_IPSR_GPSR(IP6_11_8, D9),
++ PINMUX_IPSR_GPSR(IP6_11_8, MMC_CLK),
++
++ PINMUX_IPSR_GPSR(IP6_15_12, VI1_DATA7),
++ PINMUX_IPSR_GPSR(IP6_15_12, TX4),
++ PINMUX_IPSR_GPSR(IP6_15_12, D10),
++ PINMUX_IPSR_GPSR(IP6_15_12, MMC_D4),
++
++ PINMUX_IPSR_GPSR(IP6_19_16, VI1_DATA8),
++ PINMUX_IPSR_GPSR(IP6_19_16, CTS4_N),
++ PINMUX_IPSR_GPSR(IP6_19_16, D11),
++ PINMUX_IPSR_GPSR(IP6_19_16, MMC_D5),
++
++ PINMUX_IPSR_GPSR(IP6_23_20, VI1_DATA9),
++ PINMUX_IPSR_GPSR(IP6_23_20, RTS4_N_TANS),
++ PINMUX_IPSR_GPSR(IP6_23_20, D12),
++ PINMUX_IPSR_GPSR(IP6_23_20, MMC_D6),
++ PINMUX_IPSR_GPSR(IP6_23_20, SCL3_B),
++
++ PINMUX_IPSR_GPSR(IP6_27_24, VI1_DATA10),
++ PINMUX_IPSR_GPSR(IP6_27_24, D13),
++ PINMUX_IPSR_GPSR(IP6_27_24, MMC_D7),
++ PINMUX_IPSR_GPSR(IP6_27_24, SDA3_B),
++
++ PINMUX_IPSR_GPSR(IP6_31_28, VI1_DATA11),
++ PINMUX_IPSR_GPSR(IP6_31_28, SCL4),
++ PINMUX_IPSR_GPSR(IP6_31_28, IRQ4),
++ PINMUX_IPSR_GPSR(IP6_31_28, D14),
++ PINMUX_IPSR_GPSR(IP6_31_28, MMC_WP),
++
++ /* IPSR7 */
++ PINMUX_IPSR_GPSR(IP7_3_0, VI1_FIELD),
++ PINMUX_IPSR_GPSR(IP7_3_0, SDA4),
++ PINMUX_IPSR_GPSR(IP7_3_0, IRQ5),
++ PINMUX_IPSR_GPSR(IP7_3_0, D15),
++ PINMUX_IPSR_GPSR(IP7_3_0, MMC_CD),
++
++ PINMUX_IPSR_GPSR(IP7_7_4, SCL0),
++ PINMUX_IPSR_GPSR(IP7_7_4, DU_DR0),
++ PINMUX_IPSR_GPSR(IP7_7_4, TPU0TO0),
++ PINMUX_IPSR_GPSR(IP7_7_4, CLKOUT),
++ PINMUX_IPSR_GPSR(IP7_7_4, MSIOF0_RXD),
++
++ PINMUX_IPSR_GPSR(IP7_11_8, SDA0),
++ PINMUX_IPSR_GPSR(IP7_11_8, DU_DR1),
++ PINMUX_IPSR_GPSR(IP7_11_8, TPU0TO1),
++ PINMUX_IPSR_GPSR(IP7_11_8, BS_N),
++ PINMUX_IPSR_GPSR(IP7_11_8, SCK0),
++ PINMUX_IPSR_GPSR(IP7_11_8, MSIOF0_TXD),
++
++ PINMUX_IPSR_GPSR(IP7_15_12, SCL1),
++ PINMUX_IPSR_GPSR(IP7_15_12, DU_DG0),
++ PINMUX_IPSR_GPSR(IP7_15_12, TPU0TO2),
++ PINMUX_IPSR_GPSR(IP7_15_12, RD_N),
++ PINMUX_IPSR_GPSR(IP7_15_12, CTS0_N),
++ PINMUX_IPSR_GPSR(IP7_15_12, MSIOF0_SCK),
++
++ PINMUX_IPSR_GPSR(IP7_19_16, SDA1),
++ PINMUX_IPSR_GPSR(IP7_19_16, DU_DG1),
++ PINMUX_IPSR_GPSR(IP7_19_16, TPU0TO3),
++ PINMUX_IPSR_GPSR(IP7_19_16, WE0_N),
++ PINMUX_IPSR_GPSR(IP7_19_16, RTS0_N_TANS),
++ PINMUX_IPSR_GPSR(IP7_19_16, MSIOF0_SYNC),
++
++ PINMUX_IPSR_GPSR(IP7_23_20, SCL2),
++ PINMUX_IPSR_GPSR(IP7_23_20, DU_DB0),
++ PINMUX_IPSR_MSEL(IP7_23_20, TCLK1_A, SEL_TMU_0),
++ PINMUX_IPSR_GPSR(IP7_23_20, WE1_N),
++ PINMUX_IPSR_GPSR(IP7_23_20, RX0),
++ PINMUX_IPSR_GPSR(IP7_23_20, MSIOF0_SS1),
++
++ PINMUX_IPSR_GPSR(IP7_27_24, SDA2),
++ PINMUX_IPSR_GPSR(IP7_27_24, DU_DB1),
++ PINMUX_IPSR_MSEL(IP7_27_24, TCLK2_A, SEL_TMU_0),
++ PINMUX_IPSR_GPSR(IP7_27_24, EX_WAIT0),
++ PINMUX_IPSR_GPSR(IP7_27_24, TX0),
++ PINMUX_IPSR_GPSR(IP7_27_24, MSIOF0_SS2),
++
++ PINMUX_IPSR_GPSR(IP7_31_28, AVB0_AVTP_CAPTURE),
++ PINMUX_IPSR_GPSR(IP7_31_28, FSCLKST2_N_B),
++
++ /* IPSR8 */
++ PINMUX_IPSR_MSEL(IP8_3_0, CANFD0_TX_A, SEL_CANFD0_0),
++ PINMUX_IPSR_GPSR(IP8_3_0, FXR_TXDA),
++ PINMUX_IPSR_MSEL(IP8_3_0, PWM0_B, SEL_PWM0_1),
++ PINMUX_IPSR_GPSR(IP8_3_0, DU_DISP),
++ PINMUX_IPSR_GPSR(IP8_3_0, FSCLKST2_N_C),
++
++ PINMUX_IPSR_MSEL(IP8_7_4, CANFD0_RX_A, SEL_CANFD0_0),
++ PINMUX_IPSR_GPSR(IP8_7_4, RXDA_EXTFXR),
++ PINMUX_IPSR_MSEL(IP8_7_4, PWM1_B, SEL_PWM1_1),
++ PINMUX_IPSR_GPSR(IP8_7_4, DU_CDE),
++
++ PINMUX_IPSR_GPSR(IP8_11_8, CANFD1_TX),
++ PINMUX_IPSR_GPSR(IP8_11_8, FXR_TXDB),
++ PINMUX_IPSR_MSEL(IP8_11_8, PWM2_B, SEL_PWM2_1),
++ PINMUX_IPSR_MSEL(IP8_11_8, TCLK1_B, SEL_TMU_1),
++ PINMUX_IPSR_MSEL(IP8_11_8, TX1_B, SEL_SCIF1_1),
++
++ PINMUX_IPSR_GPSR(IP8_15_12, CANFD1_RX),
++ PINMUX_IPSR_GPSR(IP8_15_12, RXDB_EXTFXR),
++ PINMUX_IPSR_MSEL(IP8_15_12, PWM3_B, SEL_PWM3_1),
++ PINMUX_IPSR_MSEL(IP8_15_12, TCLK2_B, SEL_TMU_1),
++ PINMUX_IPSR_MSEL(IP8_15_12, RX1_B, SEL_SCIF1_1),
++
++ PINMUX_IPSR_MSEL(IP8_19_16, CANFD_CLK_A, SEL_CANFD0_0),
++ PINMUX_IPSR_GPSR(IP8_19_16, CLK_EXTFXR),
++ PINMUX_IPSR_MSEL(IP8_19_16, PWM4_B, SEL_PWM4_1),
++ PINMUX_IPSR_MSEL(IP8_19_16, SPEEDIN_B, SEL_RSP_0),
++ PINMUX_IPSR_MSEL(IP8_19_16, SCIF_CLK_B, SEL_HSCIF0_1),
++
++ PINMUX_IPSR_GPSR(IP8_23_20, DIGRF_CLKIN),
++ PINMUX_IPSR_GPSR(IP8_23_20, DIGRF_CLKEN_IN),
++
++ PINMUX_IPSR_GPSR(IP8_27_24, DIGRF_CLKOUT),
++ PINMUX_IPSR_GPSR(IP8_27_24, DIGRF_CLKEN_OUT),
++};
++
++static const struct sh_pfc_pin pinmux_pins[] = {
++ PINMUX_GPIO_GP_ALL(),
++};
++
++/* - EtherAVB --------------------------------------------------------------- */
++static const unsigned int avb0_rx_ctrl_pins[] = {
++ /* AVB0_RX_CTL */
++ RCAR_GP_PIN(1, 1),
++};
++static const unsigned int avb0_rx_ctrl_mux[] = {
++ AVB0_RX_CTL_MARK,
++};
++static const unsigned int avb0_rxc_pins[] = {
++ /* AVB0_RXC */
++ RCAR_GP_PIN(1, 2),
++};
++static const unsigned int avb0_rxc_mux[] = {
++ AVB0_RXC_MARK,
++};
++static const unsigned int avb0_rd0_pins[] = {
++ /* AVB0_RD[0] */
++ RCAR_GP_PIN(1, 3),
++};
++static const unsigned int avb0_rd0_mux[] = {
++ AVB0_RD0_MARK,
++};
++static const unsigned int avb0_rd1_pins[] = {
++ /* AVB0_RD[1] */
++ RCAR_GP_PIN(1, 4),
++};
++static const unsigned int avb0_rd1_mux[] = {
++ AVB0_RD1_MARK,
++};
++static const unsigned int avb0_rd2_pins[] = {
++ /* AVB0_RD[2] */
++ RCAR_GP_PIN(1, 5),
++};
++static const unsigned int avb0_rd2_mux[] = {
++ AVB0_RD2_MARK,
++};
++static const unsigned int avb0_rd3_pins[] = {
++ /* AVB0_RD[3] */
++ RCAR_GP_PIN(1, 6),
++};
++static const unsigned int avb0_rd3_mux[] = {
++ AVB0_RD3_MARK,
++};
++static const unsigned int avb0_rd4_pins[] = {
++ /* AVB0_RD[3:0] */
++ RCAR_GP_PIN(1, 3), RCAR_GP_PIN(1, 4),
++ RCAR_GP_PIN(1, 5), RCAR_GP_PIN(1, 6),
++};
++static const unsigned int avb0_rd4_mux[] = {
++ AVB0_RD0_MARK, AVB0_RD1_MARK,
++ AVB0_RD2_MARK, AVB0_RD3_MARK,
++};
++static const unsigned int avb0_tx_ctrl_pins[] = {
++ /* AVB0_TX_CTL */
++ RCAR_GP_PIN(1, 7),
++};
++static const unsigned int avb0_tx_ctrl_mux[] = {
++ AVB0_TX_CTL_MARK,
++};
++static const unsigned int avb0_txc_pins[] = {
++ /* AVB0_TXC */
++ RCAR_GP_PIN(1, 8),
++};
++static const unsigned int avb0_txc_mux[] = {
++ AVB0_TXC_MARK,
++};
++static const unsigned int avb0_td0_pins[] = {
++ /* AVB0_TD[0] */
++ RCAR_GP_PIN(1, 9),
++};
++static const unsigned int avb0_td0_mux[] = {
++ AVB0_TD0_MARK,
++};
++static const unsigned int avb0_td1_pins[] = {
++ /* AVB0_TD[1] */
++ RCAR_GP_PIN(1, 10),
++};
++static const unsigned int avb0_td1_mux[] = {
++ AVB0_TD1_MARK,
++};
++static const unsigned int avb0_td2_pins[] = {
++ /* AVB0_TD[2] */
++ RCAR_GP_PIN(1, 11),
++};
++static const unsigned int avb0_td2_mux[] = {
++ AVB0_TD2_MARK,
++};
++static const unsigned int avb0_td3_pins[] = {
++ /* AVB0_TD[3] */
++ RCAR_GP_PIN(1, 12),
++};
++static const unsigned int avb0_td3_mux[] = {
++ AVB0_TD3_MARK,
++};
++static const unsigned int avb0_td4_pins[] = {
++ /* AVB0_TD[3:0] */
++ RCAR_GP_PIN(1, 9), RCAR_GP_PIN(1, 10),
++ RCAR_GP_PIN(1, 11), RCAR_GP_PIN(1, 12),
++};
++static const unsigned int avb0_td4_mux[] = {
++ AVB0_TD0_MARK, AVB0_TD1_MARK,
++ AVB0_TD2_MARK, AVB0_TD3_MARK,
++};
++static const unsigned int avb0_txcrefclk_pins[] = {
++ /* AVB0_TXCREFCLK */
++ RCAR_GP_PIN(1, 13),
++};
++static const unsigned int avb0_txcrefclk_mux[] = {
++ AVB0_TXCREFCLK_MARK,
++};
++static const unsigned int avb0_mdio_pins[] = {
++ /* AVB0_MDIO */
++ RCAR_GP_PIN(1, 14),
++};
++static const unsigned int avb0_mdio_mux[] = {
++ AVB0_MDIO_MARK,
++};
++static const unsigned int avb0_mdc_pins[] = {
++ /* AVB0_MDC */
++ RCAR_GP_PIN(1, 15),
++};
++static const unsigned int avb0_mdc_mux[] = {
++ AVB0_MDC_MARK,
++};
++static const unsigned int avb0_magic_pins[] = {
++ /* AVB0_MAGIC */
++ RCAR_GP_PIN(1, 16),
++};
++static const unsigned int avb0_magic_mux[] = {
++ AVB0_MAGIC_MARK,
++};
++static const unsigned int avb0_phy_int_pins[] = {
++ /* AVB0_PHY_INT */
++ RCAR_GP_PIN(1, 17),
++};
++static const unsigned int avb0_phy_int_mux[] = {
++ AVB0_PHY_INT_MARK,
++};
++static const unsigned int avb0_link_pins[] = {
++ /* AVB0_LINK */
++ RCAR_GP_PIN(1, 18),
++};
++static const unsigned int avb0_link_mux[] = {
++ AVB0_LINK_MARK,
++};
++static const unsigned int avb0_avtp_match_pins[] = {
++ /* AVB0_AVTP_MATCH */
++ RCAR_GP_PIN(1, 19),
++};
++static const unsigned int avb0_avtp_match_mux[] = {
++ AVB0_AVTP_MATCH_MARK,
++};
++static const unsigned int avb0_avtp_pps_pins[] = {
++ /* AVB0_AVTP_PPS */
++ RCAR_GP_PIN(2, 6),
++};
++static const unsigned int avb0_avtp_pps_mux[] = {
++ AVB0_AVTP_PPS_MARK,
++};
++static const unsigned int avb0_avtp_capture_pins[] = {
++ /* AVB0_AVTP_CAPTURE */
++ RCAR_GP_PIN(1, 20),
++};
++static const unsigned int avb0_avtp_capture_mux[] = {
++ AVB0_AVTP_CAPTURE_MARK,
++};
++
++/* - CANFD0 ----------------------------------------------------------------- */
++static const unsigned int canfd0_data_a_pins[] = {
++ /* TX, RX */
++ RCAR_GP_PIN(1, 21), RCAR_GP_PIN(1, 22),
++};
++static const unsigned int canfd0_data_a_mux[] = {
++ CANFD0_TX_A_MARK, CANFD0_RX_A_MARK,
++};
++static const unsigned int canfd_clk_a_pins[] = {
++ /* CLK */
++ RCAR_GP_PIN(1, 25),
++};
++static const unsigned int canfd_clk_a_mux[] = {
++ CANFD_CLK_A_MARK,
++};
++static const unsigned int canfd0_data_b_pins[] = {
++ /* TX, RX */
++ RCAR_GP_PIN(3, 6), RCAR_GP_PIN(3, 7),
++};
++static const unsigned int canfd0_data_b_mux[] = {
++ CANFD0_TX_B_MARK, CANFD0_RX_B_MARK,
++};
++static const unsigned int canfd_clk_b_pins[] = {
++ /* CLK */
++ RCAR_GP_PIN(3, 8),
++};
++static const unsigned int canfd_clk_b_mux[] = {
++ CANFD_CLK_B_MARK,
++};
++
++/* - CANFD1 ----------------------------------------------------------------- */
++static const unsigned int canfd1_data_pins[] = {
++ /* TX, RX */
++ RCAR_GP_PIN(1, 23), RCAR_GP_PIN(1, 24),
++};
++static const unsigned int canfd1_data_mux[] = {
++ CANFD1_TX_MARK, CANFD1_RX_MARK,
++};
++
++/* - DU --------------------------------------------------------------------- */
++static const unsigned int du_rgb666_pins[] = {
++ /* R[7:0] */
++ RCAR_GP_PIN(0, 5), RCAR_GP_PIN(0, 4),
++ RCAR_GP_PIN(0, 3), RCAR_GP_PIN(0, 2),
++ RCAR_GP_PIN(0, 1), RCAR_GP_PIN(0, 0),
++ /* G[7:0] */
++ RCAR_GP_PIN(0, 11), RCAR_GP_PIN(0, 10),
++ RCAR_GP_PIN(0, 9), RCAR_GP_PIN(0, 8),
++ RCAR_GP_PIN(0, 7), RCAR_GP_PIN(0, 6),
++ /* B[7:0] */
++ RCAR_GP_PIN(0, 17), RCAR_GP_PIN(0, 16),
++ RCAR_GP_PIN(0, 15), RCAR_GP_PIN(0, 14),
++ RCAR_GP_PIN(0, 13), RCAR_GP_PIN(0, 12),
++};
++static const unsigned int du_rgb666_mux[] = {
++ DU_DR7_MARK, DU_DR6_MARK,
++ DU_DR5_MARK, DU_DR4_MARK,
++ DU_DR3_MARK, DU_DR2_MARK,
++ DU_DG7_MARK, DU_DG6_MARK,
++ DU_DG5_MARK, DU_DG4_MARK,
++ DU_DG3_MARK, DU_DG2_MARK,
++ DU_DB7_MARK, DU_DB6_MARK,
++ DU_DB5_MARK, DU_DB4_MARK,
++ DU_DB3_MARK, DU_DB2_MARK,
++};
++static const unsigned int du_clk_out_0_pins[] = {
++ /* CLKOUT0 */
++ RCAR_GP_PIN(0, 18),
++};
++static const unsigned int du_clk_out_0_mux[] = {
++ DU_DOTCLKOUT_MARK,
++};
++static const unsigned int du_clk_out_1_pins[] = {
++ /* CLKOUT1 */
++ RCAR_GP_PIN(0, 18), /* @@ */
++};
++static const unsigned int du_clk_out_1_mux[] = {
++ DU_DOTCLKOUT_MARK,
++};
++static const unsigned int du_sync_pins[] = {
++ /* EXVSYNC/VSYNC, EXHSYNC/HSYNC */
++ RCAR_GP_PIN(0, 20), RCAR_GP_PIN(0, 19),
++};
++static const unsigned int du_sync_mux[] = {
++ DU_EXVSYNC_DU_VSYNC_MARK, DU_EXHSYNC_DU_HSYNC_MARK,
++};
++static const unsigned int du_oddf_pins[] = {
++ /* EXDISP/EXODDF/EXCDE */
++ RCAR_GP_PIN(0, 21),
++};
++static const unsigned int du_oddf_mux[] = {
++ DU_EXODDF_DU_ODDF_DISP_CDE_MARK,
++};
++static const unsigned int du_cde_pins[] = {
++ /* CDE */
++ RCAR_GP_PIN(1, 22),
++};
++static const unsigned int du_cde_mux[] = {
++ DU_CDE_MARK,
++};
++static const unsigned int du_disp_pins[] = {
++ /* DISP */
++ RCAR_GP_PIN(1, 21),
++};
++static const unsigned int du_disp_mux[] = {
++ DU_DISP_MARK,
++};
++
++/* - HSCIF0 ----------------------------------------------------------------- */
++static const unsigned int hscif0_data_pins[] = {
++ /* HRX0, HTX0 */
++ RCAR_GP_PIN(0, 19), RCAR_GP_PIN(0, 3),
++};
++static const unsigned int hscif0_data_mux[] = {
++ HRX0_MARK, HTX0_MARK,
++};
++static const unsigned int hscif0_clk_pins[] = {
++ /* HSCK0 */
++ RCAR_GP_PIN(0, 0),
++};
++static const unsigned int hscif0_clk_mux[] = {
++ HSCK0_MARK,
++};
++static const unsigned int hscif0_ctrl_pins[] = {
++ /* HRTS0#, HCTS0# */
++ RCAR_GP_PIN(0, 1), RCAR_GP_PIN(0, 2),
++};
++static const unsigned int hscif0_ctrl_mux[] = {
++ HRTS0_N_MARK, HCTS0_N_MARK,
++};
++
++/* - HSCIF1 ----------------------------------------------------------------- */
++static const unsigned int hscif1_data_pins[] = {
++ /* HRX1, HTX1 */
++ RCAR_GP_PIN(2, 11), RCAR_GP_PIN(2, 10),
++};
++static const unsigned int hscif1_data_mux[] = {
++ HRX1_MARK, HTX1_MARK,
++};
++static const unsigned int hscif1_clk_pins[] = {
++ /* HSCK1 */
++ RCAR_GP_PIN(2, 7),
++};
++static const unsigned int hscif1_clk_mux[] = {
++ HSCK1_MARK,
++};
++static const unsigned int hscif1_ctrl_pins[] = {
++ /* HRTS1#, HCTS1# */
++ RCAR_GP_PIN(2, 8), RCAR_GP_PIN(2, 9),
++};
++static const unsigned int hscif1_ctrl_mux[] = {
++ HRTS1_N_MARK, HCTS1_N_MARK,
++};
++
++/* - HSCIF2 ----------------------------------------------------------------- */
++static const unsigned int hscif2_data_pins[] = {
++ /* HRX2, HTX2 */
++ RCAR_GP_PIN(2, 16), RCAR_GP_PIN(2, 15),
++};
++static const unsigned int hscif2_data_mux[] = {
++ HRX2_MARK, HTX2_MARK,
++};
++static const unsigned int hscif2_clk_pins[] = {
++ /* HSCK2 */
++ RCAR_GP_PIN(2, 12),
++};
++static const unsigned int hscif2_clk_mux[] = {
++ HSCK2_MARK,
++};
++static const unsigned int hscif2_ctrl_pins[] = {
++ /* HRTS2#, HCTS2# */
++ RCAR_GP_PIN(2, 14), RCAR_GP_PIN(2, 13),
++};
++static const unsigned int hscif2_ctrl_mux[] = {
++ HRTS2_N_MARK, HCTS2_N_MARK,
++};
++
++/* - HSCIF3 ----------------------------------------------------------------- */
++static const unsigned int hscif3_data_pins[] = {
++ /* HRX3, HTX3 */
++ RCAR_GP_PIN(2, 4), RCAR_GP_PIN(2, 3),
++};
++static const unsigned int hscif3_data_mux[] = {
++ HRX3_MARK, HTX3_MARK,
++};
++static const unsigned int hscif3_clk_pins[] = {
++ /* HSCK3 */
++ RCAR_GP_PIN(2, 0),
++};
++static const unsigned int hscif3_clk_mux[] = {
++ HSCK3_MARK,
++};
++static const unsigned int hscif3_ctrl_pins[] = {
++ /* HRTS3#, HCTS3# */
++ RCAR_GP_PIN(2, 2), RCAR_GP_PIN(2, 1),
++};
++static const unsigned int hscif3_ctrl_mux[] = {
++ HRTS3_N_MARK, HCTS3_N_MARK,
++};
++
++/* - SCIF Clock ------------------------------------------------------------- */
++static const unsigned int scif_clk_a_pins[] = {
++ /* SCIF_CLK */
++ RCAR_GP_PIN(0, 18),
++};
++static const unsigned int scif_clk_a_mux[] = {
++ SCIF_CLK_A_MARK,
++};
++static const unsigned int scif_clk_b_pins[] = {
++ /* SCIF_CLK */
++ RCAR_GP_PIN(1, 25),
++};
++static const unsigned int scif_clk_b_mux[] = {
++ SCIF_CLK_B_MARK,
++};
++
++/* - I2C -------------------------------------------------------------------- */
++static const unsigned int i2c0_pins[] = {
++ /* SDA0, SCL0 */
++ RCAR_GP_PIN(4, 1), RCAR_GP_PIN(4, 0),
++};
++static const unsigned int i2c0_mux[] = {
++ SDA0_MARK, SCL0_MARK,
++};
++static const unsigned int i2c1_pins[] = {
++ /* SDA1, SCL1 */
++ RCAR_GP_PIN(4, 3), RCAR_GP_PIN(4, 2),
++};
++static const unsigned int i2c1_mux[] = {
++ SDA1_MARK, SCL1_MARK,
++};
++static const unsigned int i2c2_pins[] = {
++ /* SDA2, SCL2 */
++ RCAR_GP_PIN(4, 5), RCAR_GP_PIN(4, 4),
++};
++static const unsigned int i2c2_mux[] = {
++ SDA2_MARK, SCL2_MARK,
++};
++static const unsigned int i2c3_pins[] = {
++ /* SDA3_A, SCL3_A */
++ RCAR_GP_PIN(2, 6), RCAR_GP_PIN(2, 5),
++};
++static const unsigned int i2c3_mux[] = {
++ SDA3_A_MARK, SCL3_A_MARK,
++};
++static const unsigned int i2c4_pins[] = {
++ /* SDA4, SCL4 */
++ RCAR_GP_PIN(3, 16), RCAR_GP_PIN(3, 15),
++};
++static const unsigned int i2c4_mux[] = {
++ SDA4_MARK, SCL4_MARK,
++};
++
++/* - INTC-EX ---------------------------------------------------------------- */
++static const unsigned int intc_ex_irq0_pins[] = {
++ /* IRQ0 */
++ RCAR_GP_PIN(1, 0),
++};
++static const unsigned int intc_ex_irq0_mux[] = {
++ IRQ0_MARK,
++};
++static const unsigned int intc_ex_irq1_pins[] = {
++ /* IRQ1 */
++ RCAR_GP_PIN(0, 11),
++};
++static const unsigned int intc_ex_irq1_mux[] = {
++ IRQ1_MARK,
++};
++static const unsigned int intc_ex_irq2_pins[] = {
++ /* IRQ2 */
++ RCAR_GP_PIN(0, 12),
++};
++static const unsigned int intc_ex_irq2_mux[] = {
++ IRQ2_MARK,
++};
++static const unsigned int intc_ex_irq3_pins[] = {
++ /* IRQ3 */
++ RCAR_GP_PIN(0, 19),
++};
++static const unsigned int intc_ex_irq3_mux[] = {
++ IRQ3_MARK,
++};
++static const unsigned int intc_ex_irq4_pins[] = {
++ /* IRQ4 */
++ RCAR_GP_PIN(3, 15),
++};
++static const unsigned int intc_ex_irq4_mux[] = {
++ IRQ4_MARK,
++};
++static const unsigned int intc_ex_irq5_pins[] = {
++ /* IRQ5 */
++ RCAR_GP_PIN(3, 16),
++};
++static const unsigned int intc_ex_irq5_mux[] = {
++ IRQ5_MARK,
++};
++
++/* - MSIOF0 ----------------------------------------------------------------- */
++static const unsigned int msiof0_clk_pins[] = {
++ /* SCK */
++ RCAR_GP_PIN(4, 2),
++};
++static const unsigned int msiof0_clk_mux[] = {
++ MSIOF0_SCK_MARK,
++};
++static const unsigned int msiof0_sync_pins[] = {
++ /* SYNC */
++ RCAR_GP_PIN(4, 3),
++};
++static const unsigned int msiof0_sync_mux[] = {
++ MSIOF0_SYNC_MARK,
++};
++static const unsigned int msiof0_ss1_pins[] = {
++ /* SS1 */
++ RCAR_GP_PIN(4, 4),
++};
++static const unsigned int msiof0_ss1_mux[] = {
++ MSIOF0_SS1_MARK,
++};
++static const unsigned int msiof0_ss2_pins[] = {
++ /* SS2 */
++ RCAR_GP_PIN(4, 5),
++};
++static const unsigned int msiof0_ss2_mux[] = {
++ MSIOF0_SS2_MARK,
++};
++static const unsigned int msiof0_txd_pins[] = {
++ /* TXD */
++ RCAR_GP_PIN(4, 1),
++};
++static const unsigned int msiof0_txd_mux[] = {
++ MSIOF0_TXD_MARK,
++};
++static const unsigned int msiof0_rxd_pins[] = {
++ /* RXD */
++ RCAR_GP_PIN(4, 0),
++};
++static const unsigned int msiof0_rxd_mux[] = {
++ MSIOF0_RXD_MARK,
++};
++
++/* - MSIOF1 ----------------------------------------------------------------- */
++static const unsigned int msiof1_clk_pins[] = {
++ /* SCK */
++ RCAR_GP_PIN(3, 2),
++};
++static const unsigned int msiof1_clk_mux[] = {
++ MSIOF1_SCK_MARK,
++};
++static const unsigned int msiof1_sync_pins[] = {
++ /* SYNC */
++ RCAR_GP_PIN(3, 3),
++};
++static const unsigned int msiof1_sync_mux[] = {
++ MSIOF1_SYNC_MARK,
++};
++static const unsigned int msiof1_ss1_pins[] = {
++ /* SS1 */
++ RCAR_GP_PIN(3, 4),
++};
++static const unsigned int msiof1_ss1_mux[] = {
++ MSIOF1_SS1_MARK,
++};
++static const unsigned int msiof1_ss2_pins[] = {
++ /* SS2 */
++ RCAR_GP_PIN(3, 5),
++};
++static const unsigned int msiof1_ss2_mux[] = {
++ MSIOF1_SS2_MARK,
++};
++static const unsigned int msiof1_txd_pins[] = {
++ /* TXD */
++ RCAR_GP_PIN(3, 1),
++};
++static const unsigned int msiof1_txd_mux[] = {
++ MSIOF1_TXD_MARK,
++};
++static const unsigned int msiof1_rxd_pins[] = {
++ /* RXD */
++ RCAR_GP_PIN(3, 0),
++};
++static const unsigned int msiof1_rxd_mux[] = {
++ MSIOF1_RXD_MARK,
++};
++
++/* - MSIOF2 ----------------------------------------------------------------- */
++static const unsigned int msiof2_clk_pins[] = {
++ /* SCK */
++ RCAR_GP_PIN(2, 0),
++};
++static const unsigned int msiof2_clk_mux[] = {
++ MSIOF2_SCK_MARK,
++};
++static const unsigned int msiof2_sync_pins[] = {
++ /* SYNC */
++ RCAR_GP_PIN(2, 3),
++};
++static const unsigned int msiof2_sync_mux[] = {
++ MSIOF2_SYNC_MARK,
++};
++static const unsigned int msiof2_ss1_pins[] = {
++ /* SS1 */
++ RCAR_GP_PIN(2, 4),
++};
++static const unsigned int msiof2_ss1_mux[] = {
++ MSIOF2_SS1_MARK,
++};
++static const unsigned int msiof2_ss2_pins[] = {
++ /* SS2 */
++ RCAR_GP_PIN(2, 5),
++};
++static const unsigned int msiof2_ss2_mux[] = {
++ MSIOF2_SS2_MARK,
++};
++static const unsigned int msiof2_txd_pins[] = {
++ /* TXD */
++ RCAR_GP_PIN(2, 2),
++};
++static const unsigned int msiof2_txd_mux[] = {
++ MSIOF2_TXD_MARK,
++};
++static const unsigned int msiof2_rxd_pins[] = {
++ /* RXD */
++ RCAR_GP_PIN(2, 1),
++};
++static const unsigned int msiof2_rxd_mux[] = {
++ MSIOF2_RXD_MARK,
++};
++
++/* - MSIOF3 ----------------------------------------------------------------- */
++static const unsigned int msiof3_clk_pins[] = {
++ /* SCK */
++ RCAR_GP_PIN(0, 20),
++};
++static const unsigned int msiof3_clk_mux[] = {
++ MSIOF3_SCK_MARK,
++};
++static const unsigned int msiof3_sync_pins[] = {
++ /* SYNC */
++ RCAR_GP_PIN(0, 21),
++};
++static const unsigned int msiof3_sync_mux[] = {
++ MSIOF3_SYNC_MARK,
++};
++static const unsigned int msiof3_ss1_pins[] = {
++ /* SS1 */
++ RCAR_GP_PIN(0, 6),
++};
++static const unsigned int msiof3_ss1_mux[] = {
++ MSIOF3_SS1_MARK,
++};
++static const unsigned int msiof3_ss2_pins[] = {
++ /* SS2 */
++ RCAR_GP_PIN(0, 7),
++};
++static const unsigned int msiof3_ss2_mux[] = {
++ MSIOF3_SS2_MARK,
++};
++static const unsigned int msiof3_txd_pins[] = {
++ /* TXD */
++ RCAR_GP_PIN(0, 5),
++};
++static const unsigned int msiof3_txd_mux[] = {
++ MSIOF3_TXD_MARK,
++};
++static const unsigned int msiof3_rxd_pins[] = {
++ /* RXD */
++ RCAR_GP_PIN(0, 4),
++};
++static const unsigned int msiof3_rxd_mux[] = {
++ MSIOF3_RXD_MARK,
++};
++
++/* - PWM0 ------------------------------------------------------------------- */
++static const unsigned int pwm0_a_pins[] = {
++ /* PWM0 */
++ RCAR_GP_PIN(2, 12),
++};
++static const unsigned int pwm0_a_mux[] = {
++ PWM0_A_MARK,
++};
++static const unsigned int pwm0_b_pins[] = {
++ /* PWM0 */
++ RCAR_GP_PIN(1, 21),
++};
++static const unsigned int pwm0_b_mux[] = {
++ PWM0_B_MARK,
++};
++
++/* - PWM1 ------------------------------------------------------------------- */
++static const unsigned int pwm1_a_pins[] = {
++ /* PWM1 */
++ RCAR_GP_PIN(2, 13),
++};
++static const unsigned int pwm1_a_mux[] = {
++ PWM1_A_MARK,
++};
++static const unsigned int pwm1_b_pins[] = {
++ /* PWM1 */
++ RCAR_GP_PIN(1, 22),
++};
++static const unsigned int pwm1_b_mux[] = {
++ PWM1_B_MARK,
++};
++
++/* - PWM2 ------------------------------------------------------------------- */
++static const unsigned int pwm2_a_pins[] = {
++ /* PWM2 */
++ RCAR_GP_PIN(2, 14),
++};
++static const unsigned int pwm2_a_mux[] = {
++ PWM2_A_MARK,
++};
++static const unsigned int pwm2_b_pins[] = {
++ /* PWM2 */
++ RCAR_GP_PIN(1, 23),
++};
++static const unsigned int pwm2_b_mux[] = {
++ PWM2_B_MARK,
++};
++
++/* - PWM3 ------------------------------------------------------------------- */
++static const unsigned int pwm3_a_pins[] = {
++ /* PWM3 */
++ RCAR_GP_PIN(2, 15),
++};
++static const unsigned int pwm3_a_mux[] = {
++ PWM3_A_MARK,
++};
++static const unsigned int pwm3_b_pins[] = {
++ /* PWM3 */
++ RCAR_GP_PIN(1, 24),
++};
++static const unsigned int pwm3_b_mux[] = {
++ PWM3_B_MARK,
++};
++
++/* - PWM4 ------------------------------------------------------------------- */
++static const unsigned int pwm4_a_pins[] = {
++ /* PWM4 */
++ RCAR_GP_PIN(2, 16),
++};
++static const unsigned int pwm4_a_mux[] = {
++ PWM4_A_MARK,
++};
++static const unsigned int pwm4_b_pins[] = {
++ /* PWM4 */
++ RCAR_GP_PIN(1, 25),
++};
++static const unsigned int pwm4_b_mux[] = {
++ PWM4_B_MARK,
++};
++
++/* - SCIF0 ------------------------------------------------------------------ */
++static const unsigned int scif0_data_pins[] = {
++ /* RX, TX */
++ RCAR_GP_PIN(4, 4), RCAR_GP_PIN(4, 5),
++};
++static const unsigned int scif0_data_mux[] = {
++ RX0_MARK, TX0_MARK,
++};
++static const unsigned int scif0_clk_pins[] = {
++ /* SCK */
++ RCAR_GP_PIN(4, 1),
++};
++static const unsigned int scif0_clk_mux[] = {
++ SCK0_MARK,
++};
++
++static const unsigned int scif0_ctrl_pins[] = {
++ /* RTS, CTS */
++ RCAR_GP_PIN(4, 3), RCAR_GP_PIN(4, 2),
++};
++static const unsigned int scif0_ctrl_mux[] = {
++ RTS0_N_TANS_MARK, CTS0_N_MARK,
++};
++
++/* - SCIF1 ------------------------------------------------------------------ */
++static const unsigned int scif1_data_a_pins[] = {
++ /* RX, TX */
++ RCAR_GP_PIN(2, 8), RCAR_GP_PIN(2, 9),
++};
++static const unsigned int scif1_data_a_mux[] = {
++ RX1_A_MARK, TX1_A_MARK,
++};
++static const unsigned int scif1_clk_pins[] = {
++ /* SCK */
++ RCAR_GP_PIN(2, 5),
++};
++static const unsigned int scif1_clk_mux[] = {
++ SCK1_MARK,
++};
++static const unsigned int scif1_ctrl_pins[] = {
++ /* RTS, CTS */
++ RCAR_GP_PIN(2, 11), RCAR_GP_PIN(2, 10),
++};
++static const unsigned int scif1_ctrl_mux[] = {
++ RTS1_N_TANS_MARK, CTS1_N_MARK,
++};
++static const unsigned int scif1_data_b_pins[] = {
++ /* RX, TX */
++ RCAR_GP_PIN(1, 24), RCAR_GP_PIN(1, 23),
++};
++static const unsigned int scif1_data_b_mux[] = {
++ RX1_B_MARK, TX1_B_MARK,
++};
++
++/* - SCIF3 ------------------------------------------------------------------ */
++static const unsigned int scif3_data_pins[] = {
++ /* RX, TX */
++ RCAR_GP_PIN(2, 1), RCAR_GP_PIN(2, 2),
++};
++static const unsigned int scif3_data_mux[] = {
++ RX3_MARK, TX3_MARK,
++};
++static const unsigned int scif3_clk_pins[] = {
++ /* SCK */
++ RCAR_GP_PIN(2, 0),
++};
++static const unsigned int scif3_clk_mux[] = {
++ SCK3_MARK,
++};
++static const unsigned int scif3_ctrl_pins[] = {
++ /* RTS, CTS */
++ RCAR_GP_PIN(2, 4), RCAR_GP_PIN(2, 3),
++};
++static const unsigned int scif3_ctrl_mux[] = {
++ RTS3_N_TANS_MARK, CTS3_N_MARK,
++};
++
++/* - SCIF4 ------------------------------------------------------------------ */
++static const unsigned int scif4_data_pins[] = {
++ /* RX, TX */
++ RCAR_GP_PIN(3, 10), RCAR_GP_PIN(3, 11),
++};
++static const unsigned int scif4_data_mux[] = {
++ RX4_MARK, TX4_MARK,
++};
++static const unsigned int scif4_clk_pins[] = {
++ /* SCK */
++ RCAR_GP_PIN(3, 9),
++};
++static const unsigned int scif4_clk_mux[] = {
++ SCK4_MARK,
++};
++static const unsigned int scif4_ctrl_pins[] = {
++ /* RTS, CTS */
++ RCAR_GP_PIN(3, 13), RCAR_GP_PIN(3, 12),
++};
++static const unsigned int scif4_ctrl_mux[] = {
++ RTS4_N_TANS_MARK, CTS4_N_MARK,
++};
++
++/* - MMC -------------------------------------------------------------------- */
++static const unsigned int mmc_data1_pins[] = {
++ /* D0 */
++ RCAR_GP_PIN(3, 6),
++};
++static const unsigned int mmc_data1_mux[] = {
++ MMC_D0_MARK,
++};
++static const unsigned int mmc_data4_pins[] = {
++ /* D[0:3] */
++ RCAR_GP_PIN(3, 6), RCAR_GP_PIN(3, 7),
++ RCAR_GP_PIN(3, 8), RCAR_GP_PIN(3, 9),
++};
++static const unsigned int mmc_data4_mux[] = {
++ MMC_D0_MARK, MMC_D1_MARK,
++ MMC_D2_MARK, MMC_D3_MARK,
++};
++static const unsigned int mmc_data8_pins[] = {
++ /* D[0:7] */
++ RCAR_GP_PIN(3, 6), RCAR_GP_PIN(3, 7),
++ RCAR_GP_PIN(3, 8), RCAR_GP_PIN(3, 9),
++ RCAR_GP_PIN(3, 11), RCAR_GP_PIN(3, 12),
++ RCAR_GP_PIN(3, 13), RCAR_GP_PIN(3, 14),
++};
++static const unsigned int mmc_data8_mux[] = {
++ MMC_D0_MARK, MMC_D1_MARK,
++ MMC_D2_MARK, MMC_D3_MARK,
++ MMC_D4_MARK, MMC_D5_MARK,
++ MMC_D6_MARK, MMC_D7_MARK,
++};
++static const unsigned int mmc_ctrl_pins[] = {
++ /* CLK, CMD */
++ RCAR_GP_PIN(3,10), RCAR_GP_PIN(3, 5),
++};
++static const unsigned int mmc_ctrl_mux[] = {
++ MMC_CLK_MARK, MMC_CMD_MARK,
++};
++static const unsigned int mmc_cd_pins[] = {
++ /* CD */
++ RCAR_GP_PIN(3, 16),
++};
++static const unsigned int mmc_cd_mux[] = {
++ MMC_CD_MARK,
++};
++static const unsigned int mmc_wp_pins[] = {
++ /* WP */
++ RCAR_GP_PIN(3, 15),
++};
++static const unsigned int mmc_wp_mux[] = {
++ MMC_WP_MARK,
++};
++
++/* - TMU -------------------------------------------------------------------- */
++static const unsigned int tmu_tclk1_a_pins[] = {
++ /* TCLK1 */
++ RCAR_GP_PIN(4, 4),
++};
++static const unsigned int tmu_tclk1_a_mux[] = {
++ TCLK1_A_MARK,
++};
++static const unsigned int tmu_tclk1_b_pins[] = {
++ /* TCLK1 */
++ RCAR_GP_PIN(1, 23),
++};
++static const unsigned int tmu_tclk1_b_mux[] = {
++ TCLK1_B_MARK,
++};
++static const unsigned int tmu_tclk2_a_pins[] = {
++ /* TCLK2 */
++ RCAR_GP_PIN(4, 5),
++};
++static const unsigned int tmu_tclk2_a_mux[] = {
++ TCLK2_A_MARK,
++};
++static const unsigned int tmu_tclk2_b_pins[] = {
++ /* TCLK2 */
++ RCAR_GP_PIN(1, 24),
++};
++static const unsigned int tmu_tclk2_b_mux[] = {
++ TCLK2_B_MARK,
++};
++
++/* - VIN0 ------------------------------------------------------------------- */
++static const unsigned int vin0_data8_pins[] = {
++ RCAR_GP_PIN(2, 4), RCAR_GP_PIN(2, 5),
++ RCAR_GP_PIN(2, 6), RCAR_GP_PIN(2, 7),
++ RCAR_GP_PIN(2, 8), RCAR_GP_PIN(2, 9),
++ RCAR_GP_PIN(2, 10), RCAR_GP_PIN(2, 11),
++};
++static const unsigned int vin0_data8_mux[] = {
++ VI0_DATA0_MARK, VI0_DATA1_MARK,
++ VI0_DATA2_MARK, VI0_DATA3_MARK,
++ VI0_DATA4_MARK, VI0_DATA5_MARK,
++ VI0_DATA6_MARK, VI0_DATA7_MARK,
++};
++static const unsigned int vin0_data10_pins[] = {
++ RCAR_GP_PIN(2, 4), RCAR_GP_PIN(2, 5),
++ RCAR_GP_PIN(2, 6), RCAR_GP_PIN(2, 7),
++ RCAR_GP_PIN(2, 8), RCAR_GP_PIN(2, 9),
++ RCAR_GP_PIN(2, 10), RCAR_GP_PIN(2, 11),
++ RCAR_GP_PIN(2, 12), RCAR_GP_PIN(2, 13),
++};
++static const unsigned int vin0_data10_mux[] = {
++ VI0_DATA0_MARK, VI0_DATA1_MARK,
++ VI0_DATA2_MARK, VI0_DATA3_MARK,
++ VI0_DATA4_MARK, VI0_DATA5_MARK,
++ VI0_DATA6_MARK, VI0_DATA7_MARK,
++ VI0_DATA8_MARK, VI0_DATA9_MARK,
++};
++static const unsigned int vin0_data12_pins[] = {
++ RCAR_GP_PIN(2, 4), RCAR_GP_PIN(2, 5),
++ RCAR_GP_PIN(2, 6), RCAR_GP_PIN(2, 7),
++ RCAR_GP_PIN(2, 8), RCAR_GP_PIN(2, 9),
++ RCAR_GP_PIN(2, 10), RCAR_GP_PIN(2, 11),
++ RCAR_GP_PIN(2, 12), RCAR_GP_PIN(2, 13),
++ RCAR_GP_PIN(2, 14), RCAR_GP_PIN(2, 15),
++};
++static const unsigned int vin0_data12_mux[] = {
++ VI0_DATA0_MARK, VI0_DATA1_MARK,
++ VI0_DATA2_MARK, VI0_DATA3_MARK,
++ VI0_DATA4_MARK, VI0_DATA5_MARK,
++ VI0_DATA6_MARK, VI0_DATA7_MARK,
++ VI0_DATA8_MARK, VI0_DATA9_MARK,
++ VI0_DATA10_MARK, VI0_DATA11_MARK,
++};
++static const unsigned int vin0_sync_pins[] = {
++ /* VSYNC_N, HSYNC_N */
++ RCAR_GP_PIN(2, 3), RCAR_GP_PIN(2, 2),
++};
++static const unsigned int vin0_sync_mux[] = {
++ VI0_HSYNC_N_MARK, VI0_VSYNC_N_MARK,
++};
++static const unsigned int vin0_field_pins[] = {
++ /* FIELD */
++ RCAR_GP_PIN(2, 16),
++};
++static const unsigned int vin0_field_mux[] = {
++ VI0_FIELD_MARK,
++};
++static const unsigned int vin0_clkenb_pins[] = {
++ /* CLKENB */
++ RCAR_GP_PIN(2, 1),
++};
++static const unsigned int vin0_clkenb_mux[] = {
++ VI0_CLKENB_MARK,
++};
++static const unsigned int vin0_clk_pins[] = {
++ /* CLK */
++ RCAR_GP_PIN(2, 0),
++};
++static const unsigned int vin0_clk_mux[] = {
++ VI0_CLK_MARK,
++};
++/* - VIN1 ------------------------------------------------------------------- */
++static const unsigned int vin1_data8_pins[] = {
++ RCAR_GP_PIN(3, 4), RCAR_GP_PIN(3, 5),
++ RCAR_GP_PIN(3, 6), RCAR_GP_PIN(3, 7),
++ RCAR_GP_PIN(3, 8), RCAR_GP_PIN(3, 9),
++ RCAR_GP_PIN(3, 10), RCAR_GP_PIN(3, 11),
++};
++static const unsigned int vin1_data8_mux[] = {
++ VI1_DATA0_MARK, VI1_DATA1_MARK,
++ VI1_DATA2_MARK, VI1_DATA3_MARK,
++ VI1_DATA4_MARK, VI1_DATA5_MARK,
++ VI1_DATA6_MARK, VI1_DATA7_MARK,
++};
++static const unsigned int vin1_data10_pins[] = {
++ RCAR_GP_PIN(3, 4), RCAR_GP_PIN(3, 5),
++ RCAR_GP_PIN(3, 6), RCAR_GP_PIN(3, 7),
++ RCAR_GP_PIN(3, 8), RCAR_GP_PIN(3, 9),
++ RCAR_GP_PIN(3, 10), RCAR_GP_PIN(3, 11),
++ RCAR_GP_PIN(3, 12), RCAR_GP_PIN(3, 13),
++};
++static const unsigned int vin1_data10_mux[] = {
++ VI1_DATA0_MARK, VI1_DATA1_MARK,
++ VI1_DATA2_MARK, VI1_DATA3_MARK,
++ VI1_DATA4_MARK, VI1_DATA5_MARK,
++ VI1_DATA6_MARK, VI1_DATA7_MARK,
++ VI1_DATA8_MARK, VI1_DATA9_MARK,
++};
++static const unsigned int vin1_data12_pins[] = {
++ RCAR_GP_PIN(3, 4), RCAR_GP_PIN(3, 5),
++ RCAR_GP_PIN(3, 6), RCAR_GP_PIN(3, 7),
++ RCAR_GP_PIN(3, 8), RCAR_GP_PIN(3, 9),
++ RCAR_GP_PIN(3, 10), RCAR_GP_PIN(3, 11),
++ RCAR_GP_PIN(3, 12), RCAR_GP_PIN(3, 13),
++ RCAR_GP_PIN(3, 14), RCAR_GP_PIN(3, 15),
++};
++static const unsigned int vin1_data12_mux[] = {
++ VI1_DATA0_MARK, VI1_DATA1_MARK,
++ VI1_DATA2_MARK, VI1_DATA3_MARK,
++ VI1_DATA4_MARK, VI1_DATA5_MARK,
++ VI1_DATA6_MARK, VI1_DATA7_MARK,
++ VI1_DATA8_MARK, VI1_DATA9_MARK,
++ VI1_DATA10_MARK, VI1_DATA11_MARK,
++};
++static const unsigned int vin1_sync_pins[] = {
++ /* VSYNC_N, HSYNC_N */
++ RCAR_GP_PIN(3, 3), RCAR_GP_PIN(3, 2),
++};
++static const unsigned int vin1_sync_mux[] = {
++ VI1_HSYNC_N_MARK, VI1_VSYNC_N_MARK,
++};
++static const unsigned int vin1_field_pins[] = {
++ /* FIELD */
++ RCAR_GP_PIN(3, 16),
++};
++static const unsigned int vin1_field_mux[] = {
++ VI1_FIELD_MARK,
++};
++static const unsigned int vin1_clkenb_pins[] = {
++ /* CLKENB */
++ RCAR_GP_PIN(3, 1),
++};
++static const unsigned int vin1_clkenb_mux[] = {
++ VI1_CLKENB_MARK,
++};
++static const unsigned int vin1_clk_pins[] = {
++ /* CLK */
++ RCAR_GP_PIN(3, 0),
++};
++static const unsigned int vin1_clk_mux[] = {
++ VI1_CLK_MARK,
++};
++
++static const struct sh_pfc_pin_group pinmux_groups[] = {
++ SH_PFC_PIN_GROUP(avb0_rx_ctrl),
++ SH_PFC_PIN_GROUP(avb0_rxc),
++ SH_PFC_PIN_GROUP(avb0_rd0),
++ SH_PFC_PIN_GROUP(avb0_rd1),
++ SH_PFC_PIN_GROUP(avb0_rd2),
++ SH_PFC_PIN_GROUP(avb0_rd3),
++ SH_PFC_PIN_GROUP(avb0_rd4),
++ SH_PFC_PIN_GROUP(avb0_tx_ctrl),
++ SH_PFC_PIN_GROUP(avb0_txc),
++ SH_PFC_PIN_GROUP(avb0_td0),
++ SH_PFC_PIN_GROUP(avb0_td1),
++ SH_PFC_PIN_GROUP(avb0_td2),
++ SH_PFC_PIN_GROUP(avb0_td3),
++ SH_PFC_PIN_GROUP(avb0_td4),
++ SH_PFC_PIN_GROUP(avb0_txcrefclk),
++ SH_PFC_PIN_GROUP(avb0_mdio),
++ SH_PFC_PIN_GROUP(avb0_mdc),
++ SH_PFC_PIN_GROUP(avb0_magic),
++ SH_PFC_PIN_GROUP(avb0_phy_int),
++ SH_PFC_PIN_GROUP(avb0_link),
++ SH_PFC_PIN_GROUP(avb0_avtp_match),
++ SH_PFC_PIN_GROUP(avb0_avtp_pps),
++ SH_PFC_PIN_GROUP(avb0_avtp_capture),
++ SH_PFC_PIN_GROUP(canfd0_data_a),
++ SH_PFC_PIN_GROUP(canfd_clk_a),
++ SH_PFC_PIN_GROUP(canfd0_data_b),
++ SH_PFC_PIN_GROUP(canfd_clk_b),
++ SH_PFC_PIN_GROUP(canfd1_data),
++ SH_PFC_PIN_GROUP(du_rgb666),
++ SH_PFC_PIN_GROUP(du_clk_out_0),
++ SH_PFC_PIN_GROUP(du_clk_out_1),
++ SH_PFC_PIN_GROUP(du_sync),
++ SH_PFC_PIN_GROUP(du_oddf),
++ SH_PFC_PIN_GROUP(du_cde),
++ SH_PFC_PIN_GROUP(du_disp),
++ SH_PFC_PIN_GROUP(hscif0_data),
++ SH_PFC_PIN_GROUP(hscif0_clk),
++ SH_PFC_PIN_GROUP(hscif0_ctrl),
++ SH_PFC_PIN_GROUP(hscif1_data),
++ SH_PFC_PIN_GROUP(hscif1_clk),
++ SH_PFC_PIN_GROUP(hscif1_ctrl),
++ SH_PFC_PIN_GROUP(hscif2_data),
++ SH_PFC_PIN_GROUP(hscif2_clk),
++ SH_PFC_PIN_GROUP(hscif2_ctrl),
++ SH_PFC_PIN_GROUP(hscif3_data),
++ SH_PFC_PIN_GROUP(hscif3_clk),
++ SH_PFC_PIN_GROUP(hscif3_ctrl),
++ SH_PFC_PIN_GROUP(scif_clk_a),
++ SH_PFC_PIN_GROUP(scif_clk_b),
++ SH_PFC_PIN_GROUP(i2c0),
++ SH_PFC_PIN_GROUP(i2c1),
++ SH_PFC_PIN_GROUP(i2c2),
++ SH_PFC_PIN_GROUP(i2c3),
++ SH_PFC_PIN_GROUP(i2c4),
++ SH_PFC_PIN_GROUP(intc_ex_irq0),
++ SH_PFC_PIN_GROUP(intc_ex_irq1),
++ SH_PFC_PIN_GROUP(intc_ex_irq2),
++ SH_PFC_PIN_GROUP(intc_ex_irq3),
++ SH_PFC_PIN_GROUP(intc_ex_irq4),
++ SH_PFC_PIN_GROUP(intc_ex_irq5),
++ SH_PFC_PIN_GROUP(msiof0_clk),
++ SH_PFC_PIN_GROUP(msiof0_sync),
++ SH_PFC_PIN_GROUP(msiof0_ss1),
++ SH_PFC_PIN_GROUP(msiof0_ss2),
++ SH_PFC_PIN_GROUP(msiof0_txd),
++ SH_PFC_PIN_GROUP(msiof0_rxd),
++ SH_PFC_PIN_GROUP(msiof1_clk),
++ SH_PFC_PIN_GROUP(msiof1_sync),
++ SH_PFC_PIN_GROUP(msiof1_ss1),
++ SH_PFC_PIN_GROUP(msiof1_ss2),
++ SH_PFC_PIN_GROUP(msiof1_txd),
++ SH_PFC_PIN_GROUP(msiof1_rxd),
++ SH_PFC_PIN_GROUP(msiof2_clk),
++ SH_PFC_PIN_GROUP(msiof2_sync),
++ SH_PFC_PIN_GROUP(msiof2_ss1),
++ SH_PFC_PIN_GROUP(msiof2_ss2),
++ SH_PFC_PIN_GROUP(msiof2_txd),
++ SH_PFC_PIN_GROUP(msiof2_rxd),
++ SH_PFC_PIN_GROUP(msiof3_clk),
++ SH_PFC_PIN_GROUP(msiof3_sync),
++ SH_PFC_PIN_GROUP(msiof3_ss1),
++ SH_PFC_PIN_GROUP(msiof3_ss2),
++ SH_PFC_PIN_GROUP(msiof3_txd),
++ SH_PFC_PIN_GROUP(msiof3_rxd),
++ SH_PFC_PIN_GROUP(pwm0_a),
++ SH_PFC_PIN_GROUP(pwm0_b),
++ SH_PFC_PIN_GROUP(pwm1_a),
++ SH_PFC_PIN_GROUP(pwm1_b),
++ SH_PFC_PIN_GROUP(pwm2_a),
++ SH_PFC_PIN_GROUP(pwm2_b),
++ SH_PFC_PIN_GROUP(pwm3_a),
++ SH_PFC_PIN_GROUP(pwm3_b),
++ SH_PFC_PIN_GROUP(pwm4_a),
++ SH_PFC_PIN_GROUP(pwm4_b),
++ SH_PFC_PIN_GROUP(scif0_data),
++ SH_PFC_PIN_GROUP(scif0_clk),
++ SH_PFC_PIN_GROUP(scif0_ctrl),
++ SH_PFC_PIN_GROUP(scif1_data_a),
++ SH_PFC_PIN_GROUP(scif1_clk),
++ SH_PFC_PIN_GROUP(scif1_ctrl),
++ SH_PFC_PIN_GROUP(scif1_data_b),
++ SH_PFC_PIN_GROUP(scif3_data),
++ SH_PFC_PIN_GROUP(scif3_clk),
++ SH_PFC_PIN_GROUP(scif3_ctrl),
++ SH_PFC_PIN_GROUP(scif4_data),
++ SH_PFC_PIN_GROUP(scif4_clk),
++ SH_PFC_PIN_GROUP(scif4_ctrl),
++ SH_PFC_PIN_GROUP(mmc_data1),
++ SH_PFC_PIN_GROUP(mmc_data4),
++ SH_PFC_PIN_GROUP(mmc_data8),
++ SH_PFC_PIN_GROUP(mmc_ctrl),
++ SH_PFC_PIN_GROUP(mmc_cd),
++ SH_PFC_PIN_GROUP(mmc_wp),
++ SH_PFC_PIN_GROUP(tmu_tclk1_a),
++ SH_PFC_PIN_GROUP(tmu_tclk1_b),
++ SH_PFC_PIN_GROUP(tmu_tclk2_a),
++ SH_PFC_PIN_GROUP(tmu_tclk2_b),
++ SH_PFC_PIN_GROUP(vin0_data8),
++ SH_PFC_PIN_GROUP(vin0_data10),
++ SH_PFC_PIN_GROUP(vin0_data12),
++ SH_PFC_PIN_GROUP(vin0_sync),
++ SH_PFC_PIN_GROUP(vin0_field),
++ SH_PFC_PIN_GROUP(vin0_clkenb),
++ SH_PFC_PIN_GROUP(vin0_clk),
++ SH_PFC_PIN_GROUP(vin1_data8),
++ SH_PFC_PIN_GROUP(vin1_data10),
++ SH_PFC_PIN_GROUP(vin1_data12),
++ SH_PFC_PIN_GROUP(vin1_sync),
++ SH_PFC_PIN_GROUP(vin1_field),
++ SH_PFC_PIN_GROUP(vin1_clkenb),
++ SH_PFC_PIN_GROUP(vin1_clk),
++};
++
++static const char * const avb0_groups[] = {
++ "avb0_rx_ctrl",
++ "avb0_rxc",
++ "avb0_rd1",
++ "avb0_rd4",
++ "avb0_tx_ctrl",
++ "avb0_txc",
++ "avb0_td1",
++ "avb0_td4",
++ "avb0_txcrefclk",
++ "avb0_mdio",
++ "avb0_mdc",
++ "avb0_magic",
++ "avb0_phy_int",
++ "avb0_link",
++ "avb0_avtp_match",
++ "avb0_avtp_pps",
++ "avb0_avtp_capture",
++};
++
++static const char * const canfd0_groups[] = {
++ "canfd0_data_a",
++ "canfd_clk_a",
++ "canfd0_data_b",
++ "canfd_clk_b",
++};
++
++static const char * const canfd1_groups[] = {
++ "canfd1_data",
++};
++
++static const char * const du_groups[] = {
++ "du_rgb666",
++ "du_clk_out_0",
++ "du_clk_out_1",
++ "du_sync",
++ "du_oddf",
++ "du_cde",
++ "du_disp",
++};
++
++static const char * const hscif0_groups[] = {
++ "hscif0_data",
++ "hscif0_clk",
++ "hscif0_ctrl",
++};
++
++static const char * const hscif1_groups[] = {
++ "hscif1_data",
++ "hscif1_clk",
++ "hscif1_ctrl",
++};
++
++static const char * const hscif2_groups[] = {
++ "hscif2_data",
++ "hscif2_clk",
++ "hscif2_ctrl",
++};
++
++static const char * const hscif3_groups[] = {
++ "hscif3_data",
++ "hscif3_clk",
++ "hscif3_ctrl",
++};
++
++static const char * const scif_clk_groups[] = {
++ "scif_clk_a",
++ "scif_clk_b",
++};
++
++static const char * const i2c0_groups[] = {
++ "i2c0",
++};
++
++static const char * const i2c1_groups[] = {
++ "i2c1",
++};
++
++static const char * const i2c2_groups[] = {
++ "i2c2",
++};
++
++static const char * const i2c3_groups[] = {
++ "i2c3",
++};
++
++static const char * const i2c4_groups[] = {
++ "i2c4",
++};
++
++static const char * const intc_ex_groups[] = {
++ "intc_ex_irq0",
++ "intc_ex_irq1",
++ "intc_ex_irq2",
++ "intc_ex_irq3",
++ "intc_ex_irq4",
++ "intc_ex_irq5",
++};
++
++static const char * const msiof0_groups[] = {
++ "msiof0_clk",
++ "msiof0_sync",
++ "msiof0_ss1",
++ "msiof0_ss2",
++ "msiof0_txd",
++ "msiof0_rxd",
++};
++
++static const char * const msiof1_groups[] = {
++ "msiof1_clk",
++ "msiof1_sync",
++ "msiof1_ss1",
++ "msiof1_ss2",
++ "msiof1_txd",
++ "msiof1_rxd",
++};
++
++static const char * const msiof2_groups[] = {
++ "msiof2_clk",
++ "msiof2_sync",
++ "msiof2_ss1",
++ "msiof2_ss2",
++ "msiof2_txd",
++ "msiof2_rxd",
++};
++
++static const char * const msiof3_groups[] = {
++ "msiof3_clk",
++ "msiof3_sync",
++ "msiof3_ss1",
++ "msiof3_ss2",
++ "msiof3_txd",
++ "msiof3_rxd",
++};
++
++static const char * const pwm0_groups[] = {
++ "pwm0_a",
++ "pwm0_b",
++};
++
++static const char * const pwm1_groups[] = {
++ "pwm1_a",
++ "pwm1_b",
++};
++
++static const char * const pwm2_groups[] = {
++ "pwm2_a",
++ "pwm2_b",
++};
++
++static const char * const pwm3_groups[] = {
++ "pwm3_a",
++ "pwm3_b",
++};
++
++static const char * const pwm4_groups[] = {
++ "pwm4_a",
++ "pwm4_b",
++};
++
++static const char * const scif0_groups[] = {
++ "scif0_data",
++// "scif0_clk",
++// "scif0_ctrl",
++};
++
++static const char * const scif1_groups[] = {
++ "scif1_data_a",
++ "scif1_clk",
++ "scif1_ctrl",
++ "scif1_data_b",
++};
++
++static const char * const scif3_groups[] = {
++ "scif3_data",
++ "scif3_clk",
++ "scif3_ctrl",
++};
++
++static const char * const scif4_groups[] = {
++ "scif4_data",
++ "scif4_clk",
++ "scif4_ctrl",
++};
++
++static const char * const mmc_groups[] = {
++ "mmc_data1",
++ "mmc_data4",
++ "mmc_data8",
++ "mmc_ctrl",
++ "mmc_cd",
++ "mmc_wp",
++};
++
++static const char * const tmu_groups[] = {
++ "tmu_tclk1_a",
++ "tmu_tclk1_b",
++ "tmu_tclk2_a",
++ "tmu_tclk2_b",
++};
++
++static const char * const vin0_groups[] = {
++ "vin0_data8",
++ "vin0_data10",
++ "vin0_data12",
++ "vin0_sync",
++ "vin0_field",
++ "vin0_clkenb",
++ "vin0_clk",
++};
++
++static const char * const vin1_groups[] = {
++ "vin1_data8",
++ "vin1_data10",
++ "vin1_data12",
++ "vin1_sync",
++ "vin1_field",
++ "vin1_clkenb",
++ "vin1_clk",
++};
++
++#define POCCTRL0 0x380
++#define POCCTRL1 0x384
++#define PIN2POCCTRL0_SHIFT(a) ({ \
++ int _gp = (a) >> 5; \
++ int _bit = (a) & 0x1f; \
++ ((_gp == 3) && (_bit < 17)) ? _bit + 7 : -1; \
++})
++
++
++static const struct sh_pfc_function pinmux_functions[] = {
++ SH_PFC_FUNCTION(avb0),
++ SH_PFC_FUNCTION(canfd0),
++ SH_PFC_FUNCTION(canfd1),
++ SH_PFC_FUNCTION(du),
++ SH_PFC_FUNCTION(hscif0),
++ SH_PFC_FUNCTION(hscif1),
++ SH_PFC_FUNCTION(hscif2),
++ SH_PFC_FUNCTION(hscif3),
++ SH_PFC_FUNCTION(scif_clk),
++ SH_PFC_FUNCTION(i2c0),
++ SH_PFC_FUNCTION(i2c1),
++ SH_PFC_FUNCTION(i2c2),
++ SH_PFC_FUNCTION(i2c3),
++ SH_PFC_FUNCTION(i2c4),
++ SH_PFC_FUNCTION(intc_ex),
++ SH_PFC_FUNCTION(msiof0),
++ SH_PFC_FUNCTION(msiof1),
++ SH_PFC_FUNCTION(msiof2),
++ SH_PFC_FUNCTION(msiof3),
++ SH_PFC_FUNCTION(pwm0),
++ SH_PFC_FUNCTION(pwm1),
++ SH_PFC_FUNCTION(pwm2),
++ SH_PFC_FUNCTION(pwm3),
++ SH_PFC_FUNCTION(pwm4),
++ SH_PFC_FUNCTION(scif0),
++ SH_PFC_FUNCTION(scif1),
++ SH_PFC_FUNCTION(scif3),
++ SH_PFC_FUNCTION(scif4),
++ SH_PFC_FUNCTION(mmc),
++ SH_PFC_FUNCTION(tmu),
++ SH_PFC_FUNCTION(vin0),
++ SH_PFC_FUNCTION(vin1),
++};
++
++static const struct pinmux_cfg_reg pinmux_config_regs[] = {
++#define F_(x, y) FN_##y
++#define FM(x) FN_##x
++ { PINMUX_CFG_REG("GPSR0", 0xe6060100, 32, 1) {
++ 0, 0,
++ 0, 0,
++ 0, 0,
++ 0, 0,
++ 0, 0,
++ 0, 0,
++ 0, 0,
++ 0, 0,
++ 0, 0,
++ 0, 0,
++ GP_0_21_FN, GPSR0_21,
++ GP_0_20_FN, GPSR0_20,
++ GP_0_19_FN, GPSR0_19,
++ GP_0_18_FN, GPSR0_18,
++ GP_0_17_FN, GPSR0_17,
++ GP_0_16_FN, GPSR0_16,
++ GP_0_15_FN, GPSR0_15,
++ GP_0_14_FN, GPSR0_14,
++ GP_0_13_FN, GPSR0_13,
++ GP_0_12_FN, GPSR0_12,
++ GP_0_11_FN, GPSR0_11,
++ GP_0_10_FN, GPSR0_10,
++ GP_0_9_FN, GPSR0_9,
++ GP_0_8_FN, GPSR0_8,
++ GP_0_7_FN, GPSR0_7,
++ GP_0_6_FN, GPSR0_6,
++ GP_0_5_FN, GPSR0_5,
++ GP_0_4_FN, GPSR0_4,
++ GP_0_3_FN, GPSR0_3,
++ GP_0_2_FN, GPSR0_2,
++ GP_0_1_FN, GPSR0_1,
++ GP_0_0_FN, GPSR0_0, }
++ },
++ { PINMUX_CFG_REG("GPSR1", 0xe6060104, 32, 1) {
++ 0, 0,
++ 0, 0,
++ 0, 0,
++ 0, 0,
++ GP_1_27_FN, GPSR1_27,
++ GP_1_26_FN, GPSR1_26,
++ GP_1_25_FN, GPSR1_25,
++ GP_1_24_FN, GPSR1_24,
++ GP_1_23_FN, GPSR1_23,
++ GP_1_22_FN, GPSR1_22,
++ GP_1_21_FN, GPSR1_21,
++ GP_1_20_FN, GPSR1_20,
++ GP_1_19_FN, GPSR1_19,
++ GP_1_18_FN, GPSR1_18,
++ GP_1_17_FN, GPSR1_17,
++ GP_1_16_FN, GPSR1_16,
++ GP_1_15_FN, GPSR1_15,
++ GP_1_14_FN, GPSR1_14,
++ GP_1_13_FN, GPSR1_13,
++ GP_1_12_FN, GPSR1_12,
++ GP_1_11_FN, GPSR1_11,
++ GP_1_10_FN, GPSR1_10,
++ GP_1_9_FN, GPSR1_9,
++ GP_1_8_FN, GPSR1_8,
++ GP_1_7_FN, GPSR1_7,
++ GP_1_6_FN, GPSR1_6,
++ GP_1_5_FN, GPSR1_5,
++ GP_1_4_FN, GPSR1_4,
++ GP_1_3_FN, GPSR1_3,
++ GP_1_2_FN, GPSR1_2,
++ GP_1_1_FN, GPSR1_1,
++ GP_1_0_FN, GPSR1_0, }
++ },
++ { PINMUX_CFG_REG("GPSR2", 0xe6060108, 32, 1) {
++ 0, 0,
++ 0, 0,
++ 0, 0,
++ 0, 0,
++ 0, 0,
++ 0, 0,
++ 0, 0,
++ 0, 0,
++ 0, 0,
++ 0, 0,
++ 0, 0,
++ 0, 0,
++ 0, 0,
++ 0, 0,
++ 0, 0,
++ GP_2_16_FN, GPSR2_16,
++ GP_2_15_FN, GPSR2_15,
++ GP_2_14_FN, GPSR2_14,
++ GP_2_13_FN, GPSR2_13,
++ GP_2_12_FN, GPSR2_12,
++ GP_2_11_FN, GPSR2_11,
++ GP_2_10_FN, GPSR2_10,
++ GP_2_9_FN, GPSR2_9,
++ GP_2_8_FN, GPSR2_8,
++ GP_2_7_FN, GPSR2_7,
++ GP_2_6_FN, GPSR2_6,
++ GP_2_5_FN, GPSR2_5,
++ GP_2_4_FN, GPSR2_4,
++ GP_2_3_FN, GPSR2_3,
++ GP_2_2_FN, GPSR2_2,
++ GP_2_1_FN, GPSR2_1,
++ GP_2_0_FN, GPSR2_0, }
++ },
++ { PINMUX_CFG_REG("GPSR3", 0xe606010c, 32, 1) {
++ 0, 0,
++ 0, 0,
++ 0, 0,
++ 0, 0,
++ 0, 0,
++ 0, 0,
++ 0, 0,
++ 0, 0,
++ 0, 0,
++ 0, 0,
++ 0, 0,
++ 0, 0,
++ 0, 0,
++ 0, 0,
++ 0, 0,
++ GP_3_16_FN, GPSR3_16,
++ GP_3_15_FN, GPSR3_15,
++ GP_3_14_FN, GPSR3_14,
++ GP_3_13_FN, GPSR3_13,
++ GP_3_12_FN, GPSR3_12,
++ GP_3_11_FN, GPSR3_11,
++ GP_3_10_FN, GPSR3_10,
++ GP_3_9_FN, GPSR3_9,
++ GP_3_8_FN, GPSR3_8,
++ GP_3_7_FN, GPSR3_7,
++ GP_3_6_FN, GPSR3_6,
++ GP_3_5_FN, GPSR3_5,
++ GP_3_4_FN, GPSR3_4,
++ GP_3_3_FN, GPSR3_3,
++ GP_3_2_FN, GPSR3_2,
++ GP_3_1_FN, GPSR3_1,
++ GP_3_0_FN, GPSR3_0, }
++ },
++ { PINMUX_CFG_REG("GPSR4", 0xe6060110, 32, 1) {
++ 0, 0,
++ 0, 0,
++ 0, 0,
++ 0, 0,
++ 0, 0,
++ 0, 0,
++ 0, 0,
++ 0, 0,
++ 0, 0,
++ 0, 0,
++ 0, 0,
++ 0, 0,
++ 0, 0,
++ 0, 0,
++ 0, 0,
++ 0, 0,
++ 0, 0,
++ 0, 0,
++ 0, 0,
++ 0, 0,
++ 0, 0,
++ 0, 0,
++ 0, 0,
++ 0, 0,
++ 0, 0,
++ 0, 0,
++ GP_4_5_FN, GPSR4_5,
++ GP_4_4_FN, GPSR4_4,
++ GP_4_3_FN, GPSR4_3,
++ GP_4_2_FN, GPSR4_2,
++ GP_4_1_FN, GPSR4_1,
++ GP_4_0_FN, GPSR4_0, }
++ },
++ { PINMUX_CFG_REG("GPSR5", 0xe6060114, 32, 1) {
++ 0, 0,
++ 0, 0,
++ 0, 0,
++ 0, 0,
++ 0, 0,
++ 0, 0,
++ 0, 0,
++ 0, 0,
++ 0, 0,
++ 0, 0,
++ 0, 0,
++ 0, 0,
++ 0, 0,
++ 0, 0,
++ 0, 0,
++ 0, 0,
++ 0, 0,
++ GP_5_14_FN, GPSR5_14,
++ GP_5_13_FN, GPSR5_13,
++ GP_5_12_FN, GPSR5_12,
++ GP_5_11_FN, GPSR5_11,
++ GP_5_10_FN, GPSR5_10,
++ GP_5_9_FN, GPSR5_9,
++ GP_5_8_FN, GPSR5_8,
++ GP_5_7_FN, GPSR5_7,
++ GP_5_6_FN, GPSR5_6,
++ GP_5_5_FN, GPSR5_5,
++ GP_5_4_FN, GPSR5_4,
++ GP_5_3_FN, GPSR5_3,
++ GP_5_2_FN, GPSR5_2,
++ GP_5_1_FN, GPSR5_1,
++ GP_5_0_FN, GPSR5_0, }
++ },
++#undef F_
++#undef FM
++
++#define F_(x, y) x,
++#define FM(x) FN_##x,
++ { PINMUX_CFG_REG("IPSR0", 0xe6060200, 32, 4) {
++ IP0_31_28
++ IP0_27_24
++ IP0_23_20
++ IP0_19_16
++ IP0_15_12
++ IP0_11_8
++ IP0_7_4
++ IP0_3_0 }
++ },
++ { PINMUX_CFG_REG("IPSR1", 0xe6060204, 32, 4) {
++ IP1_31_28
++ IP1_27_24
++ IP1_23_20
++ IP1_19_16
++ IP1_15_12
++ IP1_11_8
++ IP1_7_4
++ IP1_3_0 }
++ },
++ { PINMUX_CFG_REG("IPSR2", 0xe6060208, 32, 4) {
++ IP2_31_28
++ IP2_27_24
++ IP2_23_20
++ IP2_19_16
++ IP2_15_12
++ IP2_11_8
++ IP2_7_4
++ IP2_3_0 }
++ },
++ { PINMUX_CFG_REG("IPSR3", 0xe606020c, 32, 4) {
++ IP3_31_28
++ IP3_27_24
++ IP3_23_20
++ IP3_19_16
++ IP3_15_12
++ IP3_11_8
++ IP3_7_4
++ IP3_3_0 }
++ },
++ { PINMUX_CFG_REG("IPSR4", 0xe6060210, 32, 4) {
++ IP4_31_28
++ IP4_27_24
++ IP4_23_20
++ IP4_19_16
++ IP4_15_12
++ IP4_11_8
++ IP4_7_4
++ IP4_3_0 }
++ },
++ { PINMUX_CFG_REG("IPSR5", 0xe6060214, 32, 4) {
++ IP5_31_28
++ IP5_27_24
++ IP5_23_20
++ IP5_19_16
++ IP5_15_12
++ IP5_11_8
++ IP5_7_4
++ IP5_3_0 }
++ },
++ { PINMUX_CFG_REG("IPSR6", 0xe6060218, 32, 4) {
++ IP6_31_28
++ IP6_27_24
++ IP6_23_20
++ IP6_19_16
++ IP6_15_12
++ IP6_11_8
++ IP6_7_4
++ IP6_3_0 }
++ },
++ { PINMUX_CFG_REG("IPSR7", 0xe606021c, 32, 4) {
++ IP7_31_28
++ IP7_27_24
++ IP7_23_20
++ IP7_19_16
++ IP7_15_12
++ IP7_11_8
++ IP7_7_4
++ IP7_3_0 }
++ },
++ { PINMUX_CFG_REG("IPSR8", 0xe6060220, 32, 4) {
++ IP8_31_28
++ IP8_27_24
++ IP8_23_20
++ IP8_19_16
++ IP8_15_12
++ IP8_11_8
++ IP8_7_4
++ IP8_3_0 }
++ },
++#undef F_
++#undef FM
++
++#define F_(x, y) x,
++#define FM(x) FN_##x,
++ { PINMUX_CFG_REG("MOD_SEL0", 0xe6060500, 32, 1) {
++ /* RESERVED 31..12 */
++ 0, 0,
++ 0, 0,
++ 0, 0,
++ 0, 0,
++ 0, 0,
++ 0, 0,
++ 0, 0,
++ 0, 0,
++ 0, 0,
++ 0, 0,
++ 0, 0,
++ 0, 0,
++ 0, 0,
++ 0, 0,
++ 0, 0,
++ 0, 0,
++ 0, 0,
++ 0, 0,
++ 0, 0,
++ 0, 0,
++ MOD_SEL0_11
++ MOD_SEL0_10
++ MOD_SEL0_9
++ MOD_SEL0_8
++ MOD_SEL0_7
++ MOD_SEL0_6
++ MOD_SEL0_5
++ MOD_SEL0_4
++ MOD_SEL0_3
++ MOD_SEL0_2
++ MOD_SEL0_1
++ MOD_SEL0_0 }
++ },
++ { },
++};
++
++static int r8a7797_pin_to_pocctrl(struct sh_pfc *pfc, unsigned int pin, u32 *pocctrl)
++{
++ int bit = -EINVAL;
++
++ *pocctrl = 0xe6060384;
++
++ if (pin >= RCAR_GP_PIN(3, 0) && pin <= RCAR_GP_PIN(3, 16))
++ bit = (pin & 0x1f) + 7;
++
++ return bit;
++}
++
++static const struct sh_pfc_soc_operations pinmux_ops = {
++ .pin_to_pocctrl = r8a7797_pin_to_pocctrl,
++};
++
++const struct sh_pfc_soc_info r8a7797_pinmux_info = {
++ .name = "r8a77970_pfc",
++ .ops = &pinmux_ops,
++ .unlock_reg = 0xe6060000, /* PMMR */
++
++ .function = { PINMUX_FUNCTION_BEGIN, PINMUX_FUNCTION_END },
++
++ .pins = pinmux_pins,
++ .nr_pins = ARRAY_SIZE(pinmux_pins),
++ .groups = pinmux_groups,
++ .nr_groups = ARRAY_SIZE(pinmux_groups),
++ .functions = pinmux_functions,
++ .nr_functions = ARRAY_SIZE(pinmux_functions),
++
++ .cfg_regs = pinmux_config_regs,
++
++ .pinmux_data = pinmux_data,
++ .pinmux_data_size = ARRAY_SIZE(pinmux_data),
++};
+diff --git a/drivers/pinctrl/sh-pfc/sh_pfc.h b/drivers/pinctrl/sh-pfc/sh_pfc.h
+index c6a1855..a673a00 100644
+--- a/drivers/pinctrl/sh-pfc/sh_pfc.h
++++ b/drivers/pinctrl/sh-pfc/sh_pfc.h
+@@ -269,6 +269,7 @@ struct sh_pfc_soc_info {
+ extern const struct sh_pfc_soc_info r8a7795_pinmux_info;
+ extern const struct sh_pfc_soc_info r8a7795_es1_pinmux_info;
+ extern const struct sh_pfc_soc_info r8a7796_pinmux_info;
++extern const struct sh_pfc_soc_info r8a7797_pinmux_info;
+ extern const struct sh_pfc_soc_info sh7203_pinmux_info;
+ extern const struct sh_pfc_soc_info sh7264_pinmux_info;
+ extern const struct sh_pfc_soc_info sh7269_pinmux_info;
+@@ -374,6 +375,11 @@ struct sh_pfc_soc_info {
+ PORT_GP_CFG_1(bank, 3, fn, sfx, cfg)
+ #define PORT_GP_4(bank, fn, sfx) PORT_GP_CFG_4(bank, fn, sfx, 0)
+
++#define PORT_GP_CFG_6(bank, fn, sfx, cfg) \
++ PORT_GP_CFG_4(bank, fn, sfx, cfg), \
++ PORT_GP_CFG_1(bank, 4, fn, sfx, cfg), PORT_GP_CFG_1(bank, 5, fn, sfx, cfg)
++#define PORT_GP_6(bank, fn, sfx) PORT_GP_CFG_6(bank, fn, sfx, 0)
++
+ #define PORT_GP_CFG_8(bank, fn, sfx, cfg) \
+ PORT_GP_CFG_4(bank, fn, sfx, cfg), \
+ PORT_GP_CFG_1(bank, 4, fn, sfx, cfg), \
+@@ -420,6 +426,12 @@ struct sh_pfc_soc_info {
+ PORT_GP_CFG_1(bank, 17, fn, sfx, cfg)
+ #define PORT_GP_18(bank, fn, sfx) PORT_GP_CFG_18(bank, fn, sfx, 0)
+
++#define PORT_GP_CFG_22(bank, fn, sfx, cfg) \
++ PORT_GP_CFG_18(bank, fn, sfx, cfg), \
++ PORT_GP_CFG_1(bank, 18, fn, sfx, cfg), PORT_GP_CFG_1(bank, 19, fn, sfx, cfg), \
++ PORT_GP_CFG_1(bank, 20, fn, sfx, cfg), PORT_GP_CFG_1(bank, 21, fn, sfx, cfg)
++#define PORT_GP_22(bank, fn, sfx) PORT_GP_CFG_22(bank, fn, sfx, 0)
++
+ #define PORT_GP_CFG_23(bank, fn, sfx, cfg) \
+ PORT_GP_CFG_18(bank, fn, sfx, cfg), \
+ PORT_GP_CFG_1(bank, 18, fn, sfx, cfg), \
+diff --git a/drivers/soc/renesas/Makefile b/drivers/soc/renesas/Makefile
+index 504fb05..37cca0b 100644
+--- a/drivers/soc/renesas/Makefile
++++ b/drivers/soc/renesas/Makefile
+@@ -4,6 +4,7 @@ obj-$(CONFIG_ARCH_RCAR_GEN1) += rcar-rst.o
+ obj-$(CONFIG_ARCH_RCAR_GEN2) += rcar-rst.o
+ obj-$(CONFIG_ARCH_R8A7795) += rcar-rst.o
+ obj-$(CONFIG_ARCH_R8A7796) += rcar-rst.o
++obj-$(CONFIG_ARCH_R8A7797) += rcar-rst.o
+
+ obj-$(CONFIG_ARCH_R8A7743) += rcar-sysc.o r8a7743-sysc.o
+ obj-$(CONFIG_ARCH_R8A7745) += rcar-sysc.o r8a7745-sysc.o
+@@ -16,11 +17,14 @@ obj-$(CONFIG_ARCH_R8A7793) += rcar-sysc.o r8a7791-sysc.o
+ obj-$(CONFIG_ARCH_R8A7794) += rcar-sysc.o r8a7794-sysc.o
+ obj-$(CONFIG_ARCH_R8A7795) += rcar-sysc.o r8a7795-sysc.o
+ obj-$(CONFIG_ARCH_R8A7796) += rcar-sysc.o r8a7796-sysc.o
++obj-$(CONFIG_ARCH_R8A7797) += rcar-sysc.o r8a7797-sysc.o
+
+ obj-$(CONFIG_ARCH_R8A7795) += rcar-avs.o
+ obj-$(CONFIG_ARCH_R8A7796) += rcar-avs.o
++obj-$(CONFIG_ARCH_R8A7797) += rcar-avs.o
+ # EMS for R-Car Gen3
+ obj-$(CONFIG_ARCH_R8A7795) += rcar_ems_ctrl.o
+ obj-$(CONFIG_ARCH_R8A7796) += rcar_ems_ctrl.o
++obj-$(CONFIG_ARCH_R8A7797) += rcar_ems_ctrl.o
+
+ obj-$(CONFIG_RCAR_DDR_BACKUP) += s2ram_ddr_backup.o
+diff --git a/drivers/soc/renesas/r8a7797-sysc.c b/drivers/soc/renesas/r8a7797-sysc.c
+new file mode 100644
+index 0000000..b71bdedb
+--- /dev/null
++++ b/drivers/soc/renesas/r8a7797-sysc.c
+@@ -0,0 +1,39 @@
++/*
++ * Renesas R-Car V3M System Controller
++ *
++ * Copyright (C) 2016 Glider bvba
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; version 2 of the License.
++ */
++
++#include <linux/bug.h>
++#include <linux/kernel.h>
++
++#include <dt-bindings/power/r8a7797-sysc.h>
++
++#include "rcar-sysc.h"
++
++static const struct rcar_sysc_area r8a7797_areas[] __initconst = {
++ { "always-on", 0, 0, R8A7797_PD_ALWAYS_ON, -1, PD_ALWAYS_ON },
++ { "ca53-scu", 0x140, 0, R8A7797_PD_CA53_SCU, R8A7797_PD_ALWAYS_ON,
++ PD_SCU },
++ { "ca53-cpu0", 0x200, 0, R8A7797_PD_CA53_CPU0, R8A7797_PD_CA53_SCU,
++ PD_CPU_NOCR },
++ { "ca53-cpu1", 0x200, 1, R8A7797_PD_CA53_CPU1, R8A7797_PD_CA53_SCU,
++ PD_CPU_NOCR },
++ { "cr7", 0x240, 0, R8A7797_PD_CR7, R8A7797_PD_ALWAYS_ON },
++ { "a3ir", 0x180, 0, R8A7797_PD_A3IR, R8A7797_PD_ALWAYS_ON },
++ { "a2ir0", 0x400, 0, R8A7797_PD_A2IR0, R8A7797_PD_ALWAYS_ON },
++ { "a2ir1", 0x400, 1, R8A7797_PD_A2IR1, R8A7797_PD_A2IR0 },
++ { "a2ir2", 0x400, 2, R8A7797_PD_A2IR2, R8A7797_PD_A2IR0 },
++ { "a2ir3", 0x400, 3, R8A7797_PD_A2IR3, R8A7797_PD_A2IR0 },
++ { "a2sc0", 0x400, 4, R8A7797_PD_A2SC0, R8A7797_PD_ALWAYS_ON },
++ { "a2sc1", 0x400, 5, R8A7797_PD_A2SC1, R8A7797_PD_A2SC0 },
++};
++
++const struct rcar_sysc_info r8a7797_sysc_info __initconst = {
++ .areas = r8a7797_areas,
++ .num_areas = ARRAY_SIZE(r8a7797_areas),
++};
+diff --git a/drivers/soc/renesas/rcar-rst.c b/drivers/soc/renesas/rcar-rst.c
+index a6d1c26..2e87293 100644
+--- a/drivers/soc/renesas/rcar-rst.c
++++ b/drivers/soc/renesas/rcar-rst.c
+@@ -41,6 +41,7 @@ struct rst_config {
+ /* R-Car Gen3 is handled like R-Car Gen2 */
+ { .compatible = "renesas,r8a7795-rst", .data = &rcar_rst_gen2 },
+ { .compatible = "renesas,r8a7796-rst", .data = &rcar_rst_gen2 },
++ { .compatible = "renesas,r8a7797-rst", .data = &rcar_rst_gen2 },
+ { /* sentinel */ }
+ };
+
+diff --git a/drivers/soc/renesas/rcar-sysc.c b/drivers/soc/renesas/rcar-sysc.c
+index 042500a..e6165b6 100644
+--- a/drivers/soc/renesas/rcar-sysc.c
++++ b/drivers/soc/renesas/rcar-sysc.c
+@@ -320,6 +320,9 @@ static void __init rcar_sysc_pd_setup(struct rcar_sysc_pd *pd)
+ #ifdef CONFIG_ARCH_R8A7796
+ { .compatible = "renesas,r8a7796-sysc", .data = &r8a7796_sysc_info },
+ #endif
++#ifdef CONFIG_ARCH_R8A7797
++ { .compatible = "renesas,r8a7797-sysc", .data = &r8a7797_sysc_info },
++#endif
+ { /* sentinel */ }
+ };
+
+diff --git a/drivers/soc/renesas/rcar-sysc.h b/drivers/soc/renesas/rcar-sysc.h
+index f6e842e..e7980d5 100644
+--- a/drivers/soc/renesas/rcar-sysc.h
++++ b/drivers/soc/renesas/rcar-sysc.h
+@@ -59,4 +59,5 @@ struct rcar_sysc_info {
+ extern const struct rcar_sysc_info r8a7794_sysc_info;
+ extern const struct rcar_sysc_info r8a7795_sysc_info;
+ extern const struct rcar_sysc_info r8a7796_sysc_info;
++extern const struct rcar_sysc_info r8a7797_sysc_info;
+ #endif /* __SOC_RENESAS_RCAR_SYSC_H__ */
+diff --git a/drivers/soc/renesas/rcar_ems_ctrl.c b/drivers/soc/renesas/rcar_ems_ctrl.c
+index ca9af73..388c570 100644
+--- a/drivers/soc/renesas/rcar_ems_ctrl.c
++++ b/drivers/soc/renesas/rcar_ems_ctrl.c
+@@ -24,11 +24,17 @@
+ #include <linux/pm_runtime.h>
+ #include <linux/spinlock.h>
+ #include <linux/thermal.h>
++#include <linux/sys_soc.h>
+
+ #include <linux/soc/renesas/rcar_ems_ctrl.h>
+
+ #define EMS_THERMAL_ZONE_MAX 10
+
++static const struct soc_device_attribute r8a7797[] = {
++ { .soc_id = "r8a7797" },
++ { }
++};
++
+ static void rcar_ems_monitor(struct work_struct *ws);
+ static DECLARE_DELAYED_WORK(rcar_ems_monitor_work, rcar_ems_monitor);
+
+@@ -268,6 +274,10 @@ static int __init rcar_ems_cpu_shutdown_init(void)
+
+ for_each_online_cpu(cpu) {
+ tmp_node = of_get_cpu_node(cpu, NULL);
++ if (soc_device_match(r8a7797)) {
++ if (!of_device_is_compatible(tmp_node, "arm,cortex-a53"))
++ continue;
++ }
+ if (!of_device_is_compatible(tmp_node, "arm,cortex-a57"))
+ continue;
+ for (i = 0; i < total_target_cpu; i++) {
+diff --git a/drivers/soc/renesas/renesas-soc.c b/drivers/soc/renesas/renesas-soc.c
+index 5cab1b5..9d6fdb0 100644
+--- a/drivers/soc/renesas/renesas-soc.c
++++ b/drivers/soc/renesas/renesas-soc.c
+@@ -134,6 +134,11 @@ struct renesas_soc {
+ .id = 0x52,
+ };
+
++static const struct renesas_soc soc_rcar_v3m __initconst __maybe_unused = {
++ .family = &fam_rcar_gen3,
++ .id = 0x54,
++};
++
+ static const struct renesas_soc soc_shmobile_ag5 __initconst __maybe_unused = {
+ .family = &fam_shmobile,
+ .id = 0x37,
+@@ -183,6 +188,9 @@ struct renesas_soc {
+ #ifdef CONFIG_ARCH_R8A7796
+ { .compatible = "renesas,r8a7796", .data = &soc_rcar_m3_w },
+ #endif
++#ifdef CONFIG_ARCH_R8A7797
++ { .compatible = "renesas,r8a7797", .data = &soc_rcar_v3m },
++#endif
+ #ifdef CONFIG_ARCH_SH73A0
+ { .compatible = "renesas,sh73a0", .data = &soc_shmobile_ag5 },
+ #endif
+diff --git a/drivers/spi/spi-sh-msiof.c b/drivers/spi/spi-sh-msiof.c
+index 996869e..3281dc7 100644
+--- a/drivers/spi/spi-sh-msiof.c
++++ b/drivers/spi/spi-sh-msiof.c
+@@ -215,7 +215,8 @@ static int msiof_rcar_is_gen3(struct device *dev)
+ struct device_node *node = dev->of_node;
+
+ return of_device_is_compatible(node, "renesas,msiof-r8a7795") ||
+- of_device_is_compatible(node, "renesas,msiof-r8a7796");
++ of_device_is_compatible(node, "renesas,msiof-r8a7796") ||
++ of_device_is_compatible(node, "renesas,msiof-r8a7797");
+ }
+
+ static u32 sh_msiof_read(struct sh_msiof_spi_priv *p, int reg_offs)
+@@ -1188,6 +1189,7 @@ static int sh_msiof_transfer_one(struct spi_master *master,
+ { .compatible = "renesas,msiof-r8a7794", .data = &r8a779x_data },
+ { .compatible = "renesas,msiof-r8a7795", .data = &r8a779x_data },
+ { .compatible = "renesas,msiof-r8a7796", .data = &r8a779x_data },
++ { .compatible = "renesas,msiof-r8a7797", .data = &r8a779x_data },
+ {},
+ };
+ MODULE_DEVICE_TABLE(of, sh_msiof_match);
+diff --git a/drivers/thermal/rcar_gen3_thermal.c b/drivers/thermal/rcar_gen3_thermal.c
+index 39763c7..07b1a2e 100644
+--- a/drivers/thermal/rcar_gen3_thermal.c
++++ b/drivers/thermal/rcar_gen3_thermal.c
+@@ -385,6 +385,30 @@ static int rcar_gen3_r8a7795_thermal_init(struct rcar_thermal_priv *priv)
+ return 0;
+ }
+
++/* @@ transitional */
++static int rcar_gen3_r8a7797_thermal_init(struct rcar_thermal_priv *priv)
++{
++#if 0
++ unsigned long flags;
++ unsigned long reg_val;
++
++ spin_lock_irqsave(&priv->lock, flags);
++ rcar_thermal_write(priv, REG_GEN3_THCTR, 0x0);
++ udelay(1000);
++ rcar_thermal_write(priv, REG_GEN3_IRQCTL, 0x3F);
++ rcar_thermal_write(priv, REG_GEN3_IRQEN,
++ IRQ_TEMP1_BIT | IRQ_TEMPD2_BIT);
++ rcar_thermal_write(priv, REG_GEN3_THCTR, CTCTL | THCNTSEN(BIT_LEN_12));
++ reg_val = rcar_thermal_read(priv, REG_GEN3_THCTR);
++ reg_val &= ~CTCTL;
++ reg_val |= THSST;
++ rcar_thermal_write(priv, REG_GEN3_THCTR, reg_val);
++
++ spin_unlock_irqrestore(&priv->lock, flags);
++#endif
++ return 0;
++}
++
+ /*
+ * Interrupt
+ */
+@@ -466,9 +490,14 @@ static int rcar_gen3_thermal_remove(struct platform_device *pdev)
+ .thermal_init = rcar_gen3_r8a7796_thermal_init,
+ };
+
++static const struct rcar_thermal_data r8a7797_data = {
++ .thermal_init = rcar_gen3_r8a7797_thermal_init,
++};
++
+ static const struct of_device_id rcar_thermal_dt_ids[] = {
+ { .compatible = "renesas,thermal-r8a7795", .data = &r8a7795_data},
+ { .compatible = "renesas,thermal-r8a7796", .data = &r8a7796_data},
++ { .compatible = "renesas,thermal-r8a7797", .data = &r8a7797_data},
+ {},
+ };
+ MODULE_DEVICE_TABLE(of, rcar_thermal_dt_ids);
+diff --git a/include/dt-bindings/clock/r8a7797-cpg-mssr.h b/include/dt-bindings/clock/r8a7797-cpg-mssr.h
+new file mode 100644
+index 0000000..ae6b3af
+--- /dev/null
++++ b/include/dt-bindings/clock/r8a7797-cpg-mssr.h
+@@ -0,0 +1,48 @@
++/*
++ * Copyright (C) 2016 Renesas Electronics Corp.
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ */
++#ifndef __DT_BINDINGS_CLOCK_R8A7797_CPG_MSSR_H__
++#define __DT_BINDINGS_CLOCK_R8A7797_CPG_MSSR_H__
++
++#include <dt-bindings/clock/renesas-cpg-mssr.h>
++
++/* r8a7797 CPG Core Clocks */
++#define R8A7797_CLK_Z2 0
++#define R8A7797_CLK_ZR 1
++#define R8A7797_CLK_ZTR 2
++#define R8A7797_CLK_ZTRD2 3
++#define R8A7797_CLK_ZT 4
++#define R8A7797_CLK_ZX 5
++#define R8A7797_CLK_S1D1 6
++#define R8A7797_CLK_S1D2 7
++#define R8A7797_CLK_S1D4 8
++#define R8A7797_CLK_S2D1 9
++#define R8A7797_CLK_S2D2 10
++#define R8A7797_CLK_S2D4 11
++#define R8A7797_CLK_LB 12
++#define R8A7797_CLK_CL 13
++#define R8A7797_CLK_ZB3 14
++#define R8A7797_CLK_ZB3D2 15
++#define R8A7797_CLK_DDR 16
++#define R8A7797_CLK_CR 17
++#define R8A7797_CLK_CRD2 18
++#define R8A7797_CLK_SD0H 19
++#define R8A7797_CLK_SD0 20
++#define R8A7797_CLK_RPC 21
++#define R8A7797_CLK_RPCD2 22
++#define R8A7797_CLK_MSO 23
++#define R8A7797_CLK_CANFD 24
++#define R8A7797_CLK_CSI0 25
++#define R8A7797_CLK_CSIREF 26
++#define R8A7797_CLK_FRAY 27
++#define R8A7797_CLK_CP 28
++#define R8A7797_CLK_CPEX 29
++#define R8A7797_CLK_R 30
++#define R8A7797_CLK_OSC 31
++
++#endif /* __DT_BINDINGS_CLOCK_R8A7797_CPG_MSSR_H__ */
+diff --git a/include/dt-bindings/power/r8a7797-sysc.h b/include/dt-bindings/power/r8a7797-sysc.h
+new file mode 100644
+index 0000000..5aef212
+--- /dev/null
++++ b/include/dt-bindings/power/r8a7797-sysc.h
+@@ -0,0 +1,32 @@
++/*
++ * Copyright (C) 2016 Glider bvba
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; version 2 of the License.
++ */
++#ifndef __DT_BINDINGS_POWER_R8A7797_SYSC_H__
++#define __DT_BINDINGS_POWER_R8A7797_SYSC_H__
++
++/*
++ * These power domain indices match the numbers of the interrupt bits
++ * representing the power areas in the various Interrupt Registers
++ * (e.g. SYSCISR, Interrupt Status Register)
++ */
++
++#define R8A7797_PD_CA53_CPU0 5
++#define R8A7797_PD_CA53_CPU1 6
++#define R8A7797_PD_CR7 13
++#define R8A7797_PD_CA53_SCU 21
++#define R8A7797_PD_A2IR0 23
++#define R8A7797_PD_A3IR 24
++#define R8A7797_PD_A2IR1 27
++#define R8A7797_PD_A2IR2 28
++#define R8A7797_PD_A2IR3 29
++#define R8A7797_PD_A2SC0 30
++#define R8A7797_PD_A2SC1 31
++
++/* Always-on power area */
++#define R8A7797_PD_ALWAYS_ON 32
++
++#endif /* __DT_BINDINGS_POWER_R8A7797_SYSC_H__ */
+--
+1.9.1
+
diff --git a/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0019-Revert-media-v4l2-async-remove-unneeded-.registered_.patch b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0019-Revert-media-v4l2-async-remove-unneeded-.registered_.patch
new file mode 100644
index 0000000..72c22f5
--- /dev/null
+++ b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0019-Revert-media-v4l2-async-remove-unneeded-.registered_.patch
@@ -0,0 +1,54 @@
+From 050637736af144f4bfb096f5f47120c477349732 Mon Sep 17 00:00:00 2001
+From: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+Date: Sun, 14 May 2017 15:23:57 +0300
+Subject: [PATCH] Revert "[media] v4l2-async: remove unneeded .registered_async
+ callback"
+
+This reverts commit a53d2f299dc83340c695e153363a2f21641d5f58.
+---
+ drivers/media/v4l2-core/v4l2-async.c | 7 +++++++
+ include/media/v4l2-subdev.h | 3 +++
+ 2 files changed, 10 insertions(+)
+
+diff --git a/drivers/media/v4l2-core/v4l2-async.c b/drivers/media/v4l2-core/v4l2-async.c
+index 5bada20..a4b224d 100644
+--- a/drivers/media/v4l2-core/v4l2-async.c
++++ b/drivers/media/v4l2-core/v4l2-async.c
+@@ -119,6 +119,13 @@ static int v4l2_async_test_notify(struct v4l2_async_notifier *notifier,
+ return ret;
+ }
+
++ ret = v4l2_subdev_call(sd, core, registered_async);
++ if (ret < 0 && ret != -ENOIOCTLCMD) {
++ if (notifier->unbind)
++ notifier->unbind(notifier, sd, asd);
++ return ret;
++ }
++
+ if (list_empty(&notifier->waiting) && notifier->complete)
+ return notifier->complete(notifier);
+
+diff --git a/include/media/v4l2-subdev.h b/include/media/v4l2-subdev.h
+index cf778c5..269904d 100644
+--- a/include/media/v4l2-subdev.h
++++ b/include/media/v4l2-subdev.h
+@@ -184,6 +184,8 @@ struct v4l2_subdev_io_pin_config {
+ * for it to be warned when the value of a control changes.
+ *
+ * @unsubscribe_event: remove event subscription from the control framework.
++ *
++ * @registered_async: the subdevice has been registered async.
+ */
+ struct v4l2_subdev_core_ops {
+ int (*log_status)(struct v4l2_subdev *sd);
+@@ -209,6 +211,7 @@ struct v4l2_subdev_core_ops {
+ struct v4l2_event_subscription *sub);
+ int (*unsubscribe_event)(struct v4l2_subdev *sd, struct v4l2_fh *fh,
+ struct v4l2_event_subscription *sub);
++ int (*registered_async)(struct v4l2_subdev *sd);
+ };
+
+ /**
+--
+1.9.1
+
diff --git a/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0020-ti-st-add-device-tree-support.patch b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0020-ti-st-add-device-tree-support.patch
new file mode 100644
index 0000000..fff9a40
--- /dev/null
+++ b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0020-ti-st-add-device-tree-support.patch
@@ -0,0 +1,236 @@
+From 36122fec4390663b5c05d5836beb977ba2c09a68 Mon Sep 17 00:00:00 2001
+From: Eyal Reizer <eyalr@ti.com>
+Date: Thu, 23 May 2013 17:11:14 +0300
+Subject: [PATCH 099/104] ti-st: add device tree support
+
+When using device tree, driver configuration data need to be read from
+device node.
+Add support for getting the platform data information from the device
+tree information stored in the .dtb file in case it exists.
+
+Change-Id: I74f7f869fc257a057edb9f35c5fd8cbafb810164
+Signed-off-by: Eyal Reizer <eyalr@ti.com>
+Signed-off-by: bvijay <bvijay@ti.com>
+Signed-off-by: Andrey Gusakov <andrey.gusakov@cogentembedded.com>
+---
+ drivers/misc/ti-st/st_kim.c | 92 +++++++++++++++++++++++++++++++++++++++----
+ drivers/misc/ti-st/st_ll.c | 19 ++++++++-
+ 2 files changed, 102 insertions(+), 9 deletions(-)
+
+diff --git a/drivers/misc/ti-st/st_kim.c b/drivers/misc/ti-st/st_kim.c
+index 71b6455..a36db89 100644
+--- a/drivers/misc/ti-st/st_kim.c
++++ b/drivers/misc/ti-st/st_kim.c
+@@ -43,6 +43,9 @@ static struct platform_device *st_kim_devices[MAX_ST_DEVICES];
+ /**********************************************************************/
+ /* internal functions */
+
++struct ti_st_plat_data *dt_pdata;
++static struct ti_st_plat_data *get_platform_data(struct device *dev);
++
+ /**
+ * st_get_plat_device -
+ * function which returns the reference to the platform device
+@@ -464,7 +467,12 @@ long st_kim_start(void *kim_data)
+ struct kim_data_s *kim_gdata = (struct kim_data_s *)kim_data;
+
+ pr_info(" %s", __func__);
+- pdata = kim_gdata->kim_pdev->dev.platform_data;
++ if (kim_gdata->kim_pdev->dev.of_node) {
++ pr_debug("use device tree data");
++ pdata = dt_pdata;
++ } else {
++ pdata = kim_gdata->kim_pdev->dev.platform_data;
++ }
+
+ do {
+ /* platform specific enabling code here */
+@@ -524,12 +532,17 @@ long st_kim_stop(void *kim_data)
+ {
+ long err = 0;
+ struct kim_data_s *kim_gdata = (struct kim_data_s *)kim_data;
+- struct ti_st_plat_data *pdata =
+- kim_gdata->kim_pdev->dev.platform_data;
++ struct ti_st_plat_data *pdata;
+ struct tty_struct *tty = kim_gdata->core_data->tty;
+
+ reinit_completion(&kim_gdata->ldisc_installed);
+
++ if (kim_gdata->kim_pdev->dev.of_node) {
++ pr_debug("use device tree data");
++ pdata = dt_pdata;
++ } else
++ pdata = kim_gdata->kim_pdev->dev.platform_data;
++
+ if (tty) { /* can be called before ldisc is installed */
+ /* Flush any pending characters in the driver and discipline. */
+ tty_ldisc_flush(tty);
+@@ -721,13 +734,53 @@ static const struct file_operations list_debugfs_fops = {
+ * board-*.c file
+ */
+
++static const struct of_device_id kim_of_match[] = {
++{
++ .compatible = "kim",
++ },
++ {}
++};
++MODULE_DEVICE_TABLE(of, kim_of_match);
++
++static struct ti_st_plat_data *get_platform_data(struct device *dev)
++{
++ struct device_node *np = dev->of_node;
++ const u32 *dt_property;
++ int len;
++
++ dt_pdata = kzalloc(sizeof(*dt_pdata), GFP_KERNEL);
++
++ if (!dt_pdata)
++ pr_err("Can't allocate device_tree platform data\n");
++
++ dt_property = of_get_property(np, "dev_name", &len);
++ if (dt_property)
++ memcpy(&dt_pdata->dev_name, dt_property, len);
++ of_property_read_u32(np, "nshutdown_gpio",
++ (u32 *)&dt_pdata->nshutdown_gpio);
++ of_property_read_u32(np, "flow_cntrl", (u32 *)&dt_pdata->flow_cntrl);
++ of_property_read_u32(np, "baud_rate", (u32 *)&dt_pdata->baud_rate);
++
++ return dt_pdata;
++}
++
+ static struct dentry *kim_debugfs_dir;
+ static int kim_probe(struct platform_device *pdev)
+ {
+ struct kim_data_s *kim_gdata;
+- struct ti_st_plat_data *pdata = pdev->dev.platform_data;
++ struct ti_st_plat_data *pdata;
+ int err;
+
++ if (pdev->dev.of_node)
++ pdata = get_platform_data(&pdev->dev);
++ else
++ pdata = pdev->dev.platform_data;
++
++ if (pdata == NULL) {
++ dev_err(&pdev->dev, "Platform Data is missing\n");
++ return -ENXIO;
++ }
++
+ if ((pdev->id != -1) && (pdev->id < MAX_ST_DEVICES)) {
+ /* multiple devices could exist */
+ st_kim_devices[pdev->id] = pdev;
+@@ -808,9 +861,16 @@ err_core_init:
+ static int kim_remove(struct platform_device *pdev)
+ {
+ /* free the GPIOs requested */
+- struct ti_st_plat_data *pdata = pdev->dev.platform_data;
++ struct ti_st_plat_data *pdata;
+ struct kim_data_s *kim_gdata;
+
++ if (pdev->dev.of_node) {
++ pr_debug("use device tree data");
++ pdata = dt_pdata;
++ } else {
++ pdata = pdev->dev.platform_data;
++ }
++
+ kim_gdata = platform_get_drvdata(pdev);
+
+ /* Free the Bluetooth/FM/GPIO
+@@ -828,12 +888,22 @@ static int kim_remove(struct platform_device *pdev)
+
+ kfree(kim_gdata);
+ kim_gdata = NULL;
++ kfree(dt_pdata);
++ dt_pdata = NULL;
++
+ return 0;
+ }
+
+ static int kim_suspend(struct platform_device *pdev, pm_message_t state)
+ {
+- struct ti_st_plat_data *pdata = pdev->dev.platform_data;
++ struct ti_st_plat_data *pdata;
++
++ if (pdev->dev.of_node) {
++ pr_debug("use device tree data");
++ pdata = dt_pdata;
++ } else {
++ pdata = pdev->dev.platform_data;
++ }
+
+ if (pdata->suspend)
+ return pdata->suspend(pdev, state);
+@@ -843,7 +913,14 @@ static int kim_suspend(struct platform_device *pdev, pm_message_t state)
+
+ static int kim_resume(struct platform_device *pdev)
+ {
+- struct ti_st_plat_data *pdata = pdev->dev.platform_data;
++ struct ti_st_plat_data *pdata;
++
++ if (pdev->dev.of_node) {
++ pr_debug("use device tree data");
++ pdata = dt_pdata;
++ } else {
++ pdata = pdev->dev.platform_data;
++ }
+
+ if (pdata->resume)
+ return pdata->resume(pdev);
+@@ -860,6 +937,7 @@ static struct platform_driver kim_platform_driver = {
+ .resume = kim_resume,
+ .driver = {
+ .name = "kim",
++ .of_match_table = of_match_ptr(kim_of_match),
+ },
+ };
+
+diff --git a/drivers/misc/ti-st/st_ll.c b/drivers/misc/ti-st/st_ll.c
+index 93b4d67..644f00e 100644
+--- a/drivers/misc/ti-st/st_ll.c
++++ b/drivers/misc/ti-st/st_ll.c
+@@ -25,7 +25,10 @@
+ #include <linux/platform_device.h>
+ #include <linux/ti_wilink_st.h>
+
++extern struct ti_st_plat_data *dt_pdata;
++
+ /**********************************************************************/
++
+ /* internal functions */
+ static void send_ll_cmd(struct st_data_s *st_data,
+ unsigned char cmd)
+@@ -53,7 +56,13 @@ static void ll_device_want_to_sleep(struct st_data_s *st_data)
+
+ /* communicate to platform about chip asleep */
+ kim_data = st_data->kim_data;
+- pdata = kim_data->kim_pdev->dev.platform_data;
++ if (kim_data->kim_pdev->dev.of_node) {
++ pr_debug("use device tree data");
++ pdata = dt_pdata;
++ } else {
++ pdata = kim_data->kim_pdev->dev.platform_data;
++ }
++
+ if (pdata->chip_asleep)
+ pdata->chip_asleep(NULL);
+ }
+@@ -86,7 +95,13 @@ static void ll_device_want_to_wakeup(struct st_data_s *st_data)
+
+ /* communicate to platform about chip wakeup */
+ kim_data = st_data->kim_data;
+- pdata = kim_data->kim_pdev->dev.platform_data;
++ if (kim_data->kim_pdev->dev.of_node) {
++ pr_debug("use device tree data");
++ pdata = dt_pdata;
++ } else {
++ pdata = kim_data->kim_pdev->dev.platform_data;
++ }
++
+ if (pdata->chip_awake)
+ pdata->chip_awake(NULL);
+ }
+--
+1.7.10.4
+
diff --git a/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0021-btwilink-add-minimal-device-tree-support.patch b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0021-btwilink-add-minimal-device-tree-support.patch
new file mode 100644
index 0000000..b628784
--- /dev/null
+++ b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0021-btwilink-add-minimal-device-tree-support.patch
@@ -0,0 +1,54 @@
+From ce021cc0ed5fe1f8068edb41996d05ebe5e11954 Mon Sep 17 00:00:00 2001
+From: Eyal Reizer <eyalr@ti.com>
+Date: Thu, 23 May 2013 17:15:21 +0300
+Subject: [PATCH 100/104] btwilink: add minimal device tree support
+
+Add minimal device tree support to the btwilink driver that is used
+for binding bluetooth with the ti-st shared transport driver.
+
+Change-Id: I301c49d29046f20f8868bebb14347e82c12c8140
+Signed-off-by: Eyal Reizer <eyalr@ti.com>
+Signed-off-by: bvijay <bvijay@ti.com>
+Signed-off-by: Andrey Gusakov <andrey.gusakov@cogentembedded.com>
+---
+ drivers/bluetooth/btwilink.c | 10 ++++++++++
+ 1 file changed, 10 insertions(+)
+
+diff --git a/drivers/bluetooth/btwilink.c b/drivers/bluetooth/btwilink.c
+index 24a652f..a369bf7 100644
+--- a/drivers/bluetooth/btwilink.c
++++ b/drivers/bluetooth/btwilink.c
+@@ -30,6 +30,7 @@
+
+ #include <linux/ti_wilink_st.h>
+ #include <linux/module.h>
++#include <linux/of.h>
+
+ /* Bluetooth Driver Version */
+ #define VERSION "1.0"
+@@ -273,6 +274,14 @@ static int ti_st_send_frame(struct hci_dev *hdev, struct sk_buff *skb)
+ return 0;
+ }
+
++static const struct of_device_id btwilink_of_match[] = {
++{
++ .compatible = "btwilink",
++ },
++ {}
++};
++MODULE_DEVICE_TABLE(of, btwilink_of_match);
++
+ static int bt_ti_probe(struct platform_device *pdev)
+ {
+ static struct ti_st *hst;
+@@ -336,6 +345,7 @@ static struct platform_driver btwilink_driver = {
+ .remove = bt_ti_remove,
+ .driver = {
+ .name = "btwilink",
++ .of_match_table = of_match_ptr(btwilink_of_match),
+ },
+ };
+
+--
+1.7.10.4
+
diff --git a/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0022-ASoC-Modify-check-condition-of-multiple-bindings-of-.patch b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0022-ASoC-Modify-check-condition-of-multiple-bindings-of-.patch
new file mode 100644
index 0000000..73e2150
--- /dev/null
+++ b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0022-ASoC-Modify-check-condition-of-multiple-bindings-of-.patch
@@ -0,0 +1,88 @@
+From 2fc4f16b075264fae016ea3db1f1f81d30cb0ab6 Mon Sep 17 00:00:00 2001
+From: Andrey Gusakov <andrey.gusakov@cogentembedded.com>
+Date: Tue, 13 Dec 2016 18:08:39 +0300
+Subject: [PATCH] ASoC: Modify check condition of multiple bindings of
+ components
+
+https://patchwork.kernel.org/patch/7385501/
+...and some more hacks to bind one component (with several DAIs)
+to more than one sound card.
+
+KF has 4 sound cards (pcm3168a, ak4613, radio, wl18xx) and just one
+compinent ec500000.sound that can not be bound to all 4 cards.
+This is a lack of current implementation of sound/soc/sh/rcar/* ASoC stack
+The ec500000.sound resources (PCM/DMA, dais) needs to be shared between
+all 4 sound cards if we want all cards work runtime.
+Or we have to enable only one of them in dts file as it is designed.
+
+Signed-off-by: Andrey Gusakov <andrey.gusakov@cogentembedded.com>
+---
+ sound/soc/soc-core.c | 6 ++++--
+ sound/soc/soc-pcm.c | 9 +++++++++
+ 2 files changed, 13 insertions(+), 2 deletions(-)
+
+diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c
+index 16369ca..899d013 100644
+--- a/sound/soc/soc-core.c
++++ b/sound/soc/soc-core.c
+@@ -1373,7 +1373,8 @@ static int soc_probe_component(struct snd_soc_card *card,
+ return 0;
+
+ if (component->card) {
+- if (component->card != card) {
++ if (component->card != card &&
++ component->registered_as_component) {
+ dev_err(component->dev,
+ "Trying to bind component to card \"%s\" but is already bound to card \"%s\"\n",
+ card->name, component->card->name);
+@@ -3049,7 +3050,8 @@ int snd_soc_register_component(struct device *dev,
+ goto err_free;
+
+ cmpnt->ignore_pmdown_time = true;
+- cmpnt->registered_as_component = true;
++ if (num_dai == 1)
++ cmpnt->registered_as_component = true;
+
+ ret = snd_soc_register_dais(cmpnt, dai_drv, num_dai, true);
+ if (ret < 0) {
+diff --git a/sound/soc/soc-pcm.c b/sound/soc/soc-pcm.c
+index f6667e4..719c866 100644
+--- a/sound/soc/soc-pcm.c
++++ b/sound/soc/soc-pcm.c
+@@ -2632,11 +2632,16 @@ static void soc_pcm_free(struct snd_pcm *pcm)
+ {
+ struct snd_soc_pcm_runtime *rtd = pcm->private_data;
+ struct snd_soc_component *component;
++ struct snd_soc_platform *platform = rtd->platform;
+
+ list_for_each_entry(component, &rtd->card->component_dev_list,
+ card_list) {
++ if (!component->registered_as_component)
++ component = &platform->component;
+ if (component->pcm_free)
+ component->pcm_free(pcm);
++ if (!component->registered_as_component)
++ break;
+ }
+ }
+
+@@ -2756,6 +2761,8 @@ int soc_new_pcm(struct snd_soc_pcm_runtime *rtd, int num)
+ snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &rtd->ops);
+
+ list_for_each_entry(component, &rtd->card->component_dev_list, card_list) {
++ if (!component->registered_as_component)
++ component = &platform->component;
+ if (component->pcm_new) {
+ ret = component->pcm_new(rtd);
+ if (ret < 0) {
+@@ -2765,6 +2772,8 @@ int soc_new_pcm(struct snd_soc_pcm_runtime *rtd, int num)
+ return ret;
+ }
+ }
++ if (!component->registered_as_component)
++ break;
+ }
+ pcm->private_free = soc_pcm_free;
+ out:
+--
+1.7.10.4
diff --git a/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0023-ASoC-add-dummy-Si468x-driver.patch b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0023-ASoC-add-dummy-Si468x-driver.patch
new file mode 100644
index 0000000..fa27dc1
--- /dev/null
+++ b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0023-ASoC-add-dummy-Si468x-driver.patch
@@ -0,0 +1,123 @@
+From 8829efb30ecbecde33a266ddaed25a74cebbbaf2 Mon Sep 17 00:00:00 2001
+From: Andrey Gusakov <andrey.gusakov@cogentembedded.com>
+Date: Tue, 13 Dec 2016 18:07:13 +0300
+Subject: [PATCH 103/104] ASoC: add dummy Si468x driver
+
+
+Signed-off-by: Andrey Gusakov <andrey.gusakov@cogentembedded.com>
+---
+ sound/soc/codecs/Kconfig | 3 +++
+ sound/soc/codecs/Makefile | 2 ++
+ sound/soc/codecs/si468x.c | 66 +++++++++++++++++++++++++++++++++++++++++++++
+ 3 files changed, 71 insertions(+)
+ create mode 100644 sound/soc/codecs/si468x.c
+
+diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig
+index 4d82a58..264fe79 100644
+--- a/sound/soc/codecs/Kconfig
++++ b/sound/soc/codecs/Kconfig
+@@ -588,6 +588,9 @@ config SND_SOC_PCM3168A_SPI
+ select SND_SOC_PCM3168A
+ select REGMAP_SPI
+
++config SND_SOC_SI468X
++ tristate "Dummy sound driver for Si468x radio"
++
+ config SND_SOC_PCM5102A
+ tristate
+
+diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile
+index 0f548fd3..71a6c2f 100644
+--- a/sound/soc/codecs/Makefile
++++ b/sound/soc/codecs/Makefile
+@@ -116,6 +116,7 @@ snd-soc-sigmadsp-objs := sigmadsp.o
+ snd-soc-sigmadsp-i2c-objs := sigmadsp-i2c.o
+ snd-soc-sigmadsp-regmap-objs := sigmadsp-regmap.o
+ snd-soc-si476x-objs := si476x.o
++snd-soc-si468x-objs := si468x.o
+ snd-soc-sirf-audio-codec-objs := sirf-audio-codec.o
+ snd-soc-sn95031-objs := sn95031.o
+ snd-soc-spdif-tx-objs := spdif_transmitter.o
+@@ -328,6 +329,7 @@ obj-$(CONFIG_SND_SOC_SIGMADSP) += snd-soc-sigmadsp.o
+ obj-$(CONFIG_SND_SOC_SIGMADSP_I2C) += snd-soc-sigmadsp-i2c.o
+ obj-$(CONFIG_SND_SOC_SIGMADSP_REGMAP) += snd-soc-sigmadsp-regmap.o
+ obj-$(CONFIG_SND_SOC_SI476X) += snd-soc-si476x.o
++obj-$(CONFIG_SND_SOC_SI468X) += snd-soc-si468x.o
+ obj-$(CONFIG_SND_SOC_SN95031) +=snd-soc-sn95031.o
+ obj-$(CONFIG_SND_SOC_SPDIF) += snd-soc-spdif-rx.o snd-soc-spdif-tx.o
+ obj-$(CONFIG_SND_SOC_SSM2518) += snd-soc-ssm2518.o
+diff --git a/sound/soc/codecs/si468x.c b/sound/soc/codecs/si468x.c
+new file mode 100644
+index 0000000..18b099f
+--- /dev/null
++++ b/sound/soc/codecs/si468x.c
+@@ -0,0 +1,66 @@
++/*
++ * Dummy sound driver for Si468x DAB/FM/AM chips
++ * Copyright 2016 Andrey Gusakov <andrey.gusakov@cogentembedded.com>
++ *
++ * Based on: Driver for the DFBM-CS320 bluetooth module
++ * Copyright 2011 Lars-Peter Clausen <lars@metafoo.de>
++ *
++ * This program is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License as published by the
++ * Free Software Foundation; either version 2 of the License, or (at your
++ * option) any later version.
++ *
++ */
++
++#include <linux/init.h>
++#include <linux/module.h>
++#include <linux/platform_device.h>
++
++#include <sound/soc.h>
++
++static struct snd_soc_dai_driver si468x_dai = {
++ .name = "si468x-pcm",
++ .capture = {
++ .channels_min = 2,
++ .channels_max = 2,
++ .rates = SNDRV_PCM_RATE_48000,
++ .formats = SNDRV_PCM_FMTBIT_S16_LE,
++ },
++};
++
++static struct snd_soc_codec_driver soc_codec_dev_si468x;
++
++static int si468x_probe(struct platform_device *pdev)
++{
++ return snd_soc_register_codec(&pdev->dev, &soc_codec_dev_si468x,
++ &si468x_dai, 1);
++}
++
++static int si468x_remove(struct platform_device *pdev)
++{
++ snd_soc_unregister_codec(&pdev->dev);
++
++ return 0;
++}
++
++static const struct of_device_id si468x_of_match[] = {
++ { .compatible = "si,si468x-pcm", },
++ { }
++};
++MODULE_DEVICE_TABLE(of, si468x_of_match);
++
++static struct platform_driver si468x_driver = {
++ .driver = {
++ .name = "si468x",
++ .of_match_table = si468x_of_match,
++ .owner = THIS_MODULE,
++ },
++ .probe = si468x_probe,
++ .remove = si468x_remove,
++};
++
++module_platform_driver(si468x_driver);
++
++MODULE_AUTHOR("Andrey Gusakov <andrey.gusakov@cogentembedded.com>");
++MODULE_DESCRIPTION("ASoC Si468x radio chip driver");
++MODULE_LICENSE("GPL");
+--
+1.7.10.4
+
diff --git a/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0024-wl18xx-do-not-invert-IRQ-on-WLxxxx-side.patch b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0024-wl18xx-do-not-invert-IRQ-on-WLxxxx-side.patch
new file mode 100644
index 0000000..f956c58
--- /dev/null
+++ b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0024-wl18xx-do-not-invert-IRQ-on-WLxxxx-side.patch
@@ -0,0 +1,48 @@
+From 60d86113a92ac35421865f9b8db504530962c829 Mon Sep 17 00:00:00 2001
+From: Andrey Gusakov <andrey.gusakov@cogentembedded.com>
+Date: Mon, 22 May 2017 17:22:38 +0300
+Subject: [PATCH] wl18xx: do not invert IRQ on WLxxxx side
+
+
+Signed-off-by: Andrey Gusakov <andrey.gusakov@cogentembedded.com>
+---
+ drivers/net/wireless/ti/wl18xx/main.c | 8 ++++++++
+ 1 file changed, 8 insertions(+)
+
+diff --git a/drivers/net/wireless/ti/wl18xx/main.c b/drivers/net/wireless/ti/wl18xx/main.c
+index ae47c79..cdde6e0 100644
+--- a/drivers/net/wireless/ti/wl18xx/main.c
++++ b/drivers/net/wireless/ti/wl18xx/main.c
+@@ -876,7 +876,9 @@ static int wl18xx_pre_upload(struct wl1271 *wl)
+ {
+ u32 tmp;
+ int ret;
++#if 0
+ u16 irq_invert;
++#endif
+
+ BUILD_BUG_ON(sizeof(struct wl18xx_mac_and_phy_params) >
+ WL18XX_PHY_INIT_MEM_SIZE);
+@@ -929,6 +931,11 @@ static int wl18xx_pre_upload(struct wl1271 *wl)
+ if (ret < 0)
+ goto out;
+
++#if 0
++ /* We have level translator with inversion on IRQ line so we
++ * set IRQ_TYPE_EDGE_FALLING in DTS, but we do not need to
++ * invert IRQ logic on WLxxxx side!
++ */
+ ret = irq_get_trigger_type(wl->irq);
+ if ((ret == IRQ_TYPE_LEVEL_LOW) || (ret == IRQ_TYPE_EDGE_FALLING)) {
+ wl1271_info("using inverted interrupt logic: %d", ret);
+@@ -948,6 +955,7 @@ static int wl18xx_pre_upload(struct wl1271 *wl)
+
+ ret = wlcore_set_partition(wl, &wl->ptable[PART_PHY_INIT]);
+ }
++#endif
+
+ out:
+ return ret;
+--
+1.7.10.4
+
diff --git a/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0025-drm-adv7511-Enable-HPD-interrupts-to-support-hotplug.patch b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0025-drm-adv7511-Enable-HPD-interrupts-to-support-hotplug.patch
new file mode 100644
index 0000000..dc29695
--- /dev/null
+++ b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0025-drm-adv7511-Enable-HPD-interrupts-to-support-hotplug.patch
@@ -0,0 +1,46 @@
+From 0ec0f782c0d19b1e1293e8e281c335186ce3f3cc Mon Sep 17 00:00:00 2001
+From: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+Date: Tue, 30 May 2017 17:41:21 +0300
+Subject: [PATCH] drm: adv7511: Enable HPD interrupts to support hotplug
+
+This patch enables HPD (hot plug detect) interrupt support
+
+Signed-off-by: Andrey Gusakov <andrey.gusakov@cogentembedded.com>
+---
+ drivers/gpu/drm/bridge/adv7511/adv7511_drv.c | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c b/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c
+index a104b43..e20f475 100644
+--- a/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c
++++ b/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c
+@@ -55,7 +55,7 @@ static const struct reg_sequence adv7511_fixed_registers[] = {
+ { 0x98, 0x03 },
+ { 0x9a, 0xe0 },
+ { 0x9c, 0x30 },
+- { 0x9d, 0x61 },
++ { 0x9d, 0x01 },
+ { 0xa2, 0xa4 },
+ { 0xa3, 0xa4 },
+ { 0xe0, 0xd0 },
+@@ -369,7 +369,7 @@ static void adv7511_power_on(struct adv7511 *adv7511)
+ * Still, let's be safe and stick to the documentation.
+ */
+ regmap_write(adv7511->regmap, ADV7511_REG_INT_ENABLE(0),
+- ADV7511_INT0_EDID_READY);
++ ADV7511_INT0_EDID_READY | ADV7511_INT0_HPD);
+ regmap_write(adv7511->regmap, ADV7511_REG_INT_ENABLE(1),
+ ADV7511_INT1_DDC_ERROR);
+ }
+@@ -575,7 +575,7 @@ static int adv7511_get_modes(struct adv7511 *adv7511,
+ ADV7511_POWER_POWER_DOWN, 0);
+ if (adv7511->i2c_main->irq) {
+ regmap_write(adv7511->regmap, ADV7511_REG_INT_ENABLE(0),
+- ADV7511_INT0_EDID_READY);
++ ADV7511_INT0_EDID_READY | ADV7511_INT0_HPD);
+ regmap_write(adv7511->regmap, ADV7511_REG_INT_ENABLE(1),
+ ADV7511_INT1_DDC_ERROR);
+ }
+--
+1.9.1
+
diff --git a/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0026-drm-adv7511-add-polling-mode-when-no-irq-available.patch b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0026-drm-adv7511-add-polling-mode-when-no-irq-available.patch
new file mode 100644
index 0000000..3adfa21
--- /dev/null
+++ b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0026-drm-adv7511-add-polling-mode-when-no-irq-available.patch
@@ -0,0 +1,30 @@
+From 06473f51a6aa077cd56745bd14d114ff3269fe19 Mon Sep 17 00:00:00 2001
+From: Andrey Gusakov <andrey.gusakov@cogentembedded.com>
+Date: Tue, 30 May 2017 18:42:09 +0300
+Subject: [PATCH] drm: adv7511: add polling mode (when no irq available)
+
+Signed-off-by: Andrey Gusakov <andrey.gusakov@cogentembedded.com>
+---
+ drivers/gpu/drm/bridge/adv7511/adv7511_drv.c | 6 +++++-
+ 1 file changed, 5 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c b/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c
+index a104b43b56a0..8be1baca05d0 100644
+--- a/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c
++++ b/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c
+@@ -838,7 +838,11 @@ static int adv7511_bridge_attach(struct drm_bridge *bridge)
+ return -ENODEV;
+ }
+
+- adv->connector.polled = DRM_CONNECTOR_POLL_HPD;
++ if (adv->i2c_main->irq)
++ adv->connector.polled = DRM_CONNECTOR_POLL_HPD;
++ else
++ adv->connector.polled = DRM_CONNECTOR_POLL_CONNECT |
++ DRM_CONNECTOR_POLL_DISCONNECT;
+
+ ret = drm_connector_init(bridge->dev, &adv->connector,
+ &adv7511_connector_funcs,
+--
+2.13.0
+
diff --git a/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0027-usb-host-xhci-plat-add-firmware-for-the-R-Car-M3-W-x.patch b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0027-usb-host-xhci-plat-add-firmware-for-the-R-Car-M3-W-x.patch
new file mode 100644
index 0000000..dc79798
--- /dev/null
+++ b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0027-usb-host-xhci-plat-add-firmware-for-the-R-Car-M3-W-x.patch
@@ -0,0 +1,179 @@
+From b0668886def608d352cd0263a7ef04e64e25574a Mon Sep 17 00:00:00 2001
+From: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
+Date: Tue, 12 Apr 2016 16:28:44 +0900
+Subject: [PATCH] usb: host: xhci-plat: add firmware for the R-Car M3-W xHCI
+ controllers
+
+This patch adds a firmware for the USB 3.0 host controllers of Renesas
+R-Car M3-W SoC.
+
+ - This firmware is possible to be used on R-Car H2 and M2. However,
+ this version causes performance degradation on such SoCs.
+ - This firmware is impossible to be used on R-Car H3 because data
+ transfer might not work correctly.
+
+So, we would like to keep the v1 and v2 firmware.
+
+Signed-off-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
+Signed-off-by: Kyle McMartin <kyle@kernel.org>
+---
+ firmware/WHENCE | 3 ++-
+ firmware/r8a779x_usb3_v3.dlmem | Bin 0 -> 9472 bytes
+ 2 files changed, 2 insertions(+), 1 deletion(-)
+ create mode 100644 r8a779x_usb3_v3.dlmem
+
+diff --git a/firmware/WHENCE b/firmware/WHENCE
+index c2d83f4..02b46c7 100644
+--- a/firmware/WHENCE
++++ b/firmware/WHENCE
+@@ -2922,10 +2922,11 @@ Licence:
+
+ --------------------------------------------------------------------------
+
+-Driver: xhci-rcar -- Renesas R-Car H2/M2/H3 USB 3.0 host controller driver
++Driver: xhci-rcar -- Renesas R-Car Gen2/3 USB 3.0 host controller driver
+
+ File: r8a779x_usb3_v1.dlmem
+ File: r8a779x_usb3_v2.dlmem
++File: r8a779x_usb3_v3.dlmem
+
+ Licence: Redistributable. See LICENCE.r8a779x_usb3 for details.
+
+diff --git a/firmware/r8a779x_usb3_v3.dlmem b/firmware/r8a779x_usb3_v3.dlmem
+new file mode 100644
+index 0000000000000000000000000000000000000000..eac36a96bee1a8614eef9caa88e5a9de136af30c
+GIT binary patch
+literal 9472
+zcmai44O~=J+J9z-JD0DE%!QeY<mgB<W~{cz`bjBB=$cutpn@Ny@*$Ox*>2nRwwB{K
+zD4Ci1rfYs>HkeYmO5m31jV34~)&K>O6o(P~7+pbD-BR(s|8ob#ecSi9{C@v?&b{~C
+z=R9BMInQ~9;u*j3Mp7NIzY7#;Wi4;XjLuOsWLNsr{b*C7mr~CYucqgTozEhh{^R~y
+z;vS+T2HOp?$LiOfB6?v)tUmHIQGg^i{2qOuk!V3ieSzE5L0Y{>@tLiXt@SPOBxf;E
+zcrN-@$=L9oxZiARx2;Ij7m}7V@vjlZ%gTD4C)LZbUMqSBIZC^3^pDz$QG`+K+il|K
+zoUE)CDx}B;>vpN(*eD`dshO-vOVTf;lBi+&&3%Xx^|@h0OUc1_f4i^UdWA?Am#Du6
+zN-vUarO`e}U&H23NYn>vw6vJa9UQ0O#=ag%y4R9SWH%TEW028$gSvva0iw=m`=i-@
+z|0oUh7jq>;W}<!^zFI`dn3L&8e?eA4h1W7P#JG_8V8Lp#NU?g_s_0f3a`}OhR)1M}
+zL$KbkNSYBk&LKV}a>k{QXrMIFP-14!wKIal-C~6yJ8`HKY|@a<Xw7&~@}_>l<?=QO
+zdIY^I_*2JZ43+#duTbaq;Qg%3;F-(B{etJ>dci7j(9}uJ-_~}8Ol5ox(>FZatD9fi
+zHHEJcG-8TWD>&P0g)CnS=N58&wL+&*X0$643HCADmA#SI1-oL>RN|VTE#vIUe4Sl6
+z5LwA-U^}hkOso~U#&n*J(UYOLSUZM2Z8Tl4XB@COWn~lWTcwV^g1dx%va;gtlT+}<
+z(E)a4XTX5?FO@@gWM$#qcjeHR(BKd+8fE2ZGHla8MoYSKb+SQYWRfyJvu@Wk99u~k
+z`FTUG)Db8vv3I|>li#0iYyDm)D`9uv<zn83fI<3Js}?+6FndxvG0PQg52q>J-;UP#
+zebKXWzJ^Kmicyo6l2If0rE7^}d{Et6;vR6sc&$}!P$0f9ShrKdF^PF=aEe{=QvLI?
+z5<ST(T|D6wYr99U!<>WqTP01yCir>9m)ZtKZwustPX^?o?;pR1)71GTUI$yVc}{Yk
+z+JjgbP5o`{`yGk;X7I^Y412d{gs0Xwf@x%#__NI^{Ugw0IB3)OZ18h!a|P8K&2cNh
+z*RDobScrv}KYU(;H53z|r6sU>6<4wHvxXvJypMUAHf@=R`O|zCPqZ;_`8lxS?a&5K
+zZ4+jnZLuqEU6NjjQ@u-F;|oEBt#MiT9i(eE_V|GdewHO3G&-eOtsX<CAS<28w)W@k
+ziTcg>0=#eU({OA6Q3_wH`g4JJk*j#1q`|JNr}_!D_Rk?@g*wuc>c-stql(62J+(p?
+z0*fNe5w`ZPFy?|fhWU2UQ1-r1jUZEFSY&!b?N3qrtJHpjRaSmdW!A(WR-U}WzE}o|
+zer}uKUw*DC-U|gMgVgojD{DIE_YPUfhOCQBOjb1pwfBWwFX62&?zL`Da@-xe+9WHb
+zCKg?6?PexF-Y|VxC4YQrfgKqa%b<rbtxoYPthu#R*{y>k>S(_XRz+<XYiqBE)ShnY
+zwsynvMEzxTj7$0_vpl|@gcVk*b>co-blCjQtIV>JKOxv7E8~XQ+FL*)M$h=LwO>X5
+zA+;|nuf}^?I-%|42`om-%C#Y|_B}Gr#JFA=^Ki#(50CaCHgOd^`QW1_wsvP4lhVT}
+z*f0y4ik5n%-_$+pCk2UmS9hOjucVu@tUP(o=x@{!J#lz|2+El}B6kSlH~L+i5pnbe
+zUF3{BYa2MD-slk52?G$vxdyfi`u}Y08q5*N`z2=k!(~KxE%t}O-OmQ%{cyGK_uzqa
+zSgF2cG1c(a8=v*DN7~aBW!ZGc^yQHjQ$Moahzi^n5s<cjnocZ<_%uQ@yL3+3v}Ku=
+z^dsb$ZkfAQvpmx>H<z551=CjqtPHTE-=so3AEJ39a~0Z1dJ|*Ib*rayX`82QnWoR)
+zniI5e+jHCJyf<yfwD)s@XYZV2nHx?Y%+bzv%_*9*E8@e5-4T1{6wmo6;^T-<BKA)E
+z%bX;Aq8f1_w<pDD*{F1+85}0kO@PM3qS#upwLbyx2oCi7+wQ1;^;avNGh4b4F|x!}
+z*vq+wt>Sk^#G*h|dt#6Fh{lUgiyOQABldGC{67$R18wk1cvYsY*SasObFpzr>7<)%
+zaD$gY(YWt&h%Mdgd|lTDq4$g3>KDwyy(>xX=1f**4)Ub3$kRMXR-zv0{i^xyS9X3N
+z)>7Dmp41YIJ09Dk6<hl-WFYz=CcEF4bL0J%ZCOlpEV9iAR3qfkIGwh6xXvn-`Lq|R
+ze4Bl4QzCgUx<{Ng4IuBxP^uWFmrCCmG;-fNjp9}@OT22X<8l!3-NqvG7&VgSW0oa|
+zv;MgHs(M$fR}{CPsVfp5J|9Gh`nBp)wx5op@xIgPiIkFYz*k?Hgj@g?^y!SVjrY#K
+z>Tp)wP0rRn1{SPVrNByD%wmzgBX_1QqH*@t*^T16;z4LtV~4imCL8K(tY0N=7PV8|
+zX%(rl8F-UN_9>|jbBMk}sl{$~DFgfLyb-OBV=vH-_L@Qw0iGzRFnE9aU7wWrME&Ss
+zrm=2K(Ia|_DK56&aMAn=P94h`9LO2g2_-^3BKqd!dSnU1sR-AX={od(F1eD^B04vP
+zITMShYfK&2Zw$LX5ayKj5Tes*7EhQIuJ$5g^wt}5RH{XwXL^)fD;{N(!cr<Z9ll%}
+z=29s+1Y{h)VHrmNp5}%1aOiCRkX+|KBy+e{|97S3iDZf(6ZNHjG=O5rMuX{B^bifB
+z;WUa8Xe=esqx2X}gwJ$7S~M2)Q?8FdcA8Q-!mezh4Y(eswxM<<Qd5TOZcPEM9!<T?
+zuH4ZU;ku8zjx6aoR|(Hge|7_|u?yRfKLzMn7S&&00FU35&$QE-&!pM@Jd-AGQ6<Ot
+zb_>qL51|)TniM8YAf9d#TzGnW%z7r{4EEGAG8`P*k#{IqpC8h*;z#CW3Z_uHkHRP%
+zSCJxdH6a^)B}L|AC&>Ip-~bRaQRb6@?Gw3pnV%{w?WXX(O2G^o;h<qsDVQk=6as!L
+z^Uc7N$7KH1Nisifvdpgs9JpWdxE@r3yQygP=at$C$<Xga%x;E`2h#n}@&oiB^gNV)
+z4Nd=sM&Ruz8bc35-xDbj7>`*BAD8*ODKa1V1ZDx6fOnph`RM<W`RP+-{thraRpyTZ
+z(P=V2c$&;FoG$Z?fHqy`M*=&5Mqv0%nRm_N!P(-_9{Ju><?9Ri!oXiRAOew?dE#uD
+zuK+UV$h;ef&6N3+r=WR0zWeJe?7j|Tj(C-;6LLi_2b=Ljp0e|>0zZ6S5Jm=K<O;rJ
+zv2&Cm&}woz^cO09?u%^4CNI@ln_c{JWH7E#pYpOI=eI48l{<UPl7>!-+r(UPvvB&K
+zdh&AH&hw<HYxKV7{X!Cm(X##UH>~hdK}*fzd!lyqf0G8g+{d&vVw=uW>#%uRngp|C
+zM2whz>9n|A{91Hh9UyA3?-dz)Mw&B1s49H`jZgDQ<up&+7Gb?n%4;|sSMlfRVHJI*
+zhdrDqPz66dOozDlA@OmW;=fPWlJHFea^XPh$dAclN+MkcsB$)G+j8r;>0!Z1A(J@x
+z@^NmW8g~Y&UX+EswbPg@uCsL-^TcIludo5DApsdc->yn=gP1J3O*%@EBBcVXhIkEI
+z2bOs(KJ3!4bwF8_TrfQTV6Z<<BlnrNpSNCd@m9pCknl}v<f=~f7<LL;{Tbyd7YiLC
+zy4jPFkA%cmKE)zka;kTRd!#}k;opn4^JeE3=q*v-8OEY;N=A6#Dhhr^&})=~92Z|U
+zp>m-RUSWul-gUT5JY|WUV{=5`h~V%7(VeHGDnxnBZ122s%6+=8<jxLN$3EuEooALF
+zH?R}#UCCb7-IbF`dBw1~tK!+Acj=bEe~N{QtRd24zT{bToL<#+rO`4nf(|G4!Fo15
+zS1<U_C_DQ2Gbd(27da!AN3fO7@<8ic7mth-=ZZ0{%h7%`3SaX13!Rc7uoCCT9yxNv
+zPL6%MT&EG85k-jneI;v#Sz_nM7{)<r59c`RaJ_b^7n~VJiSh3<+~ht2UyMJj$c0O(
+z5PPZh>HWUC?9JJsCPm2-KZQ)|jn9gm!gFGs@Vr<8tF$W)L2LRu-hR!^!hX2r31<e@
+z#9XH%IJ{E)-jJ1D!ewV46#P3-fqhNdNu2g`cnx+4YsT}Jax$>vWxRMv*P)vMYu?Ar
+z;5lJhRl1H=rQ7MPX<>6>Fyi~U9;#Y2fP`6V<{VFZH|_0dp~%3p(#~?vrn$LbaN*+|
+z@ak{J^`Uysnz-Lrov<}Q7l-^dfKxR;3HcF=o&Roam(G>>>UoF+^Fy$<hXnS-kpDl*
+zj+>9DnkDmlfule|w#?548nZ(|!N>b4WZ^_uB4mqht{xF2DHkzkfq?f__q_LV+1(Ll
+z(gK;+=gIt{yfBQ}#oPIoaCYLa^i^DZjeo=O8vhos4%h&^3v2`4cj!GUiEqRn`J7oQ
+zaNIY#Uz|V6RAGf>=9l5RCLjJ34tk6E#w`?Bvzda9=sjDhA851a<-TZ+qXf%D3%oL3
+z-!JaI(a}kLCt-ie?-$3SmjB*Qbrsvu7P0u%cT#i`n~lvA^FkZ0=`XO^GGD-K$W3~=
+z@8PijV#eXvD^3TS!%xqLm=L{~(d(g=znIZFx|q?T7yX=P5z|BkxOH*vi-RSO_?d5#
+zcB(e6CT&w%@Hh>vq_y!`vv&^7ne8^`&MqF&gh-nO&E|*>VS%_48A>3$A-dqYjkUK6
+z%G9=b#dR~gcdaZl`@bmR7Kluu`GrN0bYbCj;a{IWQ^>emQ^>e0E$pcRu^i@J4!>;=
+zKwM>Xs@0LNzwufIr{+<s_!h-7@(?s#u{wB%tbDUNCxcZXWV8Wj524j#6|xZr&=2hH
+zm!KbvXRT;M(VjvZhPDZ9c=wp&=p#)prh`;MRmKZnGkpcXx*hWypDxewTsvdYMnT%i
+ztIZu*;lA@0?b!?+ot?*#PqJtiO#QLtQier)%HU2tJCCQ_@Jo1_-B@Kfn-N5L9-sQP
+z`y@`^tJ$~ajvrg**PN9?C@L<e(R;$8MP1BK86(eT2%y}jn{v}hM)^mTvZ04^4Wk@E
+zd5u1N8x`lSl@)O{o2BXG?a%jc{XV<3e-C%xKJ%3%8ejD;<yL*Q&4{X*c4|fH!Y>c&
+zP(AzWY2EnZ4fIU$)q=^$uvzx6mjd7m%w{aAWhLyN;U1ckP&?LZ%uQ%|B1>%Hyh0AH
+z4xw!Vsxz)iT=QKUaDB3<4H;nYuClTBjw%}=E9D<-z%|CzHWd1HmEpRvs9@;5qY7-Y
+zlKVj$^1sFp%5ZhM3UEy-syE&{itT^a56W=e`#}M&ajtp}`#@0<DlGmTa3DFQulk@u
+zf@uC(pJ(F=b@0`XtdgP2$xhS*0=v3*$_}=3;N*fF{gjdA=xR-{e3^LhJdyt-Q%+^(
+zerm1f;5We+JQqt)`LQcIXzVBrjXA?=J|>fv{zO@bpr?P(Q3>iy8-(#*MhSFKz4ErK
+zZ1e9>$ru@h(_u7fi%JJu+iG<P=X_L$x@$}2)Ye^Fn*2?$$J62!`eD8}dIa<N&q6Ce
+zWeMgh`9*c<+cts*l<>^xL5Mf8dJVF*9Q3{y-xMbslF~)&Pd-5_PLxn{`8R*8nr*#d
+z73?~T=@c!C(29<T<+@z{L7^~0Bfb&As*x?^Y;Os2oo@*;hd(WDu_aR=g&;dLAS;w8
+z8u_bTS%h<&UD0aU+E1yu4jZklsl=6PHy~>ntz~QfPAyyex9gmVEkRxWEIrSkrL*|i
+zq;cVSclQ2A|MMg~cWazdOOVG<f-~R8ddLcnSQgb1#CC~JHBPZPhEN+uY$P_vslUm}
+zzB*?HxR%Zac~k4)6^DXc5k;uF`A_@cui9^~t3&;kx(p5Zt1y4K6&$xltTj8OtW1_Y
+zxx4(mX2pxj)*o&i`!!LUP{F6%>Ur+&>UmzVGUb+^UP4sQ39t|`&OcYn^H%Boa+Zfp
+zHf+X;b08`OsC{m{zo8B_yxw;^pVF}!P5Ch6RO4hr$qYZmHK5qT;TlvJe#xH?`Odam
+zZha`-yl&n2hg)@jA*y&gw_Kg!J;EBP#jbi2zaMB4C|NsMRxS_IVwZ0TvPxOy4)HtG
+zBwB*XP-&;~*<)vp2v0t&9O|-~ZU?fg)?zA0z1?CW3um-RpDeSEJQT$8Ti$qB*?x19
+zTDkUH#$)huxyY;*U=P^<FL<e%+5ccQv&}fzCbG8IHYGSIu!`Yh<;QsF;1_lp`~$Op
+zp4fz(?+Mh{*7s$4wY8_Bzg_M7&#<h1@l2glG6o}Z2&}fiVilYHcpaO4=P@?>lH)z`
+z0#)DOU%{Ich0-23WMijG+89TjhV^KNq4j_3InKT<uV>#jpgPaI2iYCIr8M_k<j#7#
+z;xlf-j=A5+d~unuQ+NUS9rOKw1~z+S1EXMVU=(5-7zLNq2RtrQ$6p1HFZi{@$27?N
+zBw!Ix*uYjEi)w5pEoS*y@N!!H>&nG$sbrPzQI+lml`b30Mxx@#hn>*sm#V$E6FBpo
+z=;8W5OYA$r_}$vb_$_T@{4)J(((*(`*W0-CU+yQJWPHNEuTZ5KJLLA0=8-|L#6Gmx
+zQE@Ulf?i*>cMUz967Z}Py+LZvbJB0UUJ6Zk$AN;k`%MdeH(L_qKXa5o!>pb<^GCK;
+z3dGu>sH_wg7rWYD3`yY^hh(WWl^ma2Sm3J@@_b%_MWTJDm^HMgnKfLenRGW#vkKBK
+zawWbP(ly45>WXEg9hJ&-tn?Q{Jcd=>^%XYvBmZY^`;YLmOP<vA_^seB57mr^jL;N5
+zJ@nu6;PNsaZg?3F`_3{RQd$`gcfdnNXb%q*a9F9k?UXV?dwIx0^!<H^Is7?s%ZOy0
+z%KIR~8&Pk#kNTr(U`5R!78L_onR<GI&8}n;+e@2Hv%OT`%=XgE=6b~B+-4S;^P8DI
+z=nUiKcV`$cyU#FQ<TK3L{XEXZ-$Ng2{p4ML1SZX4CFypLja=X)%g1~?$G2aogO>do
+zzN1pKdKks|9!7DWhf$p0;_9XNMK?w5VdcuL9*WNPS)u<~wzX$_WotdlWJ_*kvh8kV
+zvemRQ*?wwevW2!W+0L~wP9~jWoXkDPIO#a&Oq>NhtFoQ$<|Od2l6#jE7dT<E)j_rv
+z0kNxFwz_kS;_Y*cV&DZvapna^arFgPFU2d}6vGcI;$4a?rmhg*6)YwT<)W{RXX~N$
+zimSaIo^tZ8r+j5BfhNBa{JNw|Y`#I4*nE30vH8TyY`(RZU5WKQ5-8pCSq>{ZZ@Q$D
+z@Rug_w?m?4{9-#KoRBLLZ3p@ph-L%HsMJpfcA<X-*oEae6}Sex96@xXn&>w0yT1|b
+z27-?gRRc$mB~|=D6jei%4NO8V@=z_t00DJGF99{c@MA=Gfb8S=?Hrg~kLN%<em{5>
+z@B#@Zh)RJejo6m}(@COdfL35+6Hy5e@FVyIoPY~x1Y+<j`c#1Zn*I&IeofB?RscJJ
+zgTPV13;YC#%|wHNaex!J1C*R0ItN61Knqv_90EGoeGAc6pau}V;NdKIMjM6J1;n-z
+z1%3lwfG58tS_rHF8i2ebL~-8{%?H*1M}TJFHZZt~C?8l0>;zhY!tXI2dQJmgX@l;4
+z;0suI31hII)c`lzF?R=1Xtb7|1o~eknh3m%{w`o#C-eqv2i&+n@(<`7xPyM!eOg*|
+zji^7``M~SfLFWee16Bb$ffC>p@G9Ql0Fr(tIsnYQ1Dz<)8EMGFY3K^_$rw}|vVm2=
+zPe5j%hPDG2f-ojTL(WhQT>~6~hIRm9VH%nblmbzGG?WJ{0$v6V0LOub{_xL%m@9_p
+z^8L^g5N9Lx?>O2i55SiAZK8BIQPl{dy(5Vp8U>67k3jes$OEhaZUfIG5N!gE0$~qh
+z955eP2;5+F&>nmQzB`uaIA9+~G$;|a#xDYKNze;m8joL5fmUGfqqtAO8km6f0PF^C
+z15+mwtp=KbwZBDw5-^$QW3>Cw-uo9dg~)?voscp2N%+qq@RpDERqz2E1e$=K0LPz*
+z>VTvrkd?upr8_{rs3oTpYq$Wm0;+(yD~M*Ugx-Lig`o8Y(ezdDI{-&}It6qBQ&wZG
+z0dwDie*yVxutwj;J#Y<}xEAvR{nnumtO51{H-XmmL_7WmHUO;efG$u7Q~{wIz$dT*
+z_;@4q`)8uhz-P%8=mikBV*N&FsdyWaWjpu=N`dJ2h+YR8fZ!eQF^s838~#2~I<Ow_
+z0&8|cwhuttg|R?v5z&xcSnt4+5AmM?Kr3L`4cb8D9@q$oFNQvVpFV>9K7n3<eL&h?
+z*a#^63z2poWCV)$6Lpl}{ileFr9_K?=rY(Bcm>!DR0B7FNe95wU!g<bozGy?NG-km
+z1$aG#IB^)yfK4)JeTj7ibOQ6s5i5Y1Um;!rVP8X^h@*vQYbtPG3A#Wba0F<LK>Uk@
+zet=y-Gtdc4G$Kv{>_3L4m_Qd;15^PWKz|AL1U3OO&<Z3(!S8`;AfYd4BIf6zT?14>
+Zzol-hJ3M=-8oCR|x&%(egRelM{{{cB@hkuU
+
+literal 0
+HcmV?d00001
+
+--
+1.9.1
+
diff --git a/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0028-usb-host-xhci-rcar-update-firmware-for-R-Car-H3-and-.patch b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0028-usb-host-xhci-rcar-update-firmware-for-R-Car-H3-and-.patch
new file mode 100644
index 0000000..2068abc
--- /dev/null
+++ b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0028-usb-host-xhci-rcar-update-firmware-for-R-Car-H3-and-.patch
@@ -0,0 +1,206 @@
+From 7c3dfc0bb21bf717dc19a6b677a866aef8b70c35 Mon Sep 17 00:00:00 2001
+From: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
+Date: Wed, 10 Aug 2016 19:56:39 +0900
+Subject: [PATCH] usb: host: xhci-rcar: update firmware for R-Car H3 and M3-W
+
+This patch updates the firmware files for R-Car H3 and M3-W to fix
+the device detection issue.
+
+The md5sum of the files are:
+645db7e9056029efa15f158e51cc8a11 r8a779x_usb3_v2.dlmem
+687d5d42f38f9850f8d5a6071dca3109 r8a779x_usb3_v3.dlmem
+
+Signed-off-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
+Signed-off-by: Kyle McMartin <kyle@kernel.org>
+---
+ firmware/r8a779x_usb3_v2.dlmem | Bin 9472 -> 9416 bytes
+ firmware/r8a779x_usb3_v3.dlmem | Bin 9472 -> 9416 bytes
+ 2 files changed, 0 insertions(+), 0 deletions(-)
+
+diff --git a/firmware/r8a779x_usb3_v2.dlmem b/firmware/r8a779x_usb3_v2.dlmem
+index 7db71726f45943e7162d8e21ce7d80885bd79184..2b85222467e555a0f33002d1dad5ecf39da9d9b8 100644
+GIT binary patch
+delta 2698
+zcmY*b4Nz3q6~6b$zQ-=?!aiA+U3U4~T_YkEsUnEF2x#y(qNq_(0hRFwm1eAyrdn14
+zmQw3zZZKr3Mu#6Q<Cu!B%}{ciSg_WTksz!}6&Dp`)Cn~Lb&{CZa~2zuo%zl^_ug~9
+zbKZI9-nXv#SLOvbEN>YKAsqyN1LU^taBu?Mb$E82Fymk61`;UU#Z1Cv<He9+txE}|
+ztstihZk0>P8{<+q%NPDZ&zz4PGn>+@=ePOQP}LGYm(qNGtoV#hvmgKEw@dY<p@hyc
+zT>qF5u83hRuQhrcgNxpEin6~z_QKkUur#rRluG%;F=%o*#ffaHzcZFNyxEtmT*-0R
+zrcv0j!p?7e9(JS3leU74nXkWO;7SBL=5H<evu`K;Cp?#7ZA=12STfF=-L2w^XB=08
+zUwg&Z|AUuHipK0>z1fXm*ES(dbP|^@qsjZ7qE3yOdb68gFE<ghbxFO&q=U+t#^wHw
+zP{LBwa~!+CY7gl$q&}p?DVF+X4Wgo4($bDPZR$fctX8ucbt>&-ch%cy8e5==i+eA<
+z3raeL)PdYhh9N>vdaFuE<VuIG%vncXq;#k(DL6mNPHG%+x{Nw4SDG`>Qp{{sje(sC
+zU9HcuR2w6bpEooJDSoiJjy=_6Xdh+N%>;|g;i+7yWU~XN&Re{t3hElOwa?&E{6sg%
+z2(cV0dAz6#m>(4(|B>y;zivmX3YnU;WzJKOiH|=M`Tb$_5c^wzQT4VqO;p%yeRO1T
+zCYNI7aOoi6EWkXMOVa^I=Bg68l*PgWZMN@V?s=U{ne({xRu-3%=5whM@D9v(EfB#@
+zVEKU=D_sk?v~D4n0vCZDpaXDVF_+{wxU_Hymqq{+v$=E`ATQ-o)G{s=<Z!7S@Xc~A
+zO<KXFYCt<+;+tGLx=I4>&FtGiTllQiTxtg7tl?4<ASRbfGuFZrNfTI#Hay6_)+GfK
+z@LR8jHNrM%<D`p4eVe#4!m6}!w3&Ub{T21HR9z%(V{3G?4Poo??bTDP+4H<sl?JNQ
+z$j<4O(QlY4=wyIyTbI@`=zvZ-&CUh=jBaGTLHYD8mJ$3<n#8nvThN(xTxwYlx#R^v
+zOgnSxZIMZNP``XG)dMaA5(~Jr6wqD}2sZcFKD{9zc_Tc>CN0b_v6Fg3P}(LgeGe!s
+z)WO<u)~cTzE^f0L%S*$PEeW^eWAaA%DrA{c<OaE)>E*bL38Ez-JlULP%7QmtWJ$0Z
+zDH)xQ+E-$4?6~t^k(jc~X~=^N=AC^Y7w<%#99ANmri2z_oS9#hl_KA$?<43Xxfp%_
+z@3*lS{Vo@y-}7SDCNF+NE+2OICvat`-0d4Z`-iPKKl)p@wHs2-mm5`^d}+T~Q3uHs
+zR19l>x}H~or28w7^bFfF)>hKu(|7-F?@ATH16wKeDp5(zaLAhvXijj2AK0)`fZ0VD
+z{b0NRqew<A&Vug$Qf~lV1N*mO41}>0MjebDFb2Q0X#-s*q=7V%Msn3K@b^b{77${f
+z=`1?LNkdtFh>7~KUxTh;e+}7LBGk6d;mXF^Dv)#Q`rvp9_3oMZa<A&1b_2*#ts4&O
+zCpA?d&9!~;5Uth?@?c$g{Ew~59dI4h^ub|nuW^IiQ(F!)xvtCbV=Fw=mKrz6`kHc(
+z<Hg!8D3gwTY>1>o>>9`iY|s!*8<{@TNF!KmXe^!2mW9T{1MGv9gY3i5Q!_77Ed7l3
+zVW6mJZw2|hy$ZViImObCe2JwW>L_#es$ZnMhxbq+-V;$tQCKXt*J#u>(K2JN+N*Db
+zk4F(ZX^ak7LC~x73$C1IUl=3p6>WCos@#3@)0d}Z$S4q+xEF4JJUc>|Kr{(#N!Vh#
+zf_)UWOt2@ip|B`;27}2#JuKB^)t_m@Y`$(o-rc~vkZm!=#phka$c1t@@GdHKimOd{
+zpF0M#K`->_qjx%f15U8dO$IseI`VX1N1h9v_%&eN<_Ws6E?j=zh08h*i!x6dJHt~2
+zwOHuEja(0I6tH}=RlC~5B^RI`@EQBPIXZsCXCvM~o2VPeS!UE~1kt6ycSV|eLl8@R
+z+U6Tv+QDv_<4R&~B5UVO^muY})T38Tmln$CVZK!Y46o)cnBzCg{uODp!twFkvL>nF
+zi3VVV_MFZY(rryL`Lv0kMG^{YPhfYPPYdfFt-=os0g4P}DxffTvxDJgdWiigJU(vV
+zHopDocksDy-@yzMd+-lIJ*jp6BH%^JJ@{TlCAr9_%0WggHq|Hp#;V3zCXc;+4?QQ{
+zN6&%#=(&e&w-^P@3%1{qlu>b~%HdLS33jyHgB?Aq2Rr)xo-Sy;qdnMwwLRE?$#;>c
+z;Vu$+?;_F2T`W=#Q!GaMHZxkIO-Wv~$@QX5wHIv$yl7L+vaLp8+;?oNb<&zE_g{sy
+zJiw6eJiw6N2N=@74?`yOVaUurq>JcBI#)l^9qC89@ej+Ks{&v4{GHLBC;p!*N7*w-
+zLh}&4raVNiv;p)wG=N?$EIz^rr)*9{q+l6jg%J^^<i}{b?lGG7KStB}Ptf!VI|ioR
+z%pI{_-);~{%QZs6+6gHDEIIFpTtl<BLJwC1Mh0Q)KZJCG9%>dy#8X1%0%n1}12F4r
+zLN)`A11e#D<r)0t16&5(1E?G#q#wrd?8~S~ReCsFkZd^W1Nw;lA^LUe_waA&LMkCm
+zGYH9=2~hy9S%i#p5@Kdgqd!nz)C)wE1+t4Bjya|O47A2S64C>Zk3zz1p3O!Nu<f?L
+U&;jPKPot;VTKh+StJ4YjA4B_1P5=M^
+
+delta 2932
+zcmY*b4Ny~87QXMndyfQOfCnK22n3Q~714moimn6^6}6)H|3fP%vR3hLckAvtx}*ro
+zb{q%2i{0*4RwbZS$FT@@wQ{GE1y?)NA|;4aAVfg?sedhYw*qg^4OrUDeCM8b&-u<h
+z_vhT3>+`Jh{mv|(<O)Phi2nLepz*MunK^fOW(B*c|C2s5!<@rfHcoRsuwS&wK}<c!
+zX>1K=m9spo@+F+j{)g$lIM!n(!`Lrw@hoS!G*7EseKCOlj+wZ`zaR)Pv(-da1=o$K
+zYB4=sxX;2Xy;!st5&3j*GM|qMgluGbs<m2pBc9=9QG1!38Fn3!GfjqHF<{YwWfwl|
+z6_6htV$^Vh1yYv?ZA+1Kc(7C)^*Qa1n(~W?1o}M8bgWg;&WtvW$Q{u{4jwbg>iCIe
+z6(Ye;HP)F?1%A!rl6ecVx^s)$Z{c|btAwPT8CSrVgJTt|O?e6y?LiLp^!p65@Vnh#
+zXLwn*i%e66IQ_l?dQ0$G#dM|t-&bs5rsAc_n3%t(IA8@QqY99_P(MWLO{wSDcp|r{
+z3N00AFtLdXOQheI@W)D1Owg<fk;rwksHZBmp7Q`piOS~oED)o3H0jJ4HqjG$bMgO_
+zv&0v(DrSI3YX1}>AHnmyr%YP$PAM$sxXnFktL(|wfDGr0U`s0V91!_M9*tkNmB!EA
+zR?pE$cKnIATKhNAW;ulh5|7YPmeW!634X9dR@~`riuhwH5ys6X!co8_K-3%}qyWn1
+zaPdS~j14{pgXdf#bO7F*M}*yJL`a%Xgd>0g_};UC2R|i#$7j~c;sr#=eUk`*3&9W2
+z2KZ|_5keLbVcB9L3;`x*5aA{uWC;=8SW1M=%ZShlU{??!0dO493Yff#2)5M%#NL5D
+zL__GDHAJWbWUeKG9WXAF2&r#*fju726hnQ-zhxC*R>I_U3h48~Tf`WF<n?SM@(?~I
+z#xT|RhWMw*J}+a!IiwFtMjp=?wFhU?9NTA1TBcGad#7=*md$vBYNlGhj_ztDL)Q{z
+z*K<l(%PaV@YAN#qi@qnkgSI$C(^C^1r{nmt??fgKKk&_FcH;$pH<%=>_BZ%ezfFXO
+zb&zG2H)Jy&&-FKKNXmkh%_hQmz)irk^+Z?$XkG6EJ`aU_WYe5N+0repN?b45IR{6C
+z<Q$msMiJ~^{LJp+)=Mr9vJ=ua5`oVp!nRx$_*CLA{o_JaTXdSDg3zg9<~!0cDM$JO
+zW|5g!1M(2oN-<(QA7&1n8j`F{qbDRo(j-=HYyW{q+O&{l%A)>J+j~H+*iKoQ+mm^D
+zhgInE+mHCZ`iFH7c;^8mv=TWSpO7?RAv-AhH8XDqW!~IDnP?|&meLo66!n|D%tRh2
+zs&Tg+`}=kD+jgKv*9IwOOI6%PcbZwn6|f1Li~Gf2_HQbtK@Szvpw)P1fMIKcTmSQ4
+z_O9d*y?x#nx@3LARXEml2bIT(eC^<dl`MP_Xg#653N4R@JuZRnHKJF6t^|8Gv_8<@
+zg;oV^8?=5SKFyd39K+1VV*@Rr;Rhey*R#53-*ja)-qU!aVDpAn*KIvZWFNdQ(85Ug
+z-+|lLDQ)$$iJWIE1({ya1BI-tteKH5b#X3n1IPlg2Fm*L@=}mdww_oR&sGESXhl)%
+z&%KIFa7mT-K-ssJ*MKav6@g5~ht&ZA#_}2{`19pOAk8)htV|I8R2{(#;M*YY;vdwJ
+z+AG(Tea;6}YMt3CA4fCb9!~6}ms}8z3mVI$;I%=q+WFU%PG^@(3<DoC`Zf3rUxfSd
+ziJ(&^mZdwA+Sm`Hlr+|ZM7K(zIHt06M}}_E9T~t|H5yYJW3zNAMy{DZ3|}+Ju#$GB
+zP}8Mw`d7hIa}Iy3iS#~-DC_Q*M81F>nuwf|2BT(m=6llf*x{mjtYHxozZV%b@4ix+
+z4@tLlg_`V4mhY79gTq>f?Ba}N@4otaB0@c4osjzKb-#V^b${J~)K|mtrUkPI2M4D!
+zhwyKLm$HxJ@YP^Fa}~D-n<ke1m<FeZz8N-mmM$(wdI6`gKrDs1{=R|E@=62EHwp3$
+z#Bth~MQ?mXXOt_o!6mS;z``HV(s$7GGz0W9w@y#w@H@1rsZgU<!k&sv-0;rRxXn#8
+z?#Zud+&%cLcB0DJOnW|e(4H0t?$b^P@NA*3fi2WvY@vp6cx;GHjB0_p2W$fr<E0^y
+zvBd3j)9usOLLa<Bji_XKs|>H4pt{ZS`EJd88}3+qA|xjN;cXiAqgEQVx^<Y*rC^ri
+zN|fPh&4&o1-)VQ~bh450398pY;g;ReB`9EPFF-3HG>ypDLDRam??H<|4D?ll7VXxY
+zcZL__rwGw<8yGnV;Tkb@Ay3U7g*`}s3$O}SiayV)@XpZKm<xC5sbkyeV%XYg+CR3_
+zzb%!>X4&aInCOCMR-a%+wekvlBh<iIzajD_{5&*nyv;?KFI|**;T~nCc2njMFjxA#
+zW+Km8xoH5Whb63C++J$3%9)53Tw6OWIKG1xTxN#@iXf+hmO@@fKZHY_H1uyfY3S3P
+zG&Jd?YZ>M&wEPZ|a=*174i^DpYN2F1!y@B{+$^J$va+0%b-_tlSzWeK)@LIuwpM=f
+z3didvtSz}WnpXEcnpR3TP3v?wO{=k+ruE-$nwC!wO{=$u4v^MM2Y9=e4)CnE(6Sn4
+z>`tqFWB{*P_yhErE;6pEm$C+WDa)&mvR3s`*1<m8DC@}x%db|Juoxb}c0a)r!o%ax
+zBT9~bM9JqLQL^-yl1m=jERNSh$|Gcbt$Y&i4PWPfUCpApuMi4uL})!A?c%rLYnhCb
+zP(6)+mrud;3?ZKo7NrBipCdE}unY7`K++3@HUY{2cKE*j9sK1541ul+WzqZJBNPs8
+z7XDBl!R-d^C9c(fz_{@8$hpi*d@M2)ZtBaCA1KcIvuFsAhgV0P^8c5_qN;x&)B%t_
+gLTC;4HyD^gJjL)S<HX;>-_7ILWc;UR@mYla4-;9yJOBUy
+
+diff --git a/firmware/r8a779x_usb3_v3.dlmem b/firmware/r8a779x_usb3_v3.dlmem
+index eac36a96bee1a8614eef9caa88e5a9de136af30c..1e09014d1876e1acd638db7b067f96397216af1b 100644
+GIT binary patch
+delta 2698
+zcmY*b4Nz3q6~6buzQ-=?!aiA+U3U4~T_PeDsUnEFC}{kTC~8zxKxO<vr5Woasg{)h
+zrPMl_8;qH%(cwqSIHsa&GnCvW7OZv1NDx+~ii-*|>Vz7BI!VmyIg5?S&V1*dd+#~l
+zIq$r4?_1aWEAv7cmbVOrk`98u0dm`RC?tvQIyAFR=#M)$kVNS&W)dbEFNO|lT}l{j
+z1vyo4t6WN+pG)B^U-&0Ib3Wd0CZ$);Z}YFAswMs|rTP3A@fn?BKmP0Qmg-Bxh~I3(
+z^-l=liWuJVTBFA?xad8nC<h2+FRYyi&k##UsgzF~gC>_#9M2{PIOB=Kn|;a3l^lm{
+z3WXgj?EKc}VK=Hg87qk2eElT@S0dT50Bgx#d^@v##&a3g{E{%jk~nX6w~8yCIIe`e
+z_KL6nM=zHYgW1J<vm3##ZCr-vBrab@6DypePK}v*vzuTqHyN{aNxj9SgUVUP<pGW`
+z!qU{U9lOA459u<bKcvJdmilH5qM}^V(vCW9`a?CW9$_`=blS=8s<+V$wm_4R@cyhW
+zDCs0p2XZ$Vh6p{gT2(?aS2}cM&N}iUtwUu=!}(cuQsYR_W!7oA(wvEwVpgll4|Xbb
+zwLZ&IZLCOs+0Y=Q`NQfu_EeLpeUw=@9W1hjCv&BW%?zA8Z}FCDsB7%jK7&i~7u_Hu
+z#d4_R@uDtZepH0~hqojDx*e@5WNOluIZr_*KK?A^4}jH!?C*g_)!W((QDHOnF;T@?
+zT#B8|r2~Mo0P`F!O$8jDqe|w|Tow^zvwaV9&+A;un#ZNL=5i@zK9{Nh@4|f70uk&4
+zmLHV4(zSp~>lSh;Xc5=}Isp3@b4h-KOAD89X#_Ann@g7g@=`8EFXK`{4wu>i-!A9U
+zgcV#m0%!+}f0Ii`S4qIVnSB>zi<q&ROU;0sHC$=}#O88o+FE!bX&g(_Mg-f}x}*>S
+ze(Tk+M%V^zf^@N{ZxdHWShY5RHnT6Z?@%vG*G17bwnjJ85WXJYUOmN{J<n@ZX`nid
+z?3`{H{g$bMPX_9?b!i=g4(O!Q>|F3K=tkBXoKN3knIZq8DNL)k1)o{RrIz)OOI{$v
+zv@@sP7L}3*^~>i{J>W7RxqwSc0qq4rU~`Y{(;EU)H^Osl(!%@_JE=DWXKdoq4}ii#
+z9jqN^t@?=(;x?<Xyfh-!l5|TxCU2ClLY6s2ZjcpBFDGP<6D>&*spbsRTzJz(mL#i@
+zlF|97eHHe`jywMqiD|Am19_0ayt5DF;+@Eo!%Ae+q_AR)GyUtbQsf);eFVKE7o+e0
+z{Wcb(-{oTTdtS`i<i&5u<-?AEB(4mVyM3dlV%UoFqrY=oyCLO#xly&rm-d^Lb&yO!
+z<*@eW>v@$(T2YClXV{i8wvrZ~zWeukSE>je*ea=4iB4&TL*Be!bAl^;|Av(U%r3&{
+z590+GMKWq}7W9CZdIRVh*uM>95R9EL>R{}EG32F98|X424Wx-QlB<S+e>}3Yz)%C7
+z#bQF8G>qkkny5ef4d@#7x6qv>LT&48u57HW205p$500l$@1CA7_p0t`H-IeFy5X>X
+zT2l?uT-%oj(Q4fw57d<>{?w}60oPGY9~|cP8aK#2wdEjF>$(g-wZcPfsd0m>uPFyP
+zR;=xUGU?bShA2A3u7P~O1`RQ^k?F&XG?K-K#nbt0Sy&=Gz&=<xz&;8)HT@FB(obt2
+z28zn|R*=uztD)<kQ!M?+S6KR?jxuMj`bFCNcn=lgJrSJ}jm2VnjYe$~Ei?A2z4}J@
+zcoead#+bkr1id=H<jQIGr7_B0*=9Gc%H1bFeR*1ji~^y_d*SxSvm=BHM3cmpgfFHm
+z*vH|^1bZ?Y3Xg_oFqj<F!_rMw{h2n*=9@O;-3`18*%nhmV%{~3Tqt(~@1jztxY~sG
+zxnnRJ^g^FLdZ*(z-~{`^WRQcdBTx5r<hjs^Ujx={9;XZM!sX{(xUBQAX!C?I(>&Es
+zi-jKC$o1ex0n0aAwW~c`aslcApR+%hV-iPvHsTGmiN1lHWk#(=5M2s<SEM;N1hK@Y
+zZN9;!9qg7lp(OSuvUc7?k0&=rJ$lu2X`zfB=36De@M`XYIexS3Uz1iV93RguYl<44
+zXaGiN&#7D?-PRP7Pa6+f6rr&81a{+mT6p(p6@Fw0RAewy0fo7n9f&Z~gY3@{i3tO@
+z@$FB&gU@~Y4rZ9#gMSF>Nv-o&fiKeT!S^aU#YH|-4lru5sXqNTRyE!-am?*|=sDp&
+zdJf!2&pm9r#VBZAunJ2`X62n~hfB#N*wJzicJz!M?C1}Ax}f!r_Fx0n_Fx01-bJE@
+zyGZ1{i$o)Lu}C>gu^8#w%xH}<rFhXM*NZksyl6AvMVlim+iDczzGqvl6V_b0|0<;A
+z0fv0{0fzKGz>oob7&563LuU0MU1UGfx%!dra6i(GeOTsP74)*_?~L|53HVGo%AP?I
+znuq8$=^=V$44~J+0rYBNiIGM)WwRrr1j`^RjEpp;K1S1ZkI}UMF`CYQf~Hs4F);0B
+z?#T7}c7s4#t`QR6PDlY@$$3ZA8k)TodiV%nWDvIgLr5p+VP=6uJ|$!hU<T+r05iTJ
+zWHaD6pbF+!p21%}z-7=qfT|%v`e7W)zKV`g&5D2vk_|_HNFT93#=LI*0sbvrNGGIe
+z8X<G1Lll5(1|e}yLd@)G%!lfWdVz?tKz6Z1v8VK(gVy*bLV5u5QAn80v)Sl=w%ztu
+UI=~$EDfBd3Yya5)+B<~&507_F0RR91
+
+delta 2932
+zcmY*b4Ny~87QXMndoKyR2oFLMAP`7`RYU_SD|RJ_sHhdi{~uaGk+q6{yIXhH(IrJt
+zw&OVHUF>$ZvMK?sbsUReS1WfqEV$aC7AYW7fg}RrPyK7LyA^nQZotxJ<~#Sid(L<6
+zxj*OLT$^W~?{{YTWOpEHLiE>%0?mj0tjyWNGt1dZ-6wrkhB=G%Y^?TNV83XWgP3}d
+z)7fgyE@yh#<%>9r{SVW9VVu`YhN-=<#k-8*QoZeR)rA25J7&@n|NJ22HCsbuwXSY#
+zWvk`M!hJSgrC`xsMC8-DBt8%23t7nWL~pn8W;{b-(<m&?^jZUvGc2ZGF<>!(WfwlI
+z2*`^HHfy=Te90w3+gd0c9xM?@eNKC#CjTNLfj%!Q9cxvTGrgT7a%U8gbz?_aoj<Yc
+zLIn7!$2rq0!LNCI5^qCxPj0dMZ9K1JRgknZ{W2J{ag1`cC0EI!J*Y+V`aK5O_}!kb
+zGrTO<icC|v`1(C1^cLffm9H}m_?~hLGYv0QMMwWVxdm2m3MvP=3-v>^-sF0YjU#fq
+zy1-VB1{0dN&;<H@5r3qzL<h|(7l~Xqi+ZY4>Nzj46ssK`&wMeGN0ZN-VH3QeHwXVu
+zHA{Rxt9%A{r1VcE@)11GXX@k?Z<oMwj^Es)vCH0kHOMf&5VoWuw*?|U&!zE8x6=4I
+z+v+(QsTP0YqtX9Obl6UzfrKM;l;w03W4s?MksWvWSi=99LWJ?NiEtEf5fC|t2+4rb
+zIb0kO7GsmI$>cqk2%Ug8<`H3cDiIRr6X6ITAHMf2;K5IY-}argvS<Mja^4_9;6m^N
+zv;+Q{Mugx+L|C?%2t$A==|s2z2wp;j*On4t^D-i|0oWBphzA@8v;n59B7$SJ0I_#q
+zFVPe-XAKeR02ynEPzxBJL4=ey6=09UGsTcG6W+87Fe_ooIwkZe@D?#zAh|soi9Cdl
+ziP20IzApYLqEBItKZ}e(NyzIdqw(S_+GG37iObZgB%f3c*0LFIP|wsD*U??AVCY(+
+zta?rbYk3)8QZHqmV{yz0pP(%*qUDJNj?-~`Y0M-h7vCR~#q7ol{H`;JSmSRRQ}q@R
+z8rDIUnLd!s1U%Q@v>`DQRyK<W=KwbV)7KMW4WMnkFZetV@{mJ&3S~(*xk_=pRLiw+
+zL`cep8E+K9{>9JiZf?Eg<{&#Ebt4h@93pJXQG-tf{?b1-M7_nJEzA#@7HYjM9h0)9
+zFJKlKxz!*KVZ9VB#_^%nkZHk5`c!&C(j{#|#kP(gc%)AaPNFR8AGy5;<cjT-m9agE
+zmv`6&m*0NG_tihByU#lhAfb)OVfcik4GrEw*{_(nJ1FzU4$4G3akG@RD7diSqOcNq
+zps?E0cJA*t&~L|qYC}7um?c$m8$D@e7L~&$Y%b~-f7!pOhz31WM1xl0odKq;4Icf^
+zf7!c|L-h7}PjJb`_$zR%>kg`p6Zz`F4J%prBG7t6dj(n^4SQS!T`{6pg02F4H?+Rc
+z-hoyPZ9BAnBR<WT2^`DJ$KwKRAz=p}+%vL<r{B0T8}Dj;kj}cH&3((r64@8;3$!s3
+z{&(Q^bt*^wY$E46N<gNS_dp@5DynB>NiNPUZUC7tRzq2TURDA!($NzG<2kB99xX47
+z`MFo21um(w9w_^^vTBe8jzW-0_^>7*z+6@h1%Ixr5Tw=70xJ`QKh=aY1NaumJNO4p
+zg#PkXRiE>IrN&^j%g50SxQ7$E=p`3~V}r&q$#`v0jDG%AmDA~Ri=p6SMZX50;fruT
+zJ`r@v!m@NnQX2bVl;XyEkmzO!6vs4{?#R$hx+4R4t5$1iXB;+{a^#x%!|*ke1S?s~
+z6lh&ar++0pHD~ch+6bSch_dc{N#ygmMH`-7++fzO&UjaP7BgH_kF+de;`So5_MMk1
+z>mli;p+K9J!SY>l?clK1DZ4py={qmKo`g`3SSO^seAQn&_^Q9|K+4PEc++((!a7|V
+za|r)Nx0HPpi?8U6%oW_BvrH=eF%?b^eKQ=MEZtnT^c+rOzE}ct{e1(S<>dyNZzALy
+zh-3B9i(dPR&L~G}hf82#zKuVkr|+QUNjm7I9-W@Z;df|LQ-M~af;|<RxZ$0rahscH
+z+>>9^xO?!&`blbMGwu1jh4!?z;6DAt0Pj}n8rVt==2mJLkH-ZY#K=~td%!k85ndV`
+z5kovaH#|Olt@Obw(26RSx6AO#3F=!cpXbr6x8RP&CxWB%9^9f)KWw8>tJ;PcE+w-h
+zN1_aOTOLFh{Z742r;~-uk5Rn=3b*vOAzlevdmdT|q3J}v2AbZZeGghVVxX@Iv?!0}
+zygj@iKShX=+rh{|2=|D|g}k+Ul(j(uT!59ZQuKLVg?EO;M4!JyPaWGq7sJs()Bdr8
+z{%xs14%<$j!2~xvv&MKks*zXV>mer2{tb~g;b$SS6C7^JeBq|d^LHsTrJFK`fVtB5
+z6%%>a$V~${Ei``Z;*JuFUCuzX;MzNA!SS86;4(T}pa`-%X({A(_Cq+-MMM9#i-tbk
+zMMIM=x|X5N0^9E(DbHK`!Eg~ErUpv3D>Nc*$ip%_DJ#=SS?8UUmFaSfvOXJOu{HAJ
+zmpINaac%M4(X_hn(zKGhX<DbdX<CilG_C)3)3khhXj;8Jbb!=eI>1}KbbzP51-8{N
+zV^3NgBLgUE;1AGehKSgvUdkHir7T4sWv%L?tb=`yQP$%TmS2r5VKFS6?S70WhK0qV
+zhm;)kkdn_mq-5z4B^N((*jio<DUXniHS$TkH*B5%H4TgEzCuXXh|qdK>V<E^)-vfQ
+zp?VqtFP?zuDMG%%EJ_1}Jws>?U>E2WfW+qrZ32`6YT^6Zckq`NFa)|fghlUtk5Cx2
+znfL=^IJX<L7r4gwKI6vABjz$M@Ue&xxT!Biystdx&!QnfE?ymZ%Ku*yiz@$tP$xk8
+g5TP~L-(+G6@Kn>Mj1zwge>aa~i}|14jS7VR52nDsPyhe`
+
+--
+1.9.1
+
diff --git a/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0029-i2c-mux-pca954x-fix-i2c-mux-selection-caching.patch b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0029-i2c-mux-pca954x-fix-i2c-mux-selection-caching.patch
new file mode 100644
index 0000000..1640b51
--- /dev/null
+++ b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0029-i2c-mux-pca954x-fix-i2c-mux-selection-caching.patch
@@ -0,0 +1,51 @@
+From 7f638c1cb0a1112dbe0b682a42db30521646686b Mon Sep 17 00:00:00 2001
+From: Russell King <rmk+kernel@armlinux.org.uk>
+Date: Sat, 17 Dec 2016 12:10:56 +0000
+Subject: [PATCH] i2c: mux: pca954x: fix i2c mux selection caching
+
+smbus functions return -ve on error, 0 on success. However,
+__i2c_transfer() have a different return signature - -ve on error, or
+number of buffers transferred (which may be zero or greater.)
+
+The upshot of this is that the sense of the test is reversed when using
+the mux on a bus supporting the master_xfer method: we cache the value
+and never retry if we fail to transfer any buffers, but if we succeed,
+we clear the cached value.
+
+Fix this by making pca954x_reg_write() return a negative error code for
+all failure cases.
+
+Fixes: 463e8f845cbf ("i2c: mux: pca954x: retry updating the mux selection on failure")
+Acked-by: Peter Rosin <peda@axentia.se>
+Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
+Signed-off-by: Wolfram Sang <wsa@the-dreams.de>
+---
+ drivers/i2c/muxes/i2c-mux-pca954x.c | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/i2c/muxes/i2c-mux-pca954x.c b/drivers/i2c/muxes/i2c-mux-pca954x.c
+index 9a348ee..dd18b9c 100644
+--- a/drivers/i2c/muxes/i2c-mux-pca954x.c
++++ b/drivers/i2c/muxes/i2c-mux-pca954x.c
+@@ -167,6 +167,9 @@ static int pca954x_reg_write(struct i2c_adapter *adap,
+ buf[0] = val;
+ msg.buf = buf;
+ ret = __i2c_transfer(adap, &msg, 1);
++
++ if (ret >= 0 && ret != 1)
++ ret = -EREMOTEIO;
+ } else {
+ union i2c_smbus_data data;
+ ret = adap->algo->smbus_xfer(adap, client->addr,
+@@ -195,7 +198,7 @@ static int pca954x_select_chan(struct i2c_mux_core *muxc, u32 chan)
+ /* Only select the channel if its different from the last channel */
+ if (data->last_chan != regval) {
+ ret = pca954x_reg_write(muxc->parent, client, regval);
+- data->last_chan = ret ? 0 : regval;
++ data->last_chan = ret < 0 ? 0 : regval;
+ }
+
+ return ret;
+--
+1.9.1
+
diff --git a/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0030-Gen3-LVDS-cameras.patch b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0030-Gen3-LVDS-cameras.patch
new file mode 100644
index 0000000..96c1601
--- /dev/null
+++ b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0030-Gen3-LVDS-cameras.patch
@@ -0,0 +1,7616 @@
+From 7a6b0c38e5e1502f309b89b16fad8c70645e1221 Mon Sep 17 00:00:00 2001
+From: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+Date: Sun, 14 May 2017 15:20:01 +0300
+Subject: [PATCH] Gen3: LVDS cameras
+
+This add Gen3 LVDS cameras support:
+- deserializers: MAX9286, TI964, TI954, TI960
+- cameras: ov10635, ov490+ov10640, ov495+OV2775, ar0132
+
+Signed-off-by: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+---
+ drivers/media/i2c/soc_camera/Kconfig | 47 +
+ drivers/media/i2c/soc_camera/Makefile | 7 +
+ drivers/media/i2c/soc_camera/ar0132.c | 548 +++++++++++
+ drivers/media/i2c/soc_camera/ar0132.h | 213 ++++
+ drivers/media/i2c/soc_camera/max9286_max9271.c | 567 +++++++++++
+ drivers/media/i2c/soc_camera/max9286_max9271.h | 243 +++++
+ drivers/media/i2c/soc_camera/ov10635.c | 759 ++++++++++++++
+ drivers/media/i2c/soc_camera/ov10635.h | 1139 ++++++++++++++++++++++
+ drivers/media/i2c/soc_camera/ov10635_debug.h | 54 +
+ drivers/media/i2c/soc_camera/ov106xx.c | 106 ++
+ drivers/media/i2c/soc_camera/ov490_ov10640.c | 1046 ++++++++++++++++++++
+ drivers/media/i2c/soc_camera/ov490_ov10640.h | 88 ++
+ drivers/media/i2c/soc_camera/ov495_ov2775.c | 658 +++++++++++++
+ drivers/media/i2c/soc_camera/ov495_ov2775.h | 23 +
+ drivers/media/i2c/soc_camera/ti954_ti9x3.c | 417 ++++++++
+ drivers/media/i2c/soc_camera/ti964_ti9x3.c | 385 ++++++++
+ drivers/media/i2c/soc_camera/ti9x4_ti9x3.h | 153 +++
+ drivers/media/platform/soc_camera/rcar_csi2.c | 297 ++++--
+ drivers/media/platform/soc_camera/rcar_vin.c | 174 +++-
+ drivers/media/platform/soc_camera/soc_camera.c | 17 +-
+ drivers/media/platform/soc_camera/soc_mediabus.c | 16 +
+ include/media/drv-intf/soc_mediabus.h | 3 +
+ include/media/soc_camera.h | 1 +
+ 23 files changed, 6852 insertions(+), 109 deletions(-)
+ create mode 100644 drivers/media/i2c/soc_camera/ar0132.c
+ create mode 100644 drivers/media/i2c/soc_camera/ar0132.h
+ create mode 100644 drivers/media/i2c/soc_camera/max9286_max9271.c
+ create mode 100644 drivers/media/i2c/soc_camera/max9286_max9271.h
+ create mode 100644 drivers/media/i2c/soc_camera/ov10635.c
+ create mode 100644 drivers/media/i2c/soc_camera/ov10635.h
+ create mode 100644 drivers/media/i2c/soc_camera/ov10635_debug.h
+ create mode 100644 drivers/media/i2c/soc_camera/ov106xx.c
+ create mode 100644 drivers/media/i2c/soc_camera/ov490_ov10640.c
+ create mode 100644 drivers/media/i2c/soc_camera/ov490_ov10640.h
+ create mode 100644 drivers/media/i2c/soc_camera/ov495_ov2775.c
+ create mode 100644 drivers/media/i2c/soc_camera/ov495_ov2775.h
+ create mode 100644 drivers/media/i2c/soc_camera/ti954_ti9x3.c
+ create mode 100644 drivers/media/i2c/soc_camera/ti964_ti9x3.c
+ create mode 100644 drivers/media/i2c/soc_camera/ti9x4_ti9x3.h
+
+diff --git a/drivers/media/i2c/soc_camera/Kconfig b/drivers/media/i2c/soc_camera/Kconfig
+index 7704bcf..82da59f 100644
+--- a/drivers/media/i2c/soc_camera/Kconfig
++++ b/drivers/media/i2c/soc_camera/Kconfig
+@@ -6,6 +6,53 @@ config SOC_CAMERA_IMX074
+ help
+ This driver supports IMX074 cameras from Sony
+
++config SOC_CAMERA_MAX9286_MAX9271
++ tristate "max9286-max9271 GMSL support"
++ depends on SOC_CAMERA && I2C
++ help
++ This is a MAXIM max9286-max9271 GMSL driver
++
++config SOC_CAMERA_OV106XX
++ tristate "ov106xx camera support"
++ depends on SOC_CAMERA && SOC_CAMERA_MAX9286_MAX9271 && I2C
++ help
++ This is a runtime detected OmniVision ov10635 or ov490-ov10640
++ or ov495-ov2775 sensors camera driver
++
++if !SOC_CAMERA_OV106XX
++
++config SOC_CAMERA_OV10635
++ tristate "ov10635 camera support"
++ depends on SOC_CAMERA && SOC_CAMERA_MAX9286_MAX9271 && I2C
++ help
++ This is an OmniVision ov10635 sensor camera driver
++
++config SOC_CAMERA_OV490_OV10640
++ tristate "ov490-ov10640 camera support"
++ depends on SOC_CAMERA && SOC_CAMERA_MAX9286_MAX9271 && I2C
++ help
++ This is an OmniVision ov490-ov10640 sensor camera driver
++
++config SOC_CAMERA_OV495_OV2775
++ tristate "ov495-ov2775 camera support"
++ depends on SOC_CAMERA && I2C
++ help
++ This is an OmniVision ov495-ov2775 sensor camera driver
++
++endif
++
++config SOC_CAMERA_TI964_TI9X3
++ tristate "ti964-ti9x3 FPDLinkIII support"
++ depends on SOC_CAMERA && I2C
++ help
++ This is an Texas Instruments ti964-ti9X3 FPDLinkIII driver
++
++config SOC_CAMERA_TI954_TI9X3
++ tristate "ti954-ti9X3 FPDLinkIII support"
++ depends on SOC_CAMERA && I2C
++ help
++ This is an Texas Instruments ti954-ti9X3 FPDLinkIII driver
++
+ config SOC_CAMERA_MT9M001
+ tristate "mt9m001 support"
+ depends on SOC_CAMERA && I2C
+diff --git a/drivers/media/i2c/soc_camera/Makefile b/drivers/media/i2c/soc_camera/Makefile
+index 6f994f9..7d4c1ab 100644
+--- a/drivers/media/i2c/soc_camera/Makefile
++++ b/drivers/media/i2c/soc_camera/Makefile
+@@ -1,8 +1,15 @@
+ obj-$(CONFIG_SOC_CAMERA_IMX074) += imx074.o
++obj-$(CONFIG_SOC_CAMERA_MAX9286_MAX9271) += max9286_max9271.o
++obj-$(CONFIG_SOC_CAMERA_TI964_TI9X3) += ti964_ti9x3.o
++obj-$(CONFIG_SOC_CAMERA_TI954_TI9X3) += ti954_ti9x3.o
+ obj-$(CONFIG_SOC_CAMERA_MT9M001) += mt9m001.o
+ obj-$(CONFIG_SOC_CAMERA_MT9T031) += mt9t031.o
+ obj-$(CONFIG_SOC_CAMERA_MT9T112) += mt9t112.o
+ obj-$(CONFIG_SOC_CAMERA_MT9V022) += mt9v022.o
++obj-$(CONFIG_SOC_CAMERA_OV10635) += ov10635.o
++obj-$(CONFIG_SOC_CAMERA_OV490_OV10640) += ov490_ov10640.o
++obj-$(CONFIG_SOC_CAMERA_OV495_OV2775) += ov495_ov2775.o
++obj-$(CONFIG_SOC_CAMERA_OV106XX) += ov106xx.o
+ obj-$(CONFIG_SOC_CAMERA_OV2640) += ov2640.o
+ obj-$(CONFIG_SOC_CAMERA_OV5642) += ov5642.o
+ obj-$(CONFIG_SOC_CAMERA_OV6650) += ov6650.o
+diff --git a/drivers/media/i2c/soc_camera/ar0132.c b/drivers/media/i2c/soc_camera/ar0132.c
+new file mode 100644
+index 0000000..284c522
+--- /dev/null
++++ b/drivers/media/i2c/soc_camera/ar0132.c
+@@ -0,0 +1,548 @@
++/*
++ * Aptina AR0132 sensor camera driver
++ *
++ * Copyright (C) 2017 Cogent Embedded, Inc.
++ *
++ * This program is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License as published by the
++ * Free Software Foundation; either version 2 of the License, or (at your
++ * option) any later version.
++ */
++
++#include <linux/delay.h>
++#include <linux/init.h>
++#include <linux/i2c.h>
++#include <linux/module.h>
++#include <linux/videodev2.h>
++
++#include <media/soc_camera.h>
++#include <media/v4l2-common.h>
++#include <media/v4l2-ctrls.h>
++#include <media/v4l2-of.h>
++
++#include "ar0132.h"
++
++#define AR0132_I2C_ADDR 0x18
++//#define AR0132_I2C_ADDR 0x50 // eeprom
++
++#define AR0132_PID 0x3000
++#define AR0132_VERSION_REG 0x2400
++
++#define AR0132_MEDIA_BUS_FMT MEDIA_BUS_FMT_SBGGR12_1X12
++
++struct ar0132_priv {
++ struct v4l2_subdev sd;
++ struct v4l2_ctrl_handler hdl;
++ struct media_pad pad;
++ struct v4l2_rect rect;
++ int init_complete;
++ u8 id[6];
++ int exposure;
++ int gain;
++ int autogain;
++ int dvp_order;
++ /* serializers */
++ int ti964_addr;
++ int ti954_addr;
++ int ti9x3_addr;
++ int port;
++ int gpio_resetb;
++ int gpio_fsin;
++
++};
++
++static inline struct ar0132_priv *to_ar0132(const struct i2c_client *client)
++{
++ return container_of(i2c_get_clientdata(client), struct ar0132_priv, sd);
++}
++
++static int ar0132_set_regs(struct i2c_client *client,
++ const struct ar0132_reg *regs, int nr_regs)
++{
++ int i;
++
++ for (i = 0; i < nr_regs; i++) {
++ if (regs[i].reg == AR0132_DELAY) {
++ mdelay(regs[i].val);
++ continue;
++ }
++
++ reg16_write16(client, regs[i].reg, regs[i].val);
++ }
++
++ return 0;
++}
++
++static int ar0132_s_stream(struct v4l2_subdev *sd, int enable)
++{
++ return 0;
++}
++
++static int ar0132_get_fmt(struct v4l2_subdev *sd,
++ struct v4l2_subdev_pad_config *cfg,
++ struct v4l2_subdev_format *format)
++{
++ struct v4l2_mbus_framefmt *mf = &format->format;
++ struct i2c_client *client = v4l2_get_subdevdata(sd);
++ struct ar0132_priv *priv = to_ar0132(client);
++
++ if (format->pad)
++ return -EINVAL;
++
++ mf->width = priv->rect.width;
++ mf->height = priv->rect.height;
++ mf->code = AR0132_MEDIA_BUS_FMT;
++ mf->colorspace = V4L2_COLORSPACE_SMPTE170M;
++ mf->field = V4L2_FIELD_NONE;
++
++ return 0;
++}
++
++static int ar0132_set_fmt(struct v4l2_subdev *sd,
++ struct v4l2_subdev_pad_config *cfg,
++ struct v4l2_subdev_format *format)
++{
++ struct v4l2_mbus_framefmt *mf = &format->format;
++
++ mf->code = AR0132_MEDIA_BUS_FMT;
++ mf->colorspace = V4L2_COLORSPACE_SMPTE170M;
++ mf->field = V4L2_FIELD_NONE;
++
++ if (format->which == V4L2_SUBDEV_FORMAT_TRY)
++ cfg->try_fmt = *mf;
++
++ return 0;
++}
++
++static int ar0132_enum_mbus_code(struct v4l2_subdev *sd,
++ struct v4l2_subdev_pad_config *cfg,
++ struct v4l2_subdev_mbus_code_enum *code)
++{
++ if (code->pad || code->index > 0)
++ return -EINVAL;
++
++ code->code = AR0132_MEDIA_BUS_FMT;
++
++ return 0;
++}
++
++static int ar0132_get_edid(struct v4l2_subdev *sd, struct v4l2_edid *edid)
++{
++ struct i2c_client *client = v4l2_get_subdevdata(sd);
++ struct ar0132_priv *priv = to_ar0132(client);
++
++ memcpy(edid->edid, priv->id, 6);
++
++ edid->edid[6] = 0xff;
++ edid->edid[7] = client->addr;
++ edid->edid[8] = AR0132_VERSION_REG >> 8;
++ edid->edid[9] = AR0132_VERSION_REG & 0xff;
++
++ return 0;
++}
++
++static int ar0132_set_selection(struct v4l2_subdev *sd,
++ struct v4l2_subdev_pad_config *cfg,
++ struct v4l2_subdev_selection *sel)
++{
++ struct v4l2_rect *rect = &sel->r;
++ struct i2c_client *client = v4l2_get_subdevdata(sd);
++ struct ar0132_priv *priv = to_ar0132(client);
++
++ if (sel->which != V4L2_SUBDEV_FORMAT_ACTIVE ||
++ sel->target != V4L2_SEL_TGT_CROP)
++ return -EINVAL;
++
++ rect->left = ALIGN(rect->left, 2);
++ rect->top = ALIGN(rect->top, 2);
++ rect->width = ALIGN(rect->width, 2);
++ rect->height = ALIGN(rect->height, 2);
++
++ if ((rect->left + rect->width > AR0132_MAX_WIDTH) ||
++ (rect->top + rect->height > AR0132_MAX_HEIGHT))
++ *rect = priv->rect;
++
++ priv->rect.left = rect->left;
++ priv->rect.top = rect->top;
++ priv->rect.width = rect->width;
++ priv->rect.height = rect->height;
++
++ return 0;
++}
++
++static int ar0132_get_selection(struct v4l2_subdev *sd,
++ struct v4l2_subdev_pad_config *cfg,
++ struct v4l2_subdev_selection *sel)
++{
++ struct i2c_client *client = v4l2_get_subdevdata(sd);
++ struct ar0132_priv *priv = to_ar0132(client);
++
++ if (sel->which != V4L2_SUBDEV_FORMAT_ACTIVE)
++ return -EINVAL;
++
++ switch (sel->target) {
++ case V4L2_SEL_TGT_CROP_BOUNDS:
++ sel->r.left = 0;
++ sel->r.top = 0;
++ sel->r.width = AR0132_MAX_WIDTH;
++ sel->r.height = AR0132_MAX_HEIGHT;
++ return 0;
++ case V4L2_SEL_TGT_CROP_DEFAULT:
++ sel->r.left = 0;
++ sel->r.top = 0;
++ sel->r.width = AR0132_MAX_WIDTH;
++ sel->r.height = AR0132_MAX_HEIGHT;
++ return 0;
++ case V4L2_SEL_TGT_CROP:
++ sel->r = priv->rect;
++ return 0;
++ default:
++ return -EINVAL;
++ }
++}
++
++static int ar0132_g_mbus_config(struct v4l2_subdev *sd,
++ struct v4l2_mbus_config *cfg)
++{
++ cfg->flags = V4L2_MBUS_CSI2_1_LANE | V4L2_MBUS_CSI2_CHANNEL_0 |
++ V4L2_MBUS_CSI2_CONTINUOUS_CLOCK;
++ cfg->type = V4L2_MBUS_CSI2;
++
++ return 0;
++}
++
++#ifdef CONFIG_VIDEO_ADV_DEBUG
++static int ar0132_g_register(struct v4l2_subdev *sd,
++ struct v4l2_dbg_register *reg)
++{
++ struct i2c_client *client = v4l2_get_subdevdata(sd);
++ int ret;
++ u16 val = 0;
++
++ ret = reg16_read16(client, (u16)reg->reg, &val);
++ if (ret < 0)
++ return ret;
++
++ reg->val = val;
++ reg->size = sizeof(u16);
++
++ return 0;
++}
++
++static int ar0132_s_register(struct v4l2_subdev *sd,
++ const struct v4l2_dbg_register *reg)
++{
++ struct i2c_client *client = v4l2_get_subdevdata(sd);
++
++ return reg16_write16(client, (u16)reg->reg, (u16)reg->val);
++}
++#endif
++
++static struct v4l2_subdev_core_ops ar0132_core_ops = {
++#ifdef CONFIG_VIDEO_ADV_DEBUG
++ .g_register = ar0132_g_register,
++ .s_register = ar0132_s_register,
++#endif
++};
++
++static int ar0132_s_ctrl(struct v4l2_ctrl *ctrl)
++{
++ struct v4l2_subdev *sd = to_sd(ctrl);
++ struct i2c_client *client = v4l2_get_subdevdata(sd);
++ struct ar0132_priv *priv = to_ar0132(client);
++ int ret = -EINVAL;
++
++ if (!priv->init_complete)
++ return 0;
++
++ switch (ctrl->id) {
++ case V4L2_CID_BRIGHTNESS:
++ case V4L2_CID_CONTRAST:
++ case V4L2_CID_SATURATION:
++ case V4L2_CID_HUE:
++ case V4L2_CID_GAMMA:
++ case V4L2_CID_SHARPNESS:
++ case V4L2_CID_AUTOGAIN:
++ case V4L2_CID_GAIN:
++ case V4L2_CID_EXPOSURE:
++ case V4L2_CID_HFLIP:
++ case V4L2_CID_VFLIP:
++ break;
++ }
++
++ return ret;
++}
++
++static const struct v4l2_ctrl_ops ar0132_ctrl_ops = {
++ .s_ctrl = ar0132_s_ctrl,
++};
++
++static struct v4l2_subdev_video_ops ar0132_video_ops = {
++ .s_stream = ar0132_s_stream,
++ .g_mbus_config = ar0132_g_mbus_config,
++};
++
++static const struct v4l2_subdev_pad_ops ar0132_subdev_pad_ops = {
++ .get_edid = ar0132_get_edid,
++ .enum_mbus_code = ar0132_enum_mbus_code,
++ .get_selection = ar0132_get_selection,
++ .set_selection = ar0132_set_selection,
++ .get_fmt = ar0132_get_fmt,
++ .set_fmt = ar0132_set_fmt,
++};
++
++static struct v4l2_subdev_ops ar0132_subdev_ops = {
++ .core = &ar0132_core_ops,
++ .video = &ar0132_video_ops,
++ .pad = &ar0132_subdev_pad_ops,
++};
++
++static void ar0132_otp_id_read(struct i2c_client *client)
++{
++}
++
++static ssize_t ar0132_otp_id_show(struct device *dev,
++ struct device_attribute *attr, char *buf)
++{
++ struct v4l2_subdev *sd = i2c_get_clientdata(to_i2c_client(dev));
++ struct i2c_client *client = v4l2_get_subdevdata(sd);
++ struct ar0132_priv *priv = to_ar0132(client);
++
++ return snprintf(buf, 32, "%02x:%02x:%02x:%02x:%02x:%02x\n",
++ priv->id[0], priv->id[1], priv->id[2], priv->id[3], priv->id[4], priv->id[5]);
++}
++
++static DEVICE_ATTR(otp_id_ar0132, S_IRUGO, ar0132_otp_id_show, NULL);
++
++static int ar0132_initialize(struct i2c_client *client)
++{
++ struct ar0132_priv *priv = to_ar0132(client);
++ u16 val = 0;
++ u16 pid = 0;
++ int ret = 0;
++
++ /* check and show model ID */
++ reg16_read16(client, AR0132_PID, &pid);
++
++ if (pid != AR0132_VERSION_REG) {
++ dev_dbg(&client->dev, "Product ID error %x\n", pid);
++ ret = -ENODEV;
++ goto err;
++ }
++
++ /* Program wizard registers */
++ ar0132_set_regs(client, ar0132_regs_wizard, ARRAY_SIZE(ar0132_regs_wizard));
++
++ /* Enable stream */
++ reg16_read16(client, 0x301a, &val); // read inital reset_register value
++ val |= (1 << 2); // Set streamOn bit
++ reg16_write16(client, 0x301a, val); // Start Streaming
++
++ /* Read OTP IDs */
++ ar0132_otp_id_read(client);
++
++ dev_info(&client->dev, "ar0132 PID %x, res %dx%d, OTP_ID %02x:%02x:%02x:%02x:%02x:%02x\n",
++ pid, AR0132_MAX_WIDTH, AR0132_MAX_HEIGHT, priv->id[0], priv->id[1], priv->id[2], priv->id[3], priv->id[4], priv->id[5]);
++err:
++ return ret;
++}
++
++static int ar0132_parse_dt(struct device_node *np, struct ar0132_priv *priv)
++{
++ struct i2c_client *client = v4l2_get_subdevdata(&priv->sd);
++ int i;
++ struct device_node *endpoint = NULL, *rendpoint = NULL;
++ int tmp_addr = 0;
++
++ for (i = 0; ; i++) {
++ endpoint = of_graph_get_next_endpoint(np, endpoint);
++ if (!endpoint)
++ break;
++
++ of_node_put(endpoint);
++
++ of_property_read_u32(endpoint, "dvp-order", &priv->dvp_order);
++
++ rendpoint = of_parse_phandle(endpoint, "remote-endpoint", 0);
++ if (!rendpoint)
++ continue;
++
++ if (!of_property_read_u32(rendpoint, "ti9x3-addr", &priv->ti9x3_addr) &&
++ !of_property_match_string(rendpoint->parent->parent, "compatible", "ti,ti964-ti9x3") &&
++ !of_property_read_u32(rendpoint->parent->parent, "reg", &priv->ti964_addr) &&
++ !kstrtouint(strrchr(rendpoint->full_name, '@') + 1, 0, &priv->port))
++ break;
++
++ if (!of_property_read_u32(rendpoint, "ti9x3-addr", &priv->ti9x3_addr) &&
++ !of_property_match_string(rendpoint->parent->parent, "compatible", "ti,ti954-ti9x3") &&
++ !of_property_read_u32(rendpoint->parent->parent, "reg", &priv->ti954_addr) &&
++ !kstrtouint(strrchr(rendpoint->full_name, '@') + 1, 0, &priv->port))
++ break;
++ }
++
++ if (!priv->ti964_addr && !priv->ti954_addr) {
++ dev_err(&client->dev, "deserializer does not present\n");
++ return -EINVAL;
++ }
++
++ /* setup I2C translator address */
++ tmp_addr = client->addr;
++ if (priv->ti964_addr) {
++ client->addr = priv->ti964_addr; /* Deserializer I2C address */
++
++ reg8_write(client, 0x4c, (priv->port << 4) | (1 << priv->port)); /* Select RX port number */
++ usleep_range(2000, 2500); /* wait 2ms */
++ reg8_write(client, 0x65, tmp_addr << 1); /* Sensor translated I2C address */
++ reg8_write(client, 0x5d, AR0132_I2C_ADDR << 1); /* Sensor native I2C address */
++
++ reg8_write(client, 0x6e, 0xa9); /* GPIO0 - reset, GPIO1 - fsin */
++ }
++ if (priv->ti954_addr) {
++ client->addr = priv->ti954_addr; /* Deserializer I2C address */
++
++ reg8_write(client, 0x4c, (priv->port << 4) | (1 << priv->port)); /* Select RX port number */
++ usleep_range(2000, 2500); /* wait 2ms */
++ reg8_write(client, 0x65, tmp_addr << 1); /* Sensor translated I2C address */
++ reg8_write(client, 0x5d, AR0132_I2C_ADDR << 1); /* Sensor native I2C address */
++
++ reg8_write(client, 0x6e, 0xa9); /* GPIO0 - reset, GPIO1 - fsin */
++ }
++ client->addr = tmp_addr;
++
++ mdelay(10);
++
++ return 0;
++}
++
++static int ar0132_probe(struct i2c_client *client,
++ const struct i2c_device_id *did)
++{
++ struct ar0132_priv *priv;
++ int ret;
++
++ priv = devm_kzalloc(&client->dev, sizeof(*priv), GFP_KERNEL);
++ if (!priv)
++ return -ENOMEM;
++
++ v4l2_i2c_subdev_init(&priv->sd, client, &ar0132_subdev_ops);
++ priv->sd.flags = V4L2_SUBDEV_FL_HAS_DEVNODE;
++
++ priv->exposure = 0x100;
++ priv->gain = 0x100;
++ priv->autogain = 1;
++ v4l2_ctrl_handler_init(&priv->hdl, 4);
++ v4l2_ctrl_new_std(&priv->hdl, &ar0132_ctrl_ops,
++ V4L2_CID_BRIGHTNESS, 0, 16, 1, 7);
++ v4l2_ctrl_new_std(&priv->hdl, &ar0132_ctrl_ops,
++ V4L2_CID_CONTRAST, 0, 16, 1, 7);
++ v4l2_ctrl_new_std(&priv->hdl, &ar0132_ctrl_ops,
++ V4L2_CID_SATURATION, 0, 7, 1, 2);
++ v4l2_ctrl_new_std(&priv->hdl, &ar0132_ctrl_ops,
++ V4L2_CID_HUE, 0, 23, 1, 12);
++ v4l2_ctrl_new_std(&priv->hdl, &ar0132_ctrl_ops,
++ V4L2_CID_GAMMA, -128, 128, 1, 0);
++ v4l2_ctrl_new_std(&priv->hdl, &ar0132_ctrl_ops,
++ V4L2_CID_SHARPNESS, 0, 10, 1, 3);
++ v4l2_ctrl_new_std(&priv->hdl, &ar0132_ctrl_ops,
++ V4L2_CID_AUTOGAIN, 0, 1, 1, priv->autogain);
++ v4l2_ctrl_new_std(&priv->hdl, &ar0132_ctrl_ops,
++ V4L2_CID_GAIN, 0, 0xffff, 1, priv->gain);
++ v4l2_ctrl_new_std(&priv->hdl, &ar0132_ctrl_ops,
++ V4L2_CID_EXPOSURE, 0, 0xffff, 1, priv->exposure);
++ v4l2_ctrl_new_std(&priv->hdl, &ar0132_ctrl_ops,
++ V4L2_CID_HFLIP, 0, 1, 1, 1);
++ v4l2_ctrl_new_std(&priv->hdl, &ar0132_ctrl_ops,
++ V4L2_CID_VFLIP, 0, 1, 1, 0);
++ priv->sd.ctrl_handler = &priv->hdl;
++
++ ret = priv->hdl.error;
++ if (ret)
++ goto cleanup;
++
++ v4l2_ctrl_handler_setup(&priv->hdl);
++
++ priv->pad.flags = MEDIA_PAD_FL_SOURCE;
++ priv->sd.entity.flags |= MEDIA_ENT_F_CAM_SENSOR;
++ ret = media_entity_pads_init(&priv->sd.entity, 1, &priv->pad);
++ if (ret < 0)
++ goto cleanup;
++
++ ret = ar0132_parse_dt(client->dev.of_node, priv);
++ if (ret)
++ goto cleanup;
++
++ ret = ar0132_initialize(client);
++ if (ret < 0)
++ goto cleanup;
++
++ priv->rect.left = 0;
++ priv->rect.top = 0;
++ priv->rect.width = AR0132_MAX_WIDTH;
++ priv->rect.height = AR0132_MAX_HEIGHT;
++
++ ret = v4l2_async_register_subdev(&priv->sd);
++ if (ret)
++ goto cleanup;
++
++ if (device_create_file(&client->dev, &dev_attr_otp_id_ar0132) != 0) {
++ dev_err(&client->dev, "sysfs otp_id entry creation failed\n");
++ goto cleanup;
++ }
++
++ priv->init_complete = 1;
++
++ return 0;
++
++cleanup:
++ media_entity_cleanup(&priv->sd.entity);
++ v4l2_ctrl_handler_free(&priv->hdl);
++ v4l2_device_unregister_subdev(&priv->sd);
++#ifdef CONFIG_SOC_CAMERA_AR0132
++ v4l_err(client, "failed to probe @ 0x%02x (%s)\n",
++ client->addr, client->adapter->name);
++#endif
++ return ret;
++}
++
++static int ar0132_remove(struct i2c_client *client)
++{
++ struct ar0132_priv *priv = i2c_get_clientdata(client);
++
++ device_remove_file(&client->dev, &dev_attr_otp_id_ar0132);
++ v4l2_async_unregister_subdev(&priv->sd);
++ media_entity_cleanup(&priv->sd.entity);
++ v4l2_ctrl_handler_free(&priv->hdl);
++ v4l2_device_unregister_subdev(&priv->sd);
++
++ return 0;
++}
++
++#ifdef CONFIG_SOC_CAMERA_AR0132
++static const struct i2c_device_id ar0132_id[] = {
++ { "ar0132", 0 },
++ { }
++};
++MODULE_DEVICE_TABLE(i2c, ar0132_id);
++
++static const struct of_device_id ar0132_of_ids[] = {
++ { .compatible = "aptina,ar0132", },
++ { }
++};
++MODULE_DEVICE_TABLE(of, ar0132_of_ids);
++
++static struct i2c_driver ar0132_i2c_driver = {
++ .driver = {
++ .name = "ar0132",
++ .of_match_table = ar0132_of_ids,
++ },
++ .probe = ar0132_probe,
++ .remove = ar0132_remove,
++ .id_table = ar0132_id,
++};
++
++module_i2c_driver(ar0132_i2c_driver);
++
++MODULE_DESCRIPTION("SoC Camera driver for AR0132");
++MODULE_AUTHOR("Vladimir Barinov");
++MODULE_LICENSE("GPL");
++#endif
+diff --git a/drivers/media/i2c/soc_camera/ar0132.h b/drivers/media/i2c/soc_camera/ar0132.h
+new file mode 100644
+index 0000000..055841d
+--- /dev/null
++++ b/drivers/media/i2c/soc_camera/ar0132.h
+@@ -0,0 +1,213 @@
++/*
++ * OmniVision ar0132 sensor camera wizard 1110x620@30/BGGR/BT601/12bit
++ *
++ * Copyright (C) 2017 Cogent Embedded, Inc.
++ *
++ * This program is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License as published by the
++ * Free Software Foundation; either version 2 of the License, or (at your
++ * option) any later version.
++ */
++
++//#define AR0132_DISPLAY_PATTERN_FIXED
++//#define AR0132_DISPLAY_PATTERN_COLOR_BAR
++
++#define AR0132_EMBEDDED_LINE
++
++#define AR0132_MAX_WIDTH 1665 // (1110*3/2)
++#define AR0132_MAX_HEIGHT 624
++
++#define AR0132_DELAY 0xffff
++
++#define AR0132_MAX_ROI_DIM_X 1288
++#define AR0132_MAX_ROI_DIM_Y 968
++#define AR0132_InfoLines 4
++
++#define AR0132_ROI_DIM_X 1110 // 1104
++#define AR0132_ROI_DIM_Y 620 // AR0132_MAX_HEIGHT
++
++#define AR0132_ROI_Y_START 0x00AE
++#define AR0132_ROI_X_START 0x005C
++#define AR0132_ROI_Y_END AR0132_ROI_Y_START+AR0132_ROI_DIM_Y-1
++#define AR0132_ROI_X_END AR0132_ROI_X_START+AR0132_ROI_DIM_X-1
++
++#define AR0132_FrameLength_Lines 0x029E
++#define AR0132_LineLength_Ticks 0x06B6
++
++#define AR0132_PLL_VT_Pix_Clk_Div 0x0008
++#define AR0132_PLL_VT_Sys_Clk_Div 0x0001
++#define AR0132_PLL_Pre_Clk_Div 0x0004
++#define AR0132_PLL_Multiplier 0x003C
++
++#define AR0132_DigitalTest 0x2002
++
++struct ar0132_reg {
++ u16 reg;
++ u16 val;
++};
++
++static const struct ar0132_reg ar0132_regs_wizard[] = {
++{0x301A, 0x0001}, // reset
++{AR0132_DELAY, 100},
++{0x301A, 0x10D8}, // Stream off and setup parallel
++{0x3070, 0x0001},
++{0x3070, 0x0000}, // 1: Solid color test pattern,
++ // 2: Full color bar test pattern,
++ // 3: Fade to grey color bar test pattern,
++ //256: Walking 1 test pattern (12 bit)
++#ifdef AR0132_DISPLAY_PATTERN_FIXED
++{0x3070, 0x0001},
++{0x3072, 0x0123}, // R
++{0x3074, 0x0456}, // G(GR row)
++{0x3076, 0x0abc}, // B
++{0x3078, 0x0def}, // G(GB row)
++#endif
++#ifdef AR0132_DISPLAY_PATTERN_COLOR_BAR
++{0x3070, 0x0002},
++#endif
++{AR0132_DELAY, 250},
++// patch begin
++{0x3088, 0x8000},
++{0x3086, 0x0025}, {0x3086, 0x5050}, {0x3086, 0x2D26}, {0x3086, 0x0828}, {0x3086, 0x0D17}, {0x3086, 0x0926}, {0x3086, 0x0028}, {0x3086, 0x0526},
++{0x3086, 0xA728}, {0x3086, 0x0725}, {0x3086, 0x8080}, {0x3086, 0x2925}, {0x3086, 0x0040}, {0x3086, 0x2702}, {0x3086, 0x1616}, {0x3086, 0x2706},
++{0x3086, 0x1736}, {0x3086, 0x26A6}, {0x3086, 0x1703}, {0x3086, 0x26A4}, {0x3086, 0x171F}, {0x3086, 0x2805}, {0x3086, 0x2620}, {0x3086, 0x2804},
++{0x3086, 0x2520}, {0x3086, 0x2027}, {0x3086, 0x0017}, {0x3086, 0x1D25}, {0x3086, 0x0020}, {0x3086, 0x1F17}, {0x3086, 0x1028}, {0x3086, 0x0519},
++{0x3086, 0x1703}, {0x3086, 0x2706}, {0x3086, 0x1703}, {0x3086, 0x1741}, {0x3086, 0x2660}, {0x3086, 0x17AE}, {0x3086, 0x2500}, {0x3086, 0x9027},
++{0x3086, 0x0026}, {0x3086, 0x1828}, {0x3086, 0x002E}, {0x3086, 0x2A28}, {0x3086, 0x081C}, {0x3086, 0x1470}, {0x3086, 0x7003}, {0x3086, 0x1470},
++{0x3086, 0x7004}, {0x3086, 0x1470}, {0x3086, 0x7005}, {0x3086, 0x1470}, {0x3086, 0x7009}, {0x3086, 0x170C}, {0x3086, 0x0014}, {0x3086, 0x0020},
++{0x3086, 0x2300}, {0x3086, 0x1400}, {0x3086, 0x5003}, {0x3086, 0x1400}, {0x3086, 0x2003}, {0x3086, 0x1400}, {0x3086, 0x5022}, {0x3086, 0x0414},
++{0x3086, 0x0020}, {0x3086, 0x0414}, {0x3086, 0x0050}, {0x3086, 0x0514}, {0x3086, 0x0020}, {0x3086, 0x2405}, {0x3086, 0x1400}, {0x3086, 0x5001},
++{0x3086, 0x2550}, {0x3086, 0x502D}, {0x3086, 0x2608}, {0x3086, 0x280D}, {0x3086, 0x1709}, {0x3086, 0x2600}, {0x3086, 0x2805}, {0x3086, 0x26A7},
++{0x3086, 0x2807}, {0x3086, 0x2580}, {0x3086, 0x8029}, {0x3086, 0x2500}, {0x3086, 0x4027}, {0x3086, 0x0216}, {0x3086, 0x1627}, {0x3086, 0x0617},
++{0x3086, 0x3626}, {0x3086, 0xA617}, {0x3086, 0x0326}, {0x3086, 0xA417}, {0x3086, 0x1F28}, {0x3086, 0x0526}, {0x3086, 0x2028}, {0x3086, 0x0425},
++{0x3086, 0x2020}, {0x3086, 0x2700}, {0x3086, 0x171D}, {0x3086, 0x2500}, {0x3086, 0x2020}, {0x3086, 0x1710}, {0x3086, 0x2805}, {0x3086, 0x1A17},
++{0x3086, 0x0327}, {0x3086, 0x0617}, {0x3086, 0x0317}, {0x3086, 0x4126}, {0x3086, 0x6017}, {0x3086, 0xAE25}, {0x3086, 0x0090}, {0x3086, 0x2700},
++{0x3086, 0x2618}, {0x3086, 0x2800}, {0x3086, 0x2E2A}, {0x3086, 0x2808}, {0x3086, 0x1D05}, {0x3086, 0x1470}, {0x3086, 0x7009}, {0x3086, 0x1720},
++{0x3086, 0x1400}, {0x3086, 0x2024}, {0x3086, 0x1400}, {0x3086, 0x5002}, {0x3086, 0x2550}, {0x3086, 0x502D}, {0x3086, 0x2608}, {0x3086, 0x280D},
++{0x3086, 0x1709}, {0x3086, 0x2600}, {0x3086, 0x2805}, {0x3086, 0x26A7}, {0x3086, 0x2807}, {0x3086, 0x2580}, {0x3086, 0x8029}, {0x3086, 0x2500},
++{0x3086, 0x4027}, {0x3086, 0x0216}, {0x3086, 0x1627}, {0x3086, 0x0617}, {0x3086, 0x3626}, {0x3086, 0xA617}, {0x3086, 0x0326}, {0x3086, 0xA417},
++{0x3086, 0x1F28}, {0x3086, 0x0526}, {0x3086, 0x2028}, {0x3086, 0x0425}, {0x3086, 0x2020}, {0x3086, 0x2700}, {0x3086, 0x171D}, {0x3086, 0x2500},
++{0x3086, 0x2021}, {0x3086, 0x1710}, {0x3086, 0x2805}, {0x3086, 0x1B17}, {0x3086, 0x0327}, {0x3086, 0x0617}, {0x3086, 0x0317}, {0x3086, 0x4126},
++{0x3086, 0x6017}, {0x3086, 0xAE25}, {0x3086, 0x0090}, {0x3086, 0x2700}, {0x3086, 0x2618}, {0x3086, 0x2800}, {0x3086, 0x2E2A}, {0x3086, 0x2808},
++{0x3086, 0x1E17}, {0x3086, 0x0A05}, {0x3086, 0x1470}, {0x3086, 0x7009}, {0x3086, 0x1616}, {0x3086, 0x1616}, {0x3086, 0x1616}, {0x3086, 0x1616},
++{0x3086, 0x1616}, {0x3086, 0x1616}, {0x3086, 0x1616}, {0x3086, 0x1616}, {0x3086, 0x1616}, {0x3086, 0x1616}, {0x3086, 0x1616}, {0x3086, 0x1616},
++{0x3086, 0x1616}, {0x3086, 0x1616}, {0x3086, 0x1616}, {0x3086, 0x1616}, {0x3086, 0x1400}, {0x3086, 0x2024}, {0x3086, 0x1400}, {0x3086, 0x502B},
++{0x3086, 0x302C}, {0x3086, 0x2C2C}, {0x3086, 0x2C00}, {0x3086, 0x0225}, {0x3086, 0x5050}, {0x3086, 0x2D26}, {0x3086, 0x0828}, {0x3086, 0x0D17},
++{0x3086, 0x0926}, {0x3086, 0x0028}, {0x3086, 0x0526}, {0x3086, 0xA728}, {0x3086, 0x0725}, {0x3086, 0x8080}, {0x3086, 0x2917}, {0x3086, 0x0525},
++{0x3086, 0x0040}, {0x3086, 0x2702}, {0x3086, 0x1616}, {0x3086, 0x2706}, {0x3086, 0x1736}, {0x3086, 0x26A6}, {0x3086, 0x1703}, {0x3086, 0x26A4},
++{0x3086, 0x171F}, {0x3086, 0x2805}, {0x3086, 0x2620}, {0x3086, 0x2804}, {0x3086, 0x2520}, {0x3086, 0x2027}, {0x3086, 0x0017}, {0x3086, 0x1E25},
++{0x3086, 0x0020}, {0x3086, 0x2117}, {0x3086, 0x1028}, {0x3086, 0x051B}, {0x3086, 0x1703}, {0x3086, 0x2706}, {0x3086, 0x1703}, {0x3086, 0x1747},
++{0x3086, 0x2660}, {0x3086, 0x17AE}, {0x3086, 0x2500}, {0x3086, 0x9027}, {0x3086, 0x0026}, {0x3086, 0x1828}, {0x3086, 0x002E}, {0x3086, 0x2A28},
++{0x3086, 0x081E}, {0x3086, 0x0831}, {0x3086, 0x1440}, {0x3086, 0x4014}, {0x3086, 0x2020}, {0x3086, 0x1410}, {0x3086, 0x1034}, {0x3086, 0x1400},
++{0x3086, 0x1014}, {0x3086, 0x0020}, {0x3086, 0x1400}, {0x3086, 0x4013}, {0x3086, 0x1802}, {0x3086, 0x1470}, {0x3086, 0x7004}, {0x3086, 0x1470},
++{0x3086, 0x7003}, {0x3086, 0x1470}, {0x3086, 0x7017}, {0x3086, 0x2002}, {0x3086, 0x1400}, {0x3086, 0x2002}, {0x3086, 0x1400}, {0x3086, 0x5004},
++{0x3086, 0x1400}, {0x3086, 0x2004}, {0x3086, 0x1400}, {0x3086, 0x5022}, {0x3086, 0x0314}, {0x3086, 0x0020}, {0x3086, 0x0314}, {0x3086, 0x0050},
++{0x3086, 0x2C2C}, {0x3086, 0x2C2C},
++{0x309E, 0x0186},
++{0x309E, 0x0186},
++// patch end
++{AR0132_DELAY, 250},
++{0x301A, 0x10D8}, // WR= RESET_REGISTER, 0x10D8 - stop streaming
++{0x3082, 0x0028}, // Set HiDy OPERATION_MODE_CTRL(A) Requested integration time ratio (T2 to T3): 8 & (T1 t0 T2): 16
++{0x3084, 0x0028}, // Set HiDy OPERATION_MODE_CTRL(B) Requested integration time ratio (T2 to T3): 16 & (T1 t0 T2): 16
++{0x301E, 0x00C8}, // set datapedestal to 200 to avoid clipping near saturation
++{0x3EDA, 0x0F03}, // Set vln_dac to 0x3 as recommended by Sergey
++{0x3EDE, 0xC007},
++{0x3ED8, 0x01EF}, // Vrst_low = +1
++{0x3EE2, 0xA46B},
++{0x3EE0, 0x067D}, // enable anti eclipse and adjust setting for high conversion gain
++{0x3EDC, 0x0070}, // adjust anti eclipse setting for low conversion gain
++{0x3044, 0x0404}, // disable digital row noise correction and cancels TX during column correction
++{0x3EE6, 0x4303}, // Helps with column noise at low light
++{0x3EE4, 0xD208}, // enable analog row noise correction
++{0x3ED6, 0x00BD},
++{0x3EE6, 0x8303}, // improves low light FPN
++{0x30E4, 0x6372}, // ADC settings to improve noise performance
++{0x30E2, 0x7253},
++{0x30E0, 0x5470},
++{0x30E6, 0xC4CC},
++{0x30E8, 0x8050},
++{AR0132_DELAY, 250},
++{0x3058, 0x003F}, // WR= BLUE_GAIN, 0x003F
++{0x3014, 0}, // Fine_IT_Time(A)
++{0x3002, AR0132_ROI_Y_START}, // WR= Y_ADDR_START_(A)
++{0x3004, AR0132_ROI_X_START}, // WR= X_ADDR_START_(A)
++{0x3006, AR0132_ROI_Y_END}, // WR= Y_ADDR_END_(A)
++{0x3008, AR0132_ROI_X_END}, // WR= X_ADDR_END_(A)
++{0x300A, AR0132_FrameLength_Lines}, // WR= FRAME_LENGTH_LINES_(A)
++{0x3018, 0}, // Fine_IT_Time(B)
++{0x308C, AR0132_ROI_Y_START}, // Y_ADDR_START_(B)
++{0x308A, AR0132_ROI_X_START}, // X_ADDR_START_(B)
++{0x3090, AR0132_ROI_Y_END}, // Y_ADDR_END_(B)
++{0x308E, AR0132_ROI_X_END}, // X_ADDR_END_(B)
++{0x30AA, AR0132_FrameLength_Lines}, // FRAME_LENGTH_LINES_(B)
++{0x300C, AR0132_LineLength_Ticks}, // Line Length
++{0x301A, 0x10D8}, // Disable Streaming and setup parallel
++{0x31D0, 0x0001}, // Set to 12 bits
++{0x3028, 0x0010}, // ROW_SPEED = 16
++{0x302A, AR0132_PLL_VT_Pix_Clk_Div},
++{0x302C, AR0132_PLL_VT_Sys_Clk_Div},
++{0x302E, AR0132_PLL_Pre_Clk_Div},
++{0x3030, AR0132_PLL_Multiplier},
++{0x3032, 0x0000}, // SCALING_MODE = 0
++{0x3040, 0xC000}, // READ_MODE = read_mode_vert_flip | read_mode_horiz_mirror
++{0x3044, 0x0404}, // Dark Control = 1028
++{0x30A6, 0x0001}, // Y Odd Inc. (A) = 1
++{0x30A8, 0x0001}, // Y Odd Inc. (B) = 1
++{0x30B0, AR0132_DigitalTest},
++{AR0132_DELAY, 100},
++#ifdef AR0132_EMBEDDED_LINE
++{0x3064, 0x1982}, // Embedded Data on
++#else
++{0x3064, 0x1802}, // Embedded Data off
++#endif
++{0x3100, 0x0084}, // WR= AECTRLREG,
++{0x3190, 0x6BA0},
++{0x3194, 0x0E74},
++{0x3196, 0x0ED8},
++{0x3198, 0x0FA0},
++{0x319E, 0x5040}, // resetvalue
++{0x31A2, 0x0FA0},
++//FrontCamera Specific Section
++//Common
++#ifdef AR0132_EMBEDDED_LINE
++{0x3064, 0x1982},
++#else
++{0x3064, 0x1802},
++#endif
++{0x30B4, 0x0011},
++{0x30ba, 0x0008},
++{0x3180, 0xE000},
++{0x3182, 0x012C},
++{0x3190, 0x6BA0},
++{0x3194, 0x0E74},
++{0x3196, 0x0ED8},
++{0x3198, 0x0FA0},
++{0x319E, 0x5040},
++{0x31A2, 0x0FA0},
++//Context A:0
++{0x3012, 0x0021},
++{0x3014, 0x0000},
++{0x30A6, 0x0001},
++{0x3056, 0x0008},
++{0x3058, 0x0008},
++{0x305A, 0x0008},
++{0x305C, 0x0008},
++{0x305E, 0x0008},
++{0x3082, 0x0014},
++//Context B:0
++{0x3016, 0x007F},
++{0x3018, 0x0000},
++{0x30A8, 0x0001},
++{0x30BC, 0x0020},
++{0x30BE, 0x0020},
++{0x30C0, 0x0020},
++{0x30C2, 0x0020},
++{0x30C4, 0x0020},
++{0x3084, 0x0028},
++//not covered
++{0x301E, 0x00C8},
++{0x3044, 0x0404},
++{0x31D0, 0x0001},
++{0x30B0, 0x2002},
++};
+diff --git a/drivers/media/i2c/soc_camera/max9286_max9271.c b/drivers/media/i2c/soc_camera/max9286_max9271.c
+new file mode 100644
+index 0000000..9797d24
+--- /dev/null
++++ b/drivers/media/i2c/soc_camera/max9286_max9271.c
+@@ -0,0 +1,567 @@
++/*
++ * MAXIM max9286-max9271 GMSL driver
++ *
++ * Copyright (C) 2015-2017 Cogent Embedded, Inc.
++ *
++ * This program is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License as published by the
++ * Free Software Foundation; either version 2 of the License, or (at your
++ * option) any later version.
++ */
++
++#include <linux/delay.h>
++#include <linux/i2c.h>
++#include <linux/module.h>
++#include <linux/of_gpio.h>
++#include <linux/videodev2.h>
++#include <linux/notifier.h>
++
++#include <media/v4l2-common.h>
++#include <media/v4l2-device.h>
++#include <media/v4l2-of.h>
++#include <media/v4l2-subdev.h>
++
++#include "max9286_max9271.h"
++
++#define MAXIM_I2C_I2C_SPEED_837KHZ (0x7 << 2) /* 837kbps */
++#define MAXIM_I2C_I2C_SPEED_533KHZ (0x6 << 2) /* 533kbps */
++#define MAXIM_I2C_I2C_SPEED_339KHZ (0x5 << 2) /* 339 kbps */
++#define MAXIM_I2C_I2C_SPEED_173KHZ (0x4 << 2) /* 174kbps */
++#define MAXIM_I2C_I2C_SPEED_105KHZ (0x3 << 2) /* 105 kbps */
++#define MAXIM_I2C_I2C_SPEED_085KHZ (0x2 << 2) /* 84.7 kbps */
++#define MAXIM_I2C_I2C_SPEED_028KHZ (0x1 << 2) /* 28.3 kbps */
++#define MAXIM_I2C_I2C_SPEED MAXIM_I2C_I2C_SPEED_339KHZ
++
++struct max9286_max9271_priv {
++ struct v4l2_subdev sd[4];
++ struct device_node *sd_of_node[4];
++ int des_addr;
++ int des_quirk_addr; /* second MAX9286 on the same I2C bus */
++ int links;
++ int links_mask;
++ int lanes;
++ int csi_rate;
++ const char *fsync_mode;
++ int fsync_period;
++ char pclk_rising_edge;
++ int gpio_resetb;
++ int active_low_resetb;
++ int timeout;
++ atomic_t use_count;
++ u32 csi2_outord;
++ struct i2c_client *client;
++ int max9271_addr_map[4];
++};
++
++static int force_conf_link;
++
++static __init int max9286_max9271_force_conf_link(char *str)
++{
++ /* force configuration link */
++ /* used only if robust firmware flashing required (f.e. recovery) */
++ force_conf_link = 1;
++ return 0;
++}
++early_param("force_conf_link", max9286_max9271_force_conf_link);
++
++static void max9286_max9271_preinit(struct i2c_client *client, int addr)
++{
++ client->addr = addr; /* MAX9286-CAMx I2C */
++ reg8_write(client, 0x0a, 0x00); /* disable reverse control for all cams */
++ reg8_write(client, 0x00, 0x00); /* disable all GMSL links [0:3] */
++ usleep_range(2000, 2500); /* wait 2ms after any change of reverse channel settings */
++}
++
++static void max9286_max9271_sensor_reset(struct i2c_client *client, int addr)
++{
++ struct max9286_max9271_priv *priv = i2c_get_clientdata(client);
++
++ if (priv->gpio_resetb < 1 || priv->gpio_resetb > 5)
++ return;
++
++ /* get out from sensor reset */
++ client->addr = addr; /* MAX9271-CAMx I2C */
++ reg8_write(client, 0x0f, (0xfe & ~BIT(priv->gpio_resetb)) |
++ (priv->active_low_resetb ? 0 : BIT(priv->gpio_resetb))); /* set GPIOn value to reset */
++ reg8_write(client, 0x0e, 0x42 | BIT(priv->gpio_resetb)); /* set GPIOn direction output */
++ usleep_range(2000, 2500); /* wait 2ms */
++ reg8_write(client, 0x0f, (0xfe & ~BIT(priv->gpio_resetb)) |
++ (priv->active_low_resetb ? BIT(priv->gpio_resetb) : 0)); /* set GPIOn value to un-reset */
++ usleep_range(2000, 2500); /* wait 2ms */
++}
++
++static void max9286_max9271_postinit(struct i2c_client *client, int addr)
++{
++ struct max9286_max9271_priv *priv = i2c_get_clientdata(client);
++
++ client->addr = addr; /* MAX9286 I2C */
++ reg8_write(client, 0x0a, 0x00); /* disable reverse control for all cams */
++ reg8_write(client, 0x00, 0xe0 | priv->links_mask); /* enable GMSL link for CAMs */
++ reg8_write(client, 0x0b, priv->csi2_outord); /* CSI2 output order */
++ reg8_write(client, 0x15, 0x9b); /* enable CSI output, VC is set accordingly to Link number, BIT7 magic must be set */
++ reg8_write(client, 0x1b, priv->links_mask); /* enable equalizer for CAMs */
++ usleep_range(5000, 5500); /* wait 2ms after any change of reverse channel settings */
++}
++
++static int max9286_max9271_reverse_channel_setup(struct i2c_client *client, int idx)
++{
++ struct max9286_max9271_priv *priv = i2c_get_clientdata(client);
++ u8 val = 0;
++ int timeout = priv->timeout;
++ int ret = 0;
++
++ /* Reverse channel enable */
++ client->addr = priv->des_addr; /* MAX9286-CAMx I2C */
++ reg8_write(client, 0x3f, 0x4f); /* enable custom reverse channel & first pulse length */
++ reg8_write(client, 0x34, 0xa2 | MAXIM_I2C_I2C_SPEED); /* enable artificial ACKs, I2C speed set */
++ usleep_range(2000, 2500); /* wait 2ms after any change of reverse channel settings */
++ reg8_write(client, 0x00, 0xe0 | BIT(idx)); /* enable GMSL link for CAMx */
++ reg8_write(client, 0x0a, 0x11 << idx); /* enable reverse control for CAMx */
++ usleep_range(2000, 2500); /* wait 2ms after any change of reverse channel settings */
++
++ for (;;) {
++ client->addr = priv->des_addr; /* MAX9286-CAMx I2C */
++ reg8_write(client, 0x3b, 0x1e); /* first pulse length rise time changed from 300ns to 200ns, amplitude 100mV */
++ usleep_range(2000, 2500); /* wait 2ms after any change of reverse channel settings */
++
++ client->addr = 0x40; /* MAX9271-CAMx I2C */
++ reg8_write(client, 0x08, 0x1); /* reverse channel receiver high threshold enable */
++ usleep_range(2000, 2500); /* wait 2ms after any change of reverse channel settings */
++
++ client->addr = priv->des_addr; /* MAX9286-CAMx I2C */
++ reg8_write(client, 0x3b, 0x19); /* reverse channel increase amplitude 170mV to compensate high threshold enabled */
++ usleep_range(2000, 2500); /* wait 2ms after any change of reverse channel settings */
++
++ client->addr = 0x40; /* MAX9271-CAMx I2C */
++ reg8_write(client, 0x04, 0x43); /* wake-up, enable reverse_control/conf_link */
++ usleep_range(2000, 2500); /* wait 2ms after any change of reverse channel settings */
++
++ client->addr = 0x40; /* MAX9271-CAMx I2C */
++ reg8_read(client, 0x1e, &val); /* read max9271 ID */
++ if (val == MAX9271_ID || --timeout == 0)
++ break;
++
++ /* Check if already initialized (after reboot/reset ?) */
++ client->addr = priv->max9271_addr_map[idx]; /* MAX9271-CAMx I2C */
++ reg8_read(client, 0x1e, &val); /* read max9271 ID */
++ if (val == MAX9271_ID) {
++ reg8_write(client, 0x04, 0x43); /* enable reverse_control/conf_link */
++ usleep_range(2000, 2500); /* wait 2ms after any change of reverse channel settings */
++ ret = -EADDRINUSE;
++ break;
++ }
++ }
++
++ max9286_max9271_sensor_reset(client, client->addr); /* sensor reset */
++
++ if (!timeout) {
++ ret = -ETIMEDOUT;
++ goto out;
++ }
++
++ priv->links_mask |= BIT(idx);
++ priv->csi2_outord &= ~(0x3 << (idx * 2));
++ priv->csi2_outord |= ((hweight8(priv->links_mask) - 1) << (idx * 2));
++
++out:
++ dev_info(&client->dev, "link%d MAX9271 %sat 0x%x %s\n", idx,
++ ret == -EADDRINUSE ? "already " : "", priv->max9271_addr_map[idx],
++ ret == -ETIMEDOUT ? "not found: timeout GMSL link establish" : "");
++
++ return ret;
++}
++
++static void max9286_max9271_initial_setup(struct i2c_client *client)
++{
++ struct max9286_max9271_priv *priv = i2c_get_clientdata(client);
++
++ /* Initial setup */
++ client->addr = priv->des_addr; /* MAX9286-CAMx I2C */
++ reg8_write(client, 0x15, 0x13); /* disable CSI output, VC is set accordingly to Link number */
++ reg8_write(client, 0x69, 0x0f); /* mask CSI forwarding from all links */
++ switch (priv->lanes) {
++ case 1:
++ reg8_write(client, 0x12, 0x33); /* enable CSI-2 Lane D0, DBL mode, YUV422 8-bit*/
++ break;
++ case 2:
++ reg8_write(client, 0x12, 0x73); /* enable CSI-2 Lanes D0,D1, DBL mode, YUV422 8-bit*/
++ break;
++ case 3:
++ reg8_write(client, 0x12, 0xd3); /* enable CSI-2 Lanes D0-D2, DBL mode, YUV422 8-bit*/
++ break;
++ case 4:
++ reg8_write(client, 0x12, 0xf3); /* enable CSI-2 Lanes D0-D3, DBL mode, YUV422 8-bit*/
++ break;
++ default:
++ dev_err(&client->dev, "CSI2 lanes number is invalid (%d)\n", priv->lanes);
++ }
++
++ if (strcmp(priv->fsync_mode, "manual") == 0) {
++ reg8_write(client, 0x06, priv->fsync_period & 0xff);
++ reg8_write(client, 0x07, (priv->fsync_period >> 8) & 0xff);
++ reg8_write(client, 0x08, priv->fsync_period >> 16);
++ reg8_write(client, 0x01, 0x00); /* manual: FRAMESYNC set manually via [0x06:0x08] regs */
++ } else if (strcmp(priv->fsync_mode, "automatic") == 0) {
++ reg8_write(client, 0x01, 0x02); /* automatic: FRAMESYNC taken from the slowest Link */
++ } else if (strcmp(priv->fsync_mode, "semi-automatic") == 0) {
++ reg8_write(client, 0x01, 0x01); /* semi-automatic: FRAMESYNC taken from the slowest Link */
++ } else if (strcmp(priv->fsync_mode, "external") == 0) {
++ reg8_write(client, 0x01, 0xc0); /* ECU (aka MCU) based FrameSync using GPI-to-GPO */
++ }
++
++ reg8_write(client, 0x63, 0); /* disable overlap window */
++ reg8_write(client, 0x64, 0);
++ reg8_write(client, 0x0c, 0x89); /* enable HS/VS encoding, use D14/15 for HS/VS, invert VS */
++}
++
++static void max9286_max9271_gmsl_link_setup(struct i2c_client *client, int idx)
++{
++ struct max9286_max9271_priv *priv = i2c_get_clientdata(client);
++
++ /* GMSL setup */
++ client->addr = 0x40; /* MAX9271-CAMx I2C */
++ reg8_write(client, 0x0d, 0x22 | MAXIM_I2C_I2C_SPEED); /* disable artificial ACK, I2C speed set */
++ reg8_write(client, 0x07, 0x84 | (priv->pclk_rising_edge ? 0 : 0x10)); /* RAW/YUV, PCLK edge, HS/VS encoding enabled */
++ usleep_range(2000, 2500); /* wait 2ms */
++ reg8_write(client, 0x02, 0xff); /* spread spectrum +-4%, pclk range automatic, Gbps automatic */
++ usleep_range(2000, 2500); /* wait 2ms */
++
++ client->addr = priv->des_addr; /* MAX9286-CAMx I2C */
++ reg8_write(client, 0x34, 0x22 | MAXIM_I2C_I2C_SPEED); /* disable artificial ACK, I2C speed set */
++ usleep_range(2000, 2500); /* wait 2ms */
++
++ /* I2C translator setup */
++ client->addr = 0x40; /* MAX9271-CAMx I2C */
++// reg8_write(client, 0x09, maxim_map[2][idx] << 1); /* SENSOR I2C translated - must be set by sensor driver */
++// reg8_write(client, 0x0A, 0x30 << 1); /* SENSOR I2C native - must be set by sensor driver */
++ reg8_write(client, 0x0B, BROADCAST << 1); /* broadcast I2C */
++ reg8_write(client, 0x0C, priv->max9271_addr_map[idx] << 1); /* MAX9271-CAMx I2C new */
++ /* I2C addresse change */
++ reg8_write(client, 0x01, priv->des_addr << 1); /* MAX9286 I2C */
++ reg8_write(client, 0x00, priv->max9271_addr_map[idx] << 1); /* MAX9271-CAM0 I2C new */
++ usleep_range(2000, 2500); /* wait 2ms */
++ /* put MAX9271 in configuration link state */
++ client->addr = priv->max9271_addr_map[idx]; /* MAX9271-CAMx I2C new */
++ reg8_write(client, 0x04, 0x43); /* enable reverse_control/conf_link */
++ usleep_range(2000, 2500); /* wait 2ms */
++#ifdef MAXIM_DUMP
++ client->addr = priv->des_addr; /* MAX9286-CAMx I2C */
++ maxim_max927x_dump_regs(client);
++ client->addr = priv->max9271_addr_map[idx]; /* MAX9271-CAMx I2C new */
++ maxim_max927x_dump_regs(client);
++#endif
++}
++
++static int max9286_max9271_initialize(struct i2c_client *client)
++{
++ struct max9286_max9271_priv *priv = i2c_get_clientdata(client);
++ int idx, ret;
++
++ dev_info(&client->dev, "LINKs=%d, LANES=%d, FSYNC mode=%s, FSYNC period=%d, PCLK edge=%s\n",
++ priv->links, priv->lanes, priv->fsync_mode, priv->fsync_period,
++ priv->pclk_rising_edge ? "rising" : "falling");
++
++ if (priv->des_quirk_addr)
++ max9286_max9271_preinit(client, priv->des_quirk_addr);
++
++ max9286_max9271_preinit(client, priv->des_addr);
++ max9286_max9271_initial_setup(client);
++
++ for (idx = 0; idx < priv->links; idx++) {
++ ret = max9286_max9271_reverse_channel_setup(client, idx);
++ if (ret)
++ continue;
++ max9286_max9271_gmsl_link_setup(client, idx);
++ }
++
++ max9286_max9271_postinit(client, priv->des_addr);
++
++ client->addr = priv->des_addr;
++
++ return 0;
++}
++
++#ifdef CONFIG_VIDEO_ADV_DEBUG
++static int max9286_max9271_g_register(struct v4l2_subdev *sd,
++ struct v4l2_dbg_register *reg)
++{
++ struct max9286_max9271_priv *priv = v4l2_get_subdevdata(sd);
++ struct i2c_client *client = priv->client;
++ int ret;
++ u8 val = 0;
++
++ ret = reg8_read(client, (u8)reg->reg, &val);
++ if (ret < 0)
++ return ret;
++
++ reg->val = val;
++ reg->size = sizeof(u8);
++
++ return 0;
++}
++
++static int max9286_max9271_s_register(struct v4l2_subdev *sd,
++ const struct v4l2_dbg_register *reg)
++{
++ struct max9286_max9271_priv *priv = v4l2_get_subdevdata(sd);
++ struct i2c_client *client = priv->client;
++
++ return reg8_write(client, (u8)reg->reg, (u8)reg->val);
++}
++#endif
++
++static int max9286_max9271_s_power(struct v4l2_subdev *sd, int on)
++{
++ struct max9286_max9271_priv *priv = v4l2_get_subdevdata(sd);
++ struct i2c_client *client = priv->client;
++
++ if (on) {
++ if (atomic_inc_return(&priv->use_count) == 1)
++ reg8_write(client, 0x69, priv->links_mask ^ 0x0f); /* unmask CSI forwarding from detected links */
++ } else {
++ if (atomic_dec_return(&priv->use_count) == 0)
++ reg8_write(client, 0x69, 0x0f); /* mask CSI forwarding from all links */
++ }
++
++ return 0;
++}
++
++static int max9286_max9271_registered_async(struct v4l2_subdev *sd)
++{
++ struct max9286_max9271_priv *priv = v4l2_get_subdevdata(sd);
++ struct i2c_client *client = priv->client;
++ int idx, tmp_addr;
++
++ /* switch to GMSL serial_link for streaming video */
++ tmp_addr = client->addr;
++ idx = sd->grp_id;
++
++ client->addr = priv->des_addr; /* MAX9286 I2C */
++ reg8_write(client, 0x0a, 0x11 << idx); /* enable reverse/forward control for CAMx */
++
++ client->addr = priv->max9271_addr_map[idx]; /* MAX9271-CAMx */
++ reg8_write(client, 0x04, force_conf_link ? 0x43 : 0x83); /* enable reverse_control/serial_link */
++ usleep_range(2000, 2500); /* wait 2ms after changing reverse_control */
++
++ client->addr = priv->des_addr; /* MAX9286 I2C */
++ reg8_write(client, 0x0a, (priv->links_mask << 4) | priv->links_mask); /* enable reverse/forward control for all CAMs */
++
++ client->addr = tmp_addr;
++
++ return 0;
++}
++
++static struct v4l2_subdev_core_ops max9286_max9271_subdev_core_ops = {
++#ifdef CONFIG_VIDEO_ADV_DEBUG
++ .g_register = max9286_max9271_g_register,
++ .s_register = max9286_max9271_s_register,
++#endif
++ .s_power = max9286_max9271_s_power,
++ .registered_async = max9286_max9271_registered_async,
++};
++
++static struct v4l2_subdev_ops max9286_max9271_subdev_ops = {
++ .core = &max9286_max9271_subdev_core_ops,
++};
++
++static int max9286_max9271_parse_dt(struct i2c_client *client)
++{
++ struct max9286_max9271_priv *priv = i2c_get_clientdata(client);
++ struct device_node *np = client->dev.of_node;
++ struct device_node *endpoint = NULL;
++ struct property *prop;
++ int err, pwen, i;
++ int sensor_delay, gpio0 = 1, gpio1 = 1;
++ char fsync_mode_default[20] = "manual"; /* manual, automatic, semi-automatic, external */
++ u8 val = 0;
++
++ if (of_property_read_u32(np, "maxim,links", &priv->links))
++ priv->links = 4;
++
++ if (of_property_read_u32(np, "maxim,lanes", &priv->lanes))
++ priv->lanes = 4;
++
++ pwen = of_get_gpio(np, 0);
++ if (pwen > 0) {
++ err = gpio_request_one(pwen, GPIOF_OUT_INIT_HIGH, dev_name(&client->dev));
++ if (err)
++ dev_err(&client->dev, "cannot request PWEN gpio %d: %d\n", pwen, err);
++ }
++
++ mdelay(250);
++
++ reg8_read(client, 0x1e, &val); /* read max9286 ID */
++ if (val != MAX9286_ID) {
++ prop = of_find_property(np, "reg", NULL);
++ if (prop)
++ of_remove_property(np, prop);
++ return -ENODEV;
++ }
++
++ if (!of_property_read_u32(np, "maxim,gpio0", &gpio0) ||
++ !of_property_read_u32(np, "maxim,gpio1", &gpio1))
++ reg8_write(client, 0x0f, 0x08 | (gpio1 << 1) | gpio0);
++
++ if (of_property_read_u32(np, "maxim,resetb-gpio", &priv->gpio_resetb)) {
++ priv->gpio_resetb = -1;
++ } else {
++ if (of_property_read_bool(np, "maxim,resetb-active-high"))
++ priv->active_low_resetb = false;
++ else
++ priv->active_low_resetb = true;
++ }
++
++ if (!of_property_read_u32(np, "maxim,sensor_delay", &sensor_delay))
++ mdelay(sensor_delay);
++
++ if (of_property_read_string(np, "maxim,fsync-mode", &priv->fsync_mode))
++ priv->fsync_mode = fsync_mode_default;
++
++ if (of_property_read_u32(np, "maxim,fsync-period", &priv->fsync_period))
++ priv->fsync_period = 3200000; /* 96MHz/30fps */
++ priv->pclk_rising_edge = true;
++ if (of_property_read_bool(np, "maxim,pclk-falling-edge"))
++ priv->pclk_rising_edge = false;
++ if (of_property_read_u32(np, "maxim,timeout", &priv->timeout))
++ priv->timeout = 100;
++ if (of_property_read_u32(np, "maxim,i2c-quirk", &priv->des_quirk_addr))
++ priv->des_quirk_addr = 0;
++
++ for (i = 0; i < priv->links; i++) {
++ endpoint = of_graph_get_next_endpoint(np, endpoint);
++ if (!endpoint)
++ break;
++
++ of_node_put(endpoint);
++
++ if (of_property_read_u32(endpoint, "max9271-addr", &priv->max9271_addr_map[i])) {
++ dev_err(&client->dev, "max9271-addr not set\n");
++ return -EINVAL;
++ }
++
++ priv->sd_of_node[i] = endpoint;
++ }
++
++ return 0;
++}
++
++static void max9286_max9271_setup_remote_endpoint(struct i2c_client *client)
++{
++ struct max9286_max9271_priv *priv = i2c_get_clientdata(client);
++ struct device_node *np = client->dev.of_node;
++ struct device_node *endpoint = NULL, *rendpoint = NULL;
++ int i;
++ struct property *csi_rate_prop, *dvp_order_prop;
++
++ for (i = 0; ; i++) {
++ endpoint = of_graph_get_next_endpoint(np, endpoint);
++ if (!endpoint)
++ break;
++
++ of_node_put(endpoint);
++
++ rendpoint = of_parse_phandle(endpoint, "remote-endpoint", 0);
++ if (!rendpoint)
++ continue;
++
++ csi_rate_prop = of_find_property(endpoint, "csi-rate", NULL);
++ if (csi_rate_prop) {
++ /* CSI2_RATE = PCLK*sizeof(YUV8)*links/lanes */
++ priv->csi_rate = cpu_to_be32(100 * 8 * hweight8(priv->links_mask) / priv->lanes);
++ csi_rate_prop->value = &priv->csi_rate;
++ of_update_property(rendpoint, csi_rate_prop);
++ }
++
++ dvp_order_prop = of_find_property(endpoint, "dvp-order", NULL);
++ if (dvp_order_prop)
++ of_update_property(rendpoint, dvp_order_prop);
++ }
++}
++
++static int max9286_max9271_probe(struct i2c_client *client,
++ const struct i2c_device_id *did)
++{
++ struct max9286_max9271_priv *priv;
++ int err, i;
++
++ priv = devm_kzalloc(&client->dev, sizeof(*priv), GFP_KERNEL);
++ if (!priv)
++ return -ENOMEM;
++
++ i2c_set_clientdata(client, priv);
++ priv->des_addr = client->addr;
++ priv->client = client;
++ atomic_set(&priv->use_count, 0);
++ priv->csi2_outord = 0xff;
++
++ err = max9286_max9271_parse_dt(client);
++ if (err)
++ goto out;
++
++ err = max9286_max9271_initialize(client);
++ if (err < 0)
++ goto out;
++
++ max9286_max9271_setup_remote_endpoint(client);
++
++ for (i = 0; i < 4; i++) {
++ v4l2_subdev_init(&priv->sd[i], &max9286_max9271_subdev_ops);
++ priv->sd[i].owner = client->dev.driver->owner;
++ priv->sd[i].dev = &client->dev;
++ priv->sd[i].grp_id = i;
++ v4l2_set_subdevdata(&priv->sd[i], priv);
++ priv->sd[i].of_node = priv->sd_of_node[i];
++
++ snprintf(priv->sd[i].name, V4L2_SUBDEV_NAME_SIZE, "%s.%d %d-%04x",
++ client->dev.driver->name, i, i2c_adapter_id(client->adapter),
++ client->addr);
++
++ err = v4l2_async_register_subdev(&priv->sd[i]);
++ if (err < 0)
++ goto out;
++ }
++
++out:
++ return err;
++}
++
++static int max9286_max9271_remove(struct i2c_client *client)
++{
++ struct max9286_max9271_priv *priv = i2c_get_clientdata(client);
++ int i;
++
++ for (i = 0; i < 4; i++) {
++ v4l2_async_unregister_subdev(&priv->sd[i]);
++ v4l2_device_unregister_subdev(&priv->sd[i]);
++ }
++
++ return 0;
++}
++
++static const struct of_device_id max9286_max9271_dt_ids[] = {
++ { .compatible = "maxim,max9286-max9271" },
++ {},
++};
++MODULE_DEVICE_TABLE(of, max9286_max9271_dt_ids);
++
++static const struct i2c_device_id max9286_max9271_id[] = {
++ { "max9286_max9271", 0 },
++ { }
++};
++MODULE_DEVICE_TABLE(i2c, max9286_max9271_id);
++
++static struct i2c_driver max9286_max9271_i2c_driver = {
++ .driver = {
++ .name = "max9286_max9271",
++ .of_match_table = of_match_ptr(max9286_max9271_dt_ids),
++ },
++ .probe = max9286_max9271_probe,
++ .remove = max9286_max9271_remove,
++ .id_table = max9286_max9271_id,
++};
++
++module_i2c_driver(max9286_max9271_i2c_driver);
++
++MODULE_DESCRIPTION("GMSL driver for MAX9286-MAX9271");
++MODULE_AUTHOR("Vladimir Barinov");
++MODULE_LICENSE("GPL");
+diff --git a/drivers/media/i2c/soc_camera/max9286_max9271.h b/drivers/media/i2c/soc_camera/max9286_max9271.h
+new file mode 100644
+index 0000000..0016f28a
+--- /dev/null
++++ b/drivers/media/i2c/soc_camera/max9286_max9271.h
+@@ -0,0 +1,243 @@
++/*
++ * MAXIM max9286-max9271 GMSL driver include file
++ *
++ * Copyright (C) 2015-2017 Cogent Embedded, Inc.
++ *
++ * This program is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License as published by the
++ * Free Software Foundation; either version 2 of the License, or (at your
++ * option) any later version.
++ */
++
++#ifndef _MAX9286_MAX9271_H
++#define _MAX9286_MAX9271_H
++
++//#define DEBUG
++#ifdef DEBUG
++//#define WRITE_VERIFY
++#define MAXIM_DUMP
++#undef dev_dbg
++#define dev_dbg dev_info
++#endif
++
++#define REG8_NUM_RETRIES 1 /* number of read/write retries */
++#define REG16_NUM_RETRIES 10 /* number of read/write retries */
++#define MAX9271_ID 0x9
++#define MAX9286_ID 0x40
++#define BROADCAST 0x6f
++
++static inline int reg8_read(struct i2c_client *client, u8 reg, u8 *val)
++{
++ int ret, retries;
++
++ for (retries = REG8_NUM_RETRIES; retries; retries--) {
++ ret = i2c_smbus_read_byte_data(client, reg);
++ if (!(ret < 0))
++ break;
++ }
++
++ if (ret < 0) {
++ dev_dbg(&client->dev,
++ "read fail: chip 0x%x register 0x%x: %d\n",
++ client->addr, reg, ret);
++ } else {
++ *val = ret;
++ }
++
++ return ret < 0 ? ret : 0;
++}
++
++static inline int reg8_write(struct i2c_client *client, u8 reg, u8 val)
++{
++ int ret, retries;
++
++ for (retries = REG8_NUM_RETRIES; retries; retries--) {
++ ret = i2c_smbus_write_byte_data(client, reg, val);
++ if (!(ret < 0))
++ break;
++ }
++
++ if (ret < 0) {
++ dev_dbg(&client->dev,
++ "write fail: chip 0x%x register 0x%x: %d\n",
++ client->addr, reg, ret);
++ } else {
++#ifdef WRITE_VERIFY
++ u8 val2;
++ reg8_read(client, reg, &val2);
++ if (val != val2)
++ dev_err(&client->dev,
++ "write verify mismatch: chip 0x%x reg=0x%x "
++ "0x%x->0x%x\n", client->addr, reg, val, val2);
++#endif
++ }
++
++ return ret < 0 ? ret : 0;
++}
++
++static inline int reg16_read(struct i2c_client *client, u16 reg, u8 *val)
++{
++ int ret, retries;
++ u8 buf[2] = {reg >> 8, reg & 0xff};
++
++ for (retries = REG16_NUM_RETRIES; retries; retries--) {
++ ret = i2c_master_send(client, buf, 2);
++ if (ret == 2) {
++ ret = i2c_master_recv(client, buf, 1);
++ if (ret == 1)
++ break;
++ }
++ }
++
++ if (ret < 0) {
++ dev_dbg(&client->dev,
++ "read fail: chip 0x%x register 0x%x: %d\n",
++ client->addr, reg, ret);
++ } else {
++ *val = buf[0];
++ }
++
++ return ret < 0 ? ret : 0;
++}
++
++static inline int reg16_write(struct i2c_client *client, u16 reg, u8 val)
++{
++ int ret, retries;
++ u8 buf[3] = {reg >> 8, reg & 0xff, val};
++
++ for (retries = REG16_NUM_RETRIES; retries; retries--) {
++ ret = i2c_master_send(client, buf, 3);
++ if (ret == 3)
++ break;
++ }
++
++ if (ret < 0) {
++ dev_dbg(&client->dev,
++ "write fail: chip 0x%x register 0x%x: %d\n",
++ client->addr, reg, ret);
++ } else {
++#ifdef WRITE_VERIFY
++ u8 val2;
++ reg16_read(client, reg, &val2);
++ if (val != val2)
++ dev_err(&client->dev,
++ "write verify mismatch: chip 0x%x reg=0x%x "
++ "0x%x->0x%x\n", client->addr, reg, val, val2);
++#endif
++ }
++
++ return ret < 0 ? ret : 0;
++}
++
++
++static inline int reg16_read16(struct i2c_client *client, u16 reg, u16 *val)
++{
++ int ret, retries;
++ u8 buf[2] = {reg >> 8, reg & 0xff};
++
++ for (retries = REG8_NUM_RETRIES; retries; retries--) {
++ ret = i2c_master_send(client, buf, 2);
++ if (ret == 2) {
++ ret = i2c_master_recv(client, buf, 2);
++ if (ret == 2)
++ break;
++ }
++ }
++
++ if (ret < 0) {
++ dev_err(&client->dev,
++ "read fail: chip 0x%x register 0x%x: %d\n",
++ client->addr, reg, ret);
++ } else {
++ *val = ((u16)buf[0] << 8) | buf[1];
++ }
++
++ return ret < 0 ? ret : 0;
++}
++
++static inline int reg16_write16(struct i2c_client *client, u16 reg, u16 val)
++{
++ int ret, retries;
++ u8 buf[4] = {reg >> 8, reg & 0xff, val >> 8, val & 0xff};
++
++ for (retries = REG8_NUM_RETRIES; retries; retries--) {
++ ret = i2c_master_send(client, buf, 4);
++ if (ret == 4)
++ break;
++ }
++
++ if (ret < 0) {
++ dev_err(&client->dev,
++ "write fail: chip 0x%x register 0x%x: %d\n",
++ client->addr, reg, ret);
++ }
++
++ return ret < 0 ? ret : 0;
++}
++
++
++#ifdef MAXIM_DUMP
++static void maxim_ovsensor_dump_regs(struct i2c_client *client)
++{
++ int ret, i;
++ u8 val = 0;
++ u16 regs[] = {0x300a, 0x300b, 0x300c};
++
++ dev_dbg(&client->dev, "dump regs 0x%x\n", client->addr);
++
++ for (i = 0; i < sizeof(regs) / 2; i++) {
++ ret = reg16_read(client, regs[i], &val);
++ if (ret < 0)
++ dev_err(&client->dev,
++ "read fail: chip 0x%x register 0x%02x: %d\n",
++ client->addr, regs[i], ret);
++ printk("0x%02x -> 0x%x\n", regs[i], val);
++ }
++}
++
++static void maxim_ov10635_dump_format_regs(struct i2c_client *client)
++{
++ int ret, i;
++ u8 val;
++ u16 regs[] = {0x3003, 0x3004, 0x4300,
++ 0x4605, 0x3621, 0x3702, 0x3703, 0x3704,
++ 0x3802, 0x3803, 0x3806, 0x3807, 0x3808, 0x3809, 0x380a,
++ 0x380b, 0x380c, 0x380d, 0x380e, 0x380f,
++ 0x4606, 0x4607, 0x460a, 0x460b,
++ 0xc488, 0xc489, 0xc48a, 0xc48b,
++ 0xc4cc, 0xc4cd, 0xc4ce, 0xc4cf, 0xc512, 0xc513,
++ 0xc518, 0xc519, 0xc51a, 0xc51b,
++ };
++
++ dev_dbg(&client->dev, "dump regs 0x%x\n", client->addr);
++
++ for (i = 0; i < sizeof(regs) / 2; i++) {
++ ret = reg16_read(client, regs[i], &val);
++ if (ret < 0)
++ dev_err(&client->dev,
++ "read fail: chip 0x%x register 0x%02x: %d\n",
++ client->addr, regs[i], ret);
++ printk("0x%02x -> 0x%x\n", regs[i], val);
++ }
++}
++
++static void maxim_max927x_dump_regs(struct i2c_client *client)
++{
++ int ret;
++ u8 reg;
++
++ dev_dbg(&client->dev, "dump regs 0x%x\n", client->addr);
++
++ for (reg = 0; reg < 0x20; reg++) {
++ ret = i2c_smbus_read_byte_data(client, reg);
++ if (ret < 0)
++ dev_err(&client->dev,
++ "read fail: chip 0x%x register 0x%x: %d\n",
++ client->addr, reg, ret);
++ printk("0x%02x ", ret);
++ if (((reg + 1) % 0x10) == 0)
++ printk("\n");
++ }
++}
++#endif /* MAXIM_DUMP */
++#endif /* _MAX9286_MAX9271_H */
+diff --git a/drivers/media/i2c/soc_camera/ov10635.c b/drivers/media/i2c/soc_camera/ov10635.c
+new file mode 100644
+index 0000000..45169de
+--- /dev/null
++++ b/drivers/media/i2c/soc_camera/ov10635.c
+@@ -0,0 +1,759 @@
++/*
++ * OmniVision ov10635 sensor camera driver
++ *
++ * Copyright (C) 2015-2017 Cogent Embedded, Inc.
++ *
++ * This program is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License as published by the
++ * Free Software Foundation; either version 2 of the License, or (at your
++ * option) any later version.
++ */
++
++#include <linux/delay.h>
++#include <linux/init.h>
++#include <linux/i2c.h>
++#include <linux/module.h>
++#include <linux/videodev2.h>
++
++#include <media/soc_camera.h>
++#include <media/v4l2-common.h>
++#include <media/v4l2-ctrls.h>
++#include <media/v4l2-of.h>
++
++#include "max9286_max9271.h"
++#include "ov10635.h"
++
++#define OV10635_I2C_ADDR 0x30
++
++#define OV10635_PID 0x300a
++#define OV10635_VER 0x300b
++#define OV10635_VERSION_REG 0xa635
++#define OV10635_VERSION(pid, ver) (((pid) << 8) | ((ver) & 0xff))
++
++struct ov10635_priv {
++ struct v4l2_subdev sd;
++ struct v4l2_ctrl_handler hdl;
++ struct media_pad pad;
++ struct v4l2_rect rect;
++ int subsampling;
++ int fps_denominator;
++ int init_complete;
++ u8 id[6];
++ int dvp_order;
++ /* serializers */
++ int max9286_addr;
++ int max9271_addr;
++ int ti964_addr;
++ int ti954_addr;
++ int ti9x3_addr;
++ int port;
++ int gpio_resetb;
++ int gpio_fsin;
++};
++
++static inline struct ov10635_priv *to_ov10635(const struct i2c_client *client)
++{
++ return container_of(i2c_get_clientdata(client), struct ov10635_priv, sd);
++}
++
++static inline struct v4l2_subdev *to_sd(struct v4l2_ctrl *ctrl)
++{
++ return &container_of(ctrl->handler, struct ov10635_priv, hdl)->sd;
++}
++
++static void ov10635_s_port(struct i2c_client *client, int fwd_en)
++{
++ struct ov10635_priv *priv = to_ov10635(client);
++ int tmp_addr;
++
++ if (priv->max9286_addr) {
++ tmp_addr = client->addr;
++ client->addr = priv->max9286_addr; /* Deserializer I2C address */
++ reg8_write(client, 0x0a, fwd_en ? 0x11 << priv->port : 0); /* Enable/disable reverse/forward control for this port */
++ client->addr = tmp_addr;
++ };
++}
++
++static int ov10635_set_regs(struct i2c_client *client,
++ const struct ov10635_reg *regs, int nr_regs)
++{
++ int i;
++
++ for (i = 0; i < nr_regs; i++) {
++ if (reg16_write(client, regs[i].reg, regs[i].val)) {
++ usleep_range(100, 150); /* wait 100ns */
++ reg16_write(client, regs[i].reg, regs[i].val);
++ }
++ }
++
++ return 0;
++}
++
++static int ov10635_s_stream(struct v4l2_subdev *sd, int enable)
++{
++ return 0;
++}
++
++static int ov10635_set_window(struct v4l2_subdev *sd, int subsampling)
++{
++ struct i2c_client *client = v4l2_get_subdevdata(sd);
++ struct ov10635_priv *priv = to_ov10635(client);
++
++ /* disable clocks */
++ reg16_write(client, 0x302e, 0x00);
++ reg16_write(client, 0x301b, 0xff);
++ reg16_write(client, 0x301c, 0xff);
++ reg16_write(client, 0x301a, 0xff);
++
++ /* setup resolution */
++ reg16_write(client, 0x3808, priv->rect.width >> 8);
++ reg16_write(client, 0x3809, priv->rect.width & 0xff);
++ reg16_write(client, 0x380a, priv->rect.height >> 8);
++ reg16_write(client, 0x380b, priv->rect.height & 0xff);
++
++ /* enable/disable subsampling */
++ reg16_write(client, 0x5005, subsampling ? 0x89 : 0x08);
++ reg16_write(client, 0x3007, subsampling ? 0x02 : 0x01);
++ reg16_write(client, 0x4004, subsampling ? 0x02 : 0x04);
++
++#if 0 /* This is implemented in VIN via SOC_CAMERA layer, hence skip */
++ /* horiz crop start */
++ reg16_write(client, 0x3800, priv->rect.left >> 8);
++ reg16_write(client, 0x3801, priv->rect.left & 0xff);
++ /* horiz crop end */
++ reg16_write(client, 0x3804, (priv->rect.left + priv->rect.width + 1) >> 8);
++ reg16_write(client, 0x3805, (priv->rect.left + priv->rect.width + 1) & 0xff);
++ /* vert crop start */
++ reg16_write(client, 0x3802, priv->rect.top >> 8);
++ reg16_write(client, 0x3803, priv->rect.top & 0xff);
++ /* vert crop end */
++ reg16_write(client, 0x3806, (priv->rect.top + priv->rect.height + 1) >> 8);
++ reg16_write(client, 0x3807, (priv->rect.top + priv->rect.height + 1) & 0xff);
++#endif
++ /* enable clocks */
++ reg16_write(client, 0x301b, 0xf0);
++ reg16_write(client, 0x301c, 0xf0);
++ reg16_write(client, 0x301a, 0xf0);
++ reg16_write(client, 0x302e, 0x01);
++
++ return 0;
++};
++
++static int ov10635_get_fmt(struct v4l2_subdev *sd,
++ struct v4l2_subdev_pad_config *cfg,
++ struct v4l2_subdev_format *format)
++{
++ struct v4l2_mbus_framefmt *mf = &format->format;
++ struct i2c_client *client = v4l2_get_subdevdata(sd);
++ struct ov10635_priv *priv = to_ov10635(client);
++
++ if (format->pad)
++ return -EINVAL;
++
++ mf->width = priv->rect.width;
++ mf->height = priv->rect.height;
++ mf->code = MEDIA_BUS_FMT_YUYV8_2X8;
++ mf->colorspace = V4L2_COLORSPACE_SMPTE170M;
++ mf->field = V4L2_FIELD_NONE;
++
++ return 0;
++}
++
++static int ov10635_set_fmt(struct v4l2_subdev *sd,
++ struct v4l2_subdev_pad_config *cfg,
++ struct v4l2_subdev_format *format)
++{
++ struct v4l2_mbus_framefmt *mf = &format->format;
++
++ mf->code = MEDIA_BUS_FMT_YUYV8_2X8;
++ mf->colorspace = V4L2_COLORSPACE_SMPTE170M;
++ mf->field = V4L2_FIELD_NONE;
++
++ if (format->which == V4L2_SUBDEV_FORMAT_TRY)
++ cfg->try_fmt = *mf;
++
++ return 0;
++}
++
++static int ov10635_enum_mbus_code(struct v4l2_subdev *sd,
++ struct v4l2_subdev_pad_config *cfg,
++ struct v4l2_subdev_mbus_code_enum *code)
++{
++ if (code->pad || code->index > 0)
++ return -EINVAL;
++
++ code->code = MEDIA_BUS_FMT_YUYV8_2X8;
++
++ return 0;
++}
++
++static int ov10635_get_edid(struct v4l2_subdev *sd, struct v4l2_edid *edid)
++{
++ struct i2c_client *client = v4l2_get_subdevdata(sd);
++ struct ov10635_priv *priv = to_ov10635(client);
++
++ memcpy(edid->edid, priv->id, 6);
++
++ edid->edid[6] = 0xff;
++ edid->edid[7] = client->addr;
++ edid->edid[8] = OV10635_VERSION_REG >> 8;
++ edid->edid[9] = OV10635_VERSION_REG & 0xff;
++
++ return 0;
++}
++
++static int ov10635_set_selection(struct v4l2_subdev *sd,
++ struct v4l2_subdev_pad_config *cfg,
++ struct v4l2_subdev_selection *sel)
++{
++ struct v4l2_rect *rect = &sel->r;
++ struct i2c_client *client = v4l2_get_subdevdata(sd);
++ struct ov10635_priv *priv = to_ov10635(client);
++ int subsampling = 0;
++
++ if (sel->which != V4L2_SUBDEV_FORMAT_ACTIVE ||
++ sel->target != V4L2_SEL_TGT_CROP)
++ return -EINVAL;
++
++ rect->left = ALIGN(rect->left, 2);
++ rect->top = ALIGN(rect->top, 2);
++ rect->width = ALIGN(rect->width, 2);
++ rect->height = ALIGN(rect->height, 2);
++
++ if ((rect->left + rect->width > OV10635_MAX_WIDTH) ||
++ (rect->top + rect->height > OV10635_MAX_HEIGHT))
++ *rect = priv->rect;
++
++ if (rect->width == OV10635_MAX_WIDTH / 2 &&
++ rect->height == OV10635_MAX_HEIGHT / 2)
++ subsampling = 1;
++
++ priv->rect.left = rect->left;
++ priv->rect.top = rect->top;
++ priv->rect.width = rect->width;
++ priv->rect.height = rect->height;
++
++ /* change window only for subsampling, crop is done by VIN */
++ if (subsampling != priv->subsampling) {
++ ov10635_set_window(sd, subsampling);
++ priv->subsampling = subsampling;
++ }
++
++ return 0;
++}
++
++static int ov10635_get_selection(struct v4l2_subdev *sd,
++ struct v4l2_subdev_pad_config *cfg,
++ struct v4l2_subdev_selection *sel)
++{
++ struct i2c_client *client = v4l2_get_subdevdata(sd);
++ struct ov10635_priv *priv = to_ov10635(client);
++
++ if (sel->which != V4L2_SUBDEV_FORMAT_ACTIVE)
++ return -EINVAL;
++
++ switch (sel->target) {
++ case V4L2_SEL_TGT_CROP_BOUNDS:
++ sel->r.left = 0;
++ sel->r.top = 0;
++ sel->r.width = OV10635_MAX_WIDTH;
++ sel->r.height = OV10635_MAX_HEIGHT;
++ return 0;
++ case V4L2_SEL_TGT_CROP_DEFAULT:
++ sel->r.left = 0;
++ sel->r.top = 0;
++ sel->r.width = OV10635_MAX_WIDTH;
++ sel->r.height = OV10635_MAX_HEIGHT;
++ return 0;
++ case V4L2_SEL_TGT_CROP:
++ sel->r = priv->rect;
++ return 0;
++ default:
++ return -EINVAL;
++ }
++}
++
++static int ov10635_g_mbus_config(struct v4l2_subdev *sd,
++ struct v4l2_mbus_config *cfg)
++{
++ cfg->flags = V4L2_MBUS_CSI2_1_LANE | V4L2_MBUS_CSI2_CHANNEL_0 |
++ V4L2_MBUS_CSI2_CONTINUOUS_CLOCK;
++ cfg->type = V4L2_MBUS_CSI2;
++
++ return 0;
++}
++
++static int ov10635_g_parm(struct v4l2_subdev *sd, struct v4l2_streamparm *parms)
++{
++ struct i2c_client *client = v4l2_get_subdevdata(sd);
++ struct ov10635_priv *priv = to_ov10635(client);
++ struct v4l2_captureparm *cp = &parms->parm.capture;
++
++ if (parms->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
++ return -EINVAL;
++
++ memset(cp, 0, sizeof(struct v4l2_captureparm));
++ cp->capability = V4L2_CAP_TIMEPERFRAME;
++ cp->timeperframe.numerator = 1;
++ cp->timeperframe.denominator = priv->fps_denominator;
++
++ return 0;
++}
++
++static int ov10635_s_parm(struct v4l2_subdev *sd, struct v4l2_streamparm *parms)
++{
++ struct i2c_client *client = v4l2_get_subdevdata(sd);
++ struct ov10635_priv *priv = to_ov10635(client);
++ struct v4l2_captureparm *cp = &parms->parm.capture;
++ int ret = 0;
++
++ if (parms->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
++ return -EINVAL;
++ if (cp->extendedmode != 0)
++ return -EINVAL;
++
++ if (priv->fps_denominator != cp->timeperframe.denominator) {
++ switch (cp->timeperframe.denominator) {
++ case 5:
++ ret = ov10635_set_regs(client, ov10635_regs_5fps,
++ ARRAY_SIZE(ov10635_regs_5fps));
++ break;
++ case 10:
++ ret = ov10635_set_regs(client, ov10635_regs_10fps,
++ ARRAY_SIZE(ov10635_regs_10fps));
++ break;
++ case 15:
++ ret = ov10635_set_regs(client, ov10635_regs_15fps,
++ ARRAY_SIZE(ov10635_regs_15fps));
++ break;
++ case 30:
++ ret = ov10635_set_regs(client, ov10635_regs_30fps,
++ ARRAY_SIZE(ov10635_regs_30fps));
++ break;
++ default:
++ ret = -EINVAL;
++ goto out;
++ }
++
++ priv->fps_denominator = cp->timeperframe.denominator;
++ }
++
++out:
++ return ret;
++}
++
++#ifdef CONFIG_VIDEO_ADV_DEBUG
++static int ov10635_g_register(struct v4l2_subdev *sd,
++ struct v4l2_dbg_register *reg)
++{
++ struct i2c_client *client = v4l2_get_subdevdata(sd);
++ int ret;
++ u8 val = 0;
++
++ ret = reg16_read(client, (u16)reg->reg, &val);
++ if (ret < 0)
++ return ret;
++
++ reg->val = val;
++ reg->size = sizeof(u16);
++
++ return 0;
++}
++
++static int ov10635_s_register(struct v4l2_subdev *sd,
++ const struct v4l2_dbg_register *reg)
++{
++ struct i2c_client *client = v4l2_get_subdevdata(sd);
++
++ return reg16_write(client, (u16)reg->reg, (u8)reg->val);
++}
++#endif
++
++static struct v4l2_subdev_core_ops ov10635_core_ops = {
++#ifdef CONFIG_VIDEO_ADV_DEBUG
++ .g_register = ov10635_g_register,
++ .s_register = ov10635_s_register,
++#endif
++};
++
++static int ov10635_s_ctrl(struct v4l2_ctrl *ctrl)
++{
++ struct v4l2_subdev *sd = to_sd(ctrl);
++ struct i2c_client *client = v4l2_get_subdevdata(sd);
++ struct ov10635_priv *priv = to_ov10635(client);
++ int ret = -EINVAL;
++ u8 val = 0;
++
++ if (!priv->init_complete)
++ return 0;
++
++ switch (ctrl->id) {
++ case V4L2_CID_BRIGHTNESS:
++ /* AEC/AGC target */
++ ret = reg16_write(client, 0xc46a, ctrl->val);
++ break;
++ case V4L2_CID_CONTRAST:
++ udelay(100);
++ ret = ov10635_set_regs(client, &ov10635_regs_contrast[ctrl->val][0], 18);
++ break;
++ case V4L2_CID_SATURATION:
++ ret = reg16_write(client, 0xc316, ctrl->val);
++ break;
++ case V4L2_CID_HUE:
++ /* CMX ? */
++ ret = 0;
++ break;
++ case V4L2_CID_GAMMA:
++ ret = reg16_write(client, 0xc4be, ctrl->val >> 8);
++ ret |= reg16_write(client, 0xc4bf, ctrl->val & 0xff);
++ break;
++ case V4L2_CID_AUTOGAIN:
++ /* automatic gain/exposure */
++ ret = reg16_write(client, 0x56d0, !ctrl->val);
++ break;
++ case V4L2_CID_GAIN:
++ /* manual gain */
++ ret = reg16_write(client, 0x3504, 0);
++ ret |= reg16_write(client, 0x56d1, ctrl->val >> 8);
++ ret |= reg16_write(client, 0x56d2, ctrl->val & 0xff);
++ ret |= reg16_write(client, 0x3504, 1); /* validate gain */
++ break;
++ case V4L2_CID_EXPOSURE:
++ /* manual exposure */
++ ret = reg16_write(client, 0x3504, 0);
++ ret |= reg16_write(client, 0x56d5, ctrl->val >> 8);
++ ret |= reg16_write(client, 0x56d6, ctrl->val & 0xff);
++ ret |= reg16_write(client, 0x3504, 1); /* validate exposure */
++ break;
++ case V4L2_CID_HFLIP:
++ ret = reg16_read(client, 0x381d, &val);
++ if (ret < 0)
++ goto out;
++ if (ctrl->val)
++ val |= 0x3;
++ else
++ val &= ~0x3;
++ ret = reg16_write(client, 0x381d, val);
++ break;
++ case V4L2_CID_VFLIP:
++ ret = reg16_read(client, 0x381c, &val);
++ if (ctrl->val)
++ val |= 0xc0;
++ else
++ val &= ~0xc0;
++ ret = reg16_write(client, 0x381c, val);
++ break;
++ case V4L2_CID_MIN_BUFFERS_FOR_CAPTURE:
++ ret = 0;
++ break;
++ }
++
++out:
++ return ret;
++}
++
++static const struct v4l2_ctrl_ops ov10635_ctrl_ops = {
++ .s_ctrl = ov10635_s_ctrl,
++};
++
++static struct v4l2_subdev_video_ops ov10635_video_ops = {
++ .s_stream = ov10635_s_stream,
++ .g_mbus_config = ov10635_g_mbus_config,
++ .g_parm = ov10635_g_parm,
++ .s_parm = ov10635_s_parm,
++};
++
++static const struct v4l2_subdev_pad_ops ov10635_subdev_pad_ops = {
++ .get_edid = ov10635_get_edid,
++ .enum_mbus_code = ov10635_enum_mbus_code,
++ .get_selection = ov10635_get_selection,
++ .set_selection = ov10635_set_selection,
++ .get_fmt = ov10635_get_fmt,
++ .set_fmt = ov10635_set_fmt,
++};
++
++static struct v4l2_subdev_ops ov10635_subdev_ops = {
++ .core = &ov10635_core_ops,
++ .video = &ov10635_video_ops,
++ .pad = &ov10635_subdev_pad_ops,
++};
++
++static void ov10635_otp_id_read(struct i2c_client *client)
++{
++ struct ov10635_priv *priv = to_ov10635(client);
++ int i;
++
++ /* read camera id from OTP memory */
++ reg16_write(client, 0x3d10, 1);
++
++ usleep_range(15000, 16000); /* wait 15ms */
++
++ for (i = 0; i < 6; i++)
++ reg16_read(client, 0x3d00 + i, &priv->id[i]);
++}
++
++static ssize_t ov10635_otp_id_show(struct device *dev,
++ struct device_attribute *attr, char *buf)
++{
++ struct v4l2_subdev *sd = i2c_get_clientdata(to_i2c_client(dev));
++ struct i2c_client *client = v4l2_get_subdevdata(sd);
++ struct ov10635_priv *priv = to_ov10635(client);
++
++ return snprintf(buf, 32, "%02x:%02x:%02x:%02x:%02x:%02x\n",
++ priv->id[0], priv->id[1], priv->id[2], priv->id[3], priv->id[4], priv->id[5]);
++}
++
++static DEVICE_ATTR(otp_id_ov10635, S_IRUGO, ov10635_otp_id_show, NULL);
++
++static int ov10635_initialize(struct i2c_client *client)
++{
++ struct ov10635_priv *priv = to_ov10635(client);
++ u8 pid = 0, ver = 0;
++ int ret = 0;
++
++ ov10635_s_port(client, 1);
++
++ /* check and show product ID and manufacturer ID */
++ reg16_read(client, OV10635_PID, &pid);
++ reg16_read(client, OV10635_VER, &ver);
++
++ if (OV10635_VERSION(pid, ver) != OV10635_VERSION_REG) {
++ dev_dbg(&client->dev, "Product ID error %x:%x\n", pid, ver);
++ ret = -ENODEV;
++ goto out;
++ }
++
++ /* s/w reset sensor */
++ reg16_write(client, 0x103, 0x1);
++ udelay(100);
++ /* Program wizard registers */
++ ov10635_set_regs(client, ov10635_regs_wizard, ARRAY_SIZE(ov10635_regs_wizard));
++ /* Set DVP bit swap */
++ reg16_write(client, 0x4709, priv->dvp_order << 4);
++ /* Read OTP IDs */
++ ov10635_otp_id_read(client);
++
++ dev_info(&client->dev, "ov10635 Product ID %x Manufacturer ID %x OTP_ID %02x:%02x:%02x:%02x:%02x:%02x\n",
++ pid, ver, priv->id[0], priv->id[1], priv->id[2], priv->id[3], priv->id[4], priv->id[5]);
++
++out:
++ ov10635_s_port(client, 0);
++
++ return ret;
++}
++
++static int ov10635_parse_dt(struct device_node *np, struct ov10635_priv *priv)
++{
++ struct i2c_client *client = v4l2_get_subdevdata(&priv->sd);
++ int i;
++ struct device_node *endpoint = NULL, *rendpoint = NULL;
++ int tmp_addr = 0;
++
++ for (i = 0; ; i++) {
++ endpoint = of_graph_get_next_endpoint(np, endpoint);
++ if (!endpoint)
++ break;
++
++ of_node_put(endpoint);
++
++ of_property_read_u32(endpoint, "dvp-order", &priv->dvp_order);
++
++ rendpoint = of_parse_phandle(endpoint, "remote-endpoint", 0);
++ if (!rendpoint)
++ continue;
++
++ if (!of_property_read_u32(rendpoint, "max9271-addr", &priv->max9271_addr) &&
++ !of_property_read_u32(rendpoint->parent->parent, "reg", &priv->max9286_addr) &&
++ !kstrtouint(strrchr(rendpoint->full_name, '@') + 1, 0, &priv->port))
++ break;
++
++ if (!of_property_read_u32(rendpoint, "ti9x3-addr", &priv->ti9x3_addr) &&
++ !of_property_match_string(rendpoint->parent->parent, "compatible", "ti,ti964-ti9x3") &&
++ !of_property_read_u32(rendpoint->parent->parent, "reg", &priv->ti964_addr) &&
++ !kstrtouint(strrchr(rendpoint->full_name, '@') + 1, 0, &priv->port))
++ break;
++
++ if (!of_property_read_u32(rendpoint, "ti9x3-addr", &priv->ti9x3_addr) &&
++ !of_property_match_string(rendpoint->parent->parent, "compatible", "ti,ti954-ti9x3") &&
++ !of_property_read_u32(rendpoint->parent->parent, "reg", &priv->ti954_addr) &&
++ !kstrtouint(strrchr(rendpoint->full_name, '@') + 1, 0, &priv->port))
++ break;
++ }
++
++ if (!priv->max9286_addr && !priv->ti964_addr && !priv->ti954_addr) {
++ dev_err(&client->dev, "deserializer does not present\n");
++ return -EINVAL;
++ }
++
++ ov10635_s_port(client, 1);
++
++ /* setup I2C translator address */
++ tmp_addr = client->addr;
++ if (priv->max9286_addr) {
++ client->addr = priv->max9271_addr; /* Serializer I2C address */
++
++ reg8_write(client, 0x09, tmp_addr << 1); /* Sensor translated I2C address */
++ reg8_write(client, 0x0A, OV10635_I2C_ADDR << 1); /* Sensor native I2C address */
++ usleep_range(2000, 2500); /* wait 2ms */
++ };
++
++ if (priv->ti964_addr) {
++ client->addr = priv->ti964_addr; /* Deserializer I2C address */
++
++ reg8_write(client, 0x4c, (priv->port << 4) | (1 << priv->port)); /* Select RX port number */
++ usleep_range(2000, 2500); /* wait 2ms */
++ reg8_write(client, 0x65, tmp_addr << 1); /* Sensor translated I2C address */
++ reg8_write(client, 0x5d, OV10635_I2C_ADDR << 1); /* Sensor native I2C address */
++
++ reg8_write(client, 0x6e, 0xa9); /* GPIO0 - resetb, GPIO1 - fsin */
++ }
++
++ if (priv->ti954_addr) {
++ client->addr = priv->ti954_addr; /* Deserializer I2C address */
++
++ reg8_write(client, 0x4c, (priv->port << 4) | (1 << priv->port)); /* Select RX port number */
++ usleep_range(2000, 2500); /* wait 2ms */
++ reg8_write(client, 0x65, tmp_addr << 1); /* Sensor translated I2C address */
++ reg8_write(client, 0x5d, OV10635_I2C_ADDR << 1); /* Sensor native I2C address */
++
++ reg8_write(client, 0x6e, 0xa9); /* GPIO0 - resetb, GPIO1 - fsin */
++ }
++ client->addr = tmp_addr;
++
++ udelay(100);
++
++ return 0;
++}
++
++static int ov10635_probe(struct i2c_client *client,
++ const struct i2c_device_id *did)
++{
++ struct ov10635_priv *priv;
++ struct v4l2_ctrl *ctrl;
++ int ret;
++
++ priv = devm_kzalloc(&client->dev, sizeof(*priv), GFP_KERNEL);
++ if (!priv)
++ return -ENOMEM;
++
++ v4l2_i2c_subdev_init(&priv->sd, client, &ov10635_subdev_ops);
++ priv->sd.flags = V4L2_SUBDEV_FL_HAS_DEVNODE;
++ priv->rect.left = 0;
++ priv->rect.top = 0;
++ priv->rect.width = OV10635_MAX_WIDTH;
++ priv->rect.height = OV10635_MAX_HEIGHT;
++ priv->fps_denominator = 30;
++
++ v4l2_ctrl_handler_init(&priv->hdl, 4);
++ v4l2_ctrl_new_std(&priv->hdl, &ov10635_ctrl_ops,
++ V4L2_CID_BRIGHTNESS, 0, 0xff, 1, 0x30);
++ v4l2_ctrl_new_std(&priv->hdl, &ov10635_ctrl_ops,
++ V4L2_CID_CONTRAST, 0, 4, 1, 2);
++ v4l2_ctrl_new_std(&priv->hdl, &ov10635_ctrl_ops,
++ V4L2_CID_SATURATION, 0, 0xff, 1, 0xff);
++ v4l2_ctrl_new_std(&priv->hdl, &ov10635_ctrl_ops,
++ V4L2_CID_HUE, 0, 255, 1, 0);
++ v4l2_ctrl_new_std(&priv->hdl, &ov10635_ctrl_ops,
++ V4L2_CID_GAMMA, 0, 0xffff, 1, 0x233);
++ v4l2_ctrl_new_std(&priv->hdl, &ov10635_ctrl_ops,
++ V4L2_CID_AUTOGAIN, 0, 1, 1, 1);
++ v4l2_ctrl_new_std(&priv->hdl, &ov10635_ctrl_ops,
++ V4L2_CID_GAIN, 0, 0x3ff, 1, 0x10);
++ v4l2_ctrl_new_std(&priv->hdl, &ov10635_ctrl_ops,
++ V4L2_CID_EXPOSURE, 0, 0xffff, 1, 0x80);
++ v4l2_ctrl_new_std(&priv->hdl, &ov10635_ctrl_ops,
++ V4L2_CID_HFLIP, 0, 1, 1, 0);
++ v4l2_ctrl_new_std(&priv->hdl, &ov10635_ctrl_ops,
++ V4L2_CID_VFLIP, 0, 1, 1, 0);
++ ctrl = v4l2_ctrl_new_std(&priv->hdl, &ov10635_ctrl_ops,
++ V4L2_CID_MIN_BUFFERS_FOR_CAPTURE, 1, 32, 1, 9);
++ if (ctrl)
++ ctrl->flags &= ~V4L2_CTRL_FLAG_READ_ONLY;
++ priv->sd.ctrl_handler = &priv->hdl;
++
++ ret = priv->hdl.error;
++ if (ret)
++ goto cleanup;
++
++ v4l2_ctrl_handler_setup(&priv->hdl);
++
++ priv->pad.flags = MEDIA_PAD_FL_SOURCE;
++ priv->sd.entity.flags |= MEDIA_ENT_F_CAM_SENSOR;
++ ret = media_entity_pads_init(&priv->sd.entity, 1, &priv->pad);
++ if (ret < 0)
++ goto cleanup;
++
++ ret = ov10635_parse_dt(client->dev.of_node, priv);
++ if (ret)
++ goto cleanup;
++
++ ret = ov10635_initialize(client);
++ if (ret < 0)
++ goto cleanup;
++
++ ret = v4l2_async_register_subdev(&priv->sd);
++ if (ret)
++ goto cleanup;
++
++ if (device_create_file(&client->dev, &dev_attr_otp_id_ov10635) != 0) {
++ dev_err(&client->dev, "sysfs otp_id entry creation failed\n");
++ goto cleanup;
++ }
++
++ priv->init_complete = 1;
++
++ return 0;
++
++cleanup:
++ media_entity_cleanup(&priv->sd.entity);
++ v4l2_ctrl_handler_free(&priv->hdl);
++ v4l2_device_unregister_subdev(&priv->sd);
++#ifdef CONFIG_SOC_CAMERA_OV10635
++ v4l_err(client, "failed to probe @ 0x%02x (%s)\n",
++ client->addr, client->adapter->name);
++#endif
++ return ret;
++}
++
++static int ov10635_remove(struct i2c_client *client)
++{
++ struct ov10635_priv *priv = i2c_get_clientdata(client);
++
++ device_remove_file(&client->dev, &dev_attr_otp_id_ov10635);
++ v4l2_async_unregister_subdev(&priv->sd);
++ media_entity_cleanup(&priv->sd.entity);
++ v4l2_ctrl_handler_free(&priv->hdl);
++ v4l2_device_unregister_subdev(&priv->sd);
++
++ return 0;
++}
++
++#ifdef CONFIG_SOC_CAMERA_OV10635
++static const struct i2c_device_id ov10635_id[] = {
++ { "ov10635", 0 },
++ { }
++};
++MODULE_DEVICE_TABLE(i2c, ov10635_id);
++
++static const struct of_device_id ov10635_of_ids[] = {
++ { .compatible = "ovti,ov10635", },
++ { }
++};
++MODULE_DEVICE_TABLE(of, ov10635_of_ids);
++
++static struct i2c_driver ov10635_i2c_driver = {
++ .driver = {
++ .name = "ov10635",
++ .of_match_table = ov10635_of_ids,
++ },
++ .probe = ov10635_probe,
++ .remove = ov10635_remove,
++ .id_table = ov10635_id,
++};
++
++module_i2c_driver(ov10635_i2c_driver);
++
++MODULE_DESCRIPTION("SoC Camera driver for OV10635");
++MODULE_AUTHOR("Vladimir Barinov");
++MODULE_LICENSE("GPL");
++#endif
+diff --git a/drivers/media/i2c/soc_camera/ov10635.h b/drivers/media/i2c/soc_camera/ov10635.h
+new file mode 100644
+index 0000000..66cc490
+--- /dev/null
++++ b/drivers/media/i2c/soc_camera/ov10635.h
+@@ -0,0 +1,1139 @@
++/*
++ * OmniVision ov10635 sensor camera wizard 1280x800@30/UYVY/BT601/8bit
++ *
++ * Copyright (C) 2015-2017 Cogent Embedded, Inc.
++ *
++ * This program is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License as published by the
++ * Free Software Foundation; either version 2 of the License, or (at your
++ * option) any later version.
++ */
++
++//#define OV10635_DISPLAY_PATTERN
++
++#define OV10635_SENSOR_WIDTH 1312
++#define OV10635_SENSOR_HEIGHT 814
++
++#define OV10635_MAX_WIDTH 1280
++#define OV10635_MAX_HEIGHT 800
++
++//#define OV10635_PCLK_96MHZ
++#define OV10635_PCLK_88MHZ
++
++#if defined(OV10635_PCLK_96MHZ)
++/* VTS=PCLK/FPS/HTS/2 (=96MHz/30/1600/2) */
++ #define OV10635_HTS 1600
++ #define OV10635_VTS 1000 /* fps=30 */
++#elif defined(OV10635_PCLK_88MHZ)
++/* VTS=PCLK/FPS/HTS/2 (=88MHz/1572/30/2) */
++ #define OV10635_HTS 1572
++ #define OV10635_VTS 933 /* fps=29.9998 */
++#else
++ #error PCLK not defined
++#endif
++
++struct ov10635_reg {
++ u16 reg;
++ u8 val;
++};
++
++static const struct ov10635_reg ov10635_regs_wizard[] = {
++//{0x0103, 0x01},
++{0x300C, 0x61},
++{0x300C, 0x61},
++{0x300C, 0x61},
++{0x300C, 0x61},
++{0x300C, 0x61},
++{0x300C, 0x61},
++{0x300C, 0x61},
++{0x300C, 0x61},
++{0x300C, 0x61},
++{0x300C, 0x61},
++{0x300C, 0x61},
++{0x300C, 0x61},
++{0x300C, 0x61},
++{0x300C, 0x61},
++{0x300C, 0x61},
++{0x300C, 0x61},
++{0x300C, 0x61},
++{0x300C, 0x61},
++{0x300C, 0x61},
++{0x300C, 0x61},
++{0x300C, 0x61},
++{0x300C, 0x61},
++{0x300C, 0x61},
++{0x301B, 0xFF},
++{0x301C, 0xFF},
++{0x301A, 0xFF},
++{0x3011, 0x42},
++{0x6900, 0x0C},
++{0x6901, 0x19},
++{0x3503, 0x10},
++{0x3025, 0x03},
++#if defined(OV10635_PCLK_96MHZ)
++{0x3003, 0x20},
++{0x3004, 0x21},
++#elif defined(OV10635_PCLK_88MHZ)
++{0x3003, 0x16},
++{0x3004, 0x30},
++#endif
++{0x3005, 0x40},
++{0x3006, 0x91},
++{0x3600, 0x74},
++{0x3601, 0x2B},
++{0x3612, 0x00},
++{0x3611, 0x67},
++{0x3633, 0xCA},
++{0x3602, 0xAF},
++{0x3603, 0x04},
++{0x3630, 0x28},
++{0x3631, 0x16},
++{0x3714, 0x10},
++{0x371D, 0x01},
++{0x4300, 0x3A},
++{0x3007, 0x01},
++{0x3024, 0x03},
++{0x3020, 0x0A},
++{0x3702, 0x0D},
++{0x3703, 0x20},
++{0x3704, 0x15},
++{0x3709, 0xA8},
++{0x370C, 0xC7},
++{0x370D, 0x80},
++{0x3712, 0x00},
++{0x3713, 0x20},
++{0x3715, 0x04},
++{0x381D, 0x40},
++{0x381C, 0x00},
++{0x3822, 0x50},
++{0x3824, 0x10},
++{0x3815, 0x8C},
++{0x3804, 0x05},
++{0x3805, 0x1F},
++{0x3800, 0x00},
++{0x3801, 0x00},
++{0x3806, 0x03},
++{0x3807, 0x28},
++{0x3802, 0x00},
++{0x3803, 0x07},
++{0x3808, 0x05},
++{0x3809, 0x00},
++{0x380A, 0x03},
++{0x380B, 0x20},
++{0x380C, OV10635_HTS >> 8},
++{0x380D, OV10635_HTS & 0xff},
++{0x380E, OV10635_VTS >> 8},
++{0x380F, OV10635_VTS & 0xff},
++{0x3813, 0x02},
++{0x3811, 0x08},
++{0x381F, 0x0C},
++{0x3819, 0x04},
++{0x3804, 0x01},
++{0x3805, 0x00},
++{0x3828, 0x03},
++{0x3829, 0x10},
++{0x382A, 0x10},
++{0x3621, 0x63},
++{0x5005, 0x08},
++{0x56D5, 0x00},
++{0x56D6, 0x80},
++{0x56D7, 0x00},
++{0x56D8, 0x00},
++{0x56D9, 0x00},
++{0x56DA, 0x80},
++{0x56DB, 0x00},
++{0x56DC, 0x00},
++{0x56E8, 0x00},
++{0x56E9, 0x7F},
++{0x56EA, 0x00},
++{0x56EB, 0x7F},
++{0x5100, 0x00},
++{0x5101, 0x80},
++{0x5102, 0x00},
++{0x5103, 0x80},
++{0x5104, 0x00},
++{0x5105, 0x80},
++{0x5106, 0x00},
++{0x5107, 0x80},
++{0x5108, 0x00},
++{0x5109, 0x00},
++{0x510A, 0x00},
++{0x510B, 0x00},
++{0x510C, 0x00},
++{0x510D, 0x00},
++{0x510E, 0x00},
++{0x510F, 0x00},
++{0x5110, 0x00},
++{0x5111, 0x80},
++{0x5112, 0x00},
++{0x5113, 0x80},
++{0x5114, 0x00},
++{0x5115, 0x80},
++{0x5116, 0x00},
++{0x5117, 0x80},
++{0x5118, 0x00},
++{0x5119, 0x00},
++{0x511A, 0x00},
++{0x511B, 0x00},
++{0x511C, 0x00},
++{0x511D, 0x00},
++{0x511E, 0x00},
++{0x511F, 0x00},
++{0x56D0, 0x00},
++{0x5006, 0x04},
++{0x5608, 0x05},
++{0x52D7, 0x06},
++{0x528D, 0x08},
++{0x5293, 0x12},
++{0x52D3, 0x12},
++{0x5288, 0x06},
++{0x5289, 0x20},
++{0x52C8, 0x06},
++{0x52C9, 0x20},
++{0x52CD, 0x04},
++{0x5381, 0x00},
++{0x5382, 0xFF},
++{0x5589, 0x76},
++{0x558A, 0x47},
++{0x558B, 0xEF},
++{0x558C, 0xC9},
++{0x558D, 0x49},
++{0x558E, 0x30},
++{0x558F, 0x67},
++{0x5590, 0x3F},
++{0x5591, 0xF0},
++{0x5592, 0x10},
++{0x55A2, 0x6D},
++{0x55A3, 0x55},
++{0x55A4, 0xC3},
++{0x55A5, 0xB5},
++{0x55A6, 0x43},
++{0x55A7, 0x38},
++{0x55A8, 0x5F},
++{0x55A9, 0x4B},
++{0x55AA, 0xF0},
++{0x55AB, 0x10},
++{0x5581, 0x52},
++{0x5300, 0x01},
++{0x5301, 0x00},
++{0x5302, 0x00},
++{0x5303, 0x0E},
++{0x5304, 0x00},
++{0x5305, 0x0E},
++{0x5306, 0x00},
++{0x5307, 0x36},
++{0x5308, 0x00},
++{0x5309, 0xD9},
++{0x530A, 0x00},
++{0x530B, 0x0F},
++{0x530C, 0x00},
++{0x530D, 0x2C},
++{0x530E, 0x00},
++{0x530F, 0x59},
++{0x5310, 0x00},
++{0x5311, 0x7B},
++{0x5312, 0x00},
++{0x5313, 0x22},
++{0x5314, 0x00},
++{0x5315, 0xD5},
++{0x5316, 0x00},
++{0x5317, 0x13},
++{0x5318, 0x00},
++{0x5319, 0x18},
++{0x531A, 0x00},
++{0x531B, 0x26},
++{0x531C, 0x00},
++{0x531D, 0xDC},
++{0x531E, 0x00},
++{0x531F, 0x02},
++{0x5320, 0x00},
++{0x5321, 0x24},
++{0x5322, 0x00},
++{0x5323, 0x56},
++{0x5324, 0x00},
++{0x5325, 0x85},
++{0x5326, 0x00},
++{0x5327, 0x20},
++{0x5609, 0x01},
++{0x560A, 0x40},
++{0x560B, 0x01},
++{0x560C, 0x40},
++{0x560D, 0x00},
++{0x560E, 0xFA},
++{0x560F, 0x00},
++{0x5610, 0xFA},
++{0x5611, 0x02},
++{0x5612, 0x80},
++{0x5613, 0x02},
++{0x5614, 0x80},
++{0x5615, 0x01},
++{0x5616, 0x2C},
++{0x5617, 0x01},
++{0x5618, 0x2C},
++{0x563B, 0x01},
++{0x563C, 0x01},
++{0x563D, 0x01},
++{0x563E, 0x01},
++{0x563F, 0x03},
++{0x5640, 0x03},
++{0x5641, 0x03},
++{0x5642, 0x05},
++{0x5643, 0x09},
++{0x5644, 0x05},
++{0x5645, 0x05},
++{0x5646, 0x05},
++{0x5647, 0x05},
++{0x5651, 0x00},
++{0x5652, 0x80},
++{0x521A, 0x01},
++{0x521B, 0x03},
++{0x521C, 0x06},
++{0x521D, 0x0A},
++{0x521E, 0x0E},
++{0x521F, 0x12},
++{0x5220, 0x16},
++{0x5223, 0x02},
++{0x5225, 0x04},
++{0x5227, 0x08},
++{0x5229, 0x0C},
++{0x522B, 0x12},
++{0x522D, 0x18},
++{0x522F, 0x1E},
++{0x5241, 0x04},
++{0x5242, 0x01},
++{0x5243, 0x03},
++{0x5244, 0x06},
++{0x5245, 0x0A},
++{0x5246, 0x0E},
++{0x5247, 0x12},
++{0x5248, 0x16},
++{0x524A, 0x03},
++{0x524C, 0x04},
++{0x524E, 0x08},
++{0x5250, 0x0C},
++{0x5252, 0x12},
++{0x5254, 0x18},
++{0x5256, 0x1E},
++{0x4606, (2*OV10635_HTS) >> 8}, /* fifo_line_length = 2*hts */
++{0x4607, (2*OV10635_HTS) & 0xff},
++{0x460a, (2*(OV10635_HTS-OV10635_MAX_WIDTH)) >> 8}, /* fifo_hsync_start = 2*(hts - xres) */
++{0x460b, (2*(OV10635_HTS-OV10635_MAX_WIDTH)) & 0xff },
++{0x460C, 0x00},
++{0x4620, 0x0E},
++#if 0
++{0x4700, 0x02}, // BT656: mode is acceptable but artefact lines on left/bottom due to BT656 SAV/EAV are parsed as image data
++#else
++{0x4700, 0x04}, // BT601: 0x08 is also accaptable as HS/VS mode
++#endif
++{0x4701, 0x00},
++{0x4702, 0x01},
++{0x4004, 0x04},
++{0x4005, 0x18},
++{0x4001, 0x06},
++{0x4050, 0x22},
++{0x4051, 0x24},
++{0x4052, 0x02},
++{0x4057, 0x9C},
++{0x405A, 0x00},
++{0x4202, 0x02},
++{0x3023, 0x10},
++{0x0100, 0x01},
++{0x0100, 0x01},
++{0x6F10, 0x07},
++{0x6F11, 0x82},
++{0x6F12, 0x04},
++{0x6F13, 0x00},
++{0xD000, 0x19},
++{0xD001, 0xA0},
++{0xD002, 0x00},
++{0xD003, 0x01},
++{0xD004, 0xA9},
++{0xD005, 0xAD},
++{0xD006, 0x10},
++{0xD007, 0x40},
++{0xD008, 0x44},
++{0xD009, 0x00},
++{0xD00A, 0x68},
++{0xD00B, 0x00},
++{0xD00C, 0x15},
++{0xD00D, 0x00},
++{0xD00E, 0x00},
++{0xD00F, 0x00},
++{0xD040, 0x9C},
++{0xD041, 0x21},
++{0xD042, 0xFF},
++{0xD043, 0xF8},
++{0xD044, 0xD4},
++{0xD045, 0x01},
++{0xD046, 0x48},
++{0xD047, 0x00},
++{0xD048, 0xD4},
++{0xD049, 0x01},
++{0xD04A, 0x50},
++{0xD04B, 0x04},
++{0xD04C, 0x18},
++{0xD04D, 0x60},
++{0xD04E, 0x00},
++{0xD04F, 0x01},
++{0xD050, 0xA8},
++{0xD051, 0x63},
++{0xD052, 0x02},
++{0xD053, 0xA4},
++{0xD054, 0x85},
++{0xD055, 0x43},
++{0xD056, 0x00},
++{0xD057, 0x00},
++{0xD058, 0x18},
++{0xD059, 0x60},
++{0xD05A, 0x00},
++{0xD05B, 0x01},
++{0xD05C, 0xA8},
++{0xD05D, 0x63},
++{0xD05E, 0x03},
++{0xD05F, 0xF0},
++{0xD060, 0x98},
++{0xD061, 0xA3},
++{0xD062, 0x00},
++{0xD063, 0x00},
++{0xD064, 0x8C},
++{0xD065, 0x6A},
++{0xD066, 0x00},
++{0xD067, 0x6E},
++{0xD068, 0xE5},
++{0xD069, 0x85},
++{0xD06A, 0x18},
++{0xD06B, 0x00},
++{0xD06C, 0x10},
++{0xD06D, 0x00},
++{0xD06E, 0x00},
++{0xD06F, 0x10},
++{0xD070, 0x9C},
++{0xD071, 0x80},
++{0xD072, 0x00},
++{0xD073, 0x03},
++{0xD074, 0x18},
++{0xD075, 0x60},
++{0xD076, 0x00},
++{0xD077, 0x01},
++{0xD078, 0xA8},
++{0xD079, 0x63},
++{0xD07A, 0x07},
++{0xD07B, 0x80},
++{0xD07C, 0x07},
++{0xD07D, 0xFF},
++{0xD07E, 0xF9},
++{0xD07F, 0x03},
++{0xD080, 0x8C},
++{0xD081, 0x63},
++{0xD082, 0x00},
++{0xD083, 0x00},
++{0xD084, 0xA5},
++{0xD085, 0x6B},
++{0xD086, 0x00},
++{0xD087, 0xFF},
++{0xD088, 0x18},
++{0xD089, 0x80},
++{0xD08A, 0x00},
++{0xD08B, 0x01},
++{0xD08C, 0xA8},
++{0xD08D, 0x84},
++{0xD08E, 0x01},
++{0xD08F, 0x04},
++{0xD090, 0xE1},
++{0xD091, 0x6B},
++{0xD092, 0x58},
++{0xD093, 0x00},
++{0xD094, 0x94},
++{0xD095, 0x6A},
++{0xD096, 0x00},
++{0xD097, 0x70},
++{0xD098, 0xE1},
++{0xD099, 0x6B},
++{0xD09A, 0x20},
++{0xD09B, 0x00},
++{0xD09C, 0x95},
++{0xD09D, 0x6B},
++{0xD09E, 0x00},
++{0xD09F, 0x00},
++{0xD0A0, 0xE4},
++{0xD0A1, 0x8B},
++{0xD0A2, 0x18},
++{0xD0A3, 0x00},
++{0xD0A4, 0x0C},
++{0xD0A5, 0x00},
++{0xD0A6, 0x00},
++{0xD0A7, 0x23},
++{0xD0A8, 0x15},
++{0xD0A9, 0x00},
++{0xD0AA, 0x00},
++{0xD0AB, 0x00},
++{0xD0AC, 0x18},
++{0xD0AD, 0x60},
++{0xD0AE, 0x80},
++{0xD0AF, 0x06},
++{0xD0B0, 0xA8},
++{0xD0B1, 0x83},
++{0xD0B2, 0x40},
++{0xD0B3, 0x08},
++{0xD0B4, 0xA8},
++{0xD0B5, 0xE3},
++{0xD0B6, 0x38},
++{0xD0B7, 0x2A},
++{0xD0B8, 0xA8},
++{0xD0B9, 0xC3},
++{0xD0BA, 0x40},
++{0xD0BB, 0x09},
++{0xD0BC, 0xA8},
++{0xD0BD, 0xA3},
++{0xD0BE, 0x38},
++{0xD0BF, 0x29},
++{0xD0C0, 0x8C},
++{0xD0C1, 0x65},
++{0xD0C2, 0x00},
++{0xD0C3, 0x00},
++{0xD0C4, 0xD8},
++{0xD0C5, 0x04},
++{0xD0C6, 0x18},
++{0xD0C7, 0x00},
++{0xD0C8, 0x8C},
++{0xD0C9, 0x67},
++{0xD0CA, 0x00},
++{0xD0CB, 0x00},
++{0xD0CC, 0xD8},
++{0xD0CD, 0x06},
++{0xD0CE, 0x18},
++{0xD0CF, 0x00},
++{0xD0D0, 0x18},
++{0xD0D1, 0x60},
++{0xD0D2, 0x80},
++{0xD0D3, 0x06},
++{0xD0D4, 0xA8},
++{0xD0D5, 0xE3},
++{0xD0D6, 0x67},
++{0xD0D7, 0x02},
++{0xD0D8, 0xA9},
++{0xD0D9, 0x03},
++{0xD0DA, 0x67},
++{0xD0DB, 0x03},
++{0xD0DC, 0xA8},
++{0xD0DD, 0xC3},
++{0xD0DE, 0x3D},
++{0xD0DF, 0x05},
++{0xD0E0, 0x8C},
++{0xD0E1, 0x66},
++{0xD0E2, 0x00},
++{0xD0E3, 0x00},
++{0xD0E4, 0xB8},
++{0xD0E5, 0x63},
++{0xD0E6, 0x00},
++{0xD0E7, 0x18},
++{0xD0E8, 0xB8},
++{0xD0E9, 0x63},
++{0xD0EA, 0x00},
++{0xD0EB, 0x98},
++{0xD0EC, 0xBC},
++{0xD0ED, 0x03},
++{0xD0EE, 0x00},
++{0xD0EF, 0x00},
++{0xD0F0, 0x10},
++{0xD0F1, 0x00},
++{0xD0F2, 0x00},
++{0xD0F3, 0x16},
++{0xD0F4, 0xB8},
++{0xD0F5, 0x83},
++{0xD0F6, 0x00},
++{0xD0F7, 0x19},
++{0xD0F8, 0x8C},
++{0xD0F9, 0x67},
++{0xD0FA, 0x00},
++{0xD0FB, 0x00},
++{0xD0FC, 0xB8},
++{0xD0FD, 0xA4},
++{0xD0FE, 0x00},
++{0xD0FF, 0x98},
++{0xD100, 0xB8},
++{0xD101, 0x83},
++{0xD102, 0x00},
++{0xD103, 0x08},
++{0xD104, 0x8C},
++{0xD105, 0x68},
++{0xD106, 0x00},
++{0xD107, 0x00},
++{0xD108, 0xE0},
++{0xD109, 0x63},
++{0xD10A, 0x20},
++{0xD10B, 0x04},
++{0xD10C, 0xE0},
++{0xD10D, 0x65},
++{0xD10E, 0x18},
++{0xD10F, 0x00},
++{0xD110, 0xA4},
++{0xD111, 0x83},
++{0xD112, 0xFF},
++{0xD113, 0xFF},
++{0xD114, 0xB8},
++{0xD115, 0x64},
++{0xD116, 0x00},
++{0xD117, 0x48},
++{0xD118, 0xD8},
++{0xD119, 0x07},
++{0xD11A, 0x18},
++{0xD11B, 0x00},
++{0xD11C, 0xD8},
++{0xD11D, 0x08},
++{0xD11E, 0x20},
++{0xD11F, 0x00},
++{0xD120, 0x9C},
++{0xD121, 0x60},
++{0xD122, 0x00},
++{0xD123, 0x00},
++{0xD124, 0xD8},
++{0xD125, 0x06},
++{0xD126, 0x18},
++{0xD127, 0x00},
++{0xD128, 0x00},
++{0xD129, 0x00},
++{0xD12A, 0x00},
++{0xD12B, 0x08},
++{0xD12C, 0x15},
++{0xD12D, 0x00},
++{0xD12E, 0x00},
++{0xD12F, 0x00},
++{0xD130, 0x8C},
++{0xD131, 0x6A},
++{0xD132, 0x00},
++{0xD133, 0x76},
++{0xD134, 0xBC},
++{0xD135, 0x23},
++{0xD136, 0x00},
++{0xD137, 0x00},
++{0xD138, 0x13},
++{0xD139, 0xFF},
++{0xD13A, 0xFF},
++{0xD13B, 0xE6},
++{0xD13C, 0x18},
++{0xD13D, 0x60},
++{0xD13E, 0x80},
++{0xD13F, 0x06},
++{0xD140, 0x03},
++{0xD141, 0xFF},
++{0xD142, 0xFF},
++{0xD143, 0xDD},
++{0xD144, 0xA8},
++{0xD145, 0x83},
++{0xD146, 0x40},
++{0xD147, 0x08},
++{0xD148, 0x85},
++{0xD149, 0x21},
++{0xD14A, 0x00},
++{0xD14B, 0x00},
++{0xD14C, 0x85},
++{0xD14D, 0x41},
++{0xD14E, 0x00},
++{0xD14F, 0x04},
++{0xD150, 0x44},
++{0xD151, 0x00},
++{0xD152, 0x48},
++{0xD153, 0x00},
++{0xD154, 0x9C},
++{0xD155, 0x21},
++{0xD156, 0x00},
++{0xD157, 0x08},
++{0x6F0E, 0x03},
++{0x6F0F, 0x00},
++{0x460E, 0x08},
++{0x460F, 0x01},
++{0x4610, 0x00},
++{0x4611, 0x01},
++{0x4612, 0x00},
++{0x4613, 0x01},
++{0x4605, 0x08}, // 8bit
++//{0x4709, 0x10}, // swap data bits order [9:0] -> [0:9]
++{0x4608, 0x00},
++{0x4609, 0x08},
++{0x6804, 0x00},
++{0x6805, 0x06},
++{0x6806, 0x00},
++{0x5120, 0x00},
++{0x3510, 0x00},
++{0x3504, 0x00},
++{0x6800, 0x00},
++{0x6F0D, 0x01},
++{0x4708, 0x01}, // PCLK rising edge
++{0x5000, 0xFF},
++{0x5001, 0xBF},
++{0x5002, 0x7E},
++#ifdef OV10635_DISPLAY_PATTERN
++{0x503d, 0x80},
++#else
++{0x503D, 0x00},
++#endif
++{0xC450, 0x01}, /* AA mode */
++{0xC452, 0x04},
++{0xC453, 0x00},
++{0xC454, 0x00},
++{0xC455, 0x01},
++{0xC456, 0x01},
++{0xC457, 0x00},
++{0xC458, 0x00},
++{0xC459, 0x00},
++{0xC45B, 0x00},
++{0xC45C, 0x01},
++{0xC45D, 0x00},
++{0xC45E, 0x00},
++{0xC45F, 0x00},
++{0xC460, 0x00},
++{0xC461, 0x01},
++{0xC462, 0x01},
++{0xC464, 0x03},
++{0xC465, 0x00},
++{0xC466, 0x8A},
++{0xC467, 0x00},
++{0xC468, 0x86},
++{0xC469, 0x00},
++{0xC46A, 0x30},
++{0xC46B, 0x50},
++{0xC46C, 0x30},
++{0xC46D, 0x28},
++{0xC46E, 0x60},
++{0xC46F, 0x40},
++{0xC47C, 0x01},
++{0xC47D, 0x38},
++{0xC47E, 0x00},
++{0xC47F, 0x00},
++{0xC480, 0x00},
++{0xC481, 0xFF},
++{0xC482, 0x00},
++{0xC483, 0x40},
++{0xC484, 0x00},
++{0xC485, 0x18},
++{0xC486, 0x00},
++{0xC487, 0x18},
++{0xC488, (OV10635_VTS-8)*16 >> 8},
++{0xC489, (OV10635_VTS-8)*16 & 0xff},
++{0xC48A, (OV10635_VTS-8)*16 >> 8},
++{0xC48B, (OV10635_VTS-8)*16 & 0xff},
++{0xC48C, 0x00},
++{0xC48D, 0x04},
++{0xC48E, 0x00},
++{0xC48F, 0x04},
++{0xC490, 0x03},
++{0xC492, 0x20},
++{0xC493, 0x08},
++{0xC498, 0x02},
++{0xC499, 0x00},
++{0xC49A, 0x02},
++{0xC49B, 0x00},
++{0xC49C, 0x02},
++{0xC49D, 0x00},
++{0xC49E, 0x02},
++{0xC49F, 0x60},
++{0xC4A0, 0x03},
++{0xC4A1, 0x00},
++{0xC4A2, 0x04},
++{0xC4A3, 0x00},
++{0xC4A4, 0x00},
++{0xC4A5, 0x10},
++{0xC4A6, 0x00},
++{0xC4A7, 0x40},
++{0xC4A8, 0x00},
++{0xC4A9, 0x80},
++{0xC4AA, 0x0D},
++{0xC4AB, 0x00},
++{0xC4AC, 0x0F},
++{0xC4AD, 0xC0},
++{0xC4B4, 0x01},
++{0xC4B5, 0x01},
++{0xC4B6, 0x00},
++{0xC4B7, 0x01},
++{0xC4B8, 0x00},
++{0xC4B9, 0x01},
++{0xC4BA, 0x01},
++{0xC4BB, 0x00},
++{0xC4BC, 0x01},
++{0xC4BD, 0x60},
++{0xC4BE, 0x02},
++{0xC4BF, 0x33},
++{0xC4C8, 0x03},
++{0xC4C9, 0xD0},
++{0xC4CA, 0x0E},
++{0xC4CB, 0x00},
++{0xC4CC, 0x0E},
++{0xC4CD, 0x51},
++{0xC4CE, 0x0E},
++{0xC4CF, 0x51},
++{0xC4D0, 0x04},
++{0xC4D1, 0x80},
++{0xC4E0, 0x04},
++{0xC4E1, 0x02},
++{0xC4E2, 0x01},
++{0xC4E4, 0x10},
++{0xC4E5, 0x20},
++{0xC4E6, 0x30},
++{0xC4E7, 0x40},
++{0xC4E8, 0x50},
++{0xC4E9, 0x60},
++{0xC4EA, 0x70},
++{0xC4EB, 0x80},
++{0xC4EC, 0x90},
++{0xC4ED, 0xA0},
++{0xC4EE, 0xB0},
++{0xC4EF, 0xC0},
++{0xC4F0, 0xD0},
++{0xC4F1, 0xE0},
++{0xC4F2, 0xF0},
++{0xC4F3, 0x80},
++{0xC4F4, 0x00},
++{0xC4F5, 0x20},
++{0xC4F6, 0x02},
++{0xC4F7, 0x00},
++{0xC4F8, 0x00},
++{0xC4F9, 0x00},
++{0xC4FA, 0x00},
++{0xC4FB, 0x01},
++{0xC4FC, 0x01},
++{0xC4FD, 0x00},
++{0xC4FE, 0x04},
++{0xC4FF, 0x02},
++{0xC500, 0x48},
++{0xC501, 0x74},
++{0xC502, 0x58},
++{0xC503, 0x80},
++{0xC504, 0x05},
++{0xC505, 0x80},
++{0xC506, 0x03},
++{0xC507, 0x80},
++{0xC508, 0x01},
++{0xC509, 0xC0},
++{0xC50A, 0x01},
++{0xC50B, 0xA0},
++{0xC50C, 0x01},
++{0xC50D, 0x2C},
++{0xC50E, 0x01},
++{0xC50F, 0x0A},
++{0xC510, 0x00},
++{0xC511, 0x00},
++{0xC512, 0xE5},
++{0xC513, 0x14},
++{0xC514, 0x04},
++{0xC515, 0x00},
++{0xC518, OV10635_VTS >> 8},
++{0xC519, OV10635_VTS & 0xff},
++{0xC51A, OV10635_HTS >> 8},
++{0xC51B, OV10635_HTS & 0xff},
++{0xC2E0, 0x00},
++{0xC2E1, 0x51},
++{0xC2E2, 0x00},
++{0xC2E3, 0xD6},
++{0xC2E4, 0x01},
++{0xC2E5, 0x5E},
++{0xC2E9, 0x01},
++{0xC2EA, 0x7A},
++{0xC2EB, 0x90},
++{0xC2ED, 0x00},
++{0xC2EE, 0x7A},
++{0xC2EF, 0x64},
++{0xC308, 0x00},
++{0xC309, 0x00},
++{0xC30A, 0x00},
++{0xC30C, 0x00},
++{0xC30D, 0x01},
++{0xC30E, 0x00},
++{0xC30F, 0x00},
++{0xC310, 0x01},
++{0xC311, 0x60},
++{0xC312, 0xFF},
++{0xC313, 0x08},
++{0xC314, 0x01},
++{0xC315, 0x00}, /* min saturation gain */
++{0xC316, 0xFF}, /* max saturation gain */
++{0xC317, 0x0B},
++{0xC318, 0x00},
++{0xC319, 0x0C},
++{0xC31A, 0x00},
++{0xC31B, 0xE0},
++{0xC31C, 0x00},
++{0xC31D, 0x14},
++{0xC31E, 0x00},
++{0xC31F, 0xC5},
++{0xC320, 0xFF},
++{0xC321, 0x4B},
++{0xC322, 0xFF},
++{0xC323, 0xF0},
++{0xC324, 0xFF},
++{0xC325, 0xE8},
++{0xC326, 0x00},
++{0xC327, 0x46},
++{0xC328, 0xFF},
++{0xC329, 0xD2},
++{0xC32A, 0xFF},
++{0xC32B, 0xE4},
++{0xC32C, 0xFF},
++{0xC32D, 0xBB},
++{0xC32E, 0x00},
++{0xC32F, 0x61},
++{0xC330, 0xFF},
++{0xC331, 0xF9},
++{0xC332, 0x00},
++{0xC333, 0xD9},
++{0xC334, 0x00},
++{0xC335, 0x2E},
++{0xC336, 0x00},
++{0xC337, 0xB1},
++{0xC338, 0xFF},
++{0xC339, 0x64},
++{0xC33A, 0xFF},
++{0xC33B, 0xEB},
++{0xC33C, 0xFF},
++{0xC33D, 0xE8},
++{0xC33E, 0x00},
++{0xC33F, 0x48},
++{0xC340, 0xFF},
++{0xC341, 0xD0},
++{0xC342, 0xFF},
++{0xC343, 0xED},
++{0xC344, 0xFF},
++{0xC345, 0xAD},
++{0xC346, 0x00},
++{0xC347, 0x66},
++{0xC348, 0x01},
++{0xC349, 0x00},
++{0x6700, 0x04},
++{0x6701, 0x7B},
++{0x6702, 0xFD},
++{0x6703, 0xF9},
++{0x6704, 0x3D},
++{0x6705, 0x71},
++{0x6706, 0x78},
++{0x6708, 0x05},
++{0x6F06, 0x6F},
++{0x6F07, 0x00},
++{0x6F0A, 0x6F},
++{0x6F0B, 0x00},
++{0x6F00, 0x03},
++{0xC34C, 0x01},
++{0xC34D, 0x00},
++{0xC34E, 0x46},
++{0xC34F, 0x55},
++{0xC350, 0x00},
++{0xC351, 0x40},
++{0xC352, 0x00},
++{0xC353, 0xFF},
++{0xC354, 0x04},
++{0xC355, 0x08},
++{0xC356, 0x01},
++{0xC357, 0xEF},
++{0xC358, 0x30},
++{0xC359, 0x01},
++{0xC35A, 0x64},
++{0xC35B, 0x46},
++{0xC35C, 0x00},
++{0x3042, 0xF0},
++{0x3042, 0xF0},
++{0x3042, 0xF0},
++{0x3042, 0xF0},
++{0x3042, 0xF0},
++{0x3042, 0xF0},
++{0x3042, 0xF0},
++{0x3042, 0xF0},
++{0x3042, 0xF0},
++{0x3042, 0xF0},
++{0x3042, 0xF0},
++{0x3042, 0xF0},
++{0x3042, 0xF0},
++{0x3042, 0xF0},
++{0x3042, 0xF0},
++{0x3042, 0xF0},
++{0x3042, 0xF0},
++{0x3042, 0xF0},
++{0x3042, 0xF0},
++{0x3042, 0xF0},
++{0x3042, 0xF0},
++{0x3042, 0xF0},
++{0x3042, 0xF0},
++{0x3042, 0xF0},
++{0x3042, 0xF0},
++{0x3042, 0xF0},
++{0xC261, 0x01},
++{0x301B, 0xF0},
++{0x301C, 0xF0},
++{0x301A, 0xF0},
++{0x6F00, 0xC3},
++{0xC46A, 0x30},
++{0xC46D, 0x20},
++{0xC464, 0x84},
++{0xC465, 0x00},
++{0x6F00, 0x03},
++{0x6F00, 0x43},
++{0x381C, 0x00},
++{0x381D, 0x40},
++{0xC454, 0x01},
++{0x6F00, 0xC3},
++{0xC454, 0x00},
++{0xC4B1, 0x02},
++{0xC4B2, 0x01},
++{0xC4B3, 0x03},
++{0x6F00, 0x03},
++{0x6F00, 0x43},
++/* enable FSIN (FRAMESYNC input) functionality */
++{0x3832, (0x0d+2*0x20+0x15+38) >> 8},
++{0x3833, (0x0d+2*0x20+0x15+38) & 0xff},
++{0x3834, OV10635_VTS >> 8},
++{0x3835, OV10635_VTS & 0xff},
++{0x302E, 0x01},
++};
++
++static const struct ov10635_reg ov10635_regs_30fps[] = {
++/* disable clocks */
++{0x301b, 0xff},
++{0x301c, 0xff},
++{0x301a, 0xff},
++/* clk = 24Mhz/2*32/2(1+1)=96Mhz, 30fps */
++{0x3003, 0x20},
++{0x3004, 0x21},
++/* enable clocks */
++{0x301b, 0xf0},
++{0x301c, 0xf0},
++{0x301a, 0xf0},
++};
++
++static const struct ov10635_reg ov10635_regs_15fps[] = {
++/* disable clocks */
++{0x301b, 0xff},
++{0x301c, 0xff},
++{0x301a, 0xff},
++/* clk = 24Mhz/2*32/2(1+3)=48Mhz, 15fps */
++{0x3003, 0x20},
++{0x3004, 0x23},
++/* enable clocks */
++{0x301b, 0xf0},
++{0x301c, 0xf0},
++{0x301a, 0xf0},
++};
++
++static const struct ov10635_reg ov10635_regs_10fps[] = {
++/* disable clocks */
++{0x301b, 0xff},
++{0x301c, 0xff},
++{0x301a, 0xff},
++/* clk = 24Mhz/2*32/2(1+5)=32Mhz, 10fps */
++{0x3003, 0x20},
++{0x3004, 0x25},
++/* enable clocks */
++{0x301b, 0xf0},
++{0x301c, 0xf0},
++{0x301a, 0xf0},
++};
++
++static const struct ov10635_reg ov10635_regs_5fps[] = {
++/* disable clocks */
++{0x301b, 0xff},
++{0x301c, 0xff},
++{0x301a, 0xff},
++/* clk = 24Mhz/4*32/2(1+5)=96Mhz, 5fps */
++{0x3003, 0x20},
++{0x3004, 0x45},
++/* enable clocks */
++{0x301b, 0xf0},
++{0x301c, 0xf0},
++{0x301a, 0xf0},
++};
++
++static const struct ov10635_reg ov10635_regs_contrast[5][18] = {
++{
++ {0x6f00, 0xc3},
++ {0xc4e4, 0x20},
++ {0xc4e5, 0x40},
++ {0xc4e6, 0x60},
++ {0xc4e7, 0x80},
++ {0xc4e8, 0xa0},
++ {0xc4e9, 0xb4},
++ {0xc4ea, 0xc0},
++ {0xc4eb, 0xcb},
++ {0xc4ec, 0xd5},
++ {0xc4ed, 0xde},
++ {0xc4ee, 0xe6},
++ {0xc4ef, 0xed},
++ {0xc4f0, 0xf3},
++ {0xc4f1, 0xf8},
++ {0xc4f2, 0xfc},
++ {0x6f00, 0x03},
++ {0x6f00, 0x43},
++}, {
++ {0x6f00, 0xc3},
++ {0xc4e4, 0x18},
++ {0xc4e5, 0x30},
++ {0xc4e6, 0x48},
++ {0xc4e7, 0x60},
++ {0xc4e8, 0x78},
++ {0xc4e9, 0x90},
++ {0xc4ea, 0xa4},
++ {0xc4eb, 0xb4},
++ {0xc4ec, 0xc2},
++ {0xc4ed, 0xcf},
++ {0xc4ee, 0xdb},
++ {0xc4ef, 0xe5},
++ {0xc4f0, 0xee},
++ {0xc4f1, 0xf6},
++ {0xc4f2, 0xfc},
++ {0x6f00, 0x03},
++ {0x6f00, 0x43},
++}, {
++ {0x6f00, 0xc3},
++ {0xc4e4, 0x10},
++ {0xc4e5, 0x20},
++ {0xc4e6, 0x30},
++ {0xc4e7, 0x40},
++ {0xc4e8, 0x50},
++ {0xc4e9, 0x60},
++ {0xc4ea, 0x70},
++ {0xc4eb, 0x80},
++ {0xc4ec, 0x90},
++ {0xc4ed, 0xa0},
++ {0xc4ee, 0xb0},
++ {0xc4ef, 0xc0},
++ {0xc4f0, 0xd0},
++ {0xc4f1, 0xe0},
++ {0xc4f2, 0xf0},
++ {0x6f00, 0x03},
++ {0x6f00, 0x43},
++}, {
++ {0x6f00, 0xc3},
++ {0xc4e4, 0x0c},
++ {0xc4e5, 0x18},
++ {0xc4e6, 0x24},
++ {0xc4e7, 0x30},
++ {0xc4e8, 0x3c},
++ {0xc4e9, 0x48},
++ {0xc4ea, 0x54},
++ {0xc4eb, 0x62},
++ {0xc4ec, 0x72},
++ {0xc4ed, 0x84},
++ {0xc4ee, 0x94},
++ {0xc4ef, 0xa6},
++ {0xc4f0, 0xb9},
++ {0xc4f1, 0xcd},
++ {0xc4f2, 0xe2},
++ {0x6f00, 0x03},
++ {0x6f00, 0x43},
++}, {
++ {0x6f00, 0xc3},
++ {0xc4e4, 0x06},
++ {0xc4e5, 0x0d},
++ {0xc4e6, 0x15},
++ {0xc4e7, 0x1e},
++ {0xc4e8, 0x28},
++ {0xc4e9, 0x32},
++ {0xc4ea, 0x3c},
++ {0xc4eb, 0x48},
++ {0xc4ec, 0x56},
++ {0xc4ed, 0x66},
++ {0xc4ee, 0x78},
++ {0xc4ef, 0x8c},
++ {0xc4f0, 0xa2},
++ {0xc4f1, 0xba},
++ {0xc4f2, 0xd4},
++ {0x6f00, 0x03},
++ {0x6f00, 0x43},
++}
++};
+diff --git a/drivers/media/i2c/soc_camera/ov10635_debug.h b/drivers/media/i2c/soc_camera/ov10635_debug.h
+new file mode 100644
+index 0000000..4c3515a
+--- /dev/null
++++ b/drivers/media/i2c/soc_camera/ov10635_debug.h
+@@ -0,0 +1,54 @@
++
++#if 0
++{0x4700, 0x02}, // BT656
++{0x381d, 0x40}, // mirror off
++{0x381c, 0x00}, // flip off
++{0x4300, 0x3a}, // YUV: UYVY
++{0x4708, 0x00}, // PCLK rising edge
++
++// clk = 24Mhz/3*22/2= 88Mhz
++{0x3003, 0x16},
++{0x3004, 0x30},
++#endif
++
++#define WIDTH 1280
++#define HEIGHT 720
++
++// DVP frame size
++{0x3808, WIDTH >> 8},
++{0x3809, WIDTH & 0xff},
++{0x380a, HEIGHT >> 8},
++{0x380b, HEIGHT & 0xff},
++
++{0x3802, ((814 - HEIGHT)/2) >> 8}, // vert crop start
++{0x3803, ((814 - HEIGHT)/2) & 0xff},
++{0x3806, ((814 - HEIGHT)/2 + HEIGHT + 1) >> 8}, // vert crop end
++{0x3807, ((814 - HEIGHT)/2 + HEIGHT + 1) & 0xff},
++
++#if 0
++#define HTS 0x6f6 // got from above table 1782
++#define VTS (0x2ec+80) // got from above table 748 + 80
++
++{0x380c, HTS >> 8}, // hts
++{0x380d, HTS & 0xff},
++{0x380e, VTS >> 8}, // vts
++{0x380f, VTS & 0xff},
++
++// fifo
++{0x4606, (2*HTS) >> 8}, // fifo_line_length = 2*hts
++{0x4607, (2*HTS) & 0xff},
++{0x460a, (2*(HTS-1280)) >> 8}, // fifo_hsync_start = 2*(hts - xres)
++{0x460b, (2*(HTS-1280)) & 0xff },
++
++// exposure
++{0xC488, (VTS-8)*16 >> 8},
++{0xC489, (VTS-8)*16 & 0xff},
++{0xC48A, (VTS-8)*16 >> 8},
++{0xC48B, (VTS-8)*16 & 0xff},
++
++// vts/hts
++{0xC518, VTS >> 8},
++{0xC519, VTS & 0xff},
++{0xC51A, HTS >> 8},
++{0xC51B, HTS & 0xff},
++#endif
+diff --git a/drivers/media/i2c/soc_camera/ov106xx.c b/drivers/media/i2c/soc_camera/ov106xx.c
+new file mode 100644
+index 0000000..f2bb706
+--- /dev/null
++++ b/drivers/media/i2c/soc_camera/ov106xx.c
+@@ -0,0 +1,106 @@
++/*
++ * OmniVision ov10635/ov490-ov10640/ov495-ov2775 sensor camera driver
++ *
++ * Copyright (C) 2016-2017 Cogent Embedded, Inc.
++ *
++ * This program is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License as published by the
++ * Free Software Foundation; either version 2 of the License, or (at your
++ * option) any later version.
++ */
++
++#include "ov10635.c"
++#include "ov490_ov10640.c"
++#include "ov495_ov2775.c"
++#include "ar0132.c"
++
++static enum {
++ ID_OV10635,
++ ID_OV490_OV10640,
++ ID_OV495_OV2775,
++ ID_AR0132,
++} chip_id;
++
++static int ov106xx_probe(struct i2c_client *client,
++ const struct i2c_device_id *did)
++{
++ int ret;
++ chip_id = -EINVAL;
++
++ ret = ov10635_probe(client, did);
++ if (!ret) {
++ chip_id = ID_OV10635;
++ goto out;
++ }
++
++ ret = ov490_probe(client, did);
++ if (!ret) {
++ chip_id = ID_OV490_OV10640;
++ goto out;
++ }
++
++ ret = ov495_probe(client, did);
++ if (!ret) {
++ chip_id = ID_OV495_OV2775;
++ goto out;
++ }
++
++ ret = ar0132_probe(client, did);
++ if (!ret) {
++ chip_id = ID_AR0132;
++ goto out;
++ }
++
++ v4l_err(client, "failed to probe @ 0x%02x (%s)\n",
++ client->addr, client->adapter->name);
++out:
++ return ret;
++}
++
++static int ov106xx_remove(struct i2c_client *client)
++{
++ switch (chip_id) {
++ case ID_OV10635:
++ ov10635_remove(client);
++ break;
++ case ID_OV490_OV10640:
++ ov490_remove(client);
++ break;
++ case ID_OV495_OV2775:
++ ov495_remove(client);
++ break;
++ case ID_AR0132:
++ ar0132_remove(client);
++ break;
++ };
++
++ return 0;
++}
++
++static const struct i2c_device_id ov106xx_id[] = {
++ { "ov106xx", 0 },
++ { }
++};
++MODULE_DEVICE_TABLE(i2c, ov106xx_id);
++
++static const struct of_device_id ov106xx_of_ids[] = {
++ { .compatible = "ovti,ov106xx", },
++ { }
++};
++MODULE_DEVICE_TABLE(of, ov106xx_of_ids);
++
++static struct i2c_driver ov106xx_i2c_driver = {
++ .driver = {
++ .name = "ov106xx",
++ .of_match_table = ov106xx_of_ids,
++ },
++ .probe = ov106xx_probe,
++ .remove = ov106xx_remove,
++ .id_table = ov106xx_id,
++};
++
++module_i2c_driver(ov106xx_i2c_driver);
++
++MODULE_DESCRIPTION("SoC Camera driver for OV10635 or OV490/OV10640 or OV495/OV2775 or AR0132");
++MODULE_AUTHOR("Vladimir Barinov");
++MODULE_LICENSE("GPL");
+diff --git a/drivers/media/i2c/soc_camera/ov490_ov10640.c b/drivers/media/i2c/soc_camera/ov490_ov10640.c
+new file mode 100644
+index 0000000..15acc51
+--- /dev/null
++++ b/drivers/media/i2c/soc_camera/ov490_ov10640.c
+@@ -0,0 +1,1046 @@
++/*
++ * OmniVision ov490-ov10640 sensor camera driver
++ *
++ * Copyright (C) 2016-2017 Cogent Embedded, Inc.
++ *
++ * This program is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License as published by the
++ * Free Software Foundation; either version 2 of the License, or (at your
++ * option) any later version.
++ */
++
++#include <linux/delay.h>
++#include <linux/init.h>
++#include <linux/i2c.h>
++#include <linux/module.h>
++#include <linux/videodev2.h>
++
++#include <media/soc_camera.h>
++#include <media/v4l2-common.h>
++#include <media/v4l2-ctrls.h>
++#include <media/v4l2-of.h>
++
++#include "max9286_max9271.h"
++#include "ov490_ov10640.h"
++
++#define OV490_I2C_ADDR 0x24
++
++#define OV490_PID 0x300a
++#define OV490_VER 0x300b
++#define OV490_VERSION_REG 0x0490
++#define OV490_VERSION(pid, ver) (((pid) << 8) | ((ver) & 0xff))
++
++#define OV490_ISP_HSIZE_LOW 0x60
++#define OV490_ISP_HSIZE_HIGH 0x61
++#define OV490_ISP_VSIZE_LOW 0x62
++#define OV490_ISP_VSIZE_HIGH 0x63
++
++struct ov490_priv {
++ struct v4l2_subdev sd;
++ struct v4l2_ctrl_handler hdl;
++ struct media_pad pad;
++ struct v4l2_rect rect;
++ int max_width;
++ int max_height;
++ char is_fixed_sensor;
++ int init_complete;
++ u8 id[6];
++ int exposure;
++ int gain;
++ int autogain;
++ int dvp_order;
++ /* serializers */
++ int max9286_addr;
++ int max9271_addr;
++ int ti964_addr;
++ int ti954_addr;
++ int ti9x3_addr;
++ int port;
++ int gpio_resetb;
++ int active_low_resetb;
++ int gpio_fsin;
++};
++
++static int force_conf_link;
++
++static __init int ov490_force_conf_link(char *str)
++{
++ /* force configuration link */
++ /* used only if robust firmware flashing required (f.e. recovery) */
++ force_conf_link = 1;
++ return 0;
++}
++early_param("force_conf_link", ov490_force_conf_link);
++
++static inline struct ov490_priv *to_ov490(const struct i2c_client *client)
++{
++ return container_of(i2c_get_clientdata(client), struct ov490_priv, sd);
++}
++
++static void ov490_s_port(struct i2c_client *client, int fwd_en)
++{
++ struct ov490_priv *priv = to_ov490(client);
++ int tmp_addr;
++
++ if (priv->max9286_addr) {
++ tmp_addr = client->addr;
++ client->addr = priv->max9286_addr; /* Deserializer I2C address */
++ reg8_write(client, 0x0a, fwd_en ? 0x11 << priv->port : 0); /* Enable/disable reverse/forward control for this port */
++ usleep_range(2000, 2500); /* wait 2ms */
++ client->addr = tmp_addr;
++ };
++}
++
++static void ov490_reset(struct i2c_client *client)
++{
++ struct ov490_priv *priv = to_ov490(client);
++ int tmp_addr;
++
++ if (priv->max9286_addr) {
++ if (priv->gpio_resetb < 1 || priv->gpio_resetb > 5)
++ return;
++
++ tmp_addr = client->addr;
++ /* get out from sensor reset */
++ client->addr = priv->max9271_addr; /* MAX9271 I2C address */
++ reg8_write(client, 0x0f, (0xfe & ~BIT(priv->gpio_resetb)) |
++ (priv->active_low_resetb ? 0 : BIT(priv->gpio_resetb))); /* set GPIOn value to reset */
++ usleep_range(2000, 2500); /* wait 2ms */
++ reg8_write(client, 0x0f, (0xfe & ~BIT(priv->gpio_resetb)) |
++ (priv->active_low_resetb ? BIT(priv->gpio_resetb) : 0)); /* set GPIOn value to un-reset */
++ usleep_range(2000, 2500); /* wait 2ms */
++ client->addr = tmp_addr;
++ }
++
++ if (priv->ti964_addr) {
++ client->addr = priv->ti964_addr; /* TI964 I2C address */
++
++ reg8_write(client, 0x4c, (priv->port << 4) | (1 << priv->port)); /* Select RX port number */
++ usleep_range(2000, 2500); /* wait 2ms */
++ reg8_write(client, 0x6e, 0x8a); /* set GPIO1 value to reset */
++ usleep_range(2000, 2500); /* wait 2ms */
++ reg8_write(client, 0x6e, 0x9a); /* set GPIO1 value to un-reset */
++ }
++
++ if (priv->ti954_addr) {
++ client->addr = priv->ti954_addr; /* TI964 I2C address */
++
++ reg8_write(client, 0x4c, (priv->port << 4) | (1 << priv->port)); /* Select RX port number */
++ usleep_range(2000, 2500); /* wait 2ms */
++ reg8_write(client, 0x6e, 0x8a); /* set GPIO1 value to reset */
++ usleep_range(2000, 2500); /* wait 2ms */
++ reg8_write(client, 0x6e, 0x9a); /* set GPIO1 value to un-reset */
++ }
++}
++
++static int ov490_set_regs(struct i2c_client *client,
++ const struct ov490_reg *regs, int nr_regs)
++{
++ int i;
++
++ for (i = 0; i < nr_regs; i++) {
++ if (reg16_write(client, regs[i].reg, regs[i].val)) {
++ usleep_range(100, 150); /* wait 100 us */
++ reg16_write(client, regs[i].reg, regs[i].val);
++ }
++ }
++
++ return 0;
++}
++
++static int ov490_s_stream(struct v4l2_subdev *sd, int enable)
++{
++ return 0;
++}
++
++static int ov490_get_fmt(struct v4l2_subdev *sd,
++ struct v4l2_subdev_pad_config *cfg,
++ struct v4l2_subdev_format *format)
++{
++ struct v4l2_mbus_framefmt *mf = &format->format;
++ struct i2c_client *client = v4l2_get_subdevdata(sd);
++ struct ov490_priv *priv = to_ov490(client);
++
++ if (format->pad)
++ return -EINVAL;
++
++ mf->width = priv->rect.width;
++ mf->height = priv->rect.height;
++ mf->code = MEDIA_BUS_FMT_YUYV8_2X8;
++ mf->colorspace = V4L2_COLORSPACE_SMPTE170M;
++ mf->field = V4L2_FIELD_NONE;
++
++ return 0;
++}
++
++static int ov490_set_fmt(struct v4l2_subdev *sd,
++ struct v4l2_subdev_pad_config *cfg,
++ struct v4l2_subdev_format *format)
++{
++ struct v4l2_mbus_framefmt *mf = &format->format;
++
++ mf->code = MEDIA_BUS_FMT_YUYV8_2X8;
++ mf->colorspace = V4L2_COLORSPACE_SMPTE170M;
++ mf->field = V4L2_FIELD_NONE;
++
++ if (format->which == V4L2_SUBDEV_FORMAT_TRY)
++ cfg->try_fmt = *mf;
++
++ return 0;
++}
++
++static int ov490_enum_mbus_code(struct v4l2_subdev *sd,
++ struct v4l2_subdev_pad_config *cfg,
++ struct v4l2_subdev_mbus_code_enum *code)
++{
++ if (code->pad || code->index > 0)
++ return -EINVAL;
++
++ code->code = MEDIA_BUS_FMT_YUYV8_2X8;
++
++ return 0;
++}
++
++static int ov490_get_edid(struct v4l2_subdev *sd, struct v4l2_edid *edid)
++{
++ struct i2c_client *client = v4l2_get_subdevdata(sd);
++ struct ov490_priv *priv = to_ov490(client);
++
++ memcpy(edid->edid, priv->id, 6);
++
++ edid->edid[6] = 0xff;
++ edid->edid[7] = client->addr;
++ edid->edid[8] = OV490_VERSION_REG >> 8;
++ edid->edid[9] = OV490_VERSION_REG & 0xff;
++
++ return 0;
++}
++
++static int ov490_set_selection(struct v4l2_subdev *sd,
++ struct v4l2_subdev_pad_config *cfg,
++ struct v4l2_subdev_selection *sel)
++{
++ struct v4l2_rect *rect = &sel->r;
++ struct i2c_client *client = v4l2_get_subdevdata(sd);
++ struct ov490_priv *priv = to_ov490(client);
++
++ if (sel->which != V4L2_SUBDEV_FORMAT_ACTIVE ||
++ sel->target != V4L2_SEL_TGT_CROP)
++ return -EINVAL;
++
++ rect->left = ALIGN(rect->left, 2);
++ rect->top = ALIGN(rect->top, 2);
++ rect->width = ALIGN(rect->width, 2);
++ rect->height = ALIGN(rect->height, 2);
++
++ if ((rect->left + rect->width > priv->max_width) ||
++ (rect->top + rect->height > priv->max_height))
++ *rect = priv->rect;
++
++ priv->rect.left = rect->left;
++ priv->rect.top = rect->top;
++ priv->rect.width = rect->width;
++ priv->rect.height = rect->height;
++
++ return 0;
++}
++
++static int ov490_get_selection(struct v4l2_subdev *sd,
++ struct v4l2_subdev_pad_config *cfg,
++ struct v4l2_subdev_selection *sel)
++{
++ struct i2c_client *client = v4l2_get_subdevdata(sd);
++ struct ov490_priv *priv = to_ov490(client);
++
++ if (sel->which != V4L2_SUBDEV_FORMAT_ACTIVE)
++ return -EINVAL;
++
++ switch (sel->target) {
++ case V4L2_SEL_TGT_CROP_BOUNDS:
++ sel->r.left = 0;
++ sel->r.top = 0;
++ sel->r.width = priv->max_width;
++ sel->r.height = priv->max_height;
++ return 0;
++ case V4L2_SEL_TGT_CROP_DEFAULT:
++ sel->r.left = 0;
++ sel->r.top = 0;
++ sel->r.width = priv->max_width;
++ sel->r.height = priv->max_height;
++ return 0;
++ case V4L2_SEL_TGT_CROP:
++ sel->r = priv->rect;
++ return 0;
++ default:
++ return -EINVAL;
++ }
++}
++
++static int ov490_g_mbus_config(struct v4l2_subdev *sd,
++ struct v4l2_mbus_config *cfg)
++{
++ cfg->flags = V4L2_MBUS_CSI2_1_LANE | V4L2_MBUS_CSI2_CHANNEL_0 |
++ V4L2_MBUS_CSI2_CONTINUOUS_CLOCK;
++ cfg->type = V4L2_MBUS_CSI2;
++
++ return 0;
++}
++
++#ifdef CONFIG_VIDEO_ADV_DEBUG
++static int ov490_g_register(struct v4l2_subdev *sd,
++ struct v4l2_dbg_register *reg)
++{
++ struct i2c_client *client = v4l2_get_subdevdata(sd);
++ int ret;
++ u8 val = 0;
++
++ ret = reg16_read(client, (u16)reg->reg, &val);
++ if (ret < 0)
++ return ret;
++
++ reg->val = val;
++ reg->size = sizeof(u16);
++
++ return 0;
++}
++
++static int ov490_s_register(struct v4l2_subdev *sd,
++ const struct v4l2_dbg_register *reg)
++{
++ struct i2c_client *client = v4l2_get_subdevdata(sd);
++ int ret;
++
++ ret = reg16_write(client, (u16)reg->reg, (u8)reg->val);
++ if ((u8)reg->reg == 0xFFFD)
++ usleep_range(100, 150); /* wait 100 us */
++ if ((u8)reg->reg == 0xFFFE)
++ usleep_range(100, 150); /* wait 100 us */
++ return ret;
++}
++#endif
++
++static struct v4l2_subdev_core_ops ov490_core_ops = {
++#ifdef CONFIG_VIDEO_ADV_DEBUG
++ .g_register = ov490_g_register,
++ .s_register = ov490_s_register,
++#endif
++};
++
++static int ov490_s_gamma(int a, int ref)
++{
++ if ((a + ref) > 0xff)
++ return 0xff;
++
++ if ((a + ref) < 0)
++ return 0;
++
++ return a + ref;
++}
++
++static int ov490_s_ctrl(struct v4l2_ctrl *ctrl)
++{
++ struct v4l2_subdev *sd = to_sd(ctrl);
++ struct i2c_client *client = v4l2_get_subdevdata(sd);
++ struct ov490_priv *priv = to_ov490(client);
++ int ret = -EINVAL;
++
++ if (!priv->init_complete)
++ return 0;
++
++ switch (ctrl->id) {
++ case V4L2_CID_BRIGHTNESS:
++ /* SDE (rough) brightness */
++ ret = reg16_write(client, 0xFFFD, 0x80);
++ ret |= reg16_write(client, 0xFFFE, 0x19);
++ usleep_range(100, 150); /* wait 100 us */
++ ret |= reg16_write(client, 0x5000, 0x00);
++ ret |= reg16_write(client, 0x5001, ctrl->val);
++ ret |= reg16_write(client, 0xFFFE, 0x80);
++ usleep_range(100, 150); /* wait 100 us */
++ ret |= reg16_write(client, 0x00C0, 0xf1);
++ break;
++ case V4L2_CID_CONTRAST:
++ ret = reg16_write(client, 0xFFFD, 0x80);
++ ret |= reg16_write(client, 0xFFFE, 0x19);
++ usleep_range(100, 150); /* wait 100 us */
++ ret |= reg16_write(client, 0x5000, ctrl->val);
++ ret |= reg16_write(client, 0xFFFE, 0x80);
++ usleep_range(100, 150); /* wait 100 us */
++ ret |= reg16_write(client, 0x00C0, 0xfd);
++ break;
++ case V4L2_CID_SATURATION:
++ ret = reg16_write(client, 0xFFFD, 0x80);
++ ret |= reg16_write(client, 0xFFFE, 0x19);
++ usleep_range(100, 150); /* wait 100 us */
++ ret |= reg16_write(client, 0x5000, ctrl->val);
++ ret |= reg16_write(client, 0xFFFE, 0x80);
++ usleep_range(100, 150); /* wait 100 us */
++ ret |= reg16_write(client, 0x00C0, 0xf3);
++ break;
++ case V4L2_CID_HUE:
++ ret = reg16_write(client, 0xFFFD, 0x80);
++ ret |= reg16_write(client, 0xFFFE, 0x19);
++ usleep_range(100, 150); /* wait 100 us */
++ ret |= reg16_write(client, 0x5000, ctrl->val);
++ ret |= reg16_write(client, 0xFFFE, 0x80);
++ usleep_range(100, 150); /* wait 100 us */
++ ret |= reg16_write(client, 0x00C0, 0xf5);
++ break;
++ case V4L2_CID_GAMMA:
++ ret = reg16_write(client, 0xFFFD, 0x80);
++ ret |= reg16_write(client, 0xFFFE, 0x19);
++ usleep_range(100, 150); /* wait 100 us */
++ ret |= reg16_write(client, 0x5000, ov490_s_gamma(ctrl->val, 0x12));
++ ret |= reg16_write(client, 0x5001, ov490_s_gamma(ctrl->val, 0x20));
++ ret |= reg16_write(client, 0x5002, ov490_s_gamma(ctrl->val, 0x3b));
++ ret |= reg16_write(client, 0x5003, ov490_s_gamma(ctrl->val, 0x5d));
++ ret |= reg16_write(client, 0x5004, ov490_s_gamma(ctrl->val, 0x6a));
++ ret |= reg16_write(client, 0x5005, ov490_s_gamma(ctrl->val, 0x76));
++ ret |= reg16_write(client, 0x5006, ov490_s_gamma(ctrl->val, 0x81));
++ ret |= reg16_write(client, 0x5007, ov490_s_gamma(ctrl->val, 0x8b));
++ ret |= reg16_write(client, 0x5008, ov490_s_gamma(ctrl->val, 0x96));
++ ret |= reg16_write(client, 0x5009, ov490_s_gamma(ctrl->val, 0x9e));
++ ret |= reg16_write(client, 0x500a, ov490_s_gamma(ctrl->val, 0xae));
++ ret |= reg16_write(client, 0x500b, ov490_s_gamma(ctrl->val, 0xbc));
++ ret |= reg16_write(client, 0x500c, ov490_s_gamma(ctrl->val, 0xcf));
++ ret |= reg16_write(client, 0x500d, ov490_s_gamma(ctrl->val, 0xde));
++ ret |= reg16_write(client, 0x500e, ov490_s_gamma(ctrl->val, 0xec));
++ ret |= reg16_write(client, 0xFFFE, 0x80);
++ usleep_range(100, 150); /* wait 100 us */
++ ret |= reg16_write(client, 0x00C0, 0xf9);
++ break;
++ case V4L2_CID_SHARPNESS:
++ ret = reg16_write(client, 0xFFFD, 0x80);
++ ret |= reg16_write(client, 0xFFFE, 0x19);
++ usleep_range(100, 150); /* wait 100 us */
++ ret |= reg16_write(client, 0x5000, ctrl->val);
++ ret |= reg16_write(client, 0xFFFE, 0x80);
++ usleep_range(100, 150); /* wait 100 us */
++ ret |= reg16_write(client, 0x00C0, 0xfb);
++ break;
++ case V4L2_CID_AUTOGAIN:
++ case V4L2_CID_GAIN:
++ case V4L2_CID_EXPOSURE:
++ if (ctrl->id == V4L2_CID_AUTOGAIN)
++ priv->autogain = ctrl->val;
++ if (ctrl->id == V4L2_CID_GAIN)
++ priv->gain = ctrl->val;
++ if (ctrl->id == V4L2_CID_EXPOSURE)
++ priv->exposure = ctrl->val;
++
++ ret = reg16_write(client, 0xFFFD, 0x80);
++ ret |= reg16_write(client, 0xFFFE, 0x19);
++ usleep_range(100, 150); /* wait 100 us */
++ ret |= reg16_write(client, 0x5000, !priv->autogain);
++ ret |= reg16_write(client, 0x5001, priv->exposure >> 8);
++ ret |= reg16_write(client, 0x5002, priv->exposure & 0xff);
++ ret |= reg16_write(client, 0x5003, priv->exposure >> 8);
++ ret |= reg16_write(client, 0x5004, priv->exposure & 0xff);
++ ret |= reg16_write(client, 0x5005, priv->exposure >> 8);
++ ret |= reg16_write(client, 0x5006, priv->exposure & 0xff);
++ ret |= reg16_write(client, 0x5007, priv->gain >> 8);
++ ret |= reg16_write(client, 0x5008, priv->gain & 0xff);
++ ret |= reg16_write(client, 0x5009, priv->gain >> 8);
++ ret |= reg16_write(client, 0x500a, priv->gain & 0xff);
++ ret |= reg16_write(client, 0x500b, priv->gain >> 8);
++ ret |= reg16_write(client, 0x500c, priv->gain & 0xff);
++ ret |= reg16_write(client, 0xFFFE, 0x80);
++ usleep_range(100, 150); /* wait 100 us */
++ ret |= reg16_write(client, 0x00C0, 0xea);
++ break;
++ case V4L2_CID_HFLIP:
++#if 1
++ ret = reg16_write(client, 0xFFFD, 0x80);
++ ret |= reg16_write(client, 0xFFFE, 0x19);
++ usleep_range(100, 150); /* wait 100 us */
++ ret |= reg16_write(client, 0x5000, ctrl->val);
++ ret |= reg16_write(client, 0x5001, 0x00);
++ ret |= reg16_write(client, 0xFFFE, 0x80);
++ usleep_range(100, 150); /* wait 100 us */
++ ret |= reg16_write(client, 0x00C0, 0xdc);
++#else
++ ret = reg16_write(client, 0xFFFD, 0x80);
++ ret |= reg16_write(client, 0xFFFE, 0x19);
++ usleep_range(100, 150); /* wait 100 us */
++ ret |= reg16_write(client, 0x5000, 0x01); // read 0x3128
++ ret |= reg16_write(client, 0x5001, 0x31);
++ ret |= reg16_write(client, 0x5002, 0x28);
++ ret |= reg16_write(client, 0xFFFE, 0x80);
++ usleep_range(100, 150); /* wait 100 us */
++ ret |= reg16_write(client, 0x00C0, 0xc1);
++ ret |= reg16_write(client, 0xFFFE, 0x19);
++ usleep_range(100, 150); /* wait 100 us */
++ ret |= reg16_read(client, 0x5000, &val);
++ val &= ~(0x1 << 0);
++ val |= (ctrl->val << 0);
++ ret |= reg16_write(client, 0xFFFE, 0x19);
++ usleep_range(100, 150); /* wait 100 us */
++ ret |= reg16_write(client, 0x5000, 0x00); // write 0x3128
++ ret |= reg16_write(client, 0x5001, 0x31);
++ ret |= reg16_write(client, 0x5002, 0x28);
++ ret |= reg16_write(client, 0x5003, val);
++ ret |= reg16_write(client, 0xFFFE, 0x80);
++ usleep_range(100, 150); /* wait 100 us */
++ ret |= reg16_write(client, 0x00C0, 0xc1);
++
++ ret |= reg16_write(client, 0xFFFE, 0x19);
++ usleep_range(100, 150); /* wait 100 us */
++ ret |= reg16_write(client, 0x5000, 0x01); // read 0x3291
++ ret |= reg16_write(client, 0x5001, 0x32);
++ ret |= reg16_write(client, 0x5002, 0x91);
++ ret |= reg16_write(client, 0xFFFE, 0x80);
++ usleep_range(100, 150); /* wait 100 us */
++ ret |= reg16_write(client, 0x00C0, 0xc1);
++ ret |= reg16_write(client, 0xFFFE, 0x19);
++ usleep_range(100, 150); /* wait 100 us */
++ ret |= reg16_read(client, 0x5000, &val);
++ val &= ~(0x1 << 1);
++ val |= (ctrl->val << 1);
++ ret |= reg16_write(client, 0xFFFE, 0x19);
++ usleep_range(100, 150); /* wait 100 us */
++ ret |= reg16_write(client, 0x5000, 0x00); // write 0x3291
++ ret |= reg16_write(client, 0x5001, 0x32);
++ ret |= reg16_write(client, 0x5002, 0x91);
++ ret |= reg16_write(client, 0x5003, val);
++ ret |= reg16_write(client, 0xFFFE, 0x80);
++ usleep_range(100, 150); /* wait 100 us */
++ ret |= reg16_write(client, 0x00C0, 0xc1);
++
++ ret |= reg16_write(client, 0xFFFE, 0x19);
++ usleep_range(100, 150); /* wait 100 us */
++ ret |= reg16_write(client, 0x5000, 0x01); // read 0x3090
++ ret |= reg16_write(client, 0x5001, 0x30);
++ ret |= reg16_write(client, 0x5002, 0x90);
++ ret |= reg16_write(client, 0xFFFE, 0x80);
++ usleep_range(100, 150); /* wait 100 us */
++ ret |= reg16_write(client, 0x00C0, 0xc1);
++ ret |= reg16_write(client, 0xFFFE, 0x19);
++ usleep_range(100, 150); /* wait 100 us */
++ ret |= reg16_read(client, 0x5000, &val);
++ val &= ~(0x1 << 2);
++ val |= (ctrl->val << 2);
++ ret |= reg16_write(client, 0xFFFE, 0x19);
++ usleep_range(100, 150); /* wait 100 us */
++ ret |= reg16_write(client, 0x5000, 0x00); // write 0x3090
++ ret |= reg16_write(client, 0x5001, 0x30);
++ ret |= reg16_write(client, 0x5002, 0x90);
++ ret |= reg16_write(client, 0x5003, val);
++ ret |= reg16_write(client, 0xFFFE, 0x80);
++ usleep_range(100, 150); /* wait 100 us */
++ ret |= reg16_write(client, 0x00C0, 0xc1);
++#endif
++ break;
++ case V4L2_CID_VFLIP:
++#if 1
++ ret = reg16_write(client, 0xFFFD, 0x80);
++ ret |= reg16_write(client, 0xFFFE, 0x19);
++ usleep_range(100, 150); /* wait 100 us */
++ ret |= reg16_write(client, 0x5000, ctrl->val);
++ ret |= reg16_write(client, 0x5001, 0x01);
++ ret |= reg16_write(client, 0xFFFE, 0x80);
++ usleep_range(100, 150); /* wait 100 us */
++ ret |= reg16_write(client, 0x00C0, 0xdc);
++#else
++ ret = reg16_write(client, 0xFFFD, 0x80);
++ ret |= reg16_write(client, 0xFFFE, 0x19);
++ usleep_range(100, 150); /* wait 100 us */
++ ret |= reg16_write(client, 0x5000, 0x01); // read 0x3128
++ ret |= reg16_write(client, 0x5001, 0x31);
++ ret |= reg16_write(client, 0x5002, 0x28);
++ ret |= reg16_write(client, 0xFFFE, 0x80);
++ usleep_range(100, 150); /* wait 100 us */
++ ret |= reg16_write(client, 0x00C0, 0xc1);
++ ret |= reg16_write(client, 0xFFFE, 0x19);
++ usleep_range(100, 150); /* wait 100 us */
++ ret |= reg16_read(client, 0x5000, &val);
++ val &= ~(0x1 << 1);
++ val |= (ctrl->val << 1);
++ ret |= reg16_write(client, 0xFFFE, 0x19);
++ usleep_range(100, 150); /* wait 100 us */
++ ret |= reg16_write(client, 0x5000, 0x00); // write 0x3128
++ ret |= reg16_write(client, 0x5001, 0x31);
++ ret |= reg16_write(client, 0x5002, 0x28);
++ ret |= reg16_write(client, 0x5003, val);
++ ret |= reg16_write(client, 0xFFFE, 0x80);
++ usleep_range(100, 150); /* wait 100 us */
++ ret |= reg16_write(client, 0x00C0, 0xc1);
++
++ ret |= reg16_write(client, 0xFFFE, 0x19);
++ usleep_range(100, 150); /* wait 100 us */
++ ret |= reg16_write(client, 0x5000, 0x01); // read 0x3291
++ ret |= reg16_write(client, 0x5001, 0x32);
++ ret |= reg16_write(client, 0x5002, 0x91);
++ ret |= reg16_write(client, 0xFFFE, 0x80);
++ usleep_range(100, 150); /* wait 100 us */
++ ret |= reg16_write(client, 0x00C0, 0xc1);
++ ret |= reg16_write(client, 0xFFFE, 0x19);
++ usleep_range(100, 150); /* wait 100 us */
++ ret |= reg16_read(client, 0x5000, &val);
++ val &= ~(0x1 << 2);
++ val |= (ctrl->val << 2);
++ ret |= reg16_write(client, 0xFFFE, 0x19);
++ usleep_range(100, 150); /* wait 100 us */
++ ret |= reg16_write(client, 0x5000, 0x00); // write 0x3291
++ ret |= reg16_write(client, 0x5001, 0x32);
++ ret |= reg16_write(client, 0x5002, 0x91);
++ ret |= reg16_write(client, 0x5003, val);
++ ret |= reg16_write(client, 0xFFFE, 0x80);
++ usleep_range(100, 150); /* wait 100 us */
++ ret |= reg16_write(client, 0x00C0, 0xc1);
++
++ ret |= reg16_write(client, 0xFFFE, 0x19);
++ usleep_range(100, 150); /* wait 100 us */
++ ret |= reg16_write(client, 0x5000, 0x01); // read 0x3090
++ ret |= reg16_write(client, 0x5001, 0x30);
++ ret |= reg16_write(client, 0x5002, 0x90);
++ ret |= reg16_write(client, 0xFFFE, 0x80);
++ usleep_range(100, 150); /* wait 100 us */
++ ret |= reg16_write(client, 0x00C0, 0xc1);
++ ret |= reg16_write(client, 0xFFFE, 0x19);
++ usleep_range(100, 150); /* wait 100 us */
++ ret |= reg16_read(client, 0x5000, &val);
++ val &= ~(0x1 << 3);
++ val |= (ctrl->val << 3);
++ ret |= reg16_write(client, 0xFFFE, 0x19);
++ usleep_range(100, 150); /* wait 100 us */
++ ret |= reg16_write(client, 0x5000, 0x00); // write 0x3090
++ ret |= reg16_write(client, 0x5001, 0x30);
++ ret |= reg16_write(client, 0x5002, 0x90);
++ ret |= reg16_write(client, 0x5003, val);
++ ret |= reg16_write(client, 0xFFFE, 0x80);
++ usleep_range(100, 150); /* wait 100 us */
++ ret |= reg16_write(client, 0x00C0, 0xc1);
++#endif
++ break;
++ case V4L2_CID_MIN_BUFFERS_FOR_CAPTURE:
++ ret = 0;
++ break;
++ }
++
++ return ret;
++}
++
++static const struct v4l2_ctrl_ops ov490_ctrl_ops = {
++ .s_ctrl = ov490_s_ctrl,
++};
++
++static struct v4l2_subdev_video_ops ov490_video_ops = {
++ .s_stream = ov490_s_stream,
++ .g_mbus_config = ov490_g_mbus_config,
++};
++
++static const struct v4l2_subdev_pad_ops ov490_subdev_pad_ops = {
++ .get_edid = ov490_get_edid,
++ .enum_mbus_code = ov490_enum_mbus_code,
++ .get_selection = ov490_get_selection,
++ .set_selection = ov490_set_selection,
++ .get_fmt = ov490_get_fmt,
++ .set_fmt = ov490_set_fmt,
++};
++
++static struct v4l2_subdev_ops ov490_subdev_ops = {
++ .core = &ov490_core_ops,
++ .video = &ov490_video_ops,
++ .pad = &ov490_subdev_pad_ops,
++};
++
++static void ov490_otp_id_read(struct i2c_client *client)
++{
++ struct ov490_priv *priv = to_ov490(client);
++ int i;
++
++#if 0
++ /* read camera id from ov490 OTP memory */
++ reg16_write(client, 0xFFFD, 0x80);
++ reg16_write(client, 0xFFFE, 0x28);
++ usleep_range(100, 150); /* wait 100 us */
++ reg16_write(client, 0xE084, 0x40); /* manual mode, bank#0 */
++ reg16_write(client, 0xE081, 1); /* start OTP read */
++
++ usleep_range(25000, 26000); /* wait 25 ms */
++
++ for (i = 0; i < 6; i++)
++ reg16_read(client, 0xe000 + i + 4, &priv->id[i]);
++#else
++ /* read camera id from ov10640 OTP memory */
++ reg16_write(client, 0xFFFD, 0x80);
++ usleep_range(100, 150); /* wait 100 us */
++ reg16_write(client, 0xFFFE, 0x19);
++ usleep_range(100, 150); /* wait 100 us */
++ reg16_write(client, 0x5000, 0x00); /* write 0x349C -> 1 */
++ reg16_write(client, 0x5001, 0x34);
++ reg16_write(client, 0x5002, 0x9C);
++ reg16_write(client, 0x5003, 1);
++ reg16_write(client, 0xFFFE, 0x80);
++ usleep_range(100, 150); /* wait 100 us */
++ reg16_write(client, 0x00C0, 0xc1);
++
++ usleep_range(25000, 25500); /* wait 25 ms */
++
++ for (i = 0; i < 6; i++) {
++ reg16_write(client, 0xFFFE, 0x19);
++ usleep_range(100, 150); /* wait 100 us */
++ reg16_write(client, 0x5000, 0x01); /* read (0x349E + i) */
++ reg16_write(client, 0x5001, 0x34);
++ reg16_write(client, 0x5002, 0x9e + i + 6); /* first 6 bytes are equal on all ov10640 */
++ reg16_write(client, 0xFFFE, 0x80);
++ usleep_range(100, 150); /* wait 100 us */
++ reg16_write(client, 0x00C0, 0xc1);
++ reg16_write(client, 0xFFFE, 0x19);
++ usleep_range(1000, 1500); /* wait 1 ms */
++ reg16_read(client, 0x5000, &priv->id[i]);
++ }
++#endif
++}
++
++static ssize_t ov490_otp_id_show(struct device *dev,
++ struct device_attribute *attr, char *buf)
++{
++ struct v4l2_subdev *sd = i2c_get_clientdata(to_i2c_client(dev));
++ struct i2c_client *client = v4l2_get_subdevdata(sd);
++ struct ov490_priv *priv = to_ov490(client);
++
++ return snprintf(buf, 32, "%02x:%02x:%02x:%02x:%02x:%02x\n",
++ priv->id[0], priv->id[1], priv->id[2], priv->id[3], priv->id[4], priv->id[5]);
++}
++
++static DEVICE_ATTR(otp_id_ov490, S_IRUGO, ov490_otp_id_show, NULL);
++
++static int ov490_initialize(struct i2c_client *client)
++{
++ struct ov490_priv *priv = to_ov490(client);
++ u8 val = 0;
++ u8 pid = 0, ver = 0;
++ int ret = 0, timeout, retry_timeout = 3;
++
++ if (priv->is_fixed_sensor) {
++ dev_info(&client->dev, "ov490/ov10640 fixed-sensor res %dx%d\n", priv->max_width, priv->max_height);
++ return 0;
++ }
++
++ ov490_s_port(client, 1);
++
++ /* check and show product ID and manufacturer ID */
++ reg16_write(client, 0xFFFD, 0x80);
++ reg16_write(client, 0xFFFE, 0x80);
++ usleep_range(100, 150); /* wait 100 us */
++ reg16_read(client, OV490_PID, &pid);
++ reg16_read(client, OV490_VER, &ver);
++
++ if (OV490_VERSION(pid, ver) != OV490_VERSION_REG) {
++ dev_dbg(&client->dev, "Product ID error %x:%x\n", pid, ver);
++ ret = -ENODEV;
++ goto err;
++ }
++
++ if (unlikely(force_conf_link))
++ goto out;
++
++again:
++ /* Check if firmware booted by reading stream-on status */
++ reg16_write(client, 0xFFFD, 0x80);
++ reg16_write(client, 0xFFFE, 0x29);
++ usleep_range(100, 150); /* wait 100 us */
++ timeout = 300;
++ for (;;) {
++ reg16_read(client, 0xd000, &val);
++ if (val == 0x0c || --timeout == 0)
++ break;
++ mdelay(1);
++ }
++
++ if (!timeout) {
++ dev_err(&client->dev, "Timeout firmware boot wait, retrying\n");
++ /* reset OV10640 using RESETB pin controlled by OV490 GPIO0 */
++ reg16_write(client, 0xFFFD, 0x80);
++ reg16_write(client, 0xFFFE, 0x80);
++ usleep_range(100, 150); /* wait 100 us */
++ reg16_write(client, 0x0050, 0x01);
++ reg16_write(client, 0x0054, 0x01);
++ reg16_write(client, 0x0058, 0x00);
++ mdelay(10);
++ reg16_write(client, 0x0058, 0x01);
++ /* reset OV490 using RESETB pin controlled by serializer */
++ ov490_reset(client);
++ if (retry_timeout--)
++ goto again;
++ }
++
++ /* read resolution used by current firmware */
++ reg16_write(client, 0xFFFD, 0x80);
++ reg16_write(client, 0xFFFE, 0x82);
++ usleep_range(100, 150); /* wait 100 us */
++ reg16_read(client, OV490_ISP_HSIZE_HIGH, &val);
++ priv->max_width = val;
++ reg16_read(client, OV490_ISP_HSIZE_LOW, &val);
++ priv->max_width = (priv->max_width << 8) | val;
++ reg16_read(client, OV490_ISP_VSIZE_HIGH, &val);
++ priv->max_height = val;
++ reg16_read(client, OV490_ISP_VSIZE_LOW, &val);
++ priv->max_height = (priv->max_height << 8) | val;
++ /* Program wizard registers */
++ ov490_set_regs(client, ov490_regs_wizard, ARRAY_SIZE(ov490_regs_wizard));
++ /* Set DVP bit swap */
++ reg16_write(client, 0xFFFD, 0x80);
++ reg16_write(client, 0xFFFE, 0x28);
++ usleep_range(100, 150); /* wait 100 us */
++ reg16_write(client, 0x6009, priv->dvp_order << 4);
++ /* Read OTP IDs */
++ ov490_otp_id_read(client);
++
++out:
++ dev_info(&client->dev, "ov490/ov10640 PID %x%x, res %dx%d, OTP_ID %02x:%02x:%02x:%02x:%02x:%02x\n",
++ pid, ver, priv->max_width, priv->max_height, priv->id[0], priv->id[1], priv->id[2], priv->id[3], priv->id[4], priv->id[5]);
++err:
++ ov490_s_port(client, 0);
++
++ return ret;
++}
++
++static int ov490_parse_dt(struct device_node *np, struct ov490_priv *priv)
++{
++ struct i2c_client *client = v4l2_get_subdevdata(&priv->sd);
++ int err, i;
++ const char *fixed_sensor;
++ struct device_node *endpoint = NULL, *rendpoint = NULL;
++ int tmp_addr = 0;
++
++ for (i = 0; ; i++) {
++ endpoint = of_graph_get_next_endpoint(np, endpoint);
++ if (!endpoint)
++ break;
++
++ of_node_put(endpoint);
++
++ of_property_read_u32(endpoint, "dvp-order", &priv->dvp_order);
++
++ rendpoint = of_parse_phandle(endpoint, "remote-endpoint", 0);
++ if (!rendpoint)
++ continue;
++
++ if (!of_property_read_u32(rendpoint, "max9271-addr", &priv->max9271_addr) &&
++ !of_property_read_u32(rendpoint->parent->parent, "reg", &priv->max9286_addr) &&
++ !kstrtouint(strrchr(rendpoint->full_name, '@') + 1, 0, &priv->port)) {
++ if (of_property_read_u32(rendpoint->parent->parent, "maxim,resetb-gpio", &priv->gpio_resetb)) {
++ priv->gpio_resetb = -1;
++ } else {
++ if (of_property_read_bool(rendpoint->parent->parent, "maxim,resetb-active-high"))
++ priv->active_low_resetb = false;
++ else
++ priv->active_low_resetb = true;
++ }
++ break;
++ }
++
++ if (!of_property_read_u32(rendpoint, "ti9x3-addr", &priv->ti9x3_addr) &&
++ !of_property_match_string(rendpoint->parent->parent, "compatible", "ti,ti964-ti9x3") &&
++ !of_property_read_u32(rendpoint->parent->parent, "reg", &priv->ti964_addr) &&
++ !kstrtouint(strrchr(rendpoint->full_name, '@') + 1, 0, &priv->port))
++ break;
++
++ if (!of_property_read_u32(rendpoint, "ti9x3-addr", &priv->ti9x3_addr) &&
++ !of_property_match_string(rendpoint->parent->parent, "compatible", "ti,ti954-ti9x3") &&
++ !of_property_read_u32(rendpoint->parent->parent, "reg", &priv->ti954_addr) &&
++ !kstrtouint(strrchr(rendpoint->full_name, '@') + 1, 0, &priv->port))
++ break;
++ }
++
++ if (!priv->max9286_addr && !priv->ti964_addr && !priv->ti954_addr) {
++ dev_err(&client->dev, "deserializer does not present\n");
++ return -EINVAL;
++ }
++
++ ov490_s_port(client, 1);
++
++ /* setup I2C translator address */
++ tmp_addr = client->addr;
++ if (priv->max9286_addr) {
++ client->addr = priv->max9271_addr; /* Serializer I2C address */
++
++ reg8_write(client, 0x09, tmp_addr << 1); /* Sensor translated I2C address */
++ reg8_write(client, 0x0A, OV490_I2C_ADDR << 1); /* Sensor native I2C address */
++ usleep_range(2000, 2500); /* wait 2ms */
++ };
++ if (priv->ti964_addr) {
++ client->addr = priv->ti964_addr; /* Deserializer I2C address */
++
++ reg8_write(client, 0x4c, (priv->port << 4) | (1 << priv->port)); /* Select RX port number */
++ usleep_range(2000, 2500); /* wait 2ms */
++ reg8_write(client, 0x65, tmp_addr << 1); /* Sensor translated I2C address */
++ reg8_write(client, 0x5d, OV490_I2C_ADDR << 1); /* Sensor native I2C address */
++
++ reg8_write(client, 0x6e, 0x9a); /* GPIO0 - fsin, GPIO1 - resetb */
++ }
++ if (priv->ti954_addr) {
++ client->addr = priv->ti954_addr; /* Deserializer I2C address */
++
++ reg8_write(client, 0x4c, (priv->port << 4) | (1 << priv->port)); /* Select RX port number */
++ usleep_range(2000, 2500); /* wait 2ms */
++ reg8_write(client, 0x65, tmp_addr << 1); /* Sensor translated I2C address */
++ reg8_write(client, 0x5d, OV490_I2C_ADDR << 1); /* Sensor native I2C address */
++
++ reg8_write(client, 0x6e, 0x9a); /* GPIO0 - fsin, GPIO1 - resetb */
++ }
++ client->addr = tmp_addr;
++
++ err = of_property_read_string(np, "maxim,fixed-sensor", &fixed_sensor);
++ if (err)
++ return 0;
++
++ if (strcmp(fixed_sensor, "ov490") == 0) {
++ err = of_property_read_u32(np, "maxim,width", &priv->max_width);
++ if (err) {
++ dev_err(&client->dev, "maxim,width must be set for fixed-sensor\n");
++ goto out;
++ }
++
++ err = of_property_read_u32(np, "maxim,height", &priv->max_height);
++ if (err) {
++ dev_err(&client->dev, "maxim,height must be set for fixed-sensor\n");
++ goto out;
++ }
++
++ priv->is_fixed_sensor = true;
++ }
++
++out:
++ return err;
++}
++
++static int ov490_probe(struct i2c_client *client,
++ const struct i2c_device_id *did)
++{
++ struct ov490_priv *priv;
++ struct v4l2_ctrl *ctrl;
++ int ret;
++
++ priv = devm_kzalloc(&client->dev, sizeof(*priv), GFP_KERNEL);
++ if (!priv)
++ return -ENOMEM;
++
++ v4l2_i2c_subdev_init(&priv->sd, client, &ov490_subdev_ops);
++ priv->sd.flags = V4L2_SUBDEV_FL_HAS_DEVNODE;
++
++ priv->exposure = 0x100;
++ priv->gain = 0x100;
++ priv->autogain = 1;
++ v4l2_ctrl_handler_init(&priv->hdl, 4);
++ v4l2_ctrl_new_std(&priv->hdl, &ov490_ctrl_ops,
++ V4L2_CID_BRIGHTNESS, 0, 16, 1, 7);
++ v4l2_ctrl_new_std(&priv->hdl, &ov490_ctrl_ops,
++ V4L2_CID_CONTRAST, 0, 16, 1, 7);
++ v4l2_ctrl_new_std(&priv->hdl, &ov490_ctrl_ops,
++ V4L2_CID_SATURATION, 0, 7, 1, 2);
++ v4l2_ctrl_new_std(&priv->hdl, &ov490_ctrl_ops,
++ V4L2_CID_HUE, 0, 23, 1, 12);
++ v4l2_ctrl_new_std(&priv->hdl, &ov490_ctrl_ops,
++ V4L2_CID_GAMMA, -128, 128, 1, 0);
++ v4l2_ctrl_new_std(&priv->hdl, &ov490_ctrl_ops,
++ V4L2_CID_SHARPNESS, 0, 10, 1, 3);
++ v4l2_ctrl_new_std(&priv->hdl, &ov490_ctrl_ops,
++ V4L2_CID_AUTOGAIN, 0, 1, 1, priv->autogain);
++ v4l2_ctrl_new_std(&priv->hdl, &ov490_ctrl_ops,
++ V4L2_CID_GAIN, 0, 0xffff, 1, priv->gain);
++ v4l2_ctrl_new_std(&priv->hdl, &ov490_ctrl_ops,
++ V4L2_CID_EXPOSURE, 0, 0xffff, 1, priv->exposure);
++ v4l2_ctrl_new_std(&priv->hdl, &ov490_ctrl_ops,
++ V4L2_CID_HFLIP, 0, 1, 1, 1);
++ v4l2_ctrl_new_std(&priv->hdl, &ov490_ctrl_ops,
++ V4L2_CID_VFLIP, 0, 1, 1, 0);
++ ctrl = v4l2_ctrl_new_std(&priv->hdl, &ov490_ctrl_ops,
++ V4L2_CID_MIN_BUFFERS_FOR_CAPTURE, 1, 32, 1, 9);
++ if (ctrl)
++ ctrl->flags &= ~V4L2_CTRL_FLAG_READ_ONLY;
++ priv->sd.ctrl_handler = &priv->hdl;
++
++ ret = priv->hdl.error;
++ if (ret)
++ goto cleanup;
++
++ v4l2_ctrl_handler_setup(&priv->hdl);
++
++ priv->pad.flags = MEDIA_PAD_FL_SOURCE;
++ priv->sd.entity.flags |= MEDIA_ENT_F_CAM_SENSOR;
++ ret = media_entity_pads_init(&priv->sd.entity, 1, &priv->pad);
++ if (ret < 0)
++ goto cleanup;
++
++ ret = ov490_parse_dt(client->dev.of_node, priv);
++ if (ret)
++ goto cleanup;
++
++ ret = ov490_initialize(client);
++ if (ret < 0)
++ goto cleanup;
++
++ priv->rect.left = 0;
++ priv->rect.top = 0;
++ priv->rect.width = priv->max_width;
++ priv->rect.height = priv->max_height;
++
++ ret = v4l2_async_register_subdev(&priv->sd);
++ if (ret)
++ goto cleanup;
++
++ if (device_create_file(&client->dev, &dev_attr_otp_id_ov490) != 0) {
++ dev_err(&client->dev, "sysfs otp_id entry creation failed\n");
++ goto cleanup;
++ }
++
++ priv->init_complete = 1;
++
++ return 0;
++
++cleanup:
++ media_entity_cleanup(&priv->sd.entity);
++ v4l2_ctrl_handler_free(&priv->hdl);
++ v4l2_device_unregister_subdev(&priv->sd);
++#ifdef CONFIG_SOC_CAMERA_OV490_OV10640
++ v4l_err(client, "failed to probe @ 0x%02x (%s)\n",
++ client->addr, client->adapter->name);
++#endif
++ return ret;
++}
++
++static int ov490_remove(struct i2c_client *client)
++{
++ struct ov490_priv *priv = i2c_get_clientdata(client);
++
++ device_remove_file(&client->dev, &dev_attr_otp_id_ov490);
++ v4l2_async_unregister_subdev(&priv->sd);
++ media_entity_cleanup(&priv->sd.entity);
++ v4l2_ctrl_handler_free(&priv->hdl);
++ v4l2_device_unregister_subdev(&priv->sd);
++
++ return 0;
++}
++
++#ifdef CONFIG_SOC_CAMERA_OV490_OV10640
++static const struct i2c_device_id ov490_id[] = {
++ { "ov490-ov10640", 0 },
++ { }
++};
++MODULE_DEVICE_TABLE(i2c, ov490_id);
++
++static const struct of_device_id ov490_of_ids[] = {
++ { .compatible = "ovti,ov490-ov10640", },
++ { }
++};
++MODULE_DEVICE_TABLE(of, ov490_of_ids);
++
++static struct i2c_driver ov490_i2c_driver = {
++ .driver = {
++ .name = "ov490-ov10640",
++ .of_match_table = ov490_of_ids,
++ },
++ .probe = ov490_probe,
++ .remove = ov490_remove,
++ .id_table = ov490_id,
++};
++
++module_i2c_driver(ov490_i2c_driver);
++
++MODULE_DESCRIPTION("SoC Camera driver for OV490-OV10640");
++MODULE_AUTHOR("Vladimir Barinov");
++MODULE_LICENSE("GPL");
++#endif
+diff --git a/drivers/media/i2c/soc_camera/ov490_ov10640.h b/drivers/media/i2c/soc_camera/ov490_ov10640.h
+new file mode 100644
+index 0000000..d3290c7
+--- /dev/null
++++ b/drivers/media/i2c/soc_camera/ov490_ov10640.h
+@@ -0,0 +1,88 @@
++/*
++ * OmniVision ov490-ov10640 sensor camera wizard 1280x1080@30/UYVY/BT601/8bit
++ *
++ * Copyright (C) 2016-2017 Cogent Embedded, Inc.
++ *
++ * This program is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License as published by the
++ * Free Software Foundation; either version 2 of the License, or (at your
++ * option) any later version.
++ */
++
++struct ov490_reg {
++ u16 reg;
++ u8 val;
++};
++
++static const struct ov490_reg ov490_regs_wizard[] = {
++/* The following registers should match firmware */
++{0xfffd, 0x80},
++{0xfffe, 0x82},
++{0x0071, 0x11},
++{0x0075, 0x11},
++{0xfffe, 0x29},
++{0x6010, 0x01},
++/* ov490 EMB line disable in YUV and RAW data, NOTE: EMB line is still used in ISP and sensor */
++{0xe000, 0x14},
++#if 0 /* do not disable EMB line in ISP! */
++{0x4017, 0x00},
++#endif
++{0xfffe, 0x28},
++{0x6000, 0x04},
++{0x6004, 0x00},
++{0x6008, 0x00}, // PCLK polarity - useless due to silicon bug -> use 0x808000bb register
++{0xfffe, 0x80},
++{0x0091, 0x00},
++{0x00bb, 0x1d}, // bit[3]=0 - PCLK polarity workaround
++/* ov10640 EMB line disable */
++#if 0 /* do not disable EMB line in sensor! */
++{0xfffe, 0x19},
++{0x5000, 0x00},
++{0x5001, 0x30},
++{0x5002, 0x91},
++{0x5003, 0x08},
++{0xfffe, 0x80},
++{0x00c0, 0xc1},
++#endif
++/* Ov490 FSIN: app_fsin_from_fsync */
++{0xfffe, 0x85},
++{0x0008, 0x00},
++{0x0009, 0x01},
++{0x000A, 0x05}, // fsin0 src
++{0x000B, 0x00},
++{0x0030, 0x02}, // fsin0_delay
++{0x0031, 0x00},
++{0x0032, 0x00},
++{0x0033, 0x00},
++{0x0038, 0x02}, // fsin1_delay
++{0x0039, 0x00},
++{0x003A, 0x00},
++{0x003B, 0x00},
++{0x0070, 0x2C}, // fsin0_length
++{0x0071, 0x01},
++{0x0072, 0x00},
++{0x0073, 0x00},
++{0x0074, 0x64}, // fsin1_length
++{0x0075, 0x00},
++{0x0076, 0x00},
++{0x0077, 0x00},
++{0x0000, 0x14},
++{0x0001, 0x00},
++{0x0002, 0x00},
++{0x0003, 0x00},
++{0x0004, 0x32}, // load fsin0,load fsin1,load other, it will be cleared automatically.
++{0x0005, 0x00},
++{0x0006, 0x00},
++{0x0007, 0x00},
++{0xfffe, 0x80},
++{0x0081, 0x00}, // 03;SENSOR FSIN
++/* ov10640 FSIN */
++{0xfffd, 0x80},
++{0xfffe, 0x19},
++{0x5000, 0x00},
++{0x5001, 0x30},
++{0x5002, 0x8c},
++{0x5003, 0xb2},
++{0xfffe, 0x80},
++{0x00c0, 0xc1},
++};
+diff --git a/drivers/media/i2c/soc_camera/ov495_ov2775.c b/drivers/media/i2c/soc_camera/ov495_ov2775.c
+new file mode 100644
+index 0000000..881615e
+--- /dev/null
++++ b/drivers/media/i2c/soc_camera/ov495_ov2775.c
+@@ -0,0 +1,658 @@
++/*
++ * OmniVision ov495-ov2775 sensor camera driver
++ *
++ * Copyright (C) 2017 Cogent Embedded, Inc.
++ *
++ * This program is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License as published by the
++ * Free Software Foundation; either version 2 of the License, or (at your
++ * option) any later version.
++ */
++
++#include <linux/delay.h>
++#include <linux/init.h>
++#include <linux/i2c.h>
++#include <linux/module.h>
++#include <linux/videodev2.h>
++
++#include <media/soc_camera.h>
++#include <media/v4l2-common.h>
++#include <media/v4l2-ctrls.h>
++#include <media/v4l2-of.h>
++
++#include "ov495_ov2775.h"
++
++#define OV495_I2C_ADDR 0x24
++
++#define OV495_PID 0x300a
++#define OV495_VER 0x300b
++#define OV495_VERSION_REG 0x0495
++#define OV495_VERSION(pid, ver) (((pid) << 8) | ((ver) & 0xff))
++
++#define OV495_ISP_HSIZE_LOW 0x60
++#define OV495_ISP_HSIZE_HIGH 0x61
++#define OV495_ISP_VSIZE_LOW 0x62
++#define OV495_ISP_VSIZE_HIGH 0x63
++
++struct ov495_priv {
++ struct v4l2_subdev sd;
++ struct v4l2_ctrl_handler hdl;
++ struct media_pad pad;
++ struct v4l2_rect rect;
++ int max_width;
++ int max_height;
++ int init_complete;
++ u8 id[6];
++ int exposure;
++ int gain;
++ int autogain;
++ /* serializers */
++ int max9286_addr;
++ int max9271_addr;
++ int ti960_addr;
++ int ti954_addr;
++ int ti9x3_addr;
++ int port;
++ int gpio_resetb;
++ int gpio_fsin;
++
++};
++
++static int force_conf_link;
++
++static __init int ov495_force_conf_link(char *str)
++{
++ /* force configuration link */
++ /* used only if robust firmware flashing required (f.e. recovery) */
++ force_conf_link = 1;
++ return 0;
++}
++early_param("force_conf_link", ov495_force_conf_link);
++
++static inline struct ov495_priv *to_ov495(const struct i2c_client *client)
++{
++ return container_of(i2c_get_clientdata(client), struct ov495_priv, sd);
++}
++
++static int ov495_set_regs(struct i2c_client *client,
++ const struct ov495_reg *regs, int nr_regs)
++{
++ int i;
++
++ for (i = 0; i < nr_regs; i++) {
++ if (reg16_write(client, regs[i].reg, regs[i].val)) {
++ usleep_range(100, 150); /* wait 100 us */
++ reg16_write(client, regs[i].reg, regs[i].val);
++ }
++ }
++
++ return 0;
++}
++
++static int ov495_s_stream(struct v4l2_subdev *sd, int enable)
++{
++ return 0;
++}
++
++static int ov495_get_fmt(struct v4l2_subdev *sd,
++ struct v4l2_subdev_pad_config *cfg,
++ struct v4l2_subdev_format *format)
++{
++ struct v4l2_mbus_framefmt *mf = &format->format;
++ struct i2c_client *client = v4l2_get_subdevdata(sd);
++ struct ov495_priv *priv = to_ov495(client);
++
++ if (format->pad)
++ return -EINVAL;
++
++ mf->width = priv->rect.width;
++ mf->height = priv->rect.height;
++ mf->code = MEDIA_BUS_FMT_YUYV8_2X8;
++ mf->colorspace = V4L2_COLORSPACE_SMPTE170M;
++ mf->field = V4L2_FIELD_NONE;
++
++ return 0;
++}
++
++static int ov495_set_fmt(struct v4l2_subdev *sd,
++ struct v4l2_subdev_pad_config *cfg,
++ struct v4l2_subdev_format *format)
++{
++ struct v4l2_mbus_framefmt *mf = &format->format;
++
++ mf->code = MEDIA_BUS_FMT_YUYV8_2X8;
++ mf->colorspace = V4L2_COLORSPACE_SMPTE170M;
++ mf->field = V4L2_FIELD_NONE;
++
++ if (format->which == V4L2_SUBDEV_FORMAT_TRY)
++ cfg->try_fmt = *mf;
++
++ return 0;
++}
++
++static int ov495_enum_mbus_code(struct v4l2_subdev *sd,
++ struct v4l2_subdev_pad_config *cfg,
++ struct v4l2_subdev_mbus_code_enum *code)
++{
++ if (code->pad || code->index > 0)
++ return -EINVAL;
++
++ code->code = MEDIA_BUS_FMT_YUYV8_2X8;
++
++ return 0;
++}
++
++static int ov495_get_edid(struct v4l2_subdev *sd, struct v4l2_edid *edid)
++{
++ struct i2c_client *client = v4l2_get_subdevdata(sd);
++ struct ov495_priv *priv = to_ov495(client);
++
++ memcpy(edid->edid, priv->id, 6);
++
++ edid->edid[6] = 0xff;
++ edid->edid[7] = client->addr;
++ edid->edid[8] = OV495_VERSION_REG >> 8;
++ edid->edid[9] = OV495_VERSION_REG & 0xff;
++
++ return 0;
++}
++
++static int ov495_set_selection(struct v4l2_subdev *sd,
++ struct v4l2_subdev_pad_config *cfg,
++ struct v4l2_subdev_selection *sel)
++{
++ struct v4l2_rect *rect = &sel->r;
++ struct i2c_client *client = v4l2_get_subdevdata(sd);
++ struct ov495_priv *priv = to_ov495(client);
++
++ if (sel->which != V4L2_SUBDEV_FORMAT_ACTIVE ||
++ sel->target != V4L2_SEL_TGT_CROP)
++ return -EINVAL;
++
++ rect->left = ALIGN(rect->left, 2);
++ rect->top = ALIGN(rect->top, 2);
++ rect->width = ALIGN(rect->width, 2);
++ rect->height = ALIGN(rect->height, 2);
++
++ if ((rect->left + rect->width > priv->max_width) ||
++ (rect->top + rect->height > priv->max_height))
++ *rect = priv->rect;
++
++ priv->rect.left = rect->left;
++ priv->rect.top = rect->top;
++ priv->rect.width = rect->width;
++ priv->rect.height = rect->height;
++
++ return 0;
++}
++
++static int ov495_get_selection(struct v4l2_subdev *sd,
++ struct v4l2_subdev_pad_config *cfg,
++ struct v4l2_subdev_selection *sel)
++{
++ struct i2c_client *client = v4l2_get_subdevdata(sd);
++ struct ov495_priv *priv = to_ov495(client);
++
++ if (sel->which != V4L2_SUBDEV_FORMAT_ACTIVE)
++ return -EINVAL;
++
++ switch (sel->target) {
++ case V4L2_SEL_TGT_CROP_BOUNDS:
++ sel->r.left = 0;
++ sel->r.top = 0;
++ sel->r.width = priv->max_width;
++ sel->r.height = priv->max_height;
++ return 0;
++ case V4L2_SEL_TGT_CROP_DEFAULT:
++ sel->r.left = 0;
++ sel->r.top = 0;
++ sel->r.width = priv->max_width;
++ sel->r.height = priv->max_height;
++ return 0;
++ case V4L2_SEL_TGT_CROP:
++ sel->r = priv->rect;
++ return 0;
++ default:
++ return -EINVAL;
++ }
++}
++
++static int ov495_g_mbus_config(struct v4l2_subdev *sd,
++ struct v4l2_mbus_config *cfg)
++{
++ cfg->flags = V4L2_MBUS_CSI2_1_LANE | V4L2_MBUS_CSI2_CHANNEL_0 |
++ V4L2_MBUS_CSI2_CONTINUOUS_CLOCK;
++ cfg->type = V4L2_MBUS_CSI2;
++
++ return 0;
++}
++
++#ifdef CONFIG_VIDEO_ADV_DEBUG
++static int ov495_g_register(struct v4l2_subdev *sd,
++ struct v4l2_dbg_register *reg)
++{
++ struct i2c_client *client = v4l2_get_subdevdata(sd);
++ int ret;
++ u8 val = 0;
++
++ ret = reg16_read(client, (u16)reg->reg, &val);
++ if (ret < 0)
++ return ret;
++
++ reg->val = val;
++ reg->size = sizeof(u16);
++
++ return 0;
++}
++
++static int ov495_s_register(struct v4l2_subdev *sd,
++ const struct v4l2_dbg_register *reg)
++{
++ struct i2c_client *client = v4l2_get_subdevdata(sd);
++ int ret;
++
++ ret = reg16_write(client, (u16)reg->reg, (u8)reg->val);
++ if ((u8)reg->reg == 0xFFFD)
++ usleep_range(100, 150); /* wait 100 us */
++ if ((u8)reg->reg == 0xFFFE)
++ usleep_range(100, 150); /* wait 100 us */
++ return ret;
++}
++#endif
++
++static struct v4l2_subdev_core_ops ov495_core_ops = {
++#ifdef CONFIG_VIDEO_ADV_DEBUG
++ .g_register = ov495_g_register,
++ .s_register = ov495_s_register,
++#endif
++};
++
++static int ov495_s_ctrl(struct v4l2_ctrl *ctrl)
++{
++ struct v4l2_subdev *sd = to_sd(ctrl);
++ struct i2c_client *client = v4l2_get_subdevdata(sd);
++ struct ov495_priv *priv = to_ov495(client);
++ int ret = -EINVAL;
++
++ if (!priv->init_complete)
++ return 0;
++
++ switch (ctrl->id) {
++ case V4L2_CID_BRIGHTNESS:
++ break;
++ case V4L2_CID_CONTRAST:
++ break;
++ case V4L2_CID_SATURATION:
++ break;
++ case V4L2_CID_HUE:
++ break;
++ case V4L2_CID_GAMMA:
++ break;
++ case V4L2_CID_SHARPNESS:
++ break;
++ case V4L2_CID_AUTOGAIN:
++ case V4L2_CID_GAIN:
++ case V4L2_CID_EXPOSURE:
++ break;
++ case V4L2_CID_HFLIP:
++ ret = reg16_write(client, 0x3516, 0x00);
++ ret |= reg16_write(client, 0x0ffc, 0x00);
++ ret |= reg16_write(client, 0x0500, ctrl->val);
++ ret |= reg16_write(client, 0x0501, 0x00);
++ usleep_range(100, 150); /* wait 100 us */
++ ret |= reg16_write(client, 0x30C0, 0xdc);
++ ret |= reg16_write(client, 0x3516, 0x01);
++ break;
++ case V4L2_CID_VFLIP:
++ ret = reg16_write(client, 0x3516, 0x00);
++ ret |= reg16_write(client, 0x0ffc, 0x00);
++ ret |= reg16_write(client, 0x0500, ctrl->val);
++ ret |= reg16_write(client, 0x0501, 0x01);
++ usleep_range(100, 150); /* wait 100 us */
++ ret |= reg16_write(client, 0x30C0, 0xdc);
++ ret |= reg16_write(client, 0x3516, 0x01);
++ break;
++ case V4L2_CID_MIN_BUFFERS_FOR_CAPTURE:
++ ret = 0;
++ break;
++ }
++
++ return ret;
++}
++
++static const struct v4l2_ctrl_ops ov495_ctrl_ops = {
++ .s_ctrl = ov495_s_ctrl,
++};
++
++static struct v4l2_subdev_video_ops ov495_video_ops = {
++ .s_stream = ov495_s_stream,
++ .g_mbus_config = ov495_g_mbus_config,
++};
++
++static const struct v4l2_subdev_pad_ops ov495_subdev_pad_ops = {
++ .get_edid = ov495_get_edid,
++ .enum_mbus_code = ov495_enum_mbus_code,
++ .get_selection = ov495_get_selection,
++ .set_selection = ov495_set_selection,
++ .get_fmt = ov495_get_fmt,
++ .set_fmt = ov495_set_fmt,
++};
++
++static struct v4l2_subdev_ops ov495_subdev_ops = {
++ .core = &ov495_core_ops,
++ .video = &ov495_video_ops,
++ .pad = &ov495_subdev_pad_ops,
++};
++
++static void ov495_otp_id_read(struct i2c_client *client)
++{
++ struct ov495_priv *priv = to_ov495(client);
++ int i;
++
++#if 0
++ /* read camera id from ov495 OTP memory */
++ reg16_write(client, 0xFFFD, 0x80);
++ reg16_write(client, 0xFFFE, 0x20);
++ usleep_range(100, 150); /* wait 100 us */
++ reg16_write(client, 0x7384, 0x40); /* manual mode, bank#0 */
++ reg16_write(client, 0x7381, 1); /* start OTP read */
++
++ usleep_range(25000, 26000); /* wait 25 ms */
++
++ for (i = 0; i < 6; i++)
++ reg16_read(client, 0x7300 + i + 4, &priv->id[i]);
++#else
++ /* read camera id from ov2775 OTP memory */
++ reg16_write(client, 0x3516, 0x00); /* unlock write */
++ reg16_write(client, 0x0FFC, 0);
++ reg16_write(client, 0x0500, 0x00); /* write 0x34a1 -> 1 */
++ reg16_write(client, 0x0501, 0x34);
++ reg16_write(client, 0x0502, 0xa1);
++ reg16_write(client, 0x0503, 1);
++ reg16_write(client, 0x30C0, 0xc1);
++
++ usleep_range(25000, 25500); /* wait 25 ms */
++
++ for (i = 0; i < 6; i++) {
++ reg16_write(client, 0x3516, 0x00); /* unlock write */
++ reg16_write(client, 0x0500, 0x01); /* read (0x7a00 + i) */
++ reg16_write(client, 0x0501, 0x7a);
++ reg16_write(client, 0x0502, 0x00 + i + (i < 3 ? 11 : 3)); /* take bytes 11,12,13,6,7,8 */
++ reg16_write(client, 0x30C0, 0xc1);
++ usleep_range(1000, 1500); /* wait 1 ms */
++ reg16_read(client, 0x0500, &priv->id[i]);
++ }
++#endif
++}
++
++static ssize_t ov495_otp_id_show(struct device *dev,
++ struct device_attribute *attr, char *buf)
++{
++ struct v4l2_subdev *sd = i2c_get_clientdata(to_i2c_client(dev));
++ struct i2c_client *client = v4l2_get_subdevdata(sd);
++ struct ov495_priv *priv = to_ov495(client);
++
++ return snprintf(buf, 32, "%02x:%02x:%02x:%02x:%02x:%02x\n",
++ priv->id[0], priv->id[1], priv->id[2], priv->id[3], priv->id[4], priv->id[5]);
++}
++
++static DEVICE_ATTR(otp_id_ov495, S_IRUGO, ov495_otp_id_show, NULL);
++
++static int ov495_initialize(struct i2c_client *client)
++{
++ struct ov495_priv *priv = to_ov495(client);
++ u8 pid = 0, ver = 0;
++ int ret = 0;
++
++ /* check and show product ID and manufacturer ID */
++ reg16_write(client, 0xFFFD, 0x80);
++ reg16_write(client, 0xFFFE, 0x80);
++ usleep_range(100, 150); /* wait 100 us */
++ reg16_read(client, OV495_PID, &pid);
++ reg16_read(client, OV495_VER, &ver);
++
++ if (OV495_VERSION(pid, ver) != OV495_VERSION_REG) {
++ dev_err(&client->dev, "Product ID error %x:%x\n", pid, ver);
++ ret = -ENODEV;
++ goto err;
++ }
++
++ if (unlikely(force_conf_link))
++ goto out;
++
++#if 0
++ /* read resolution used by current firmware */
++ reg16_write(client, 0xFFFD, 0x80);
++ reg16_write(client, 0xFFFE, 0x82);
++ usleep_range(100, 150); /* wait 100 us */
++ reg16_read(client, OV495_ISP_HSIZE_HIGH, &val);
++ priv->max_width = val;
++ reg16_read(client, OV495_ISP_HSIZE_LOW, &val);
++ priv->max_width = (priv->max_width << 8) | val;
++ reg16_read(client, OV495_ISP_VSIZE_HIGH, &val);
++ priv->max_height = val;
++ reg16_read(client, OV495_ISP_VSIZE_LOW, &val);
++ priv->max_height = (priv->max_height << 8) | val;
++#else
++ priv->max_width = 1920;
++ priv->max_height = 1080;
++#endif
++
++ /* set virtual channel */
++ ov495_regs_wizard[3].val = 0x1e | (priv->port << 6);
++ /* Program wizard registers */
++ ov495_set_regs(client, ov495_regs_wizard, ARRAY_SIZE(ov495_regs_wizard));
++ /* Read OTP IDs */
++ ov495_otp_id_read(client);
++
++out:
++ dev_info(&client->dev, "ov495/ov2775 PID %x%x, res %dx%d, OTP_ID %02x:%02x:%02x:%02x:%02x:%02x\n",
++ pid, ver, priv->max_width, priv->max_height, priv->id[0], priv->id[1], priv->id[2], priv->id[3], priv->id[4], priv->id[5]);
++err:
++ return ret;
++}
++
++static int ov495_parse_dt(struct device_node *np, struct ov495_priv *priv)
++{
++ struct i2c_client *client = v4l2_get_subdevdata(&priv->sd);
++ int i;
++ struct device_node *endpoint = NULL, *rendpoint = NULL;
++ int tmp_addr = 0;
++
++ for (i = 0; ; i++) {
++ endpoint = of_graph_get_next_endpoint(np, endpoint);
++ if (!endpoint)
++ break;
++
++ of_node_put(endpoint);
++
++ rendpoint = of_parse_phandle(endpoint, "remote-endpoint", 0);
++ if (!rendpoint)
++ continue;
++
++ if (!of_property_read_u32(rendpoint, "ti9x3-addr", &priv->ti9x3_addr) &&
++ !of_property_match_string(rendpoint->parent->parent, "compatible", "ti,ti964-ti9x3") &&
++ !of_property_read_u32(rendpoint->parent->parent, "reg", &priv->ti960_addr) &&
++ !kstrtouint(strrchr(rendpoint->full_name, '@') + 1, 0, &priv->port))
++ break;
++
++ if (!of_property_read_u32(rendpoint, "ti9x3-addr", &priv->ti9x3_addr) &&
++ !of_property_match_string(rendpoint->parent->parent, "compatible", "ti,ti954-ti9x3") &&
++ !of_property_read_u32(rendpoint->parent->parent, "reg", &priv->ti954_addr) &&
++ !kstrtouint(strrchr(rendpoint->full_name, '@') + 1, 0, &priv->port))
++ break;
++ }
++
++ if (!priv->ti960_addr && !priv->ti954_addr) {
++ dev_err(&client->dev, "deserializer does not present\n");
++ return -EINVAL;
++ }
++
++ /* setup I2C translator address */
++ tmp_addr = client->addr;
++ if (priv->ti960_addr) {
++ client->addr = priv->ti960_addr; /* Deserializer I2C address */
++
++ reg8_write(client, 0x4c, (priv->port << 4) | (1 << priv->port)); /* Select RX port number */
++ usleep_range(2000, 2500); /* wait 2ms */
++ reg8_write(client, 0x65, tmp_addr << 1); /* Sensor translated I2C address */
++ reg8_write(client, 0x5d, OV495_I2C_ADDR << 1); /* Sensor native I2C address */
++
++ reg8_write(client, 0x6e, 0x9a); /* GPIO0 - fsin, GPIO1 - resetb */
++ /* TODO: why too long? move logic to workqueue? */
++ mdelay(350); /* time needed to boot all sensor IPs */
++ }
++ if (priv->ti954_addr) {
++ client->addr = priv->ti954_addr; /* Deserializer I2C address */
++
++ reg8_write(client, 0x4c, (priv->port << 4) | (1 << priv->port)); /* Select RX port number */
++ usleep_range(2000, 2500); /* wait 2ms */
++ reg8_write(client, 0x65, tmp_addr << 1); /* Sensor translated I2C address */
++ reg8_write(client, 0x5d, OV495_I2C_ADDR << 1); /* Sensor native I2C address */
++
++ reg8_write(client, 0x6e, 0x9a); /* GPIO0 - fsin, GPIO1 - resetb */
++ /* TODO: why too long? move logic to workqueue? */
++ mdelay(350); /* time needed to boot all sensor IPs */
++ }
++ client->addr = tmp_addr;
++
++ return 0;
++}
++
++static int ov495_probe(struct i2c_client *client,
++ const struct i2c_device_id *did)
++{
++ struct ov495_priv *priv;
++ struct v4l2_ctrl *ctrl;
++ int ret;
++
++ priv = devm_kzalloc(&client->dev, sizeof(*priv), GFP_KERNEL);
++ if (!priv)
++ return -ENOMEM;
++
++ v4l2_i2c_subdev_init(&priv->sd, client, &ov495_subdev_ops);
++ priv->sd.flags = V4L2_SUBDEV_FL_HAS_DEVNODE;
++
++ priv->exposure = 0x100;
++ priv->gain = 0x100;
++ priv->autogain = 1;
++ v4l2_ctrl_handler_init(&priv->hdl, 4);
++ v4l2_ctrl_new_std(&priv->hdl, &ov495_ctrl_ops,
++ V4L2_CID_BRIGHTNESS, 0, 16, 1, 7);
++ v4l2_ctrl_new_std(&priv->hdl, &ov495_ctrl_ops,
++ V4L2_CID_CONTRAST, 0, 16, 1, 7);
++ v4l2_ctrl_new_std(&priv->hdl, &ov495_ctrl_ops,
++ V4L2_CID_SATURATION, 0, 7, 1, 2);
++ v4l2_ctrl_new_std(&priv->hdl, &ov495_ctrl_ops,
++ V4L2_CID_HUE, 0, 23, 1, 12);
++ v4l2_ctrl_new_std(&priv->hdl, &ov495_ctrl_ops,
++ V4L2_CID_GAMMA, -128, 128, 1, 0);
++ v4l2_ctrl_new_std(&priv->hdl, &ov495_ctrl_ops,
++ V4L2_CID_SHARPNESS, 0, 10, 1, 3);
++ v4l2_ctrl_new_std(&priv->hdl, &ov495_ctrl_ops,
++ V4L2_CID_AUTOGAIN, 0, 1, 1, priv->autogain);
++ v4l2_ctrl_new_std(&priv->hdl, &ov495_ctrl_ops,
++ V4L2_CID_GAIN, 0, 0xffff, 1, priv->gain);
++ v4l2_ctrl_new_std(&priv->hdl, &ov495_ctrl_ops,
++ V4L2_CID_EXPOSURE, 0, 0xffff, 1, priv->exposure);
++ v4l2_ctrl_new_std(&priv->hdl, &ov495_ctrl_ops,
++ V4L2_CID_HFLIP, 0, 1, 1, 0);
++ v4l2_ctrl_new_std(&priv->hdl, &ov495_ctrl_ops,
++ V4L2_CID_VFLIP, 0, 1, 1, 0);
++ ctrl = v4l2_ctrl_new_std(&priv->hdl, &ov495_ctrl_ops,
++ V4L2_CID_MIN_BUFFERS_FOR_CAPTURE, 1, 32, 1, 9);
++ if (ctrl)
++ ctrl->flags &= ~V4L2_CTRL_FLAG_READ_ONLY;
++ priv->sd.ctrl_handler = &priv->hdl;
++
++ ret = priv->hdl.error;
++ if (ret)
++ goto cleanup;
++
++ v4l2_ctrl_handler_setup(&priv->hdl);
++
++ priv->pad.flags = MEDIA_PAD_FL_SOURCE;
++ priv->sd.entity.flags |= MEDIA_ENT_F_CAM_SENSOR;
++ ret = media_entity_pads_init(&priv->sd.entity, 1, &priv->pad);
++ if (ret < 0)
++ goto cleanup;
++
++ ret = ov495_parse_dt(client->dev.of_node, priv);
++ if (ret)
++ goto cleanup;
++
++ ret = ov495_initialize(client);
++ if (ret < 0)
++ goto cleanup;
++
++ priv->rect.left = 0;
++ priv->rect.top = 0;
++ priv->rect.width = priv->max_width;
++ priv->rect.height = priv->max_height;
++
++ ret = v4l2_async_register_subdev(&priv->sd);
++ if (ret)
++ goto cleanup;
++
++ if (device_create_file(&client->dev, &dev_attr_otp_id_ov495) != 0) {
++ dev_err(&client->dev, "sysfs otp_id entry creation failed\n");
++ goto cleanup;
++ }
++
++ priv->init_complete = 1;
++
++ return 0;
++
++cleanup:
++ media_entity_cleanup(&priv->sd.entity);
++ v4l2_ctrl_handler_free(&priv->hdl);
++ v4l2_device_unregister_subdev(&priv->sd);
++#ifdef CONFIG_SOC_CAMERA_OV495_OV2775
++ v4l_err(client, "failed to probe @ 0x%02x (%s)\n",
++ client->addr, client->adapter->name);
++#endif
++ return ret;
++}
++
++static int ov495_remove(struct i2c_client *client)
++{
++ struct ov495_priv *priv = i2c_get_clientdata(client);
++
++ device_remove_file(&client->dev, &dev_attr_otp_id_ov495);
++ v4l2_async_unregister_subdev(&priv->sd);
++ media_entity_cleanup(&priv->sd.entity);
++ v4l2_ctrl_handler_free(&priv->hdl);
++ v4l2_device_unregister_subdev(&priv->sd);
++
++ return 0;
++}
++
++#ifdef CONFIG_SOC_CAMERA_OV495_OV2775
++static const struct i2c_device_id ov495_id[] = {
++ { "ov495-ov2775", 0 },
++ { }
++};
++MODULE_DEVICE_TABLE(i2c, ov495_id);
++
++static const struct of_device_id ov495_of_ids[] = {
++ { .compatible = "ovti,ov495-ov2775", },
++ { }
++};
++MODULE_DEVICE_TABLE(of, ov495_of_ids);
++
++static struct i2c_driver ov495_i2c_driver = {
++ .driver = {
++ .name = "ov495-ov2775",
++ .of_match_table = ov495_of_ids,
++ },
++ .probe = ov495_probe,
++ .remove = ov495_remove,
++ .id_table = ov495_id,
++};
++
++module_i2c_driver(ov495_i2c_driver);
++
++MODULE_DESCRIPTION("SoC Camera driver for OV495-OV2775");
++MODULE_AUTHOR("Vladimir Barinov");
++MODULE_LICENSE("GPL");
++#endif
+diff --git a/drivers/media/i2c/soc_camera/ov495_ov2775.h b/drivers/media/i2c/soc_camera/ov495_ov2775.h
+new file mode 100644
+index 0000000..3f53689
+--- /dev/null
++++ b/drivers/media/i2c/soc_camera/ov495_ov2775.h
+@@ -0,0 +1,23 @@
++/*
++ * OmniVision ov495-ov2775 sensor camera wizard 1280x1080@30/UYVY/BT601/8bit
++ *
++ * Copyright (C) 2017 Cogent Embedded, Inc.
++ *
++ * This program is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License as published by the
++ * Free Software Foundation; either version 2 of the License, or (at your
++ * option) any later version.
++ */
++
++struct ov495_reg {
++ u16 reg;
++ u8 val;
++};
++
++static struct ov495_reg ov495_regs_wizard[] = {
++{0x3516, 0x00}, /* unlock write */
++{0xFFFD, 0x80},
++{0xFFFE, 0x20},
++{0x8017, 0x1e | (0 << 6)},
++{0x7c10, 0x01}, /* UYVY */
++};
+diff --git a/drivers/media/i2c/soc_camera/ti954_ti9x3.c b/drivers/media/i2c/soc_camera/ti954_ti9x3.c
+new file mode 100644
+index 0000000..fc7ccda
+--- /dev/null
++++ b/drivers/media/i2c/soc_camera/ti954_ti9x3.c
+@@ -0,0 +1,417 @@
++/*
++ * TI ti954-(ti913/ti953) FPDLinkIII driver
++ *
++ * Copyright (C) 2017 Cogent Embedded, Inc.
++ *
++ * This program is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License as published by the
++ * Free Software Foundation; either version 2 of the License, or (at your
++ * option) any later version.
++ */
++
++#include <linux/delay.h>
++#include <linux/i2c.h>
++#include <linux/module.h>
++#include <linux/of_gpio.h>
++#include <linux/videodev2.h>
++#include <linux/notifier.h>
++
++#include <media/v4l2-common.h>
++#include <media/v4l2-device.h>
++#include <media/v4l2-of.h>
++#include <media/v4l2-subdev.h>
++
++#include "ti9x4_ti9x3.h"
++
++struct ti954_ti9x3_priv {
++ struct v4l2_subdev sd[4];
++ struct device_node *sd_of_node[4];
++ int des_addr;
++ int links;
++ int lanes;
++ int csi_rate;
++ const char *forwarding_mode;
++ const char *cable_mode;
++ atomic_t use_count;
++ struct i2c_client *client;
++ int ti9x3_addr_map[4];
++ char chip_id[6];
++ int xtal_gpio;
++};
++
++static int indirect_write(struct i2c_client *client, unsigned int page, u8 reg, u8 val)
++{
++ if (page > 7)
++ return -EINVAL;
++
++ reg8_write(client, 0xb0, page << 2);
++ reg8_write(client, 0xb1, reg);
++ reg8_write(client, 0xb2, val);
++
++ return 0;
++}
++
++#if 0
++static int indirect_read(struct i2c_client *client, unsigned int page, u8 reg, u8 *val)
++{
++ if (page > 7)
++ return -EINVAL;
++
++ reg8_write(client, 0xb0, page << 2);
++ reg8_write(client, 0xb1, reg);
++ reg8_read(client, 0xb2, val);
++
++ return 0;
++}
++#endif
++
++static void ti954_ti9x3_read_chipid(struct i2c_client *client)
++{
++ struct ti954_ti9x3_priv *priv = i2c_get_clientdata(client);
++
++ /* Chip ID */
++ reg8_read(client, 0xf1, &priv->chip_id[0]);
++ reg8_read(client, 0xf2, &priv->chip_id[1]);
++ reg8_read(client, 0xf3, &priv->chip_id[2]);
++ reg8_read(client, 0xf4, &priv->chip_id[3]);
++ reg8_read(client, 0xf5, &priv->chip_id[4]);
++ priv->chip_id[5] = '\0';
++}
++
++static void ti954_ti9x3_initial_setup(struct i2c_client *client)
++{
++ struct ti954_ti9x3_priv *priv = i2c_get_clientdata(client);
++
++ /* Initial setup */
++ client->addr = priv->des_addr; /* TI954 I2C */
++ reg8_write(client, 0x08, 0x1c); /* I2C glitch filter depth */
++ reg8_write(client, 0x0a, 0x79); /* I2C high pulse width */
++ reg8_write(client, 0x0b, 0x79); /* I2C low pulse width */
++ reg8_write(client, 0x0d, 0xb9); /* VDDIO 3.3V */
++ switch (priv->csi_rate) {
++ case 1600: /* REFCLK = 25MHZ */
++ case 1450: /* REFCLK = 22.5MHZ */
++ reg8_write(client, 0x1f, 0x00); /* CSI rate 1.5/1.6Gbps */
++ break;
++ case 800: /* REFCLK = 25MHZ */
++ reg8_write(client, 0x1f, 0x02); /* CSI rate 800Mbps */
++ break;
++ case 400: /* REFCLK = 25MHZ */
++ reg8_write(client, 0x1f, 0x03); /* CSI rate 400Mbps */
++ break;
++ default:
++ dev_err(&client->dev, "unsupported CSI rate %d\n", priv->csi_rate);
++ }
++
++ if (strcmp(priv->forwarding_mode, "round-robin") == 0) {
++ reg8_write(client, 0x21, 0x01); /* Round Robin forwarding enable */
++ } else if (strcmp(priv->forwarding_mode, "synchronized") == 0) {
++ reg8_write(client, 0x21, 0x44); /* Basic Syncronized forwarding enable (FrameSync must be enabled!!) */
++ }
++
++ reg8_write(client, 0x32, 0x01); /* Select TX (CSI) port 0 */
++ reg8_write(client, 0x33, ((priv->lanes - 1) ^ 0x3) << 4); /* disable CSI output, set CSI lane count, non-continuous CSI mode */
++ reg8_write(client, 0x20, 0xf0); /* disable port forwarding */
++#if 0
++ /* FrameSync setup for REFCLK=25MHz, FPS=30: period_counts=1/2/FPS*25MHz =1/2/30*25Mhz =416666 -> FS_TIME=416666 */
++ /* FrameSync setup for REFCLK=22.5MHz, FPS=30: period_counts=1/2/FPS*22.5Mhz=1/2/30*22.5Mhz=375000 -> FS_TIME=375000 */
++// #define FS_TIME (priv->csi_rate == 1450 ? 376000 : 417666)
++ #define FS_TIME (priv->csi_rate == 1450 ? 385000 : 428000) // FPS=29.2 (new vendor's firmware AWB restriction?)
++ reg8_write(client, 0x1a, FS_TIME >> 16); /* FrameSync time 24bit */
++ reg8_write(client, 0x1b, (FS_TIME >> 8) & 0xff);
++ reg8_write(client, 0x1c, FS_TIME & 0xff);
++ reg8_write(client, 0x18, 0x43); /* Enable FrameSync, 50/50 mode, Frame clock from 25MHz */
++#else
++ /* FrameSync setup for REFCLK=25MHz, FPS=30: period_counts=1/FPS/12mks=1/30/12e-6=2777 -> HI=2, LO=2775 */
++ /* FrameSync setup for REFCLK=22.5MHz, FPS=30: period_counts=1/FPS/13.333mks=1/30/13.333e-6=2500 -> HI=2, LO=2498 */
++ #define FS_TIME (priv->csi_rate == 1450 ? (2498+15) : (2775+15))
++ reg8_write(client, 0x19, 2 >> 8); /* FrameSync high time MSB */
++ reg8_write(client, 0x1a, 2 & 0xff); /* FrameSync high time LSB */
++ reg8_write(client, 0x1b, FS_TIME >> 8); /* FrameSync low time MSB */
++ reg8_write(client, 0x1c, FS_TIME & 0xff); /* FrameSync low time LSB */
++ reg8_write(client, 0x18, 0x01); /* Enable FrameSync, HI/LO mode, Frame clock from port0 */
++#endif
++}
++
++//#define SENSOR_ID 0x30 // ov10635
++//#define SENSOR_ID 0x24 // ov490
++
++static void ti954_ti9x3_fpdlink3_setup(struct i2c_client *client, int idx)
++{
++ struct ti954_ti9x3_priv *priv = i2c_get_clientdata(client);
++
++ /* FPDLinkIII setup */
++ client->addr = priv->des_addr; /* TI954 I2C */
++ reg8_write(client, 0x4c, (idx << 4) | (1 << idx)); /* Select RX port number */
++ usleep_range(2000, 2500); /* wait 2ms */
++ reg8_write(client, 0x58, 0x58); /* Back channel: pass-through/backchannel/CRC enable, Freq=2.5Mbps */
++ reg8_write(client, 0x5c, priv->ti9x3_addr_map[idx] << 1); /* TI9X3 I2C addr */
++// reg8_write(client, 0x5d, SENSOR_ID << 1); /* SENSOR I2C native - must be set by sensor driver */
++// reg8_write(client, 0x65, (0x60 + idx) << 1); /* SENSOR I2C translated - must be set by sensor driver */
++ if (strcmp(priv->cable_mode, "coax") == 0) {
++ reg8_write(client, 0x6d, 0x7f); /* Coax, RAW10 */
++ } else if (strcmp(priv->cable_mode, "stp") == 0) {
++ reg8_write(client, 0x6d, 0x78); /* STP, CSI */
++ }
++ reg8_write(client, 0x70, (idx << 6) | 0x1e); /* CSI data type: yuv422 8-bit, assign VC */
++ reg8_write(client, 0x7c, 0x81); /* BIT(7) - magic to Use RAW10 as 8-bit mode */
++ reg8_write(client, 0x6e, 0x88); /* Sensor reset: backchannel GPIO0/GPIO1 set low */
++}
++
++static int ti954_ti9x3_initialize(struct i2c_client *client)
++{
++ struct ti954_ti9x3_priv *priv = i2c_get_clientdata(client);
++ int idx;
++
++ dev_info(&client->dev, "LINKs=%d, LANES=%d, FORWARDING=%s, CABLE=%s, ID=%s\n",
++ priv->links, priv->lanes, priv->forwarding_mode, priv->cable_mode, priv->chip_id);
++
++ ti954_ti9x3_initial_setup(client);
++
++ for (idx = 0; idx < priv->links; idx++)
++ ti954_ti9x3_fpdlink3_setup(client, idx);
++
++ client->addr = priv->des_addr;
++
++ return 0;
++}
++
++#ifdef CONFIG_VIDEO_ADV_DEBUG
++static int ti954_ti9x3_g_register(struct v4l2_subdev *sd,
++ struct v4l2_dbg_register *reg)
++{
++ struct ti954_ti9x3_priv *priv = v4l2_get_subdevdata(sd);
++ struct i2c_client *client = priv->client;
++ int ret;
++ u8 val = 0;
++
++ ret = reg8_read(client, (u8)reg->reg, &val);
++ if (ret < 0)
++ return ret;
++
++ reg->val = val;
++ reg->size = sizeof(u8);
++
++ return 0;
++}
++
++static int ti954_ti9x3_s_register(struct v4l2_subdev *sd,
++ const struct v4l2_dbg_register *reg)
++{
++ struct ti954_ti9x3_priv *priv = v4l2_get_subdevdata(sd);
++ struct i2c_client *client = priv->client;
++
++ return reg8_write(client, (u8)reg->reg, (u8)reg->val);
++}
++#endif
++
++static int ti954_ti9x3_s_power(struct v4l2_subdev *sd, int on)
++{
++ struct ti954_ti9x3_priv *priv = v4l2_get_subdevdata(sd);
++ struct i2c_client *client = priv->client;
++
++ if (on) {
++ if (atomic_inc_return(&priv->use_count) == 1)
++ reg8_write(client, 0x20, 0x00); /* enable port forwarding to CSI */
++ } else {
++ if (atomic_dec_return(&priv->use_count) == 0)
++ reg8_write(client, 0x20, 0xf0); /* disable port forwarding to CSI */
++ }
++
++ return 0;
++}
++
++static int ti954_ti9x3_registered_async(struct v4l2_subdev *sd)
++{
++ struct ti954_ti9x3_priv *priv = v4l2_get_subdevdata(sd);
++ struct i2c_client *client = priv->client;
++
++ reg8_write(client, 0x33, ((priv->lanes - 1) ^ 0x3) << 4 | 0x1); /* enable CSI output, set CSI lane count, non-continuous CSI mode */
++
++ return 0;
++}
++
++static struct v4l2_subdev_core_ops ti954_ti9x3_subdev_core_ops = {
++#ifdef CONFIG_VIDEO_ADV_DEBUG
++ .g_register = ti954_ti9x3_g_register,
++ .s_register = ti954_ti9x3_s_register,
++#endif
++ .s_power = ti954_ti9x3_s_power,
++ .registered_async = ti954_ti9x3_registered_async,
++};
++
++static struct v4l2_subdev_ops ti954_ti9x3_subdev_ops = {
++ .core = &ti954_ti9x3_subdev_core_ops,
++};
++
++static int ti954_ti9x3_parse_dt(struct i2c_client *client)
++{
++ struct ti954_ti9x3_priv *priv = i2c_get_clientdata(client);
++ struct device_node *np = client->dev.of_node;
++ struct device_node *endpoint = NULL, *rendpoint = NULL;
++ struct property *prop;
++ int err, i;
++ int sensor_delay;
++ char forwarding_mode_default[20] = "round-robin"; /* round-robin, synchronized */
++ char cable_mode_default[5] = "coax"; /* coax, stp */
++ struct property *csi_rate_prop, *dvp_order_prop;
++ u8 val = 0;
++
++ if (of_property_read_u32(np, "ti,links", &priv->links))
++ priv->links = 2;
++
++ if (of_property_read_u32(np, "ti,lanes", &priv->lanes))
++ priv->lanes = 4;
++
++ priv->xtal_gpio = of_get_gpio(np, 0);
++ if (priv->xtal_gpio > 0) {
++ err = devm_gpio_request_one(&client->dev, priv->xtal_gpio, GPIOF_OUT_INIT_LOW, dev_name(&client->dev));
++ if (err)
++ dev_err(&client->dev, "cannot request XTAL gpio %d: %d\n", priv->xtal_gpio, err);
++ else
++ mdelay(250);
++ }
++
++ reg8_read(client, 0x00, &val); /* read TI954 I2C address */
++ if (val != (priv->des_addr << 1)) {
++ prop = of_find_property(np, "reg", NULL);
++ if (prop)
++ of_remove_property(np, prop);
++ return -ENODEV;
++ }
++
++ ti954_ti9x3_read_chipid(client);
++
++ indirect_write(client, 7, 0x15, 0x30);
++ gpio_set_value(priv->xtal_gpio, 1);
++ usleep_range(5000, 5500); /* wait 5ms */
++ indirect_write(client, 7, 0x15, 0);
++
++ if (!of_property_read_u32(np, "ti,sensor_delay", &sensor_delay))
++ mdelay(sensor_delay);
++
++ err = of_property_read_string(np, "ti,forwarding-mode", &priv->forwarding_mode);
++ if (err)
++ priv->forwarding_mode = forwarding_mode_default;
++
++ err = of_property_read_string(np, "ti,cable-mode", &priv->cable_mode);
++ if (err)
++ priv->cable_mode = cable_mode_default;
++
++ for (i = 0; ; i++) {
++ endpoint = of_graph_get_next_endpoint(np, endpoint);
++ if (!endpoint)
++ break;
++
++ of_node_put(endpoint);
++
++ if (i < priv->links) {
++ if (of_property_read_u32(endpoint, "ti9x3-addr", &priv->ti9x3_addr_map[i])) {
++ dev_err(&client->dev, "ti9x3-addr not set\n");
++ return -EINVAL;
++ }
++ priv->sd_of_node[i] = endpoint;
++ }
++
++ rendpoint = of_parse_phandle(endpoint, "remote-endpoint", 0);
++ if (!rendpoint)
++ continue;
++
++ csi_rate_prop = of_find_property(endpoint, "csi-rate", NULL);
++ if (csi_rate_prop) {
++ of_property_read_u32(endpoint, "csi-rate", &priv->csi_rate);
++ of_update_property(rendpoint, csi_rate_prop);
++ }
++
++ dvp_order_prop = of_find_property(endpoint, "dvp-order", NULL);
++ if (dvp_order_prop)
++ of_update_property(rendpoint, dvp_order_prop);
++ }
++
++ return 0;
++}
++
++static int ti954_ti9x3_probe(struct i2c_client *client,
++ const struct i2c_device_id *did)
++{
++ struct ti954_ti9x3_priv *priv;
++ int err, i;
++
++ priv = devm_kzalloc(&client->dev, sizeof(*priv), GFP_KERNEL);
++ if (!priv)
++ return -ENOMEM;
++
++ i2c_set_clientdata(client, priv);
++ priv->des_addr = client->addr;
++ priv->client = client;
++ atomic_set(&priv->use_count, 0);
++
++ err = ti954_ti9x3_parse_dt(client);
++ if (err)
++ goto out;
++
++ err = ti954_ti9x3_initialize(client);
++ if (err < 0)
++ goto out;
++
++ for (i = 0; i < priv->links; i++) {
++ v4l2_subdev_init(&priv->sd[i], &ti954_ti9x3_subdev_ops);
++ priv->sd[i].owner = client->dev.driver->owner;
++ priv->sd[i].dev = &client->dev;
++ priv->sd[i].grp_id = i;
++ v4l2_set_subdevdata(&priv->sd[i], priv);
++ priv->sd[i].of_node = priv->sd_of_node[i];
++
++ snprintf(priv->sd[i].name, V4L2_SUBDEV_NAME_SIZE, "%s %d-%04x",
++ client->dev.driver->name, i2c_adapter_id(client->adapter),
++ client->addr);
++
++ err = v4l2_async_register_subdev(&priv->sd[i]);
++ if (err < 0)
++ goto out;
++ }
++
++out:
++ return err;
++}
++
++static int ti954_ti9x3_remove(struct i2c_client *client)
++{
++ struct ti954_ti9x3_priv *priv = i2c_get_clientdata(client);
++ int i;
++
++ for (i = 0; i < priv->links; i++) {
++ v4l2_async_unregister_subdev(&priv->sd[i]);
++ v4l2_device_unregister_subdev(&priv->sd[i]);
++ }
++
++ return 0;
++}
++
++static const struct of_device_id ti954_ti9x3_dt_ids[] = {
++ { .compatible = "ti,ti954-ti9x3" },
++ {},
++};
++MODULE_DEVICE_TABLE(of, ti954_ti9x3_dt_ids);
++
++static const struct i2c_device_id ti954_ti9x3_id[] = {
++ { "ti954_ti9x3", 0 },
++ { }
++};
++MODULE_DEVICE_TABLE(i2c, ti954_ti9x3_id);
++
++static struct i2c_driver ti954_ti9x3_i2c_driver = {
++ .driver = {
++ .name = "ti954_ti9x3",
++ .of_match_table = of_match_ptr(ti954_ti9x3_dt_ids),
++ },
++ .probe = ti954_ti9x3_probe,
++ .remove = ti954_ti9x3_remove,
++ .id_table = ti954_ti9x3_id,
++};
++
++module_i2c_driver(ti954_ti9x3_i2c_driver);
++
++MODULE_DESCRIPTION("FPDLinkIII driver for TI954-TI9X3");
++MODULE_AUTHOR("Vladimir Barinov");
++MODULE_LICENSE("GPL");
+diff --git a/drivers/media/i2c/soc_camera/ti964_ti9x3.c b/drivers/media/i2c/soc_camera/ti964_ti9x3.c
+new file mode 100644
+index 0000000..8dd0f99
+--- /dev/null
++++ b/drivers/media/i2c/soc_camera/ti964_ti9x3.c
+@@ -0,0 +1,385 @@
++/*
++ * TI (ti964/ti960)-(ti913/ti953) FPDLinkIII driver
++ *
++ * Copyright (C) 2017 Cogent Embedded, Inc.
++ *
++ * This program is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License as published by the
++ * Free Software Foundation; either version 2 of the License, or (at your
++ * option) any later version.
++ */
++
++#include <linux/delay.h>
++#include <linux/i2c.h>
++#include <linux/module.h>
++#include <linux/of_gpio.h>
++#include <linux/videodev2.h>
++#include <linux/notifier.h>
++
++#include <media/v4l2-common.h>
++#include <media/v4l2-device.h>
++#include <media/v4l2-of.h>
++#include <media/v4l2-subdev.h>
++
++#include "ti9x4_ti9x3.h"
++
++struct ti964_ti9x3_priv {
++ struct v4l2_subdev sd[4];
++ struct device_node *sd_of_node[4];
++ int des_addr;
++ int links;
++ int lanes;
++ int csi_rate;
++ const char *forwarding_mode;
++ const char *cable_mode;
++ atomic_t use_count;
++ struct i2c_client *client;
++ int ti9x3_addr_map[4];
++ char chip_id[6];
++};
++
++static void ti964_ti9x3_read_chipid(struct i2c_client *client)
++{
++ struct ti964_ti9x3_priv *priv = i2c_get_clientdata(client);
++
++ /* Chip ID */
++ reg8_read(client, 0xf1, &priv->chip_id[0]);
++ reg8_read(client, 0xf2, &priv->chip_id[1]);
++ reg8_read(client, 0xf3, &priv->chip_id[2]);
++ reg8_read(client, 0xf4, &priv->chip_id[3]);
++ reg8_read(client, 0xf5, &priv->chip_id[4]);
++ priv->chip_id[5] = '\0';
++}
++
++static void ti964_ti9x3_initial_setup(struct i2c_client *client)
++{
++ struct ti964_ti9x3_priv *priv = i2c_get_clientdata(client);
++
++ /* Initial setup */
++ client->addr = priv->des_addr; /* TI964 I2C */
++ reg8_write(client, 0x08, 0x1c); /* I2C glitch filter depth */
++ reg8_write(client, 0x0a, 0x79); /* I2C high pulse width */
++ reg8_write(client, 0x0b, 0x79); /* I2C low pulse width */
++ reg8_write(client, 0x0d, 0xb9); /* VDDIO 3.3V */
++ switch (priv->csi_rate) {
++ case 1600: /* REFCLK = 25MHZ */
++ case 1450: /* REFCLK = 22.5MHZ */
++ reg8_write(client, 0x1f, 0x00); /* CSI rate 1.5/1.6Gbps */
++ break;
++ case 800: /* REFCLK = 25MHZ */
++ reg8_write(client, 0x1f, 0x02); /* CSI rate 800Mbps */
++ break;
++ case 400: /* REFCLK = 25MHZ */
++ reg8_write(client, 0x1f, 0x03); /* CSI rate 400Mbps */
++ break;
++ default:
++ dev_err(&client->dev, "unsupported CSI rate %d\n", priv->csi_rate);
++ }
++
++ if (strcmp(priv->forwarding_mode, "round-robin") == 0) {
++ reg8_write(client, 0x21, 0x01); /* Round Robin forwarding enable */
++ } else if (strcmp(priv->forwarding_mode, "synchronized") == 0) {
++ reg8_write(client, 0x21, 0x44); /* Basic Syncronized forwarding enable (FrameSync must be enabled!!) */
++ }
++
++ reg8_write(client, 0x32, 0x01); /* Select TX (CSI) port 0 */
++ reg8_write(client, 0x33, ((priv->lanes - 1) ^ 0x3) << 4); /* disable CSI output, set CSI lane count, non-continuous CSI mode */
++ reg8_write(client, 0x20, 0xf0); /* disable port forwarding */
++#if 0
++ /* FrameSync setup for REFCLK=25MHz, FPS=30: period_counts=1/2/FPS*25MHz =1/2/30*25Mhz =416666 -> FS_TIME=416666 */
++ /* FrameSync setup for REFCLK=22.5MHz, FPS=30: period_counts=1/2/FPS*22.5Mhz=1/2/30*22.5Mhz=375000 -> FS_TIME=375000 */
++// #define FS_TIME (priv->csi_rate == 1450 ? 376000 : 417666)
++ #define FS_TIME (priv->csi_rate == 1450 ? 385000 : 428000) // FPS=29.2 (new vendor's firmware AWB restriction?)
++ reg8_write(client, 0x1a, FS_TIME >> 16); /* FrameSync time 24bit */
++ reg8_write(client, 0x1b, (FS_TIME >> 8) & 0xff);
++ reg8_write(client, 0x1c, FS_TIME & 0xff);
++ reg8_write(client, 0x18, 0x43); /* Enable FrameSync, 50/50 mode, Frame clock from 25MHz */
++#else
++ /* FrameSync setup for REFCLK=25MHz, FPS=30: period_counts=1/FPS/12mks=1/30/12e-6=2777 -> HI=2, LO=2775 */
++ /* FrameSync setup for REFCLK=22.5MHz, FPS=30: period_counts=1/FPS/13.333mks=1/30/13.333e-6=2500 -> HI=2, LO=2498 */
++ #define FS_TIME (priv->csi_rate == 1450 ? (2498+15) : (2775+15))
++ reg8_write(client, 0x19, 2 >> 8); /* FrameSync high time MSB */
++ reg8_write(client, 0x1a, 2 & 0xff); /* FrameSync high time LSB */
++ reg8_write(client, 0x1b, FS_TIME >> 8); /* FrameSync low time MSB */
++ reg8_write(client, 0x1c, FS_TIME & 0xff); /* FrameSync low time LSB */
++ reg8_write(client, 0x18, 0x01); /* Enable FrameSync, HI/LO mode, Frame clock from port0 */
++#endif
++}
++
++//#define SENSOR_ID 0x30 // ov10635
++//#define SENSOR_ID 0x24 // ov490
++
++static void ti964_ti9x3_fpdlink3_setup(struct i2c_client *client, int idx)
++{
++ struct ti964_ti9x3_priv *priv = i2c_get_clientdata(client);
++
++ /* FPDLinkIII setup */
++ client->addr = priv->des_addr; /* TI964 I2C */
++ reg8_write(client, 0x4c, (idx << 4) | (1 << idx)); /* Select RX port number */
++ usleep_range(2000, 2500); /* wait 2ms */
++ reg8_write(client, 0x58, 0x58); /* Back channel: pass-through/backchannel/CRC enable, Freq=2.5Mbps */
++ reg8_write(client, 0x5c, priv->ti9x3_addr_map[idx] << 1); /* TI9X3 I2C addr */
++// reg8_write(client, 0x5d, SENSOR_ID << 1); /* SENSOR I2C native - must be set by sensor driver */
++// reg8_write(client, 0x65, (0x60 + idx) << 1); /* SENSOR I2C translated - must be set by sensor driver */
++ if (strcmp(priv->cable_mode, "coax") == 0) {
++ reg8_write(client, 0x6d, 0x7f); /* Coax, RAW10 */
++ } else if (strcmp(priv->cable_mode, "stp") == 0) {
++ reg8_write(client, 0x6d, 0x78); /* STP, CSI */
++ }
++ reg8_write(client, 0x70, (idx << 6) | 0x1e); /* CSI data type: yuv422 8-bit, assign VC */
++ reg8_write(client, 0x7c, 0x81); /* BIT(7) - magic to Use RAW10 as 8-bit mode */
++ reg8_write(client, 0x6e, 0x88); /* Sensor reset: backchannel GPIO0/GPIO1 set low */
++}
++
++static int ti964_ti9x3_initialize(struct i2c_client *client)
++{
++ struct ti964_ti9x3_priv *priv = i2c_get_clientdata(client);
++ int idx;
++
++ dev_info(&client->dev, "LINKs=%d, LANES=%d, FORWARDING=%s, CABLE=%s, ID=%s\n",
++ priv->links, priv->lanes, priv->forwarding_mode, priv->cable_mode, priv->chip_id);
++
++ ti964_ti9x3_initial_setup(client);
++
++ for (idx = 0; idx < priv->links; idx++)
++ ti964_ti9x3_fpdlink3_setup(client, idx);
++
++ client->addr = priv->des_addr;
++
++ return 0;
++}
++
++#ifdef CONFIG_VIDEO_ADV_DEBUG
++static int ti964_ti9x3_g_register(struct v4l2_subdev *sd,
++ struct v4l2_dbg_register *reg)
++{
++ struct ti964_ti9x3_priv *priv = v4l2_get_subdevdata(sd);
++ struct i2c_client *client = priv->client;
++ int ret;
++ u8 val = 0;
++
++ ret = reg8_read(client, (u8)reg->reg, &val);
++ if (ret < 0)
++ return ret;
++
++ reg->val = val;
++ reg->size = sizeof(u8);
++
++ return 0;
++}
++
++static int ti964_ti9x3_s_register(struct v4l2_subdev *sd,
++ const struct v4l2_dbg_register *reg)
++{
++ struct ti964_ti9x3_priv *priv = v4l2_get_subdevdata(sd);
++ struct i2c_client *client = priv->client;
++
++ return reg8_write(client, (u8)reg->reg, (u8)reg->val);
++}
++#endif
++
++static int ti964_ti9x3_s_power(struct v4l2_subdev *sd, int on)
++{
++ struct ti964_ti9x3_priv *priv = v4l2_get_subdevdata(sd);
++ struct i2c_client *client = priv->client;
++
++ if (on) {
++ if (atomic_inc_return(&priv->use_count) == 1)
++ reg8_write(client, 0x20, 0x00); /* enable port forwarding to CSI */
++ } else {
++ if (atomic_dec_return(&priv->use_count) == 0)
++ reg8_write(client, 0x20, 0xf0); /* disable port forwarding to CSI */
++ }
++
++ return 0;
++}
++
++static int ti964_ti9x3_registered_async(struct v4l2_subdev *sd)
++{
++ struct ti964_ti9x3_priv *priv = v4l2_get_subdevdata(sd);
++ struct i2c_client *client = priv->client;
++
++ reg8_write(client, 0x33, ((priv->lanes - 1) ^ 0x3) << 4 | 0x1); /* enable CSI output, set CSI lane count, non-continuous CSI mode */
++
++ return 0;
++}
++
++static struct v4l2_subdev_core_ops ti964_ti9x3_subdev_core_ops = {
++#ifdef CONFIG_VIDEO_ADV_DEBUG
++ .g_register = ti964_ti9x3_g_register,
++ .s_register = ti964_ti9x3_s_register,
++#endif
++ .s_power = ti964_ti9x3_s_power,
++ .registered_async = ti964_ti9x3_registered_async,
++};
++
++static struct v4l2_subdev_ops ti964_ti9x3_subdev_ops = {
++ .core = &ti964_ti9x3_subdev_core_ops,
++};
++
++static int ti964_ti9x3_parse_dt(struct i2c_client *client)
++{
++ struct ti964_ti9x3_priv *priv = i2c_get_clientdata(client);
++ struct device_node *np = client->dev.of_node;
++ struct device_node *endpoint = NULL, *rendpoint = NULL;
++ struct property *prop;
++ int err, pwen, i;
++ int sensor_delay;
++ char forwarding_mode_default[20] = "round-robin"; /* round-robin, synchronized */
++ char cable_mode_default[5] = "coax"; /* coax, stp */
++ struct property *csi_rate_prop, *dvp_order_prop;
++ u8 val = 0;
++
++ if (of_property_read_u32(np, "ti,links", &priv->links))
++ priv->links = 4;
++
++ if (of_property_read_u32(np, "ti,lanes", &priv->lanes))
++ priv->lanes = 4;
++
++ pwen = of_get_gpio(np, 0);
++ if (pwen > 0) {
++ err = devm_gpio_request_one(&client->dev, pwen, GPIOF_OUT_INIT_HIGH, dev_name(&client->dev));
++ if (err)
++ dev_err(&client->dev, "cannot request PWEN gpio %d: %d\n", pwen, err);
++ else
++ mdelay(250);
++ }
++
++ reg8_read(client, 0x00, &val); /* read TI964 I2C address */
++ if (val != (priv->des_addr << 1)) {
++ prop = of_find_property(np, "reg", NULL);
++ if (prop)
++ of_remove_property(np, prop);
++ return -ENODEV;
++ }
++
++ ti964_ti9x3_read_chipid(client);
++
++ if (!of_property_read_u32(np, "ti,sensor_delay", &sensor_delay))
++ mdelay(sensor_delay);
++
++ err = of_property_read_string(np, "ti,forwarding-mode", &priv->forwarding_mode);
++ if (err)
++ priv->forwarding_mode = forwarding_mode_default;
++
++ err = of_property_read_string(np, "ti,cable-mode", &priv->cable_mode);
++ if (err)
++ priv->cable_mode = cable_mode_default;
++
++ for (i = 0; ; i++) {
++ endpoint = of_graph_get_next_endpoint(np, endpoint);
++ if (!endpoint)
++ break;
++
++ of_node_put(endpoint);
++
++ if (i < priv->links) {
++ if (of_property_read_u32(endpoint, "ti9x3-addr", &priv->ti9x3_addr_map[i])) {
++ dev_err(&client->dev, "ti9x3-addr not set\n");
++ return -EINVAL;
++ }
++ priv->sd_of_node[i] = endpoint;
++ }
++
++ rendpoint = of_parse_phandle(endpoint, "remote-endpoint", 0);
++ if (!rendpoint)
++ continue;
++
++ csi_rate_prop = of_find_property(endpoint, "csi-rate", NULL);
++ if (csi_rate_prop) {
++ of_property_read_u32(endpoint, "csi-rate", &priv->csi_rate);
++ of_update_property(rendpoint, csi_rate_prop);
++ }
++
++ dvp_order_prop = of_find_property(endpoint, "dvp-order", NULL);
++ if (dvp_order_prop)
++ of_update_property(rendpoint, dvp_order_prop);
++ }
++
++ return 0;
++}
++
++static int ti964_ti9x3_probe(struct i2c_client *client,
++ const struct i2c_device_id *did)
++{
++ struct ti964_ti9x3_priv *priv;
++ int err, i;
++
++ priv = devm_kzalloc(&client->dev, sizeof(*priv), GFP_KERNEL);
++ if (!priv)
++ return -ENOMEM;
++
++ i2c_set_clientdata(client, priv);
++ priv->des_addr = client->addr;
++ priv->client = client;
++ atomic_set(&priv->use_count, 0);
++
++ err = ti964_ti9x3_parse_dt(client);
++ if (err)
++ goto out;
++
++ err = ti964_ti9x3_initialize(client);
++ if (err < 0)
++ goto out;
++
++ for (i = 0; i < priv->links; i++) {
++ v4l2_subdev_init(&priv->sd[i], &ti964_ti9x3_subdev_ops);
++ priv->sd[i].owner = client->dev.driver->owner;
++ priv->sd[i].dev = &client->dev;
++ priv->sd[i].grp_id = i;
++ v4l2_set_subdevdata(&priv->sd[i], priv);
++ priv->sd[i].of_node = priv->sd_of_node[i];
++
++ snprintf(priv->sd[i].name, V4L2_SUBDEV_NAME_SIZE, "%s %d-%04x",
++ client->dev.driver->name, i2c_adapter_id(client->adapter),
++ client->addr);
++
++ err = v4l2_async_register_subdev(&priv->sd[i]);
++ if (err < 0)
++ goto out;
++ }
++
++out:
++ return err;
++}
++
++static int ti964_ti9x3_remove(struct i2c_client *client)
++{
++ struct ti964_ti9x3_priv *priv = i2c_get_clientdata(client);
++ int i;
++
++ for (i = 0; i < priv->links; i++) {
++ v4l2_async_unregister_subdev(&priv->sd[i]);
++ v4l2_device_unregister_subdev(&priv->sd[i]);
++ }
++
++ return 0;
++}
++
++static const struct of_device_id ti964_ti9x3_dt_ids[] = {
++ { .compatible = "ti,ti964-ti9x3" },
++ {},
++};
++MODULE_DEVICE_TABLE(of, ti964_ti9x3_dt_ids);
++
++static const struct i2c_device_id ti964_ti9x3_id[] = {
++ { "ti964_ti9x3", 0 },
++ { }
++};
++MODULE_DEVICE_TABLE(i2c, ti964_ti9x3_id);
++
++static struct i2c_driver ti964_ti9x3_i2c_driver = {
++ .driver = {
++ .name = "ti964_ti9x3",
++ .of_match_table = of_match_ptr(ti964_ti9x3_dt_ids),
++ },
++ .probe = ti964_ti9x3_probe,
++ .remove = ti964_ti9x3_remove,
++ .id_table = ti964_ti9x3_id,
++};
++
++module_i2c_driver(ti964_ti9x3_i2c_driver);
++
++MODULE_DESCRIPTION("FPDLinkIII driver for TI964-TI9X3");
++MODULE_AUTHOR("Vladimir Barinov");
++MODULE_LICENSE("GPL");
+diff --git a/drivers/media/i2c/soc_camera/ti9x4_ti9x3.h b/drivers/media/i2c/soc_camera/ti9x4_ti9x3.h
+new file mode 100644
+index 0000000..69d3728
+--- /dev/null
++++ b/drivers/media/i2c/soc_camera/ti9x4_ti9x3.h
+@@ -0,0 +1,153 @@
++/*
++ * TI FPDLinkIII driver include file
++ *
++ * Copyright (C) 2017 Cogent Embedded, Inc.
++ *
++ * This program is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License as published by the
++ * Free Software Foundation; either version 2 of the License, or (at your
++ * option) any later version.
++ */
++
++#ifndef _TI9X4_H
++#define _TI9X4_H
++
++//#define DEBUG
++#ifdef DEBUG
++#undef dev_dbg
++#define dev_dbg dev_info
++#endif
++
++#define MAXIM_NUM_RETRIES 1 /* number of read/write retries */
++#define BROADCAST 0x6f
++
++static inline int reg8_read(struct i2c_client *client, u8 reg, u8 *val)
++{
++ int ret, retries;
++
++ for (retries = MAXIM_NUM_RETRIES; retries; retries--) {
++ ret = i2c_smbus_read_byte_data(client, reg);
++ if (!(ret < 0))
++ break;
++ }
++
++ if (ret < 0) {
++ dev_dbg(&client->dev,
++ "read fail: chip 0x%x register 0x%x: %d\n",
++ client->addr, reg, ret);
++ } else {
++ *val = ret;
++ }
++
++ return ret < 0 ? ret : 0;
++}
++
++static inline int reg8_write(struct i2c_client *client, u8 reg, u8 val)
++{
++ int ret, retries;
++
++ for (retries = MAXIM_NUM_RETRIES; retries; retries--) {
++ ret = i2c_smbus_write_byte_data(client, reg, val);
++ if (!(ret < 0))
++ break;
++ }
++
++ if (ret < 0) {
++ dev_dbg(&client->dev,
++ "write fail: chip 0x%x register 0x%x: %d\n",
++ client->addr, reg, ret);
++ }
++
++ return ret < 0 ? ret : 0;
++}
++
++static inline int reg16_read(struct i2c_client *client, u16 reg, u8 *val)
++{
++ int ret, retries;
++ u8 buf[2] = {reg >> 8, reg & 0xff};
++
++ for (retries = MAXIM_NUM_RETRIES; retries; retries--) {
++ ret = i2c_master_send(client, buf, 2);
++ if (ret == 2) {
++ ret = i2c_master_recv(client, buf, 1);
++ if (ret == 1)
++ break;
++ }
++ }
++
++ if (ret < 0) {
++ dev_dbg(&client->dev,
++ "read fail: chip 0x%x register 0x%x: %d\n",
++ client->addr, reg, ret);
++ } else {
++ *val = buf[0];
++ }
++
++ return ret < 0 ? ret : 0;
++}
++
++static inline int reg16_write(struct i2c_client *client, u16 reg, u8 val)
++{
++ int ret, retries;
++ u8 buf[3] = {reg >> 8, reg & 0xff, val};
++
++ for (retries = MAXIM_NUM_RETRIES; retries; retries--) {
++ ret = i2c_master_send(client, buf, 3);
++ if (ret == 3)
++ break;
++ }
++
++ if (ret < 0) {
++ dev_dbg(&client->dev,
++ "write fail: chip 0x%x register 0x%x: %d\n",
++ client->addr, reg, ret);
++ }
++
++ return ret < 0 ? ret : 0;
++}
++
++static inline int reg16_read16(struct i2c_client *client, u16 reg, u16 *val)
++{
++ int ret, retries;
++ u8 buf[2] = {reg >> 8, reg & 0xff};
++
++ for (retries = MAXIM_NUM_RETRIES; retries; retries--) {
++ ret = i2c_master_send(client, buf, 2);
++ if (ret == 2) {
++ ret = i2c_master_recv(client, buf, 2);
++ if (ret == 2)
++ break;
++ }
++ }
++
++ if (ret < 0) {
++ dev_err(&client->dev,
++ "read fail: chip 0x%x register 0x%x: %d\n",
++ client->addr, reg, ret);
++ } else {
++ *val = ((u16)buf[0] << 8) | buf[1];
++ }
++
++ return ret < 0 ? ret : 0;
++}
++
++static inline int reg16_write16(struct i2c_client *client, u16 reg, u16 val)
++{
++ int ret, retries;
++ u8 buf[4] = {reg >> 8, reg & 0xff, val >> 8, val & 0xff};
++
++ for (retries = MAXIM_NUM_RETRIES; retries; retries--) {
++ ret = i2c_master_send(client, buf, 4);
++ if (ret == 4)
++ break;
++ }
++
++ if (ret < 0) {
++ dev_err(&client->dev,
++ "write fail: chip 0x%x register 0x%x: %d\n",
++ client->addr, reg, ret);
++ }
++
++ return ret < 0 ? ret : 0;
++}
++#endif /* _TI9X4_H */
+diff --git a/drivers/media/platform/soc_camera/rcar_csi2.c b/drivers/media/platform/soc_camera/rcar_csi2.c
+index 4d95da6..2ef27e8 100644
+--- a/drivers/media/platform/soc_camera/rcar_csi2.c
++++ b/drivers/media/platform/soc_camera/rcar_csi2.c
+@@ -37,8 +37,9 @@
+
+ #include <media/v4l2-of.h>
+
++//#define RCAR_CSI2_DUMP
++
+ #define DRV_NAME "rcar_csi2"
+-#define CONNECT_SLAVE_NAME "adv7482"
+ #define VC_MAX_CHANNEL 4
+
+ #define RCAR_CSI2_TREF 0x00
+@@ -63,6 +64,7 @@
+
+ #define RCAR_CSI2_LINKCNT 0x48
+ #define RCAR_CSI2_LSWAP 0x4C
++#define RCAR_CSI2_PHTW 0x50
+ #define RCAR_CSI2_PHTC 0x58
+ #define RCAR_CSI2_PHYPLL 0x68
+
+@@ -70,6 +72,10 @@
+ #define RCAR_CSI2_PHCLM 0x78
+ #define RCAR_CSI2_PHDLM 0x7C
+
++#define RCAR_CSI2_CSI0CLKFCPR 0x254 /* CSI0CLK Frequency Configuration Preset */
++/* CSI0CLK frequency configuration bit */
++#define CSI0CLKFREQRANGE(n) ((n & 0x3f) << 16)
++
+ #define RCAR_CSI2_PHYCNT_SHUTDOWNZ (1 << 17)
+ #define RCAR_CSI2_PHYCNT_RSTZ (1 << 16)
+ #define RCAR_CSI2_PHYCNT_ENABLECLK (1 << 4)
+@@ -106,6 +112,9 @@
+ #define RCAR_CSI2_LSWAP_L0SEL_PLANE2 (2 << 0)
+ #define RCAR_CSI2_LSWAP_L0SEL_PLANE3 (3 << 0)
+
++#define RCAR_CSI2_PHTW_DWEN (1 << 24)
++#define RCAR_CSI2_PHTW_CWEN (1 << 8)
++
+ #define RCAR_CSI2_PHTC_TESTCLR (1 << 0)
+
+ /* interrupt status registers */
+@@ -159,6 +168,11 @@
+ { }
+ };
+
++static const struct soc_device_attribute r8a7795[] = {
++ { .soc_id = "r8a7795", .revision = "ES2.0" },
++ { }
++};
++
+ enum chip_id {
+ RCAR_GEN3,
+ RCAR_GEN2,
+@@ -179,6 +193,7 @@ struct rcar_csi2_link_config {
+ unsigned char lanes;
+ unsigned long vcdt;
+ unsigned long vcdt2;
++ unsigned int csi_rate;
+ };
+
+ #define INIT_RCAR_CSI2_LINK_CONFIG(m) \
+@@ -192,8 +207,7 @@ struct rcar_csi_irq_counter_log {
+ };
+
+ struct rcar_csi2 {
+- struct v4l2_subdev subdev;
+- struct v4l2_mbus_framefmt *mf;
++ struct v4l2_subdev subdev[4];
+ unsigned int irq;
+ unsigned long mipi_flags;
+ void __iomem *base;
+@@ -205,7 +219,9 @@ struct rcar_csi2 {
+ unsigned int field;
+ unsigned int code;
+ unsigned int lanes;
++ unsigned int csi_rate;
+ spinlock_t lock;
++ atomic_t use_count;
+ };
+
+ #define RCAR_CSI_80MBPS 0
+@@ -251,6 +267,89 @@ struct rcar_csi2 {
+ #define RCAR_CSI_1400MBPS 40
+ #define RCAR_CSI_1450MBPS 41
+ #define RCAR_CSI_1500MBPS 42
++#define RCAR_CSI_NUMRATES 43
++
++#define RCAR_CSI2_PHxM0(i) (0xf0 + i * 0x08)
++#define RCAR_CSI2_PHxM1(i) (0xf4 + i * 0x08)
++#define RCAR_CSI2_PHRM(i) (0x110 + i * 0x04)
++#define RCAR_CSI2_PHCM(i) (0x120 + i * 0x04)
++#define RCAR_CSI2_SERCCNT 0x140
++#define RCAR_CSI2_SSERCCNT 0x144
++#define RCAR_CSI2_ECCCM 0x148
++#define RCAR_CSI2_ECECM 0x14c
++#define RCAR_CSI2_CRCECM 0x150
++#define RCAR_CSI2_LCNT(i) (0x160 + i * 0x04)
++#define RCAR_CSI2_LCNTM(i) (0x168 + i * 0x04)
++#define RCAR_CSI2_FCNTM 0x170
++#define RCAR_CSI2_FCNTM2 0x174
++#define RCAR_CSI2_VINSM(i) (0x190 + i * 0x04)
++#define RCAR_CSI2_PHM(i) (0x1C0 + i * 0x04)
++
++#define RCAR_CSI2_INTSTATE_ALL 0x3FFFFCDD
++
++#ifdef RCAR_CSI2_DUMP
++static void rcar_sci2_debug_show(struct rcar_csi2 *priv)
++{
++ int i;
++ u32 reg0, reg1;
++
++ printk("Debug registers:\n");
++ printk("FCNTM : 0x%08x\n", ioread32(priv->base + RCAR_CSI2_FCNTM));
++ printk("FCNTM2: 0x%08x\n", ioread32(priv->base + RCAR_CSI2_FCNTM2));
++
++ for (i = 0; i < 4; i++) {
++ reg0 = ioread32(priv->base + RCAR_CSI2_PHxM0(i));
++ reg1 = ioread32(priv->base + RCAR_CSI2_PHxM1(i));
++
++ printk("Packet header %d: dt: 0x%02x, vc: %d, wc: %d, cnt: %d\n",
++ i,
++ reg0 & 0x3F, (reg0 >> 6) & 0x03, (reg0 >> 8) & 0xffff,
++ reg1 & 0xffff);
++ }
++ for (i = 0; i < 3; i++) {
++ reg0 = ioread32(priv->base + RCAR_CSI2_PHRM(i));
++
++ printk("Packet header R %d dt: 0x%02x, vc: %d, wc: %d, ecc: 0x%02x\n",
++ i,
++ reg0 & 0x3F, (reg0 >> 6) & 0x03, (reg0 >> 8) & 0xffff,
++ (reg0 >> 24) & 0xff);
++ }
++ for (i = 0; i < 2; i++) {
++ reg0 = ioread32(priv->base + RCAR_CSI2_PHCM(i));
++
++ printk("Packet header C %d: dt: 0x%02x, vc: %d, wc: %d, cal_parity: 0x%02x\n",
++ i,
++ reg0 & 0x3F, (reg0 >> 6) & 0x03, (reg0 >> 8) & 0xffff,
++ (reg0 >> 24) & 0xff);
++ }
++ for (i = 0; i < 8; i++) {
++ reg0 = ioread32(priv->base + RCAR_CSI2_PHM(i));
++
++ printk("Packet header Monitor %d: dt: 0x%02x, vc: %d, wc: %d, ecc: 0x%02x\n",
++ i + 1,
++ reg0 & 0x3F, (reg0 >> 6) & 0x03, (reg0 >> 8) & 0xffff,
++ (reg0 >> 24) & 0xff);
++ }
++ for (i = 0; i < 3; i++)
++ printk("VINSM%d: 0x%08x\n", i, ioread32(priv->base + RCAR_CSI2_VINSM(i)));
++ printk("SERCCNT: %d\n",
++ ioread32(priv->base + RCAR_CSI2_SERCCNT));
++ printk("SSERCCNT: %d\n",
++ ioread32(priv->base + RCAR_CSI2_SSERCCNT));
++ printk("ECCCM: %d\n",
++ ioread32(priv->base + RCAR_CSI2_ECCCM));
++ printk("ECECM: %d\n",
++ ioread32(priv->base + RCAR_CSI2_ECECM));
++ printk("CRCECM: %d\n",
++ ioread32(priv->base + RCAR_CSI2_CRCECM));
++ for (i = 0; i < 2; i++)
++ printk("LCNT%d: 0x%08x\n", i, ioread32(priv->base + RCAR_CSI2_LCNT(i)));
++ for (i = 0; i < 2; i++)
++ printk("LCNTM%d: 0x%08x\n", i, ioread32(priv->base + RCAR_CSI2_LCNTM(i)));
++}
++#else
++#define rcar_sci2_debug_show(args)
++#endif /* RCAR_CSI2_DUMP */
+
+ static int rcar_csi2_set_phy_freq(struct rcar_csi2 *priv)
+ {
+@@ -265,7 +364,7 @@ static int rcar_csi2_set_phy_freq(struct rcar_csi2 *priv)
+ 0x16, 0x36, 0x56, 0x76, 0x18, /* 1150M, 1200M, 1250M, 1300M, 1350M */
+ 0x38, 0x58, 0x78 /* 1400M, 1450M, 1500M */
+ };
+- const uint32_t const hs_freq_range[43] = {
++ const uint32_t const hs_freq_range_m3[43] = {
+ 0x00, 0x10, 0x20, 0x30, 0x01, /* 0-4 */
+ 0x11, 0x21, 0x31, 0x02, 0x12, /* 5-9 */
+ 0x22, 0x32, 0x03, 0x13, 0x23, /* 10-14 */
+@@ -276,47 +375,33 @@ static int rcar_csi2_set_phy_freq(struct rcar_csi2 *priv)
+ 0x0B, 0x1B, 0x2B, 0x3B, 0x0C, /* 35-39 */
+ 0x1C, 0x2C, 0x3C /* 40-42 */
+ };
++ const uint32_t const hs_freq_range_h3[43] = {
++ 0x00, 0x10, 0x20, 0x30, 0x01, /* 0-4 */
++ 0x11, 0x21, 0x31, 0x02, 0x12, /* 5-9 */
++ 0x22, 0x32, 0x03, 0x13, 0x23, /* 10-14 */
++ 0x33, 0x04, 0x14, 0x25, 0x35, /* 15-19 */
++ 0x05, 0x26, 0x36, 0x37, 0x07, /* 20-24 */
++ 0x18, 0x28, 0x39, 0x09, 0x19, /* 25-29 */
++ 0x29, 0x3A, 0x0A, 0x1A, 0x2A, /* 30-34 */
++ 0x3B, 0x0B, 0x1B, 0x2B, 0x3C, /* 35-39 */
++ 0x0C, 0x1C, 0x2C /* 40-42 */
++ };
++ const uint32_t const csi2_rate_range[43] = {
++ 80, 90, 100, 110, 120, /* 0-4 */
++ 130, 140, 150, 160, 170, /* 5-9 */
++ 180, 190, 205, 220, 235, /* 10-14 */
++ 250, 275, 300, 325, 350, /* 15-19 */
++ 400, 450, 500, 550, 600, /* 20-24 */
++ 650, 700, 750, 800, 850, /* 25-29 */
++ 900, 950, 1000, 1050, 1100, /* 30-34 */
++ 1150, 1200, 1250, 1300, 1350, /* 35-39 */
++ 1400, 1450, 1500 /* 40-42 */
++ };
+ uint32_t bps_per_lane = RCAR_CSI_190MBPS;
+
+- dev_dbg(&priv->pdev->dev, "Input size (%dx%d%c)\n",
+- priv->mf->width, priv->mf->height,
+- (priv->mf->field == V4L2_FIELD_NONE) ? 'p' : 'i');
+-
+- switch (priv->lanes) {
+- case 1:
+- bps_per_lane = RCAR_CSI_400MBPS;
+- break;
+- case 4:
+- if (priv->mf->field == V4L2_FIELD_NONE) {
+- if ((priv->mf->width == 1920) &&
+- (priv->mf->height == 1080))
+- bps_per_lane = RCAR_CSI_900MBPS;
+- else if ((priv->mf->width == 1280) &&
+- (priv->mf->height == 720))
+- bps_per_lane = RCAR_CSI_450MBPS;
+- else if ((priv->mf->width == 720) &&
+- (priv->mf->height == 480))
+- bps_per_lane = RCAR_CSI_190MBPS;
+- else if ((priv->mf->width == 720) &&
+- (priv->mf->height == 576))
+- bps_per_lane = RCAR_CSI_190MBPS;
+- else if ((priv->mf->width == 640) &&
+- (priv->mf->height == 480))
+- bps_per_lane = RCAR_CSI_100MBPS;
+- else
+- goto error;
+- } else {
+- if ((priv->mf->width == 1920) &&
+- (priv->mf->height == 1080))
+- bps_per_lane = RCAR_CSI_450MBPS;
+- else
+- goto error;
+- }
+- break;
+- default:
+- dev_err(&priv->pdev->dev, "ERROR: lanes is invalid (%d)\n",
+- priv->lanes);
+- return -EINVAL;
++ for (bps_per_lane = 0; bps_per_lane < RCAR_CSI_NUMRATES; bps_per_lane++) {
++ if (priv->csi_rate <= csi2_rate_range[bps_per_lane])
++ break;
+ }
+
+ dev_dbg(&priv->pdev->dev, "bps_per_lane (%d)\n", bps_per_lane);
+@@ -325,16 +410,14 @@ static int rcar_csi2_set_phy_freq(struct rcar_csi2 *priv)
+ iowrite32((hs_freq_range_v3m[bps_per_lane] << 16) |
+ RCAR_CSI2_PHTW_DWEN | RCAR_CSI2_PHTW_CWEN | 0x44,
+ priv->base + RCAR_CSI2_PHTW);
++ else if (soc_device_match(r8a7795))
++ iowrite32(hs_freq_range_h3[bps_per_lane] << 16,
++ priv->base + RCAR_CSI2_PHYPLL);
+ else
+- iowrite32(hs_freq_range[bps_per_lane] << 16,
++ /* h3 ws1.x is similar to m3 */
++ iowrite32(hs_freq_range_m3[bps_per_lane] << 16,
+ priv->base + RCAR_CSI2_PHYPLL);
+ return 0;
+-
+-error:
+- dev_err(&priv->pdev->dev, "Not support resolution (%dx%d%c)\n",
+- priv->mf->width, priv->mf->height,
+- (priv->mf->field == V4L2_FIELD_NONE) ? 'p' : 'i');
+- return -EINVAL;
+ }
+
+ static irqreturn_t rcar_csi2_irq(int irq, void *data)
+@@ -392,6 +475,16 @@ static int rcar_csi2_hwinit(struct rcar_csi2 *priv)
+ iowrite32(0x0001000f, priv->base + RCAR_CSI2_FLD);
+ tmp |= 0x1;
+ break;
++ case 2:
++ /* First field number setting */
++ iowrite32(0x0001000f, priv->base + RCAR_CSI2_FLD);
++ tmp |= 0x3;
++ break;
++ case 3:
++ /* First field number setting */
++ iowrite32(0x0001000f, priv->base + RCAR_CSI2_FLD);
++ tmp |= 0x7;
++ break;
+ case 4:
+ /* First field number setting */
+ iowrite32(0x0002000f, priv->base + RCAR_CSI2_FLD);
+@@ -404,11 +497,27 @@ static int rcar_csi2_hwinit(struct rcar_csi2 *priv)
+ return -EINVAL;
+ }
+
++ if (soc_device_match(r8a7795)) {
++ /* Set PHY Test Interface Write Register in R-Car H3(ES2.0) */
++ iowrite32(0x01cc01e2, priv->base + RCAR_CSI2_PHTW);
++ iowrite32(0x010101e3, priv->base + RCAR_CSI2_PHTW);
++ iowrite32(0x010101e4, priv->base + RCAR_CSI2_PHTW);
++ iowrite32(0x01100104, priv->base + RCAR_CSI2_PHTW);
++ iowrite32(0x01030100, priv->base + RCAR_CSI2_PHTW);
++ iowrite32(0x01800107, priv->base + RCAR_CSI2_PHTW);
++ }
++
+ /* set PHY frequency */
+ ret = rcar_csi2_set_phy_freq(priv);
+ if (ret < 0)
+ return ret;
+
++ /* Set CSI0CLK Frequency Configuration Preset Register
++ * in R-Car H3(ES2.0)
++ */
++ if (soc_device_match(r8a7795))
++ iowrite32(CSI0CLKFREQRANGE(32), priv->base + RCAR_CSI2_CSI0CLKFCPR);
++
+ /* Enable lanes */
+ iowrite32(tmp, priv->base + RCAR_CSI2_PHYCNT);
+
+@@ -469,32 +578,22 @@ static int rcar_csi2_hwinit(struct rcar_csi2 *priv)
+
+ static int rcar_csi2_s_power(struct v4l2_subdev *sd, int on)
+ {
+- struct rcar_csi2 *priv = container_of(sd, struct rcar_csi2, subdev);
+- struct v4l2_subdev *tmp_sd;
+- struct v4l2_subdev_format fmt = {
+- .which = V4L2_SUBDEV_FORMAT_ACTIVE,
+- };
+- struct v4l2_mbus_framefmt *mf = &fmt.format;
++ struct rcar_csi2 *priv = v4l2_get_subdevdata(sd);
+ int ret = 0;
+
+ if (on) {
+- v4l2_device_for_each_subdev(tmp_sd, sd->v4l2_dev) {
+- if (strncmp(tmp_sd->name, CONNECT_SLAVE_NAME,
+- sizeof(CONNECT_SLAVE_NAME) - 1) == 0) {
+- v4l2_subdev_call(tmp_sd, pad, get_fmt,
+- NULL, &fmt);
+- if (ret < 0)
+- return ret;
+- }
++ if (atomic_inc_return(&priv->use_count) == 1) {
++ pm_runtime_get_sync(&priv->pdev->dev);
++ ret = rcar_csi2_hwinit(priv);
++ if (ret < 0)
++ return ret;
+ }
+- priv->mf = mf;
+- pm_runtime_get_sync(&priv->pdev->dev);
+- ret = rcar_csi2_hwinit(priv);
+- if (ret < 0)
+- return ret;
+ } else {
+- rcar_csi2_hwdeinit(priv);
+- pm_runtime_put_sync(&priv->pdev->dev);
++ if (atomic_dec_return(&priv->use_count) == 0) {
++ rcar_sci2_debug_show(priv);
++ rcar_csi2_hwdeinit(priv);
++ pm_runtime_put_sync(&priv->pdev->dev);
++ }
+ }
+
+ return ret;
+@@ -543,18 +642,19 @@ static int rcar_csi2_parse_dt(struct device_node *np,
+ return -EINVAL;
+
+ v4l2_of_parse_endpoint(endpoint, &bus_cfg);
++ ret = of_property_read_u32(endpoint, "csi-rate", &config->csi_rate);
++ if (ret < 0) {
++ printk(KERN_ERR "csi-rate not set\n");
++ return ret;
++ }
+ of_node_put(endpoint);
+
+ config->lanes = bus_cfg.bus.mipi_csi2.num_data_lanes;
+
+- ret = of_property_read_string(np, "adi,input-interface", &str);
+- if (ret < 0)
+- return ret;
+-
+ vc_np = of_get_child_by_name(np, "virtual,channel");
+
+- config->vcdt = 0;
+- config->vcdt2 = 0;
++ config->vcdt = 0x81008000;
++ config->vcdt2 = 0x83008200;
+ for (i = 0; i < VC_MAX_CHANNEL; i++) {
+ sprintf(csi_name, "csi2_vc%d", i);
+
+@@ -573,6 +673,8 @@ static int rcar_csi2_parse_dt(struct device_node *np,
+ config->vcdt |= (0x24 << (i * 16));
+ else if (!strcmp(str, "ycbcr422"))
+ config->vcdt |= (0x1e << (i * 16));
++ else if (!strcmp(str, "raw8"))
++ config->vcdt |= (0x2a << (i * 16));
+ else
+ config->vcdt |= 0;
+
+@@ -587,6 +689,8 @@ static int rcar_csi2_parse_dt(struct device_node *np,
+ config->vcdt2 |= (0x24 << (j * 16));
+ else if (!strcmp(str, "ycbcr422"))
+ config->vcdt2 |= (0x1e << (j * 16));
++ else if (!strcmp(str, "raw8"))
++ config->vcdt2 |= (0x2a << (j * 16));
+ else
+ config->vcdt2 |= 0;
+
+@@ -608,6 +712,7 @@ static int rcar_csi2_probe(struct platform_device *pdev)
+ /* Platform data specify the PHY, lanes, ECC, CRC */
+ struct rcar_csi2_pdata *pdata;
+ struct rcar_csi2_link_config link_config;
++ int i;
+
+ dev_dbg(&pdev->dev, "CSI2 probed.\n");
+
+@@ -618,12 +723,7 @@ static int rcar_csi2_probe(struct platform_device *pdev)
+ if (ret)
+ return ret;
+
+- if (link_config.lanes == 4)
+- dev_info(&pdev->dev,
+- "Detected rgb888 in rcar_csi2_parse_dt\n");
+- else
+- dev_info(&pdev->dev,
+- "Detected YCbCr422 in rcar_csi2_parse_dt\n");
++ dev_info(&pdev->dev, "Data lanes %d, link freq %d\n", link_config.lanes, link_config.csi_rate);
+ } else {
+ pdata = pdev->dev.platform_data;
+ if (!pdata)
+@@ -655,23 +755,27 @@ static int rcar_csi2_probe(struct platform_device *pdev)
+ return ret;
+
+ priv->pdev = pdev;
+- priv->subdev.owner = THIS_MODULE;
+- priv->subdev.dev = &pdev->dev;
+ priv->lanes = link_config.lanes;
+ priv->vcdt = link_config.vcdt;
+ priv->vcdt2 = link_config.vcdt2;
++ priv->csi_rate = link_config.csi_rate;
++ atomic_set(&priv->use_count, 0);
+
+- platform_set_drvdata(pdev, &priv->subdev);
++ platform_set_drvdata(pdev, priv);
+
+- v4l2_subdev_init(&priv->subdev, &rcar_csi2_subdev_ops);
+- v4l2_set_subdevdata(&priv->subdev, &pdev->dev);
++ for (i= 0; i < 4; i++) {
++ priv->subdev[i].owner = THIS_MODULE;
++ priv->subdev[i].dev = &pdev->dev;
++ v4l2_subdev_init(&priv->subdev[i], &rcar_csi2_subdev_ops);
++ v4l2_set_subdevdata(&priv->subdev[i], priv);
+
+- snprintf(priv->subdev.name, V4L2_SUBDEV_NAME_SIZE, "rcar_csi2.%s",
+- dev_name(&pdev->dev));
++ snprintf(priv->subdev[i].name, V4L2_SUBDEV_NAME_SIZE, "rcar_csi2.%s",
++ dev_name(&pdev->dev));
+
+- ret = v4l2_async_register_subdev(&priv->subdev);
+- if (ret < 0)
+- return ret;
++ ret = v4l2_async_register_subdev(&priv->subdev[i]);
++ if (ret < 0)
++ return ret;
++ }
+
+ spin_lock_init(&priv->lock);
+
+@@ -684,10 +788,11 @@ static int rcar_csi2_probe(struct platform_device *pdev)
+
+ static int rcar_csi2_remove(struct platform_device *pdev)
+ {
+- struct v4l2_subdev *subdev = platform_get_drvdata(pdev);
+- struct rcar_csi2 *priv = container_of(subdev, struct rcar_csi2, subdev);
++ struct rcar_csi2 *priv = platform_get_drvdata(pdev);
++ int i;
+
+- v4l2_async_unregister_subdev(&priv->subdev);
++ for (i= 0; i < 4; i++)
++ v4l2_async_unregister_subdev(&priv->subdev[i]);
+ pm_runtime_disable(&pdev->dev);
+
+ return 0;
+diff --git a/drivers/media/platform/soc_camera/rcar_vin.c b/drivers/media/platform/soc_camera/rcar_vin.c
+index 74fb005..496a8bd 100644
+--- a/drivers/media/platform/soc_camera/rcar_vin.c
++++ b/drivers/media/platform/soc_camera/rcar_vin.c
+@@ -106,6 +106,7 @@
+ #define VNMC_INF_YUV8_BT601 (1 << 16)
+ #define VNMC_INF_YUV10_BT656 (2 << 16)
+ #define VNMC_INF_YUV10_BT601 (3 << 16)
++#define VNMC_INF_RAW8 (4 << 16)
+ #define VNMC_INF_YUV16 (5 << 16)
+ #define VNMC_INF_RGB888 (6 << 16)
+ #define VNMC_INF_MASK (7 << 16)
+@@ -138,6 +139,7 @@
+ #define VNINTS_FOS (1 << 0)
+
+ /* Video n Data Mode Register bits */
++#define VNDMR_YMODE_Y8 (1 << 12)
+ #define VNDMR_EXRGB (1 << 8)
+ #define VNDMR_BPSM (1 << 4)
+ #define VNDMR_DTMD_YCSEP (1 << 1)
+@@ -408,6 +410,7 @@ enum csi2_fmt {
+ RCAR_CSI_FMT_NONE = -1,
+ RCAR_CSI_RGB888,
+ RCAR_CSI_YCBCR422,
++ RCAR_CSI_RAW8,
+ };
+
+ struct vin_coeff {
+@@ -773,10 +776,13 @@ struct rcar_vin_priv {
+ enum csi2_fmt csi_fmt;
+ enum virtual_ch vc;
+ bool csi_sync;
++ bool deser_sync;
+
+ struct rcar_vin_async_client *async_client;
+ /* Asynchronous CSI2 linking */
+ struct v4l2_subdev *csi2_sd;
++ /* Asynchronous Deserializer linking */
++ struct v4l2_subdev *deser_sd;
+ /* Synchronous probing compatibility */
+ struct platform_device *csi2_pdev;
+
+@@ -989,6 +995,10 @@ static int rcar_vin_setup(struct rcar_vin_priv *priv)
+ VNMC_INF_YUV10_BT656 : VNMC_INF_YUV10_BT601;
+ input_is_yuv = true;
+ break;
++ case MEDIA_BUS_FMT_SBGGR8_1X8:
++ case MEDIA_BUS_FMT_SBGGR12_1X12:
++ vnmc |= VNMC_INF_RAW8 | VNMC_BPS;
++ break;
+ default:
+ break;
+ }
+@@ -1021,6 +1031,10 @@ static int rcar_vin_setup(struct rcar_vin_priv *priv)
+ dmr = 0;
+ output_is_yuv = true;
+ break;
++ case V4L2_PIX_FMT_GREY:
++ dmr = VNDMR_DTMD_YCSEP | VNDMR_YMODE_Y8;
++ output_is_yuv = true;
++ break;
+ case V4L2_PIX_FMT_ARGB555:
+ dmr = VNDMR_DTMD_ARGB;
+ break;
+@@ -1043,6 +1057,10 @@ static int rcar_vin_setup(struct rcar_vin_priv *priv)
+
+ dmr = VNDMR_EXRGB | VNDMR_DTMD_ARGB;
+ break;
++ case V4L2_PIX_FMT_SBGGR8:
++ case V4L2_PIX_FMT_SBGGR12:
++ dmr = 0;
++ break;
+ default:
+ goto e_format;
+ }
+@@ -1061,7 +1079,9 @@ static int rcar_vin_setup(struct rcar_vin_priv *priv)
+ else
+ vnmc |= VNMC_DPINE;
+
+- if ((icd->current_fmt->host_fmt->fourcc != V4L2_PIX_FMT_NV12)
++ if ((icd->current_fmt->host_fmt->fourcc != V4L2_PIX_FMT_NV12) &&
++ (icd->current_fmt->host_fmt->fourcc != V4L2_PIX_FMT_SBGGR8) &&
++ (icd->current_fmt->host_fmt->fourcc != V4L2_PIX_FMT_SBGGR12)
+ && is_scaling(cam))
+ vnmc |= VNMC_SCLE;
+ }
+@@ -1211,6 +1231,10 @@ static void rcar_vin_videobuf_queue(struct vb2_buffer *vb)
+ */
+ static void rcar_vin_wait_stop_streaming(struct rcar_vin_priv *priv)
+ {
++ /* update the status if hardware is not stopped */
++ if (ioread32(priv->base + VNMS_REG) & VNMS_CA)
++ priv->state = RUNNING;
++
+ while (priv->state != STOPPED) {
+ /* issue stop if running */
+ if (priv->state == RUNNING)
+@@ -1361,6 +1385,31 @@ static struct v4l2_subdev *find_csi2(struct rcar_vin_priv *pcdev)
+ return NULL;
+ }
+
++static struct v4l2_subdev *find_deser(struct rcar_vin_priv *pcdev)
++{
++ struct v4l2_subdev *sd;
++ char name[] = "max9286_max9271";
++ char name2[] = "ti964_ti9x3";
++ char name3[] = "ti954_ti9x3";
++
++ v4l2_device_for_each_subdev(sd, &pcdev->ici.v4l2_dev) {
++ if (!strncmp(name, sd->name, sizeof(name) - 1)) {
++ pcdev->deser_sd = sd;
++ return sd;
++ }
++ if (!strncmp(name2, sd->name, sizeof(name2) - 1)) {
++ pcdev->deser_sd = sd;
++ return sd;
++ }
++ if (!strncmp(name3, sd->name, sizeof(name3) - 1)) {
++ pcdev->deser_sd = sd;
++ return sd;
++ }
++ }
++
++ return NULL;
++}
++
+ static int rcar_vin_add_device(struct soc_camera_device *icd)
+ {
+ struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
+@@ -1375,7 +1424,8 @@ static int rcar_vin_add_device(struct soc_camera_device *icd)
+ if (priv->chip == RCAR_H3 || priv->chip == RCAR_M3 ||
+ priv->chip == RCAR_V3M) {
+ struct v4l2_subdev *csi2_sd = find_csi2(priv);
+- int ret;
++ struct v4l2_subdev *deser_sd = find_deser(priv);
++ int ret = 0;
+
+ if (csi2_sd) {
+ csi2_sd->grp_id = soc_camera_grp_id(icd);
+@@ -1390,6 +1440,18 @@ static int rcar_vin_add_device(struct soc_camera_device *icd)
+ if (ret < 0 && ret != -ENOIOCTLCMD && ret != -ENODEV)
+ return ret;
+ }
++ if (deser_sd) {
++ v4l2_set_subdev_hostdata(deser_sd, icd);
++
++ ret = v4l2_subdev_call(deser_sd, core, s_power, 1);
++ priv->deser_sync = true;
++
++ if (ret < 0 && ret != -EINVAL)
++ priv->deser_sync = false;
++
++ if (ret < 0 && ret != -ENOIOCTLCMD && ret != -ENODEV)
++ return ret;
++ }
+ /*
+ * -ENODEV is special:
+ * either csi2_sd == NULL or the CSI-2 driver
+@@ -1417,6 +1479,7 @@ static void rcar_vin_remove_device(struct soc_camera_device *icd)
+ struct rcar_vin_priv *priv = ici->priv;
+ struct vb2_v4l2_buffer *vbuf;
+ struct v4l2_subdev *csi2_sd = find_csi2(priv);
++ struct v4l2_subdev *deser_sd = find_deser(priv);
+ int i;
+
+ /* disable capture, disable interrupts */
+@@ -1443,6 +1506,8 @@ static void rcar_vin_remove_device(struct soc_camera_device *icd)
+
+ if ((csi2_sd) && (priv->csi_sync))
+ v4l2_subdev_call(csi2_sd, core, s_power, 0);
++ if ((deser_sd) && (priv->deser_sync))
++ v4l2_subdev_call(deser_sd, core, s_power, 0);
+
+ dev_dbg(icd->parent, "R-Car VIN driver detached from camera %d\n",
+ icd->devnum);
+@@ -1621,13 +1686,19 @@ static int rcar_vin_set_rect(struct soc_camera_device *icd)
+
+ if (priv->chip == RCAR_H3 || priv->chip == RCAR_M3 ||
+ priv->chip == RCAR_V3M) {
+- if ((icd->current_fmt->host_fmt->fourcc != V4L2_PIX_FMT_NV12)
++ if ((icd->current_fmt->host_fmt->fourcc != V4L2_PIX_FMT_NV12) &&
++ (icd->current_fmt->host_fmt->fourcc != V4L2_PIX_FMT_SBGGR8) &&
++ (icd->current_fmt->host_fmt->fourcc != V4L2_PIX_FMT_SBGGR12)
+ && is_scaling(cam)) {
+ ret = rcar_vin_uds_set(priv, cam);
+ if (ret < 0)
+ return ret;
+ }
+- if (is_scaling(cam) ||
++ if ((icd->current_fmt->host_fmt->fourcc == V4L2_PIX_FMT_SBGGR8) ||
++ (icd->current_fmt->host_fmt->fourcc == V4L2_PIX_FMT_SBGGR12))
++ iowrite32(ALIGN(cam->out_width / 2, 0x10),
++ priv->base + VNIS_REG);
++ else if (is_scaling(cam) ||
+ (icd->current_fmt->host_fmt->fourcc == V4L2_PIX_FMT_NV16) ||
+ (icd->current_fmt->host_fmt->fourcc == V4L2_PIX_FMT_NV12))
+ iowrite32(ALIGN(cam->out_width, 0x20),
+@@ -1868,6 +1939,14 @@ static bool rcar_vin_packing_supported(const struct soc_mbus_pixelfmt *fmt)
+ .layout = SOC_MBUS_LAYOUT_PACKED,
+ },
+ {
++ .fourcc = V4L2_PIX_FMT_GREY,
++ .name = "GREY8",
++ .bits_per_sample = 8,
++ .packing = SOC_MBUS_PACKING_NONE,
++ .order = SOC_MBUS_ORDER_LE,
++ .layout = SOC_MBUS_LAYOUT_PACKED,
++ },
++ {
+ .fourcc = V4L2_PIX_FMT_RGB565,
+ .name = "RGB565",
+ .bits_per_sample = 16,
+@@ -1899,6 +1978,22 @@ static bool rcar_vin_packing_supported(const struct soc_mbus_pixelfmt *fmt)
+ .order = SOC_MBUS_ORDER_LE,
+ .layout = SOC_MBUS_LAYOUT_PACKED,
+ },
++ {
++ .fourcc = V4L2_PIX_FMT_SBGGR8,
++ .name = "Bayer 8 BGGR",
++ .bits_per_sample = 8,
++ .packing = SOC_MBUS_PACKING_NONE,
++ .order = SOC_MBUS_ORDER_LE,
++ .layout = SOC_MBUS_LAYOUT_PACKED,
++ },
++ {
++ .fourcc = V4L2_PIX_FMT_SBGGR12,
++ .name = "Bayer 12 BGGR",
++ .bits_per_sample = 8,
++ .packing = SOC_MBUS_PACKING_NONE,
++ .order = SOC_MBUS_ORDER_LE,
++ .layout = SOC_MBUS_LAYOUT_PACKED,
++ },
+ };
+
+ static int rcar_vin_get_formats(struct soc_camera_device *icd, unsigned int idx,
+@@ -2012,6 +2107,8 @@ static int rcar_vin_get_formats(struct soc_camera_device *icd, unsigned int idx,
+ case MEDIA_BUS_FMT_YUYV8_2X8:
+ case MEDIA_BUS_FMT_YUYV10_2X10:
+ case MEDIA_BUS_FMT_RGB888_1X24:
++ case MEDIA_BUS_FMT_SBGGR8_1X8:
++ case MEDIA_BUS_FMT_SBGGR12_1X12:
+ if (cam->extra_fmt)
+ break;
+
+@@ -2218,12 +2315,15 @@ static int rcar_vin_set_fmt(struct soc_camera_device *icd,
+ case V4L2_PIX_FMT_ABGR32:
+ case V4L2_PIX_FMT_UYVY:
+ case V4L2_PIX_FMT_YUYV:
++ case V4L2_PIX_FMT_GREY:
+ case V4L2_PIX_FMT_RGB565:
+ case V4L2_PIX_FMT_ARGB555:
+ case V4L2_PIX_FMT_NV16:
+ can_scale = true;
+ break;
+ case V4L2_PIX_FMT_NV12:
++ case V4L2_PIX_FMT_SBGGR8:
++ case V4L2_PIX_FMT_SBGGR12:
+ default:
+ can_scale = false;
+ break;
+@@ -2316,7 +2416,8 @@ static int rcar_vin_try_fmt(struct soc_camera_device *icd,
+ /* odd number clipping by pixel post clip processing, */
+ /* it is outputted to a memory per even pixels. */
+ if ((pixfmt == V4L2_PIX_FMT_NV16) || (pixfmt == V4L2_PIX_FMT_NV12) ||
+- (pixfmt == V4L2_PIX_FMT_YUYV) || (pixfmt == V4L2_PIX_FMT_UYVY))
++ (pixfmt == V4L2_PIX_FMT_YUYV) || (pixfmt == V4L2_PIX_FMT_UYVY) ||
++ (pixfmt == V4L2_PIX_FMT_GREY))
+ v4l_bound_align_image(&pix->width, 5, priv->max_width, 1,
+ &pix->height, 2, priv->max_height, 0, 0);
+ else
+@@ -2486,6 +2587,19 @@ static int rcar_vin_cropcap(struct soc_camera_device *icd,
+ }
+ #endif
+
++static int rcar_vin_get_edid(struct soc_camera_device *icd,
++ struct v4l2_edid *edid)
++{
++ struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
++ int ret;
++
++ ret = v4l2_subdev_call(sd, pad, get_edid, edid);
++ if (ret < 0)
++ return ret;
++
++ return 0;
++}
++
+ static struct soc_camera_host_ops rcar_vin_host_ops = {
+ .owner = THIS_MODULE,
+ .add = rcar_vin_add_device,
+@@ -2504,6 +2618,7 @@ static int rcar_vin_cropcap(struct soc_camera_device *icd,
+ .get_selection = rcar_vin_get_selection,
+ .cropcap = rcar_vin_cropcap,
+ #endif
++ .get_edid = rcar_vin_get_edid,
+ };
+
+ #ifdef CONFIG_OF
+@@ -2524,7 +2639,7 @@ static int rcar_vin_cropcap(struct soc_camera_device *icd,
+ MODULE_DEVICE_TABLE(of, rcar_vin_of_table);
+ #endif
+
+-#define MAP_MAX_NUM 32
++#define MAP_MAX_NUM 128
+ static DECLARE_BITMAP(device_map, MAP_MAX_NUM);
+ static DEFINE_MUTEX(list_lock);
+
+@@ -2714,7 +2829,11 @@ static int rcar_vin_probe(struct platform_device *pdev)
+ const char *str;
+ unsigned int i;
+ struct device_node *epn = NULL, *ren = NULL;
++ struct device_node *csi2_ren = NULL, *max9286_ren = NULL, *ti964_ren = NULL, *ti954_ren = NULL;
+ bool csi_use = false;
++ bool max9286_use = false;
++ bool ti964_use = false;
++ bool ti954_use = false;
+
+ match = of_match_device(of_match_ptr(rcar_vin_of_table), &pdev->dev);
+
+@@ -2741,13 +2860,27 @@ static int rcar_vin_probe(struct platform_device *pdev)
+ dev_dbg(&pdev->dev, "node name:%s\n",
+ of_node_full_name(ren->parent));
+
+- if (strcmp(ren->parent->name, "csi2") == 0)
++ if (strcmp(ren->parent->name, "csi2") == 0) {
++ csi2_ren = ren;
+ csi_use = true;
++ }
+
+- of_node_put(ren);
++ if (strcmp(ren->parent->name, "max9286-max9271") == 0) {
++ max9286_ren = of_parse_phandle(epn, "remote-endpoint", 0);
++ max9286_use = true;
++ }
+
+- if (i)
+- break;
++ if (strcmp(ren->parent->name, "ti964-ti9x3") == 0) {
++ ti964_ren = of_parse_phandle(epn, "remote-endpoint", 0);
++ ti964_use = true;
++ }
++
++ if (strcmp(ren->parent->name, "ti954-ti9x3") == 0) {
++ ti954_ren = of_parse_phandle(epn, "remote-endpoint", 0);
++ ti954_use = true;
++ }
++
++ of_node_put(ren);
+ }
+
+ ret = v4l2_of_parse_endpoint(np, &ep);
+@@ -2799,6 +2932,7 @@ static int rcar_vin_probe(struct platform_device *pdev)
+ priv->ici.drv_name = dev_name(&pdev->dev);
+ priv->ici.ops = &rcar_vin_host_ops;
+ priv->csi_sync = false;
++ priv->deser_sync = false;
+
+ priv->pdata_flags = pdata_flags;
+ if (!match) {
+@@ -2983,7 +3117,25 @@ static int rcar_vin_probe(struct platform_device *pdev)
+ goto cleanup;
+
+ if (csi_use) {
+- ret = rcar_vin_soc_of_bind(priv, &priv->ici, epn, ren->parent);
++ ret = rcar_vin_soc_of_bind(priv, &priv->ici, epn, csi2_ren->parent);
++ if (ret)
++ goto cleanup;
++ }
++
++ if (max9286_use) {
++ ret = rcar_vin_soc_of_bind(priv, &priv->ici, epn, max9286_ren);
++ if (ret)
++ goto cleanup;
++ }
++
++ if (ti964_use) {
++ ret = rcar_vin_soc_of_bind(priv, &priv->ici, epn, ti964_ren);
++ if (ret)
++ goto cleanup;
++ }
++
++ if (ti954_use) {
++ ret = rcar_vin_soc_of_bind(priv, &priv->ici, epn, ti954_ren);
+ if (ret)
+ goto cleanup;
+ }
+diff --git a/drivers/media/platform/soc_camera/soc_camera.c b/drivers/media/platform/soc_camera/soc_camera.c
+index edd1c1d..54f4c9d 100644
+--- a/drivers/media/platform/soc_camera/soc_camera.c
++++ b/drivers/media/platform/soc_camera/soc_camera.c
+@@ -49,7 +49,7 @@
+ (icd)->vb_vidq.streaming : \
+ vb2_is_streaming(&(icd)->vb2_vidq))
+
+-#define MAP_MAX_NUM 32
++#define MAP_MAX_NUM 128
+ static DECLARE_BITMAP(device_map, MAP_MAX_NUM);
+ static LIST_HEAD(hosts);
+ static LIST_HEAD(devices);
+@@ -1106,6 +1106,18 @@ static int soc_camera_s_parm(struct file *file, void *fh,
+ return -ENOIOCTLCMD;
+ }
+
++static int soc_camera_g_edid(struct file *file, void *fh,
++ struct v4l2_edid *edid)
++{
++ struct soc_camera_device *icd = file->private_data;
++ struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
++
++ if (ici->ops->get_edid)
++ return ici->ops->get_edid(icd, edid);
++
++ return -ENOIOCTLCMD;
++}
++
+ static int soc_camera_probe(struct soc_camera_host *ici,
+ struct soc_camera_device *icd);
+
+@@ -1664,7 +1676,7 @@ static void scan_of_host(struct soc_camera_host *ici)
+ of_node_put(ren);
+
+ if (i) {
+- dev_err(dev, "multiple subdevices aren't supported yet!\n");
++ dev_dbg(dev, "multiple subdevices aren't supported yet!\n");
+ break;
+ }
+ }
+@@ -2077,6 +2089,7 @@ static int soc_camera_device_register(struct soc_camera_device *icd)
+ .vidioc_s_selection = soc_camera_s_selection,
+ .vidioc_g_parm = soc_camera_g_parm,
+ .vidioc_s_parm = soc_camera_s_parm,
++ .vidioc_g_edid = soc_camera_g_edid,
+ };
+
+ static int video_dev_create(struct soc_camera_device *icd)
+diff --git a/drivers/media/platform/soc_camera/soc_mediabus.c b/drivers/media/platform/soc_camera/soc_mediabus.c
+index e3e665e..84754a4 100644
+--- a/drivers/media/platform/soc_camera/soc_mediabus.c
++++ b/drivers/media/platform/soc_camera/soc_mediabus.c
+@@ -57,6 +57,16 @@
+ .layout = SOC_MBUS_LAYOUT_PACKED,
+ },
+ }, {
++ .code = MEDIA_BUS_FMT_YUYV10_2X10,
++ .fmt = {
++ .fourcc = V4L2_PIX_FMT_YUYV,
++ .name = "YUYV",
++ .bits_per_sample = 10,
++ .packing = SOC_MBUS_PACKING_2X10_PADHI,
++ .order = SOC_MBUS_ORDER_LE,
++ .layout = SOC_MBUS_LAYOUT_PACKED,
++ },
++}, {
+ .code = MEDIA_BUS_FMT_RGB555_2X8_PADHI_LE,
+ .fmt = {
+ .fourcc = V4L2_PIX_FMT_RGB555,
+@@ -403,6 +413,10 @@ int soc_mbus_samples_per_pixel(const struct soc_mbus_pixelfmt *mf,
+ *numerator = 2;
+ *denominator = 1;
+ return 0;
++ case SOC_MBUS_PACKING_2X10_PADHI:
++ *numerator = 3;
++ *denominator = 1;
++ return 0;
+ case SOC_MBUS_PACKING_1_5X8:
+ *numerator = 3;
+ *denominator = 2;
+@@ -428,6 +442,8 @@ s32 soc_mbus_bytes_per_line(u32 width, const struct soc_mbus_pixelfmt *mf)
+ case SOC_MBUS_PACKING_2X8_PADLO:
+ case SOC_MBUS_PACKING_EXTEND16:
+ return width * 2;
++ case SOC_MBUS_PACKING_2X10_PADHI:
++ return width * 3;
+ case SOC_MBUS_PACKING_1_5X8:
+ return width * 3 / 2;
+ case SOC_MBUS_PACKING_VARIABLE:
+diff --git a/include/media/drv-intf/soc_mediabus.h b/include/media/drv-intf/soc_mediabus.h
+index 2ff7737..e5f3f53 100644
+--- a/include/media/drv-intf/soc_mediabus.h
++++ b/include/media/drv-intf/soc_mediabus.h
+@@ -21,6 +21,8 @@
+ * @SOC_MBUS_PACKING_2X8_PADHI: 16 bits transferred in 2 8-bit samples, in the
+ * possibly incomplete byte high bits are padding
+ * @SOC_MBUS_PACKING_2X8_PADLO: as above, but low bits are padding
++ * @SOC_MBUS_PACKING_2X10_PADHI:20 bits transferred in 2 10-bit samples. The
++ * high bits are padding
+ * @SOC_MBUS_PACKING_EXTEND16: sample width (e.g., 10 bits) has to be extended
+ * to 16 bits
+ * @SOC_MBUS_PACKING_VARIABLE: compressed formats with variable packing
+@@ -33,6 +35,7 @@ enum soc_mbus_packing {
+ SOC_MBUS_PACKING_NONE,
+ SOC_MBUS_PACKING_2X8_PADHI,
+ SOC_MBUS_PACKING_2X8_PADLO,
++ SOC_MBUS_PACKING_2X10_PADHI,
+ SOC_MBUS_PACKING_EXTEND16,
+ SOC_MBUS_PACKING_VARIABLE,
+ SOC_MBUS_PACKING_1_5X8,
+diff --git a/include/media/soc_camera.h b/include/media/soc_camera.h
+index 1a15c3e..dad1ed8 100644
+--- a/include/media/soc_camera.h
++++ b/include/media/soc_camera.h
+@@ -125,6 +125,7 @@ struct soc_camera_host_ops {
+ int (*set_parm)(struct soc_camera_device *, struct v4l2_streamparm *);
+ int (*enum_framesizes)(struct soc_camera_device *, struct v4l2_frmsizeenum *);
+ unsigned int (*poll)(struct file *, poll_table *);
++ int (*get_edid)(struct soc_camera_device *, struct v4l2_edid *);
+ };
+
+ #define SOCAM_SENSOR_INVERT_PCLK (1 << 0)
+--
+1.9.1
+
diff --git a/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0031-media-i2c-Add-ov5647-sensor.patch b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0031-media-i2c-Add-ov5647-sensor.patch
new file mode 100644
index 0000000..1cd366c
--- /dev/null
+++ b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0031-media-i2c-Add-ov5647-sensor.patch
@@ -0,0 +1,952 @@
+From 8b97232e3ecbb4ee38bda454915e62914ef52fcc Mon Sep 17 00:00:00 2001
+From: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+Date: Thu, 1 Jun 2017 19:59:56 +0300
+Subject: [PATCH] media: i2c: Add ov5647 sensor
+
+Add ov5647 camera sensor driver
+
+Signed-off-by: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+---
+ drivers/media/i2c/soc_camera/Kconfig | 6 +
+ drivers/media/i2c/soc_camera/Makefile | 1 +
+ drivers/media/i2c/soc_camera/ov5647.c | 649 ++++++++++++++++++++++++++++++++++
+ drivers/media/i2c/soc_camera/ov5647.h | 242 +++++++++++++
+ 4 files changed, 898 insertions(+)
+ create mode 100644 drivers/media/i2c/soc_camera/ov5647.c
+ create mode 100644 drivers/media/i2c/soc_camera/ov5647.h
+
+diff --git a/drivers/media/i2c/soc_camera/Kconfig b/drivers/media/i2c/soc_camera/Kconfig
+index e1c65ca..c272aeb 100644
+--- a/drivers/media/i2c/soc_camera/Kconfig
++++ b/drivers/media/i2c/soc_camera/Kconfig
+@@ -97,6 +97,12 @@ config SOC_CAMERA_OV5642
+ help
+ This is a V4L2 camera driver for the OmniVision OV5642 sensor
+
++config SOC_CAMERA_OV5647
++ tristate "ov5647 camera support"
++ depends on SOC_CAMERA && I2C
++ help
++ This is a V4L2 camera driver for the OmniVision OV5647 sensor
++
+ config SOC_CAMERA_OV6650
+ tristate "ov6650 sensor support"
+ depends on SOC_CAMERA && I2C
+diff --git a/drivers/media/i2c/soc_camera/Makefile b/drivers/media/i2c/soc_camera/Makefile
+index 8e24d5d..a67fff8 100644
+--- a/drivers/media/i2c/soc_camera/Makefile
++++ b/drivers/media/i2c/soc_camera/Makefile
+@@ -13,6 +13,7 @@ obj-$(CONFIG_SOC_CAMERA_OV495_OV2775) += ov495_ov2775.o
+ obj-$(CONFIG_SOC_CAMERA_OV106XX) += ov106xx.o
+ obj-$(CONFIG_SOC_CAMERA_OV2640) += ov2640.o
+ obj-$(CONFIG_SOC_CAMERA_OV5642) += ov5642.o
++obj-$(CONFIG_SOC_CAMERA_OV5647) += ov5647.o
+ obj-$(CONFIG_SOC_CAMERA_OV6650) += ov6650.o
+ obj-$(CONFIG_SOC_CAMERA_OV772X) += ov772x.o
+ obj-$(CONFIG_SOC_CAMERA_OV9640) += ov9640.o
+diff --git a/drivers/media/i2c/soc_camera/ov5647.c b/drivers/media/i2c/soc_camera/ov5647.c
+new file mode 100644
+index 0000000..caccf39
+--- /dev/null
++++ b/drivers/media/i2c/soc_camera/ov5647.c
+@@ -0,0 +1,649 @@
++/*
++ * V4L2 driver for OmniVision OV5647 cameras.
++ *
++ * Based on Samsung S5K6AAFX SXGA 1/6" 1.3M CMOS Image Sensor driver
++ * Copyright (C) 2011 Sylwester Nawrocki <s.nawrocki@samsung.com>
++ *
++ * Based on Omnivision OV7670 Camera Driver
++ * Copyright (C) 2006-7 Jonathan Corbet <corbet@lwn.net>
++ *
++ * Copyright (C) 2016, Synopsys, Inc.
++ *
++ * Copyright (C) 2017 Cogent Embedded, Inc
++ */
++
++#include <linux/init.h>
++#include <linux/module.h>
++#include <linux/slab.h>
++#include <linux/i2c.h>
++#include <linux/delay.h>
++#include <linux/videodev2.h>
++#include <media/v4l2-device.h>
++#include <media/v4l2-ctrls.h>
++#include <media/v4l2-mediabus.h>
++#include <media/v4l2-image-sizes.h>
++#include <media/v4l2-of.h>
++#include <linux/io.h>
++
++#include "ov5647.h"
++
++static bool debug = true;
++module_param(debug, bool, 0644);
++MODULE_PARM_DESC(debug, "Debug level (0-1)");
++
++#define OV5647_I2C_ADDR 0x6c
++#define SENSOR_NAME "ov5647"
++
++#define OV5647_REG_CHIPID_H 0x300A
++#define OV5647_REG_CHIPID_L 0x300B
++
++#define REG_TERM 0xfffe
++#define VAL_TERM 0xfe
++#define REG_DLY 0xffff
++
++/*define the voltage level of control signal*/
++#define CSI_STBY_ON 1
++#define CSI_STBY_OFF 0
++#define CSI_RST_ON 0
++#define CSI_RST_OFF 1
++#define CSI_PWR_ON 1
++#define CSI_PWR_OFF 0
++#define CSI_AF_PWR_ON 1
++#define CSI_AF_PWR_OFF 0
++
++#define OV5647_ROW_START 0x01
++#define OV5647_ROW_START_MIN 0
++#define OV5647_ROW_START_MAX 2004
++#define OV5647_ROW_START_DEF 54
++
++#define OV5647_COLUMN_START 0x02
++#define OV5647_COLUMN_START_MIN 0
++#define OV5647_COLUMN_START_MAX 2750
++#define OV5647_COLUMN_START_DEF 16
++
++#define OV5647_WINDOW_HEIGHT 0x03
++#define OV5647_WINDOW_HEIGHT_MIN 2
++#define OV5647_WINDOW_HEIGHT_MAX 2006
++#define OV5647_WINDOW_HEIGHT_DEF 1944
++
++#define OV5647_WINDOW_WIDTH 0x04
++#define OV5647_WINDOW_WIDTH_MIN 2
++#define OV5647_WINDOW_WIDTH_MAX 2752
++#define OV5647_WINDOW_WIDTH_DEF 2592
++
++enum power_seq_cmd {
++ CSI_SUBDEV_PWR_OFF = 0x00,
++ CSI_SUBDEV_PWR_ON = 0x01,
++};
++
++struct sensor_format_struct {
++ __u8 *desc;
++ u32 mbus_code;
++ enum v4l2_colorspace colorspace;
++ struct regval_list *regs;
++ int regs_size;
++ int bpp;
++};
++
++struct cfg_array {
++ struct regval_list *regs;
++ int size;
++};
++
++struct sensor_win_size {
++ int width;
++ int height;
++ unsigned int hoffset;
++ unsigned int voffset;
++ unsigned int hts;
++ unsigned int vts;
++ unsigned int pclk;
++ unsigned int mipi_bps;
++ unsigned int fps_fixed;
++ unsigned int bin_factor;
++ unsigned int intg_min;
++ unsigned int intg_max;
++ void *regs;
++ int regs_size;
++ int (*set_size)(struct v4l2_subdev *subdev);
++};
++
++struct ov5647 {
++ struct device *dev;
++ struct v4l2_subdev subdev;
++ struct media_pad pad;
++ struct mutex lock;
++ struct v4l2_mbus_framefmt format;
++ struct sensor_format_struct *fmt;
++ unsigned int width;
++ unsigned int height;
++ unsigned int capture_mode;
++ int hue;
++ struct v4l2_fract tpf;
++ struct sensor_win_size *current_wins;
++};
++
++static inline struct ov5647 *to_state(struct v4l2_subdev *subdev)
++{
++ return container_of(subdev, struct ov5647, subdev);
++}
++
++static struct sensor_format_struct sensor_formats[] = {
++ {
++ .mbus_code = OV5647_CODE,
++ .colorspace = V4L2_COLORSPACE_JPEG,
++ },
++};
++#define N_FMTS ARRAY_SIZE(sensor_formats)
++
++static int ov5647_write(struct v4l2_subdev *sd, uint16_t reg, uint8_t val)
++{
++ int ret;
++ unsigned char data[3] = { reg >> 8, reg & 0xff, val};
++ struct i2c_client *client = v4l2_get_subdevdata(sd);
++
++ ret = i2c_master_send(client, data, 3);
++ if (ret < 3) {
++ printk( "%s: i2c write error, reg: %x, %d\n",
++ __func__, reg, ret);
++ return ret < 0 ? ret : -EIO;
++ }
++
++ return 0;
++}
++
++static int ov5647_read(struct v4l2_subdev *sd, uint16_t reg, uint8_t *val)
++{
++ int ret;
++ unsigned char data_w[2] = { reg >> 8, reg & 0xff };
++ struct i2c_client *client = v4l2_get_subdevdata(sd);
++
++
++ ret = i2c_master_send(client, data_w, 2);
++
++ if (ret < 2) {
++ printk("%s: i2c read error, reg: %x\n",
++ __func__, reg);
++ return ret < 0 ? ret : -EIO;
++ }
++
++ ret = i2c_master_recv(client, val, 1);
++
++ if (ret < 1) {
++ printk("%s: i2c read error, reg: %x\n",
++ __func__, reg);
++ return ret < 0 ? ret : -EIO;
++ }
++
++ return 0;
++}
++
++static int ov5647_write_array(struct v4l2_subdev *subdev,
++ struct regval_list *regs, int array_size)
++{
++ int i = 0;
++ int ret = 0;
++
++ if (!regs)
++ return -EINVAL;
++
++ while (i < array_size) {
++ if (regs->addr == REG_DLY)
++ mdelay(regs->data);
++ else
++ ret = ov5647_write(subdev, regs->addr, regs->data);
++
++ if (ret == -EIO)
++ return ret;
++
++ i++;
++ regs++;
++ }
++ return 0;
++}
++
++static void ov5647_set_virtual_channel(struct v4l2_subdev *subdev, int channel)
++{
++#if 0
++ u8 channel_id;
++
++ ov5647_read(subdev, 0x4814, &channel_id);
++// channel_id = 0x1e; //override
++
++ channel_id &= ~(3 << 6);
++ channel_id |= (channel << 6);
++ printk("0x4814 = 0x%02x\n", channel_id);
++ ov5647_write(subdev, 0x4814, channel_id);
++ ov5647_write(subdev, 0x4801, 0x8f);
++#endif
++}
++
++void ov5647_stream_on(struct v4l2_subdev *subdev)
++{
++ ov5647_write(subdev, 0x4202, 0x00);
++ ov5647_write(subdev, 0x300D, 0x00);
++}
++
++void ov5647_stream_off(struct v4l2_subdev *subdev)
++{
++ ov5647_write(subdev, 0x4202, 0x0f);
++ ov5647_write(subdev, 0x300D, 0x01);
++}
++
++static int sensor_s_sw_stby(struct v4l2_subdev *subdev, int on_off)
++{
++ int ret;
++ unsigned char rdval;
++
++ ret = ov5647_read(subdev, 0x0100, &rdval);
++ if (ret != 0)
++ return ret;
++
++ if (on_off == CSI_STBY_ON)
++ ret = ov5647_write(subdev, 0x0100, rdval&0xfe);
++ else
++ ret = ov5647_write(subdev, 0x0100, rdval|0x01);
++
++ return ret;
++}
++
++static int __sensor_init(struct v4l2_subdev *subdev)
++{
++ int ret;
++ unsigned char rdval;
++
++ ret = ov5647_read(subdev, 0x0100, &rdval);
++ if (ret != 0)
++ return ret;
++
++ ov5647_write(subdev, 0x4800, 0x25);
++ ov5647_stream_off(subdev);
++
++ ov5647_write(subdev, 0x100, 0);
++ /* reset */
++ ov5647_write(subdev, 0x103, 1);
++ ov5647_write(subdev, 0x103, 1);
++ ov5647_write(subdev, 0x103, 1);
++ mdelay(10);
++
++ ret = ov5647_write_array(subdev, ov5647_recommend_settings,
++ ARRAY_SIZE(ov5647_recommend_settings));
++#if 1
++ ret = ov5647_write_array(subdev, ov5647_snap_settings,
++ ARRAY_SIZE(ov5647_snap_settings));
++#else
++ ret = ov5647_write_array(subdev, ov5647_prev_settings,
++ ARRAY_SIZE(ov5647_prev_settings));
++#endif
++ ov5647_set_virtual_channel(subdev, 0);
++
++ ov5647_write(subdev, 0x0100, 0x01);
++
++ ov5647_write(subdev, 0x04800, 0x04);
++ ov5647_stream_on(subdev);
++ msleep(30);
++
++ return 0;
++}
++
++static int sensor_power(struct v4l2_subdev *subdev, int on)
++{
++ int ret = 0;
++ struct ov5647 *ov5647 = to_state(subdev);
++
++ mutex_lock(&ov5647->lock);
++
++ switch (on) {
++ case CSI_SUBDEV_PWR_OFF:
++ ret = sensor_s_sw_stby(subdev, CSI_STBY_ON);
++ if (ret < 0)
++ printk("soft stby failed!\n");
++ break;
++ case CSI_SUBDEV_PWR_ON:
++ ret = __sensor_init(subdev);
++ if (ret < 0) {
++ v4l2_err(subdev, "Camera not available, check power\n");
++ break;
++ }
++ break;
++ default:
++ return -EINVAL;
++ }
++
++ mutex_unlock(&ov5647->lock);
++
++ return 0;
++}
++
++#ifdef CONFIG_VIDEO_ADV_DEBUG
++static int sensor_get_register(struct v4l2_subdev *subdev,
++ struct v4l2_dbg_register *reg)
++{
++ u8 val = 0;
++ int ret;
++
++ ret = ov5647_read(subdev, (u16)reg->reg, &val);
++ if (ret < 0)
++ return ret;
++
++ reg->val = val;
++ reg->size = sizeof(u8);
++
++ return ret;
++}
++
++static int sensor_set_register(struct v4l2_subdev *subdev,
++ const struct v4l2_dbg_register *reg)
++{
++ ov5647_write(subdev, (u16)reg->reg, (u8)reg->val);
++
++ return 0;
++}
++#endif
++
++static const struct v4l2_subdev_core_ops sensor_core_ops = {
++ .s_power = sensor_power,
++#ifdef CONFIG_VIDEO_ADV_DEBUG
++ .g_register = sensor_get_register,
++ .s_register = sensor_set_register,
++#endif
++};
++
++static int sensor_s_stream(struct v4l2_subdev *sd, int enable)
++{
++ if (enable)
++ ov5647_stream_on(sd);
++ else
++ ov5647_stream_off(sd);
++
++ return 0;
++}
++
++static int sensor_enum_fmt(struct v4l2_subdev *sd,
++ struct v4l2_subdev_pad_config *cfg,
++ struct v4l2_subdev_mbus_code_enum *code)
++{
++ if (code->pad || code->index >= N_FMTS)
++ return -EINVAL;
++
++ code->code = OV5647_CODE;
++
++ return 0;
++}
++
++static int sensor_try_fmt_internal(struct v4l2_subdev *subdev,
++ struct v4l2_mbus_framefmt *fmt,
++ struct sensor_format_struct **ret_fmt,
++ struct sensor_win_size **ret_wsize)
++{
++ int index;
++
++ for (index = 0; index < N_FMTS; index++)
++ if (sensor_formats[index].mbus_code == fmt->code)
++ break;
++
++ if (index >= N_FMTS)
++ return -EINVAL;
++
++ if (ret_fmt != NULL)
++ *ret_fmt = sensor_formats + index;
++
++ fmt->field = V4L2_FIELD_NONE;
++
++ return 0;
++}
++
++static int sensor_s_fmt(struct v4l2_subdev *subdev,
++ struct v4l2_subdev_pad_config *cfg,
++ struct v4l2_subdev_format *fmt)
++{
++ int ret;
++ struct sensor_format_struct *sensor_fmt;
++ struct sensor_win_size *wsize = NULL;
++ struct ov5647 *info = to_state(subdev);
++
++ ret = sensor_try_fmt_internal(subdev, &fmt->format,
++ &sensor_fmt, &wsize);
++ if (ret)
++ return ret;
++
++ info->fmt = sensor_fmt;
++ info->width = OV5647_WIDTH;
++ info->height = OV5647_HEIGHT;
++
++ return 0;
++}
++
++static int sensor_g_fmt(struct v4l2_subdev *sd,
++ struct v4l2_subdev_pad_config *cfg,
++ struct v4l2_subdev_format *format)
++{
++ struct ov5647 *info = to_state(sd);
++ struct v4l2_mbus_framefmt *mf = &format->format;
++
++ if (format->pad != 0)
++ return -EINVAL;
++
++ mf->width = OV5647_WIDTH;
++ mf->height = OV5647_HEIGHT;
++ mf->code = OV5647_CODE;
++ mf->colorspace = info->fmt->colorspace;
++ mf->field = V4L2_FIELD_NONE;
++
++ return 0;
++}
++
++static int sensor_s_parm(struct v4l2_subdev *subdev,
++ struct v4l2_streamparm *parms)
++{
++ struct v4l2_captureparm *cp = &parms->parm.capture;
++ struct ov5647 *info = to_state(subdev);
++
++ if (parms->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
++ return -EINVAL;
++
++ if (info->tpf.numerator == 0)
++ return -EINVAL;
++
++ info->capture_mode = cp->capturemode;
++
++ return 0;
++}
++
++static int sensor_g_parm(struct v4l2_subdev *subdev,
++ struct v4l2_streamparm *parms)
++{
++ struct v4l2_captureparm *cp = &parms->parm.capture;
++ struct ov5647 *info = to_state(subdev);
++
++ if (parms->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
++ return -EINVAL;
++
++ memset(cp, 0, sizeof(struct v4l2_captureparm));
++ cp->capability = V4L2_CAP_TIMEPERFRAME;
++ cp->capturemode = info->capture_mode;
++
++ return 0;
++}
++
++static int sensor_g_mbus_config(struct v4l2_subdev *sd,
++ struct v4l2_mbus_config *cfg)
++{
++ cfg->flags = V4L2_MBUS_CSI2_1_LANE | V4L2_MBUS_CSI2_CHANNEL_0 |
++ V4L2_MBUS_CSI2_CONTINUOUS_CLOCK;
++ cfg->type = V4L2_MBUS_CSI2;
++
++ return 0;
++}
++
++static const struct v4l2_subdev_pad_ops sensor_pad_ops = {
++ .enum_mbus_code = sensor_enum_fmt,
++ .set_fmt = sensor_s_fmt,
++ .get_fmt = sensor_g_fmt,
++};
++
++static const struct v4l2_subdev_video_ops sensor_video_ops = {
++ .s_stream = sensor_s_stream,
++ .s_parm = sensor_s_parm,
++ .g_parm = sensor_g_parm,
++ .g_mbus_config = sensor_g_mbus_config,
++};
++
++static const struct v4l2_subdev_ops subdev_ops = {
++ .core = &sensor_core_ops,
++ .video = &sensor_video_ops,
++ .pad = &sensor_pad_ops,
++};
++
++static int ov5647_detect(struct v4l2_subdev *sd)
++{
++ struct i2c_client *client = v4l2_get_subdevdata(sd);
++ unsigned char id_h, id_l;
++ int ret;
++
++ ret = sensor_power(sd, 1);
++ if (ret < 0)
++ return ret;
++
++ ret = ov5647_read(sd, OV5647_REG_CHIPID_H, &id_h);
++ if (ret < 0)
++ return ret;
++ ret = ov5647_read(sd, OV5647_REG_CHIPID_L, &id_l);
++ if (ret < 0)
++ return ret;
++
++ if ((id_h != 0x56) || (id_l != 0x47)) {
++ v4l2_info(sd, "Invalid device ID: %02x%02x\n", id_h, id_l);
++ return -ENODEV;
++ }
++
++ v4l2_info(sd, "OV5647 detected at address 0x%02x\n", client->addr);
++
++ ret = sensor_power(sd, 0);
++ if (ret < 0)
++ return ret;
++
++ return 0;
++}
++
++static int ov5647_registered(struct v4l2_subdev *subdev)
++{
++ return 0;
++}
++
++static int ov5647_open(struct v4l2_subdev *subdev, struct v4l2_subdev_fh *fh)
++{
++ struct v4l2_mbus_framefmt *format =
++ v4l2_subdev_get_try_format(subdev, fh->pad, 0);
++ struct v4l2_rect *crop =
++ v4l2_subdev_get_try_crop(subdev, fh->pad, 0);
++
++ crop->left = 0;
++ crop->top = 0;
++ crop->width = OV5647_WIDTH;
++ crop->height = OV5647_HEIGHT;
++
++ format->code = OV5647_CODE;
++
++ format->width = OV5647_WIDTH;
++ format->height = OV5647_HEIGHT;
++ format->field = V4L2_FIELD_NONE;
++ format->colorspace = sensor_formats[0].colorspace;
++
++ return sensor_power(subdev, 1);
++}
++
++static int ov5647_close(struct v4l2_subdev *subdev, struct v4l2_subdev_fh *fh)
++{
++ return sensor_power(subdev, 0);
++}
++
++static const struct v4l2_subdev_internal_ops ov5647_subdev_internal_ops = {
++ .registered = ov5647_registered,
++ .open = ov5647_open,
++ .close = ov5647_close,
++};
++
++static int ov5647_probe(struct i2c_client *client,
++ const struct i2c_device_id *id)
++{
++ struct device *dev = &client->dev;
++ struct ov5647 *sensor;
++ int ret = 0;
++ struct v4l2_subdev *sd;
++
++ sensor = devm_kzalloc(dev, sizeof(*sensor), GFP_KERNEL);
++ if (sensor == NULL)
++ return -ENOMEM;
++
++ mutex_init(&sensor->lock);
++ sensor->dev = dev;
++ sensor->fmt = &sensor_formats[0];
++ sensor->width = OV5647_WIDTH;
++ sensor->height = OV5647_HEIGHT;
++
++ sd = &sensor->subdev;
++ v4l2_i2c_subdev_init(sd, client, &subdev_ops);
++ sensor->subdev.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
++
++ ret = ov5647_detect(sd);
++ if (ret < 0) {
++ v4l2_err(sd, "OV5647 not found!\n");
++ goto out;
++ }
++
++ sensor->pad.flags = MEDIA_PAD_FL_SOURCE;
++ sd->entity.function = MEDIA_ENT_F_CAM_SENSOR;
++ ret = media_entity_pads_init(&sd->entity, 1, &sensor->pad);
++ if (ret < 0)
++ return ret;
++
++ ret = v4l2_async_register_subdev(sd);
++ if (ret < 0)
++ media_entity_cleanup(&sd->entity);
++
++out:
++ return ret;
++}
++
++static int ov5647_remove(struct i2c_client *client)
++{
++ struct v4l2_subdev *subdev = i2c_get_clientdata(client);
++ struct ov5647 *ov5647 = to_state(subdev);
++
++ v4l2_async_unregister_subdev(&ov5647->subdev);
++ media_entity_cleanup(&ov5647->subdev.entity);
++ v4l2_device_unregister_subdev(subdev);
++
++ return 0;
++}
++
++static const struct i2c_device_id ov5647_id[] = {
++ { "ov5647", 0 },
++ { }
++};
++MODULE_DEVICE_TABLE(i2c, ov5647_id);
++
++#if IS_ENABLED(CONFIG_OF)
++static const struct of_device_id ov5647_of_match[] = {
++ { .compatible = "ovti,ov5647" },
++ { /* sentinel */ },
++};
++MODULE_DEVICE_TABLE(of, ov5647_of_match);
++#endif
++
++static struct i2c_driver ov5647_driver = {
++ .driver = {
++ .of_match_table = of_match_ptr(ov5647_of_match),
++ .owner = THIS_MODULE,
++ .name = "ov5647",
++ },
++ .probe = ov5647_probe,
++ .remove = ov5647_remove,
++ .id_table = ov5647_id,
++};
++module_i2c_driver(ov5647_driver);
++
++MODULE_AUTHOR("Ramiro Oliveira <roliveir@synopsys.com>");
++MODULE_DESCRIPTION("A low-level driver for OmniVision ov5647 sensors");
++MODULE_LICENSE("GPL");
+diff --git a/drivers/media/i2c/soc_camera/ov5647.h b/drivers/media/i2c/soc_camera/ov5647.h
+new file mode 100644
+index 0000000..f854da8
+--- /dev/null
++++ b/drivers/media/i2c/soc_camera/ov5647.h
+@@ -0,0 +1,242 @@
++/*
++ * Copyright (c) 2012, The Linux Foundation. All rights reserved.
++ * Copyright (C) 2017 Cogent Embedded, Inc
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License version 2 and
++ * only version 2 as published by the Free Software Foundation.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ */
++
++//#define TEST_PATTERN
++
++#define OV5647_WIDTH 2592
++#define OV5647_HEIGHT 1944
++
++#define OV5647_CODE MEDIA_BUS_FMT_SBGGR8_1X8
++//#define OV5647_CODE MEDIA_BUS_FMT_YUYV8_2X8
++
++struct regval_list {
++ uint16_t addr;
++ uint8_t data;
++};
++
++enum ov5647_test_mode_t {
++ TEST_OFF,
++ TEST_1,
++ TEST_2,
++ TEST_3
++};
++
++struct regval_list ov5647_prev_settings[] = {
++ /*1280*960 Reference Setting 24M MCLK 2lane 280Mbps/lane 30fps
++ for back to preview*/
++ {0x3035, 0x21},
++ {0x3036, 0x37},
++ {0x3821, 0x07},
++ {0x3820, 0x41},
++ {0x3612, 0x09},
++ {0x3618, 0x00},
++ {0x380c, 0x07},
++ {0x380d, 0x68},
++ {0x380e, 0x03},
++ {0x380f, 0xd8},
++ {0x3814, 0x31},
++ {0x3815, 0x31},
++ {0x3709, 0x52},
++ {0x3808, 0x05}, // 1280
++ {0x3809, 0x00},
++ {0x380a, 0x03}, // 960
++ {0x380b, 0xc0},
++ {0x3800, 0x00},
++ {0x3801, 0x18},
++ {0x3802, 0x00},
++ {0x3803, 0x0e},
++ {0x3804, 0x0a},
++ {0x3805, 0x27},
++ {0x3806, 0x07},
++ {0x3807, 0x95},
++ {0x4004, 0x02},
++};
++struct regval_list ov5647_snap_settings[] = {
++ /*2608*1952 Reference Setting 24M MCLK 2lane 280Mbps/lane 30fps*/
++ {0x3035, 0x21},
++ {0x3036, 0x4f},
++ {0x3821, 0x06},
++ {0x3820, 0x00},
++ {0x3612, 0x0b},
++ {0x3618, 0x04},
++ {0x380c, 0x0a},
++ {0x380d, 0x8c},
++ {0x380e, 0x07},
++ {0x380f, 0xb0},
++ {0x3814, 0x11},
++ {0x3815, 0x11},
++ {0x3709, 0x12},
++#if 0
++ {0x3808, 0x0a},
++ {0x3809, 0x30},
++ {0x380a, 0x07},
++ {0x380b, 0xa0},
++#else
++ {0x3808, OV5647_WIDTH >> 8},
++ {0x3809, OV5647_WIDTH & 0xff},
++ {0x380a, OV5647_HEIGHT >> 8},
++ {0x380b, OV5647_HEIGHT & 0xff},
++#endif
++ {0x3800, 0x00},
++ {0x3801, 0x04},
++ {0x3802, 0x00},
++ {0x3803, 0x00},
++ {0x3804, 0x0a},
++ {0x3805, 0x3b},
++ {0x3806, 0x07},
++ {0x3807, 0xa3},
++ {0x4004, 0x04},
++};
++struct regval_list ov5647_recommend_settings[] = {
++#ifdef TEST_PATTERN
++ {0x503d, 0x80},
++#endif
++#if 0
++ {0x4814, 0x1e},
++ {0x4801, 0x8f},
++#endif
++ {0x3035, 0x11},
++ {0x303c, 0x11},
++ {0x370c, 0x03},
++ {0x5000, 0x06},
++ {0x5003, 0x08},
++ {0x5a00, 0x08},
++ {0x3000, 0xff},
++ {0x3001, 0xff},
++ {0x3002, 0xff},
++ {0x301d, 0xf0},
++ {0x3a18, 0x00},
++ {0x3a19, 0xf8},
++ {0x3c01, 0x80},
++ {0x3b07, 0x0c},
++ {0x3708, 0x64},
++ {0x3630, 0x2e},
++ {0x3632, 0xe2},
++ {0x3633, 0x23},
++ {0x3634, 0x44},
++ {0x3620, 0x64},
++ {0x3621, 0xe0},
++ {0x3600, 0x37},
++ {0x3704, 0xa0},
++ {0x3703, 0x5a},
++ {0x3715, 0x78},
++ {0x3717, 0x01},
++ {0x3731, 0x02},
++ {0x370b, 0x60},
++ {0x3705, 0x1a},
++ {0x3f05, 0x02},
++ {0x3f06, 0x10},
++ {0x3f01, 0x0a},
++ {0x3a08, 0x01},
++ {0x3a0f, 0x58},
++ {0x3a10, 0x50},
++ {0x3a1b, 0x58},
++ {0x3a1e, 0x50},
++ {0x3a11, 0x60},
++ {0x3a1f, 0x28},
++ {0x4001, 0x02},
++ {0x4000, 0x09},
++ {0x3000, 0x00},
++ {0x3001, 0x00},
++ {0x3002, 0x00},
++ {0x3017, 0xe0},
++ {0x301c, 0xfc},
++ {0x3636, 0x06},
++ {0x3016, 0x08},
++ {0x3827, 0xec},
++ {0x3018, 0x44},
++ {0x3035, 0x21},
++ {0x3106, 0xf5},
++ {0x3034, 0x18},
++ {0x301c, 0xf8},
++ /*lens setting*/
++ {0x5000, 0x86},
++ {0x5800, 0x11},
++ {0x5801, 0x0c},
++ {0x5802, 0x0a},
++ {0x5803, 0x0b},
++ {0x5804, 0x0d},
++ {0x5805, 0x13},
++ {0x5806, 0x09},
++ {0x5807, 0x05},
++ {0x5808, 0x03},
++ {0x5809, 0x03},
++ {0x580a, 0x06},
++ {0x580b, 0x08},
++ {0x580c, 0x05},
++ {0x580d, 0x01},
++ {0x580e, 0x00},
++ {0x580f, 0x00},
++ {0x5810, 0x02},
++ {0x5811, 0x06},
++ {0x5812, 0x05},
++ {0x5813, 0x01},
++ {0x5814, 0x00},
++ {0x5815, 0x00},
++ {0x5816, 0x02},
++ {0x5817, 0x06},
++ {0x5818, 0x09},
++ {0x5819, 0x05},
++ {0x581a, 0x04},
++ {0x581b, 0x04},
++ {0x581c, 0x06},
++ {0x581d, 0x09},
++ {0x581e, 0x11},
++ {0x581f, 0x0c},
++ {0x5820, 0x0b},
++ {0x5821, 0x0b},
++ {0x5822, 0x0d},
++ {0x5823, 0x13},
++ {0x5824, 0x22},
++ {0x5825, 0x26},
++ {0x5826, 0x26},
++ {0x5827, 0x24},
++ {0x5828, 0x24},
++ {0x5829, 0x24},
++ {0x582a, 0x22},
++ {0x582b, 0x20},
++ {0x582c, 0x22},
++ {0x582d, 0x26},
++ {0x582e, 0x22},
++ {0x582f, 0x22},
++ {0x5830, 0x42},
++ {0x5831, 0x22},
++ {0x5832, 0x02},
++ {0x5833, 0x24},
++ {0x5834, 0x22},
++ {0x5835, 0x22},
++ {0x5836, 0x22},
++ {0x5837, 0x26},
++ {0x5838, 0x42},
++ {0x5839, 0x26},
++ {0x583a, 0x06},
++ {0x583b, 0x26},
++ {0x583c, 0x24},
++ {0x583d, 0xce},
++ /* manual AWB,manual AE,close Lenc,open WBC*/
++ {0x3503, 0x03}, /*manual AE*/
++ {0x3501, 0x10},
++ {0x3502, 0x80},
++ {0x350a, 0x00},
++ {0x350b, 0x7f},
++ {0x5001, 0x01}, /*manual AWB*/
++ {0x5180, 0x08},
++ {0x5186, 0x04},
++ {0x5187, 0x00},
++ {0x5188, 0x04},
++ {0x5189, 0x00},
++ {0x518a, 0x04},
++ {0x518b, 0x00},
++ {0x5000, 0x06}, /*No lenc,WBC on*/
++};
+--
+1.9.1
+
diff --git a/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0032-media-i2c-Add-ov5642-sensor.patch b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0032-media-i2c-Add-ov5642-sensor.patch
new file mode 100644
index 0000000..99183fa
--- /dev/null
+++ b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0032-media-i2c-Add-ov5642-sensor.patch
@@ -0,0 +1,2173 @@
+From 79ff5931fa2dede0a4c2e22e7a83c2edddcc6c20 Mon Sep 17 00:00:00 2001
+From: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+Date: Sun, 11 Jun 2017 00:50:59 +0300
+Subject: [PATCH] media: i2c: ov5642 sensor
+
+Add ov5642 camera sensor driver update
+
+Signed-off-by: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+---
+ drivers/media/i2c/soc_camera/ov5642.c | 708 +++++-----------------------
+ drivers/media/i2c/soc_camera/ov5642.h | 592 ++++++++++++++++++++++++
+ drivers/media/i2c/soc_camera/ov5642_720p.h | 711 +++++++++++++++++++++++++++++
+ 3 files changed, 1418 insertions(+), 593 deletions(-)
+ create mode 100644 drivers/media/i2c/soc_camera/ov5642.h
+ create mode 100644 drivers/media/i2c/soc_camera/ov5642_720p.h
+
+diff --git a/drivers/media/i2c/soc_camera/ov5642.c b/drivers/media/i2c/soc_camera/ov5642.c
+index bab9ac0..b58859e 100644
+--- a/drivers/media/i2c/soc_camera/ov5642.c
++++ b/drivers/media/i2c/soc_camera/ov5642.c
+@@ -22,584 +22,16 @@
+ #include <linux/videodev2.h>
+ #include <linux/module.h>
+ #include <linux/v4l2-mediabus.h>
++#include <linux/gpio.h>
++#include <linux/gpio/consumer.h>
++#include <linux/of_gpio.h>
+
+ #include <media/soc_camera.h>
+ #include <media/v4l2-clk.h>
+ #include <media/v4l2-subdev.h>
+
+-/* OV5642 registers */
+-#define REG_CHIP_ID_HIGH 0x300a
+-#define REG_CHIP_ID_LOW 0x300b
+-
+-#define REG_WINDOW_START_X_HIGH 0x3800
+-#define REG_WINDOW_START_X_LOW 0x3801
+-#define REG_WINDOW_START_Y_HIGH 0x3802
+-#define REG_WINDOW_START_Y_LOW 0x3803
+-#define REG_WINDOW_WIDTH_HIGH 0x3804
+-#define REG_WINDOW_WIDTH_LOW 0x3805
+-#define REG_WINDOW_HEIGHT_HIGH 0x3806
+-#define REG_WINDOW_HEIGHT_LOW 0x3807
+-#define REG_OUT_WIDTH_HIGH 0x3808
+-#define REG_OUT_WIDTH_LOW 0x3809
+-#define REG_OUT_HEIGHT_HIGH 0x380a
+-#define REG_OUT_HEIGHT_LOW 0x380b
+-#define REG_OUT_TOTAL_WIDTH_HIGH 0x380c
+-#define REG_OUT_TOTAL_WIDTH_LOW 0x380d
+-#define REG_OUT_TOTAL_HEIGHT_HIGH 0x380e
+-#define REG_OUT_TOTAL_HEIGHT_LOW 0x380f
+-#define REG_OUTPUT_FORMAT 0x4300
+-#define REG_ISP_CTRL_01 0x5001
+-#define REG_AVG_WINDOW_END_X_HIGH 0x5682
+-#define REG_AVG_WINDOW_END_X_LOW 0x5683
+-#define REG_AVG_WINDOW_END_Y_HIGH 0x5686
+-#define REG_AVG_WINDOW_END_Y_LOW 0x5687
+-
+-/* active pixel array size */
+-#define OV5642_SENSOR_SIZE_X 2592
+-#define OV5642_SENSOR_SIZE_Y 1944
+-
+-/*
+- * About OV5642 resolution, cropping and binning:
+- * This sensor supports it all, at least in the feature description.
+- * Unfortunately, no combination of appropriate registers settings could make
+- * the chip work the intended way. As it works with predefined register lists,
+- * some undocumented registers are presumably changed there to achieve their
+- * goals.
+- * This driver currently only works for resolutions up to 720 lines with a
+- * 1:1 scale. Hopefully these restrictions will be removed in the future.
+- */
+-#define OV5642_MAX_WIDTH OV5642_SENSOR_SIZE_X
+-#define OV5642_MAX_HEIGHT 720
+-
+-/* default sizes */
+-#define OV5642_DEFAULT_WIDTH 1280
+-#define OV5642_DEFAULT_HEIGHT OV5642_MAX_HEIGHT
+-
+-/* minimum extra blanking */
+-#define BLANKING_EXTRA_WIDTH 500
+-#define BLANKING_EXTRA_HEIGHT 20
+-
+-/*
+- * the sensor's autoexposure is buggy when setting total_height low.
+- * It tries to expose longer than 1 frame period without taking care of it
+- * and this leads to weird output. So we set 1000 lines as minimum.
+- */
+-#define BLANKING_MIN_HEIGHT 1000
+-
+-struct regval_list {
+- u16 reg_num;
+- u8 value;
+-};
+-
+-static struct regval_list ov5642_default_regs_init[] = {
+- { 0x3103, 0x93 },
+- { 0x3008, 0x82 },
+- { 0x3017, 0x7f },
+- { 0x3018, 0xfc },
+- { 0x3810, 0xc2 },
+- { 0x3615, 0xf0 },
+- { 0x3000, 0x0 },
+- { 0x3001, 0x0 },
+- { 0x3002, 0x0 },
+- { 0x3003, 0x0 },
+- { 0x3004, 0xff },
+- { 0x3030, 0x2b },
+- { 0x3011, 0x8 },
+- { 0x3010, 0x10 },
+- { 0x3604, 0x60 },
+- { 0x3622, 0x60 },
+- { 0x3621, 0x9 },
+- { 0x3709, 0x0 },
+- { 0x4000, 0x21 },
+- { 0x401d, 0x22 },
+- { 0x3600, 0x54 },
+- { 0x3605, 0x4 },
+- { 0x3606, 0x3f },
+- { 0x3c01, 0x80 },
+- { 0x300d, 0x22 },
+- { 0x3623, 0x22 },
+- { 0x5000, 0x4f },
+- { 0x5020, 0x4 },
+- { 0x5181, 0x79 },
+- { 0x5182, 0x0 },
+- { 0x5185, 0x22 },
+- { 0x5197, 0x1 },
+- { 0x5500, 0xa },
+- { 0x5504, 0x0 },
+- { 0x5505, 0x7f },
+- { 0x5080, 0x8 },
+- { 0x300e, 0x18 },
+- { 0x4610, 0x0 },
+- { 0x471d, 0x5 },
+- { 0x4708, 0x6 },
+- { 0x370c, 0xa0 },
+- { 0x5687, 0x94 },
+- { 0x501f, 0x0 },
+- { 0x5000, 0x4f },
+- { 0x5001, 0xcf },
+- { 0x4300, 0x30 },
+- { 0x4300, 0x30 },
+- { 0x460b, 0x35 },
+- { 0x471d, 0x0 },
+- { 0x3002, 0xc },
+- { 0x3002, 0x0 },
+- { 0x4713, 0x3 },
+- { 0x471c, 0x50 },
+- { 0x4721, 0x2 },
+- { 0x4402, 0x90 },
+- { 0x460c, 0x22 },
+- { 0x3815, 0x44 },
+- { 0x3503, 0x7 },
+- { 0x3501, 0x73 },
+- { 0x3502, 0x80 },
+- { 0x350b, 0x0 },
+- { 0x3818, 0xc8 },
+- { 0x3824, 0x11 },
+- { 0x3a00, 0x78 },
+- { 0x3a1a, 0x4 },
+- { 0x3a13, 0x30 },
+- { 0x3a18, 0x0 },
+- { 0x3a19, 0x7c },
+- { 0x3a08, 0x12 },
+- { 0x3a09, 0xc0 },
+- { 0x3a0a, 0xf },
+- { 0x3a0b, 0xa0 },
+- { 0x350c, 0x7 },
+- { 0x350d, 0xd0 },
+- { 0x3a0d, 0x8 },
+- { 0x3a0e, 0x6 },
+- { 0x3500, 0x0 },
+- { 0x3501, 0x0 },
+- { 0x3502, 0x0 },
+- { 0x350a, 0x0 },
+- { 0x350b, 0x0 },
+- { 0x3503, 0x0 },
+- { 0x3a0f, 0x3c },
+- { 0x3a10, 0x32 },
+- { 0x3a1b, 0x3c },
+- { 0x3a1e, 0x32 },
+- { 0x3a11, 0x80 },
+- { 0x3a1f, 0x20 },
+- { 0x3030, 0x2b },
+- { 0x3a02, 0x0 },
+- { 0x3a03, 0x7d },
+- { 0x3a04, 0x0 },
+- { 0x3a14, 0x0 },
+- { 0x3a15, 0x7d },
+- { 0x3a16, 0x0 },
+- { 0x3a00, 0x78 },
+- { 0x3a08, 0x9 },
+- { 0x3a09, 0x60 },
+- { 0x3a0a, 0x7 },
+- { 0x3a0b, 0xd0 },
+- { 0x3a0d, 0x10 },
+- { 0x3a0e, 0xd },
+- { 0x4407, 0x4 },
+- { 0x5193, 0x70 },
+- { 0x589b, 0x0 },
+- { 0x589a, 0xc0 },
+- { 0x401e, 0x20 },
+- { 0x4001, 0x42 },
+- { 0x401c, 0x6 },
+- { 0x3825, 0xac },
+- { 0x3827, 0xc },
+- { 0x528a, 0x1 },
+- { 0x528b, 0x4 },
+- { 0x528c, 0x8 },
+- { 0x528d, 0x10 },
+- { 0x528e, 0x20 },
+- { 0x528f, 0x28 },
+- { 0x5290, 0x30 },
+- { 0x5292, 0x0 },
+- { 0x5293, 0x1 },
+- { 0x5294, 0x0 },
+- { 0x5295, 0x4 },
+- { 0x5296, 0x0 },
+- { 0x5297, 0x8 },
+- { 0x5298, 0x0 },
+- { 0x5299, 0x10 },
+- { 0x529a, 0x0 },
+- { 0x529b, 0x20 },
+- { 0x529c, 0x0 },
+- { 0x529d, 0x28 },
+- { 0x529e, 0x0 },
+- { 0x529f, 0x30 },
+- { 0x5282, 0x0 },
+- { 0x5300, 0x0 },
+- { 0x5301, 0x20 },
+- { 0x5302, 0x0 },
+- { 0x5303, 0x7c },
+- { 0x530c, 0x0 },
+- { 0x530d, 0xc },
+- { 0x530e, 0x20 },
+- { 0x530f, 0x80 },
+- { 0x5310, 0x20 },
+- { 0x5311, 0x80 },
+- { 0x5308, 0x20 },
+- { 0x5309, 0x40 },
+- { 0x5304, 0x0 },
+- { 0x5305, 0x30 },
+- { 0x5306, 0x0 },
+- { 0x5307, 0x80 },
+- { 0x5314, 0x8 },
+- { 0x5315, 0x20 },
+- { 0x5319, 0x30 },
+- { 0x5316, 0x10 },
+- { 0x5317, 0x0 },
+- { 0x5318, 0x2 },
+- { 0x5380, 0x1 },
+- { 0x5381, 0x0 },
+- { 0x5382, 0x0 },
+- { 0x5383, 0x4e },
+- { 0x5384, 0x0 },
+- { 0x5385, 0xf },
+- { 0x5386, 0x0 },
+- { 0x5387, 0x0 },
+- { 0x5388, 0x1 },
+- { 0x5389, 0x15 },
+- { 0x538a, 0x0 },
+- { 0x538b, 0x31 },
+- { 0x538c, 0x0 },
+- { 0x538d, 0x0 },
+- { 0x538e, 0x0 },
+- { 0x538f, 0xf },
+- { 0x5390, 0x0 },
+- { 0x5391, 0xab },
+- { 0x5392, 0x0 },
+- { 0x5393, 0xa2 },
+- { 0x5394, 0x8 },
+- { 0x5480, 0x14 },
+- { 0x5481, 0x21 },
+- { 0x5482, 0x36 },
+- { 0x5483, 0x57 },
+- { 0x5484, 0x65 },
+- { 0x5485, 0x71 },
+- { 0x5486, 0x7d },
+- { 0x5487, 0x87 },
+- { 0x5488, 0x91 },
+- { 0x5489, 0x9a },
+- { 0x548a, 0xaa },
+- { 0x548b, 0xb8 },
+- { 0x548c, 0xcd },
+- { 0x548d, 0xdd },
+- { 0x548e, 0xea },
+- { 0x548f, 0x1d },
+- { 0x5490, 0x5 },
+- { 0x5491, 0x0 },
+- { 0x5492, 0x4 },
+- { 0x5493, 0x20 },
+- { 0x5494, 0x3 },
+- { 0x5495, 0x60 },
+- { 0x5496, 0x2 },
+- { 0x5497, 0xb8 },
+- { 0x5498, 0x2 },
+- { 0x5499, 0x86 },
+- { 0x549a, 0x2 },
+- { 0x549b, 0x5b },
+- { 0x549c, 0x2 },
+- { 0x549d, 0x3b },
+- { 0x549e, 0x2 },
+- { 0x549f, 0x1c },
+- { 0x54a0, 0x2 },
+- { 0x54a1, 0x4 },
+- { 0x54a2, 0x1 },
+- { 0x54a3, 0xed },
+- { 0x54a4, 0x1 },
+- { 0x54a5, 0xc5 },
+- { 0x54a6, 0x1 },
+- { 0x54a7, 0xa5 },
+- { 0x54a8, 0x1 },
+- { 0x54a9, 0x6c },
+- { 0x54aa, 0x1 },
+- { 0x54ab, 0x41 },
+- { 0x54ac, 0x1 },
+- { 0x54ad, 0x20 },
+- { 0x54ae, 0x0 },
+- { 0x54af, 0x16 },
+- { 0x54b0, 0x1 },
+- { 0x54b1, 0x20 },
+- { 0x54b2, 0x0 },
+- { 0x54b3, 0x10 },
+- { 0x54b4, 0x0 },
+- { 0x54b5, 0xf0 },
+- { 0x54b6, 0x0 },
+- { 0x54b7, 0xdf },
+- { 0x5402, 0x3f },
+- { 0x5403, 0x0 },
+- { 0x3406, 0x0 },
+- { 0x5180, 0xff },
+- { 0x5181, 0x52 },
+- { 0x5182, 0x11 },
+- { 0x5183, 0x14 },
+- { 0x5184, 0x25 },
+- { 0x5185, 0x24 },
+- { 0x5186, 0x6 },
+- { 0x5187, 0x8 },
+- { 0x5188, 0x8 },
+- { 0x5189, 0x7c },
+- { 0x518a, 0x60 },
+- { 0x518b, 0xb2 },
+- { 0x518c, 0xb2 },
+- { 0x518d, 0x44 },
+- { 0x518e, 0x3d },
+- { 0x518f, 0x58 },
+- { 0x5190, 0x46 },
+- { 0x5191, 0xf8 },
+- { 0x5192, 0x4 },
+- { 0x5193, 0x70 },
+- { 0x5194, 0xf0 },
+- { 0x5195, 0xf0 },
+- { 0x5196, 0x3 },
+- { 0x5197, 0x1 },
+- { 0x5198, 0x4 },
+- { 0x5199, 0x12 },
+- { 0x519a, 0x4 },
+- { 0x519b, 0x0 },
+- { 0x519c, 0x6 },
+- { 0x519d, 0x82 },
+- { 0x519e, 0x0 },
+- { 0x5025, 0x80 },
+- { 0x3a0f, 0x38 },
+- { 0x3a10, 0x30 },
+- { 0x3a1b, 0x3a },
+- { 0x3a1e, 0x2e },
+- { 0x3a11, 0x60 },
+- { 0x3a1f, 0x10 },
+- { 0x5688, 0xa6 },
+- { 0x5689, 0x6a },
+- { 0x568a, 0xea },
+- { 0x568b, 0xae },
+- { 0x568c, 0xa6 },
+- { 0x568d, 0x6a },
+- { 0x568e, 0x62 },
+- { 0x568f, 0x26 },
+- { 0x5583, 0x40 },
+- { 0x5584, 0x40 },
+- { 0x5580, 0x2 },
+- { 0x5000, 0xcf },
+- { 0x5800, 0x27 },
+- { 0x5801, 0x19 },
+- { 0x5802, 0x12 },
+- { 0x5803, 0xf },
+- { 0x5804, 0x10 },
+- { 0x5805, 0x15 },
+- { 0x5806, 0x1e },
+- { 0x5807, 0x2f },
+- { 0x5808, 0x15 },
+- { 0x5809, 0xd },
+- { 0x580a, 0xa },
+- { 0x580b, 0x9 },
+- { 0x580c, 0xa },
+- { 0x580d, 0xc },
+- { 0x580e, 0x12 },
+- { 0x580f, 0x19 },
+- { 0x5810, 0xb },
+- { 0x5811, 0x7 },
+- { 0x5812, 0x4 },
+- { 0x5813, 0x3 },
+- { 0x5814, 0x3 },
+- { 0x5815, 0x6 },
+- { 0x5816, 0xa },
+- { 0x5817, 0xf },
+- { 0x5818, 0xa },
+- { 0x5819, 0x5 },
+- { 0x581a, 0x1 },
+- { 0x581b, 0x0 },
+- { 0x581c, 0x0 },
+- { 0x581d, 0x3 },
+- { 0x581e, 0x8 },
+- { 0x581f, 0xc },
+- { 0x5820, 0xa },
+- { 0x5821, 0x5 },
+- { 0x5822, 0x1 },
+- { 0x5823, 0x0 },
+- { 0x5824, 0x0 },
+- { 0x5825, 0x3 },
+- { 0x5826, 0x8 },
+- { 0x5827, 0xc },
+- { 0x5828, 0xe },
+- { 0x5829, 0x8 },
+- { 0x582a, 0x6 },
+- { 0x582b, 0x4 },
+- { 0x582c, 0x5 },
+- { 0x582d, 0x7 },
+- { 0x582e, 0xb },
+- { 0x582f, 0x12 },
+- { 0x5830, 0x18 },
+- { 0x5831, 0x10 },
+- { 0x5832, 0xc },
+- { 0x5833, 0xa },
+- { 0x5834, 0xb },
+- { 0x5835, 0xe },
+- { 0x5836, 0x15 },
+- { 0x5837, 0x19 },
+- { 0x5838, 0x32 },
+- { 0x5839, 0x1f },
+- { 0x583a, 0x18 },
+- { 0x583b, 0x16 },
+- { 0x583c, 0x17 },
+- { 0x583d, 0x1e },
+- { 0x583e, 0x26 },
+- { 0x583f, 0x53 },
+- { 0x5840, 0x10 },
+- { 0x5841, 0xf },
+- { 0x5842, 0xd },
+- { 0x5843, 0xc },
+- { 0x5844, 0xe },
+- { 0x5845, 0x9 },
+- { 0x5846, 0x11 },
+- { 0x5847, 0x10 },
+- { 0x5848, 0x10 },
+- { 0x5849, 0x10 },
+- { 0x584a, 0x10 },
+- { 0x584b, 0xe },
+- { 0x584c, 0x10 },
+- { 0x584d, 0x10 },
+- { 0x584e, 0x11 },
+- { 0x584f, 0x10 },
+- { 0x5850, 0xf },
+- { 0x5851, 0xc },
+- { 0x5852, 0xf },
+- { 0x5853, 0x10 },
+- { 0x5854, 0x10 },
+- { 0x5855, 0xf },
+- { 0x5856, 0xe },
+- { 0x5857, 0xb },
+- { 0x5858, 0x10 },
+- { 0x5859, 0xd },
+- { 0x585a, 0xd },
+- { 0x585b, 0xc },
+- { 0x585c, 0xc },
+- { 0x585d, 0xc },
+- { 0x585e, 0xb },
+- { 0x585f, 0xc },
+- { 0x5860, 0xc },
+- { 0x5861, 0xc },
+- { 0x5862, 0xd },
+- { 0x5863, 0x8 },
+- { 0x5864, 0x11 },
+- { 0x5865, 0x18 },
+- { 0x5866, 0x18 },
+- { 0x5867, 0x19 },
+- { 0x5868, 0x17 },
+- { 0x5869, 0x19 },
+- { 0x586a, 0x16 },
+- { 0x586b, 0x13 },
+- { 0x586c, 0x13 },
+- { 0x586d, 0x12 },
+- { 0x586e, 0x13 },
+- { 0x586f, 0x16 },
+- { 0x5870, 0x14 },
+- { 0x5871, 0x12 },
+- { 0x5872, 0x10 },
+- { 0x5873, 0x11 },
+- { 0x5874, 0x11 },
+- { 0x5875, 0x16 },
+- { 0x5876, 0x14 },
+- { 0x5877, 0x11 },
+- { 0x5878, 0x10 },
+- { 0x5879, 0xf },
+- { 0x587a, 0x10 },
+- { 0x587b, 0x14 },
+- { 0x587c, 0x13 },
+- { 0x587d, 0x12 },
+- { 0x587e, 0x11 },
+- { 0x587f, 0x11 },
+- { 0x5880, 0x12 },
+- { 0x5881, 0x15 },
+- { 0x5882, 0x14 },
+- { 0x5883, 0x15 },
+- { 0x5884, 0x15 },
+- { 0x5885, 0x15 },
+- { 0x5886, 0x13 },
+- { 0x5887, 0x17 },
+- { 0x3710, 0x10 },
+- { 0x3632, 0x51 },
+- { 0x3702, 0x10 },
+- { 0x3703, 0xb2 },
+- { 0x3704, 0x18 },
+- { 0x370b, 0x40 },
+- { 0x370d, 0x3 },
+- { 0x3631, 0x1 },
+- { 0x3632, 0x52 },
+- { 0x3606, 0x24 },
+- { 0x3620, 0x96 },
+- { 0x5785, 0x7 },
+- { 0x3a13, 0x30 },
+- { 0x3600, 0x52 },
+- { 0x3604, 0x48 },
+- { 0x3606, 0x1b },
+- { 0x370d, 0xb },
+- { 0x370f, 0xc0 },
+- { 0x3709, 0x1 },
+- { 0x3823, 0x0 },
+- { 0x5007, 0x0 },
+- { 0x5009, 0x0 },
+- { 0x5011, 0x0 },
+- { 0x5013, 0x0 },
+- { 0x519e, 0x0 },
+- { 0x5086, 0x0 },
+- { 0x5087, 0x0 },
+- { 0x5088, 0x0 },
+- { 0x5089, 0x0 },
+- { 0x302b, 0x0 },
+- { 0x3503, 0x7 },
+- { 0x3011, 0x8 },
+- { 0x350c, 0x2 },
+- { 0x350d, 0xe4 },
+- { 0x3621, 0xc9 },
+- { 0x370a, 0x81 },
+- { 0xffff, 0xff },
+-};
+-
+-static struct regval_list ov5642_default_regs_finalise[] = {
+- { 0x3810, 0xc2 },
+- { 0x3818, 0xc9 },
+- { 0x381c, 0x10 },
+- { 0x381d, 0xa0 },
+- { 0x381e, 0x5 },
+- { 0x381f, 0xb0 },
+- { 0x3820, 0x0 },
+- { 0x3821, 0x0 },
+- { 0x3824, 0x11 },
+- { 0x3a08, 0x1b },
+- { 0x3a09, 0xc0 },
+- { 0x3a0a, 0x17 },
+- { 0x3a0b, 0x20 },
+- { 0x3a0d, 0x2 },
+- { 0x3a0e, 0x1 },
+- { 0x401c, 0x4 },
+- { 0x5682, 0x5 },
+- { 0x5683, 0x0 },
+- { 0x5686, 0x2 },
+- { 0x5687, 0xcc },
+- { 0x5001, 0x4f },
+- { 0x589b, 0x6 },
+- { 0x589a, 0xc5 },
+- { 0x3503, 0x0 },
+- { 0x460c, 0x20 },
+- { 0x460b, 0x37 },
+- { 0x471c, 0xd0 },
+- { 0x471d, 0x5 },
+- { 0x3815, 0x1 },
+- { 0x3818, 0xc1 },
+- { 0x501f, 0x0 },
+- { 0x5002, 0xe0 },
+- { 0x4300, 0x32 }, /* UYVY */
+- { 0x3002, 0x1c },
+- { 0x4800, 0x14 },
+- { 0x4801, 0xf },
+- { 0x3007, 0x3b },
+- { 0x300e, 0x4 },
+- { 0x4803, 0x50 },
+- { 0x3815, 0x1 },
+- { 0x4713, 0x2 },
+- { 0x4842, 0x1 },
+- { 0x300f, 0xe },
+- { 0x3003, 0x3 },
+- { 0x3003, 0x1 },
+- { 0xffff, 0xff },
+-};
++#define USE_PREDEF
++#include "ov5642.h"
+
+ struct ov5642_datafmt {
+ u32 code;
+@@ -608,6 +40,7 @@ struct ov5642_datafmt {
+
+ struct ov5642 {
+ struct v4l2_subdev subdev;
++ struct media_pad pad;
+ const struct ov5642_datafmt *fmt;
+ struct v4l2_rect crop_rect;
+ struct v4l2_clk *clk;
+@@ -615,10 +48,14 @@ struct ov5642 {
+ /* blanking information */
+ int total_width;
+ int total_height;
++
++ struct soc_camera_subdev_desc ssdd_dt;
++ struct gpio_desc *resetb_gpio;
++ struct gpio_desc *pwdn_gpio;
+ };
+
+ static const struct ov5642_datafmt ov5642_colour_fmts[] = {
+- {MEDIA_BUS_FMT_UYVY8_2X8, V4L2_COLORSPACE_JPEG},
++ {MEDIA_BUS_FMT_YUYV8_2X8, V4L2_COLORSPACE_JPEG},
+ };
+
+ static struct ov5642 *to_ov5642(const struct i2c_client *client)
+@@ -676,10 +113,7 @@ static int reg_write(struct i2c_client *client, u16 reg, u8 val)
+ return 0;
+ }
+
+-/*
+- * convenience function to write 16 bit register values that are split up
+- * into two consecutive high and low parts
+- */
++#if 0
+ static int reg_write16(struct i2c_client *client, u16 reg, u16 val16)
+ {
+ int ret;
+@@ -689,6 +123,7 @@ static int reg_write16(struct i2c_client *client, u16 reg, u16 val16)
+ return ret;
+ return reg_write(client, reg + 1, val16 & 0x00ff);
+ }
++#endif
+
+ #ifdef CONFIG_VIDEO_ADV_DEBUG
+ static int ov5642_get_register(struct v4l2_subdev *sd, struct v4l2_dbg_register *reg)
+@@ -733,6 +168,7 @@ static int ov5642_write_array(struct i2c_client *client,
+ return 0;
+ }
+
++#ifndef USE_PREDEF
+ static int ov5642_set_resolution(struct v4l2_subdev *sd)
+ {
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
+@@ -785,6 +221,7 @@ static int ov5642_set_resolution(struct v4l2_subdev *sd)
+
+ return ret;
+ }
++#endif
+
+ static int ov5642_set_fmt(struct v4l2_subdev *sd,
+ struct v4l2_subdev_pad_config *cfg,
+@@ -866,15 +303,15 @@ static int ov5642_s_crop(struct v4l2_subdev *sd, const struct v4l2_crop *a)
+ priv->total_height = max_t(int, rect.height +
+ BLANKING_EXTRA_HEIGHT,
+ BLANKING_MIN_HEIGHT);
+- priv->crop_rect.width = rect.width;
+- priv->crop_rect.height = rect.height;
+-
++#ifdef USE_PREDEF
++ ret = ov5642_write_array(client, OV5642_720P_30FPS);
++#else
+ ret = ov5642_write_array(client, ov5642_default_regs_init);
+ if (!ret)
+ ret = ov5642_set_resolution(sd);
+ if (!ret)
+ ret = ov5642_write_array(client, ov5642_default_regs_finalise);
+-
++#endif
+ return ret;
+ }
+
+@@ -909,10 +346,10 @@ static int ov5642_cropcap(struct v4l2_subdev *sd, struct v4l2_cropcap *a)
+ static int ov5642_g_mbus_config(struct v4l2_subdev *sd,
+ struct v4l2_mbus_config *cfg)
+ {
+- cfg->type = V4L2_MBUS_CSI2;
+- cfg->flags = V4L2_MBUS_CSI2_2_LANE | V4L2_MBUS_CSI2_CHANNEL_0 |
+- V4L2_MBUS_CSI2_CONTINUOUS_CLOCK;
+-
++ cfg->type = V4L2_MBUS_PARALLEL;
++ cfg->flags = V4L2_MBUS_MASTER | V4L2_MBUS_PCLK_SAMPLE_RISING |
++ V4L2_MBUS_HSYNC_ACTIVE_LOW | V4L2_MBUS_VSYNC_ACTIVE_HIGH |
++ V4L2_MBUS_DATA_ACTIVE_HIGH;
+ return 0;
+ }
+
+@@ -930,12 +367,15 @@ static int ov5642_s_power(struct v4l2_subdev *sd, int on)
+ if (ret < 0)
+ return ret;
+
++#ifdef USE_PREDEF
++ ret = ov5642_write_array(client, OV5642_720P_30FPS);
++#else
+ ret = ov5642_write_array(client, ov5642_default_regs_init);
+ if (!ret)
+ ret = ov5642_set_resolution(sd);
+ if (!ret)
+ ret = ov5642_write_array(client, ov5642_default_regs_finalise);
+-
++#endif
+ return ret;
+ }
+
+@@ -966,6 +406,63 @@ static struct v4l2_subdev_ops ov5642_subdev_ops = {
+ .pad = &ov5642_subdev_pad_ops,
+ };
+
++/* OF probe functions */
++static int ov5642_hw_power(struct device *dev, int on)
++{
++ struct i2c_client *client = to_i2c_client(dev);
++ struct ov5642 *priv = to_ov5642(client);
++
++ dev_dbg(&client->dev, "%s: %s the camera\n",
++ __func__, on ? "ENABLE" : "DISABLE");
++
++ if (priv->pwdn_gpio)
++ gpiod_direction_output(priv->pwdn_gpio, !on);
++
++ return 0;
++}
++
++static int ov5642_hw_reset(struct device *dev)
++{
++ struct i2c_client *client = to_i2c_client(dev);
++ struct ov5642 *priv = to_ov5642(client);
++
++ if (priv->resetb_gpio) {
++ /* Active the resetb pin to perform a reset pulse */
++ gpiod_direction_output(priv->resetb_gpio, 1);
++ usleep_range(3000, 5000);
++ gpiod_direction_output(priv->resetb_gpio, 0);
++ }
++
++ return 0;
++}
++
++static int ov5642_probe_dt(struct i2c_client *client,
++ struct ov5642 *priv)
++{
++ /* Request the reset GPIO deasserted */
++ priv->resetb_gpio = devm_gpiod_get_optional(&client->dev, "resetb",
++ GPIOD_OUT_LOW);
++ if (!priv->resetb_gpio)
++ dev_dbg(&client->dev, "resetb gpio is not assigned!\n");
++ else if (IS_ERR(priv->resetb_gpio))
++ return PTR_ERR(priv->resetb_gpio);
++
++ /* Request the power down GPIO asserted */
++ priv->pwdn_gpio = devm_gpiod_get_optional(&client->dev, "pwdn",
++ GPIOD_OUT_HIGH);
++ if (!priv->pwdn_gpio)
++ dev_dbg(&client->dev, "pwdn gpio is not assigned!\n");
++ else if (IS_ERR(priv->pwdn_gpio))
++ return PTR_ERR(priv->pwdn_gpio);
++
++ /* Initialize the soc_camera_subdev_desc */
++ priv->ssdd_dt.power = ov5642_hw_power;
++ priv->ssdd_dt.reset = ov5642_hw_reset;
++ client->dev.platform_data = &priv->ssdd_dt;
++
++ return 0;
++}
++
+ static int ov5642_video_probe(struct i2c_client *client)
+ {
+ struct v4l2_subdev *subdev = i2c_get_clientdata(client);
+@@ -1008,19 +505,23 @@ static int ov5642_probe(struct i2c_client *client,
+ const struct i2c_device_id *did)
+ {
+ struct ov5642 *priv;
++ struct v4l2_subdev *sd;
+ struct soc_camera_subdev_desc *ssdd = soc_camera_i2c_to_desc(client);
+ int ret;
+
+- if (!ssdd) {
+- dev_err(&client->dev, "OV5642: missing platform data!\n");
+- return -EINVAL;
+- }
+-
+ priv = devm_kzalloc(&client->dev, sizeof(struct ov5642), GFP_KERNEL);
+ if (!priv)
+ return -ENOMEM;
+
++ if (!ssdd) {
++ ret = ov5642_probe_dt(client, priv);
++ if (ret)
++ return ret;
++ }
++
++ sd = &priv->subdev;
+ v4l2_i2c_subdev_init(&priv->subdev, client, &ov5642_subdev_ops);
++ priv->subdev.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
+
+ priv->fmt = &ov5642_colour_fmts[0];
+
+@@ -1036,8 +537,20 @@ static int ov5642_probe(struct i2c_client *client,
+ return PTR_ERR(priv->clk);
+
+ ret = ov5642_video_probe(client);
+- if (ret < 0)
++ if (ret < 0) {
+ v4l2_clk_put(priv->clk);
++ return ret;
++ }
++
++ priv->pad.flags = MEDIA_PAD_FL_SOURCE;
++ sd->entity.function = MEDIA_ENT_F_CAM_SENSOR;
++ ret = media_entity_pads_init(&sd->entity, 1, &priv->pad);
++ if (ret < 0)
++ return ret;
++
++ ret = v4l2_async_register_subdev(sd);
++ if (ret < 0)
++ media_entity_cleanup(&sd->entity);
+
+ return ret;
+ }
+@@ -1060,8 +573,17 @@ static const struct i2c_device_id ov5642_id[] = {
+ };
+ MODULE_DEVICE_TABLE(i2c, ov5642_id);
+
++#if IS_ENABLED(CONFIG_OF)
++static const struct of_device_id ov5642_of_match[] = {
++ { .compatible = "ovti,ov5642" },
++ { /* sentinel */ },
++};
++MODULE_DEVICE_TABLE(of, ov5642_of_match);
++#endif
++
+ static struct i2c_driver ov5642_i2c_driver = {
+ .driver = {
++ .of_match_table = of_match_ptr(ov5642_of_match),
+ .name = "ov5642",
+ },
+ .probe = ov5642_probe,
+diff --git a/drivers/media/i2c/soc_camera/ov5642.h b/drivers/media/i2c/soc_camera/ov5642.h
+new file mode 100644
+index 0000000..ac47a16
+--- /dev/null
++++ b/drivers/media/i2c/soc_camera/ov5642.h
+@@ -0,0 +1,592 @@
++#ifndef _OV5642_H_
++#define _OV5642_H_
++
++
++/* OV5642 registers */
++#define REG_CHIP_ID_HIGH 0x300a
++#define REG_CHIP_ID_LOW 0x300b
++
++#define REG_WINDOW_START_X_HIGH 0x3800
++#define REG_WINDOW_START_X_LOW 0x3801
++#define REG_WINDOW_START_Y_HIGH 0x3802
++#define REG_WINDOW_START_Y_LOW 0x3803
++#define REG_WINDOW_WIDTH_HIGH 0x3804
++#define REG_WINDOW_WIDTH_LOW 0x3805
++#define REG_WINDOW_HEIGHT_HIGH 0x3806
++#define REG_WINDOW_HEIGHT_LOW 0x3807
++#define REG_OUT_WIDTH_HIGH 0x3808
++#define REG_OUT_WIDTH_LOW 0x3809
++#define REG_OUT_HEIGHT_HIGH 0x380a
++#define REG_OUT_HEIGHT_LOW 0x380b
++#define REG_OUT_TOTAL_WIDTH_HIGH 0x380c
++#define REG_OUT_TOTAL_WIDTH_LOW 0x380d
++#define REG_OUT_TOTAL_HEIGHT_HIGH 0x380e
++#define REG_OUT_TOTAL_HEIGHT_LOW 0x380f
++#define REG_OUTPUT_FORMAT 0x4300
++#define REG_ISP_CTRL_00 0x5000
++#define REG_ISP_CTRL_01 0x5001
++#define REG_AVG_WINDOW_START_X_HIGH 0x5680
++#define REG_AVG_WINDOW_START_X_LOW 0x5681
++#define REG_AVG_WINDOW_END_X_HIGH 0x5682
++#define REG_AVG_WINDOW_END_X_LOW 0x5683
++#define REG_AVG_WINDOW_START_Y_HIGH 0x5684
++#define REG_AVG_WINDOW_START_Y_LOW 0x5685
++#define REG_AVG_WINDOW_END_Y_HIGH 0x5686
++#define REG_AVG_WINDOW_END_Y_LOW 0x5687
++
++/* active pixel array size */
++#define OV5642_SENSOR_SIZE_X 2592
++#define OV5642_SENSOR_SIZE_Y 1944
++
++/*
++ * About OV5642 resolution, cropping and binning:
++ * This sensor supports it all, at least in the feature description.
++ * Unfortunately, no combination of appropriate registers settings could make
++ * the chip work the intended way. As it works with predefined register lists,
++ * some undocumented registers are presumably changed there to achieve their
++ * goals.
++ * This driver currently only works for resolutions up to 720 lines with a
++ * 1:1 scale. Hopefully these restrictions will be removed in the future.
++ */
++#define OV5642_MAX_WIDTH OV5642_SENSOR_SIZE_X
++#define OV5642_MAX_HEIGHT 720
++
++/* default sizes */
++#define OV5642_DEFAULT_WIDTH 1280
++#define OV5642_DEFAULT_HEIGHT OV5642_MAX_HEIGHT
++
++/* minimum extra blanking */
++#define BLANKING_EXTRA_WIDTH 500
++#define BLANKING_EXTRA_HEIGHT 20
++
++/*
++ * the sensor's autoexposure is buggy when setting total_height low.
++ * It tries to expose longer than 1 frame period without taking care of it
++ * and this leads to weird output. So we set 1000 lines as minimum.
++ */
++#define BLANKING_MIN_HEIGHT 1000
++
++struct regval_list {
++ u16 reg_num;
++ u8 value;
++};
++
++#ifdef USE_PREDEF
++ #include "ov5642_720p.h"
++#endif
++
++#ifndef USE_PREDEF
++
++static struct regval_list ov5642_default_regs_init[] = {
++ { 0x3103, 0x93 },
++ { 0x3008, 0x82 },
++ { 0x3017, 0x7f },
++ { 0x3018, 0xfc },
++ { 0x3810, 0xc2 },
++ { 0x3615, 0xf0 },
++ { 0x3000, 0x0 },
++ { 0x3001, 0x0 },
++ { 0x3002, 0x0 },
++ { 0x3003, 0x0 },
++ { 0x3004, 0xff },
++ { 0x3030, 0x2b },
++ { 0x3011, 0x8 },
++ { 0x3010, 0x10 },
++ { 0x3604, 0x60 },
++ { 0x3622, 0x60 },
++ { 0x3621, 0x9 },
++ { 0x3709, 0x0 },
++ { 0x4000, 0x21 },
++ { 0x401d, 0x22 },
++ { 0x3600, 0x54 },
++ { 0x3605, 0x4 },
++ { 0x3606, 0x3f },
++ { 0x3c01, 0x80 },
++ { 0x300d, 0x22 },
++ { 0x3623, 0x22 },
++ { 0x5000, 0x4f },
++ { 0x5020, 0x4 },
++ { 0x5181, 0x79 },
++ { 0x5182, 0x0 },
++ { 0x5185, 0x22 },
++ { 0x5197, 0x1 },
++ { 0x5500, 0xa },
++ { 0x5504, 0x0 },
++ { 0x5505, 0x7f },
++ { 0x5080, 0x8 },
++ { 0x300e, 0x18 },
++ { 0x4610, 0x0 },
++ { 0x471d, 0x5 },
++ { 0x4708, 0x6 },
++ { 0x370c, 0xa0 },
++ { 0x5687, 0x94 },
++ { 0x501f, 0x0 },
++ { 0x5000, 0x4f },
++ { 0x5001, 0xcf },
++ { 0x4300, 0x30 },
++ { 0x4300, 0x30 },
++ { 0x460b, 0x35 },
++ { 0x471d, 0x0 },
++ { 0x3002, 0xc },
++ { 0x3002, 0x0 },
++ { 0x4713, 0x3 },
++ { 0x471c, 0x50 },
++ { 0x4721, 0x2 },
++ { 0x4402, 0x90 },
++ { 0x460c, 0x22 },
++ { 0x3815, 0x44 },
++ { 0x3503, 0x7 },
++ { 0x3501, 0x73 },
++ { 0x3502, 0x80 },
++ { 0x350b, 0x0 },
++ { 0x3818, 0xc8 },
++ { 0x3824, 0x11 },
++ { 0x3a00, 0x78 },
++ { 0x3a1a, 0x4 },
++ { 0x3a13, 0x30 },
++ { 0x3a18, 0x0 },
++ { 0x3a19, 0x7c },
++ { 0x3a08, 0x12 },
++ { 0x3a09, 0xc0 },
++ { 0x3a0a, 0xf },
++ { 0x3a0b, 0xa0 },
++ { 0x350c, 0x7 },
++ { 0x350d, 0xd0 },
++ { 0x3a0d, 0x8 },
++ { 0x3a0e, 0x6 },
++ { 0x3500, 0x0 },
++ { 0x3501, 0x0 },
++ { 0x3502, 0x0 },
++ { 0x350a, 0x0 },
++ { 0x350b, 0x0 },
++ { 0x3503, 0x0 },
++ { 0x3a0f, 0x3c },
++ { 0x3a10, 0x32 },
++ { 0x3a1b, 0x3c },
++ { 0x3a1e, 0x32 },
++ { 0x3a11, 0x80 },
++ { 0x3a1f, 0x20 },
++ { 0x3030, 0x2b },
++ { 0x3a02, 0x0 },
++ { 0x3a03, 0x7d },
++ { 0x3a04, 0x0 },
++ { 0x3a14, 0x0 },
++ { 0x3a15, 0x7d },
++ { 0x3a16, 0x0 },
++ { 0x3a00, 0x78 },
++ { 0x3a08, 0x9 },
++ { 0x3a09, 0x60 },
++ { 0x3a0a, 0x7 },
++ { 0x3a0b, 0xd0 },
++ { 0x3a0d, 0x10 },
++ { 0x3a0e, 0xd },
++ { 0x4407, 0x4 },
++ { 0x5193, 0x70 },
++ { 0x589b, 0x0 },
++ { 0x589a, 0xc0 },
++ { 0x401e, 0x20 },
++ { 0x4001, 0x42 },
++ { 0x401c, 0x6 },
++ { 0x3825, 0xac },
++ { 0x3827, 0xc },
++ { 0x528a, 0x1 },
++ { 0x528b, 0x4 },
++ { 0x528c, 0x8 },
++ { 0x528d, 0x10 },
++ { 0x528e, 0x20 },
++ { 0x528f, 0x28 },
++ { 0x5290, 0x30 },
++ { 0x5292, 0x0 },
++ { 0x5293, 0x1 },
++ { 0x5294, 0x0 },
++ { 0x5295, 0x4 },
++ { 0x5296, 0x0 },
++ { 0x5297, 0x8 },
++ { 0x5298, 0x0 },
++ { 0x5299, 0x10 },
++ { 0x529a, 0x0 },
++ { 0x529b, 0x20 },
++ { 0x529c, 0x0 },
++ { 0x529d, 0x28 },
++ { 0x529e, 0x0 },
++ { 0x529f, 0x30 },
++ { 0x5282, 0x0 },
++ { 0x5300, 0x0 },
++ { 0x5301, 0x20 },
++ { 0x5302, 0x0 },
++ { 0x5303, 0x7c },
++ { 0x530c, 0x0 },
++ { 0x530d, 0xc },
++ { 0x530e, 0x20 },
++ { 0x530f, 0x80 },
++ { 0x5310, 0x20 },
++ { 0x5311, 0x80 },
++ { 0x5308, 0x20 },
++ { 0x5309, 0x40 },
++ { 0x5304, 0x0 },
++ { 0x5305, 0x30 },
++ { 0x5306, 0x0 },
++ { 0x5307, 0x80 },
++ { 0x5314, 0x8 },
++ { 0x5315, 0x20 },
++ { 0x5319, 0x30 },
++ { 0x5316, 0x10 },
++ { 0x5317, 0x0 },
++ { 0x5318, 0x2 },
++ { 0x5380, 0x1 },
++ { 0x5381, 0x0 },
++ { 0x5382, 0x0 },
++ { 0x5383, 0x4e },
++ { 0x5384, 0x0 },
++ { 0x5385, 0xf },
++ { 0x5386, 0x0 },
++ { 0x5387, 0x0 },
++ { 0x5388, 0x1 },
++ { 0x5389, 0x15 },
++ { 0x538a, 0x0 },
++ { 0x538b, 0x31 },
++ { 0x538c, 0x0 },
++ { 0x538d, 0x0 },
++ { 0x538e, 0x0 },
++ { 0x538f, 0xf },
++ { 0x5390, 0x0 },
++ { 0x5391, 0xab },
++ { 0x5392, 0x0 },
++ { 0x5393, 0xa2 },
++ { 0x5394, 0x8 },
++ { 0x5480, 0x14 },
++ { 0x5481, 0x21 },
++ { 0x5482, 0x36 },
++ { 0x5483, 0x57 },
++ { 0x5484, 0x65 },
++ { 0x5485, 0x71 },
++ { 0x5486, 0x7d },
++ { 0x5487, 0x87 },
++ { 0x5488, 0x91 },
++ { 0x5489, 0x9a },
++ { 0x548a, 0xaa },
++ { 0x548b, 0xb8 },
++ { 0x548c, 0xcd },
++ { 0x548d, 0xdd },
++ { 0x548e, 0xea },
++ { 0x548f, 0x1d },
++ { 0x5490, 0x5 },
++ { 0x5491, 0x0 },
++ { 0x5492, 0x4 },
++ { 0x5493, 0x20 },
++ { 0x5494, 0x3 },
++ { 0x5495, 0x60 },
++ { 0x5496, 0x2 },
++ { 0x5497, 0xb8 },
++ { 0x5498, 0x2 },
++ { 0x5499, 0x86 },
++ { 0x549a, 0x2 },
++ { 0x549b, 0x5b },
++ { 0x549c, 0x2 },
++ { 0x549d, 0x3b },
++ { 0x549e, 0x2 },
++ { 0x549f, 0x1c },
++ { 0x54a0, 0x2 },
++ { 0x54a1, 0x4 },
++ { 0x54a2, 0x1 },
++ { 0x54a3, 0xed },
++ { 0x54a4, 0x1 },
++ { 0x54a5, 0xc5 },
++ { 0x54a6, 0x1 },
++ { 0x54a7, 0xa5 },
++ { 0x54a8, 0x1 },
++ { 0x54a9, 0x6c },
++ { 0x54aa, 0x1 },
++ { 0x54ab, 0x41 },
++ { 0x54ac, 0x1 },
++ { 0x54ad, 0x20 },
++ { 0x54ae, 0x0 },
++ { 0x54af, 0x16 },
++ { 0x54b0, 0x1 },
++ { 0x54b1, 0x20 },
++ { 0x54b2, 0x0 },
++ { 0x54b3, 0x10 },
++ { 0x54b4, 0x0 },
++ { 0x54b5, 0xf0 },
++ { 0x54b6, 0x0 },
++ { 0x54b7, 0xdf },
++ { 0x5402, 0x3f },
++ { 0x5403, 0x0 },
++ { 0x3406, 0x0 },
++ { 0x5180, 0xff },
++ { 0x5181, 0x52 },
++ { 0x5182, 0x11 },
++ { 0x5183, 0x14 },
++ { 0x5184, 0x25 },
++ { 0x5185, 0x24 },
++ { 0x5186, 0x6 },
++ { 0x5187, 0x8 },
++ { 0x5188, 0x8 },
++ { 0x5189, 0x7c },
++ { 0x518a, 0x60 },
++ { 0x518b, 0xb2 },
++ { 0x518c, 0xb2 },
++ { 0x518d, 0x44 },
++ { 0x518e, 0x3d },
++ { 0x518f, 0x58 },
++ { 0x5190, 0x46 },
++ { 0x5191, 0xf8 },
++ { 0x5192, 0x4 },
++ { 0x5193, 0x70 },
++ { 0x5194, 0xf0 },
++ { 0x5195, 0xf0 },
++ { 0x5196, 0x3 },
++ { 0x5197, 0x1 },
++ { 0x5198, 0x4 },
++ { 0x5199, 0x12 },
++ { 0x519a, 0x4 },
++ { 0x519b, 0x0 },
++ { 0x519c, 0x6 },
++ { 0x519d, 0x82 },
++ { 0x519e, 0x0 },
++ { 0x5025, 0x80 },
++ { 0x3a0f, 0x38 },
++ { 0x3a10, 0x30 },
++ { 0x3a1b, 0x3a },
++ { 0x3a1e, 0x2e },
++ { 0x3a11, 0x60 },
++ { 0x3a1f, 0x10 },
++ { 0x5688, 0xa6 },
++ { 0x5689, 0x6a },
++ { 0x568a, 0xea },
++ { 0x568b, 0xae },
++ { 0x568c, 0xa6 },
++ { 0x568d, 0x6a },
++ { 0x568e, 0x62 },
++ { 0x568f, 0x26 },
++ { 0x5583, 0x40 },
++ { 0x5584, 0x40 },
++ { 0x5580, 0x2 },
++ { 0x5000, 0xcf },
++ { 0x5800, 0x27 },
++ { 0x5801, 0x19 },
++ { 0x5802, 0x12 },
++ { 0x5803, 0xf },
++ { 0x5804, 0x10 },
++ { 0x5805, 0x15 },
++ { 0x5806, 0x1e },
++ { 0x5807, 0x2f },
++ { 0x5808, 0x15 },
++ { 0x5809, 0xd },
++ { 0x580a, 0xa },
++ { 0x580b, 0x9 },
++ { 0x580c, 0xa },
++ { 0x580d, 0xc },
++ { 0x580e, 0x12 },
++ { 0x580f, 0x19 },
++ { 0x5810, 0xb },
++ { 0x5811, 0x7 },
++ { 0x5812, 0x4 },
++ { 0x5813, 0x3 },
++ { 0x5814, 0x3 },
++ { 0x5815, 0x6 },
++ { 0x5816, 0xa },
++ { 0x5817, 0xf },
++ { 0x5818, 0xa },
++ { 0x5819, 0x5 },
++ { 0x581a, 0x1 },
++ { 0x581b, 0x0 },
++ { 0x581c, 0x0 },
++ { 0x581d, 0x3 },
++ { 0x581e, 0x8 },
++ { 0x581f, 0xc },
++ { 0x5820, 0xa },
++ { 0x5821, 0x5 },
++ { 0x5822, 0x1 },
++ { 0x5823, 0x0 },
++ { 0x5824, 0x0 },
++ { 0x5825, 0x3 },
++ { 0x5826, 0x8 },
++ { 0x5827, 0xc },
++ { 0x5828, 0xe },
++ { 0x5829, 0x8 },
++ { 0x582a, 0x6 },
++ { 0x582b, 0x4 },
++ { 0x582c, 0x5 },
++ { 0x582d, 0x7 },
++ { 0x582e, 0xb },
++ { 0x582f, 0x12 },
++ { 0x5830, 0x18 },
++ { 0x5831, 0x10 },
++ { 0x5832, 0xc },
++ { 0x5833, 0xa },
++ { 0x5834, 0xb },
++ { 0x5835, 0xe },
++ { 0x5836, 0x15 },
++ { 0x5837, 0x19 },
++ { 0x5838, 0x32 },
++ { 0x5839, 0x1f },
++ { 0x583a, 0x18 },
++ { 0x583b, 0x16 },
++ { 0x583c, 0x17 },
++ { 0x583d, 0x1e },
++ { 0x583e, 0x26 },
++ { 0x583f, 0x53 },
++ { 0x5840, 0x10 },
++ { 0x5841, 0xf },
++ { 0x5842, 0xd },
++ { 0x5843, 0xc },
++ { 0x5844, 0xe },
++ { 0x5845, 0x9 },
++ { 0x5846, 0x11 },
++ { 0x5847, 0x10 },
++ { 0x5848, 0x10 },
++ { 0x5849, 0x10 },
++ { 0x584a, 0x10 },
++ { 0x584b, 0xe },
++ { 0x584c, 0x10 },
++ { 0x584d, 0x10 },
++ { 0x584e, 0x11 },
++ { 0x584f, 0x10 },
++ { 0x5850, 0xf },
++ { 0x5851, 0xc },
++ { 0x5852, 0xf },
++ { 0x5853, 0x10 },
++ { 0x5854, 0x10 },
++ { 0x5855, 0xf },
++ { 0x5856, 0xe },
++ { 0x5857, 0xb },
++ { 0x5858, 0x10 },
++ { 0x5859, 0xd },
++ { 0x585a, 0xd },
++ { 0x585b, 0xc },
++ { 0x585c, 0xc },
++ { 0x585d, 0xc },
++ { 0x585e, 0xb },
++ { 0x585f, 0xc },
++ { 0x5860, 0xc },
++ { 0x5861, 0xc },
++ { 0x5862, 0xd },
++ { 0x5863, 0x8 },
++ { 0x5864, 0x11 },
++ { 0x5865, 0x18 },
++ { 0x5866, 0x18 },
++ { 0x5867, 0x19 },
++ { 0x5868, 0x17 },
++ { 0x5869, 0x19 },
++ { 0x586a, 0x16 },
++ { 0x586b, 0x13 },
++ { 0x586c, 0x13 },
++ { 0x586d, 0x12 },
++ { 0x586e, 0x13 },
++ { 0x586f, 0x16 },
++ { 0x5870, 0x14 },
++ { 0x5871, 0x12 },
++ { 0x5872, 0x10 },
++ { 0x5873, 0x11 },
++ { 0x5874, 0x11 },
++ { 0x5875, 0x16 },
++ { 0x5876, 0x14 },
++ { 0x5877, 0x11 },
++ { 0x5878, 0x10 },
++ { 0x5879, 0xf },
++ { 0x587a, 0x10 },
++ { 0x587b, 0x14 },
++ { 0x587c, 0x13 },
++ { 0x587d, 0x12 },
++ { 0x587e, 0x11 },
++ { 0x587f, 0x11 },
++ { 0x5880, 0x12 },
++ { 0x5881, 0x15 },
++ { 0x5882, 0x14 },
++ { 0x5883, 0x15 },
++ { 0x5884, 0x15 },
++ { 0x5885, 0x15 },
++ { 0x5886, 0x13 },
++ { 0x5887, 0x17 },
++ { 0x3710, 0x10 },
++ { 0x3632, 0x51 },
++ { 0x3702, 0x10 },
++ { 0x3703, 0xb2 },
++ { 0x3704, 0x18 },
++ { 0x370b, 0x40 },
++ { 0x370d, 0x3 },
++ { 0x3631, 0x1 },
++ { 0x3632, 0x52 },
++ { 0x3606, 0x24 },
++ { 0x3620, 0x96 },
++ { 0x5785, 0x7 },
++ { 0x3a13, 0x30 },
++ { 0x3600, 0x52 },
++ { 0x3604, 0x48 },
++ { 0x3606, 0x1b },
++ { 0x370d, 0xb },
++ { 0x370f, 0xc0 },
++ { 0x3709, 0x1 },
++ { 0x3823, 0x0 },
++ { 0x5007, 0x0 },
++ { 0x5009, 0x0 },
++ { 0x5011, 0x0 },
++ { 0x5013, 0x0 },
++ { 0x519e, 0x0 },
++ { 0x5086, 0x0 },
++ { 0x5087, 0x0 },
++ { 0x5088, 0x0 },
++ { 0x5089, 0x0 },
++ { 0x302b, 0x0 },
++ { 0x3503, 0x7 },
++ { 0x3011, 0x8 },
++ { 0x350c, 0x2 },
++ { 0x350d, 0xe4 },
++ { 0x3621, 0xc9 },
++ { 0x370a, 0x81 },
++ { 0xffff, 0xff },
++};
++
++static struct regval_list ov5642_default_regs_finalise[] = {
++ { 0x3810, 0xc2 },
++ { 0x3818, 0xc9 },
++ { 0x381c, 0x10 },
++ { 0x381d, 0xa0 },
++ { 0x381e, 0x5 },
++ { 0x381f, 0xb0 },
++ { 0x3820, 0x0 },
++ { 0x3821, 0x0 },
++ { 0x3824, 0x11 },
++ { 0x3a08, 0x1b },
++ { 0x3a09, 0xc0 },
++ { 0x3a0a, 0x17 },
++ { 0x3a0b, 0x20 },
++ { 0x3a0d, 0x2 },
++ { 0x3a0e, 0x1 },
++ { 0x401c, 0x4 },
++ { 0x5682, 0x5 },
++ { 0x5683, 0x0 },
++ { 0x5686, 0x2 },
++ { 0x5687, 0xcc },
++ { 0x5001, 0x4f },
++ { 0x589b, 0x6 },
++ { 0x589a, 0xc5 },
++ { 0x3503, 0x0 },
++ { 0x460c, 0x20 },
++ { 0x460b, 0x37 },
++ { 0x471c, 0xd0 },
++ { 0x471d, 0x5 },
++ { 0x3815, 0x1 },
++ { 0x3818, 0xc1 },
++ { 0x501f, 0x0 },
++ { 0x5002, 0xe0 },
++ { 0x4300, 0x32 }, /* UYVY */
++ { 0x3002, 0x1c },
++ { 0x4800, 0x14 },
++ { 0x4801, 0xf },
++ { 0x3007, 0x3b },
++ { 0x300e, 0x4 },
++ { 0x4803, 0x50 },
++ { 0x3815, 0x1 },
++ { 0x4713, 0x2 },
++ { 0x4842, 0x1 },
++ { 0x300f, 0xe },
++ { 0x3003, 0x3 },
++ { 0x3003, 0x1 },
++ { 0xffff, 0xff },
++};
++
++#endif
++
++#endif /* _OV5642_H_ */
+diff --git a/drivers/media/i2c/soc_camera/ov5642_720p.h b/drivers/media/i2c/soc_camera/ov5642_720p.h
+new file mode 100644
+index 0000000..d5a52e3
+--- /dev/null
++++ b/drivers/media/i2c/soc_camera/ov5642_720p.h
+@@ -0,0 +1,711 @@
++/* Settings array from
++ * From 5e8e49e226b29c144ddf482afe7d3ad659c9897f Mon Sep 17 00:00:00 2001
++ * From: Kazuya Nishimura <kazuya.nishimura@windriver.com>
++ * Date: Mon, 20 Oct 2014 15:12:56 +0900
++ * Subject: [PATCH] Enabled VIN driver for MMB
++ */
++
++/* 720p 30fps @ 1280x720 */
++/* for the setting , 24MHz Mlck input and 90MHz Plck output */
++/* refer to OV5642.c */
++
++static struct regval_list OV5642_720P_30FPS[] =
++{
++ {0x3103, 0x93},
++ {0x3008, 0x82},
++ {0x3017, 0x7f},
++ {0x3018, 0xfc},
++ /* drive capability 4x */
++ { 0x302c, (3 << 5) | 0x02 },
++ {0x3810, 0xc2},
++ {0x3615, 0xf0},
++ {0x3000, 0x00},
++ {0x3001, 0x00},
++ {0x3002, 0x00},
++ {0x3003, 0x00},
++ {0x3000, 0xf8},
++ {0x3001, 0x48},
++ {0x3002, 0x5c},
++ {0x3003, 0x02},
++ {0x3004, 0x07},
++ {0x3005, 0xb7},
++ {0x3006, 0x43},
++ {0x3007, 0x37},
++ {0x3011, 0x0f}, //PLL CONTROL 02 : Bit[5:0] PLL DIVP divider
++ {0x3010, 0x10}, //PLL CONTROL 01 : Bit[7:4] PLL DIVS, Bit[3:0] PLL DIVM (MIPI divider ratio)
++ //29-30fps
++ {0x460c, 0x22},
++ {0x3815, 0x04},
++ {0x370d, 0x06},
++ {0x370c, 0xa0},
++ {0x3602, 0xfc},
++ {0x3612, 0xff},
++ {0x3634, 0xc0},
++ {0x3613, 0x00},
++ {0x3605, 0x7c},
++ {0x3621, 0x09},
++ {0x3622, 0x00},
++ {0x3604, 0x40},
++ {0x3603, 0xa7},
++ {0x3603, 0x27},
++ {0x4000, 0x21},
++ {0x401d, 0x02},
++ {0x3600, 0x54},
++ {0x3605, 0x04},
++ {0x3606, 0x3f},
++ {0x3c01, 0x80},
++ {REG_ISP_CTRL_00, 0x4f},
++ {0x4300, 0x32}, /* YUV422: UYVY... */
++ {0x5020, 0x04},
++ {0x5181, 0x79},
++ {0x5182, 0x00},
++ {0x5185, 0x22},
++ {0x5197, 0x01},
++ {REG_ISP_CTRL_01, 0xff},
++ {0x5500, 0x0a},
++ {0x5504, 0x00},
++ {0x5505, 0x7f},
++ {0x5080, 0x08},
++ {0x300e, 0x18},
++ {0x4610, 0x00},
++ {0x471d, 0x05},
++ {0x4708, 0x06},
++ /* POLARITY CTRL 00
++ * [0] VSYNC - act low
++ * [1] HREF - act low
++ * [2] gate PCLK under HREF - no
++ * [3] gate PCLK under VSYNK - no
++ * [5] PCLK - falling edge
++ */
++ {0x4740, 0x20},
++ {0x3710, 0x10},
++ {0x3632, 0x41},
++ {0x3702, 0x40},
++ {0x3620, 0x37},
++ {0x3631, 0x01},
++ {REG_OUT_WIDTH_HIGH, 0x02}, // TIMING DVPHO Bit[3:0] DVP output horizontal width high byte
++ {REG_OUT_WIDTH_LOW, 0x80}, // TIMING DVPHO Bit[7:0] DVP output horizontal width low byte
++ // 0x280 => 640
++ {REG_OUT_HEIGHT_HIGH, 0x01}, // TIMING DVPVO Bit[3:0] DVP output vertical height high byte
++ {REG_OUT_HEIGHT_LOW, 0xe0}, // TIMING DVPVO Bit[7:0] DVP output vertical height low byte
++ // 0x1e0 => 480
++ {REG_OUT_TOTAL_HEIGHT_HIGH, 0x07}, // TIMING VTS Bit[3:0] Total vertical size high byte [11:8]
++ {REG_OUT_TOTAL_HEIGHT_LOW, 0xd0}, // TIMING VTS Bit[7:0] Total vertical size low byte [7:0]
++ // 0x7d0 => 2000
++ {0x501f, 0x00},
++ {REG_ISP_CTRL_00, 0x4f},
++ {REG_OUTPUT_FORMAT, 0x32}, //UYVY
++ {0x3503, 0x07},
++ {0x3501, 0x73},
++ {0x3502, 0x80},
++ {0x350b, 0x00},
++ {0x3503, 0x07},
++ {0x3824, 0x11},
++ {0x3501, 0x1e},
++ {0x3502, 0x80},
++ {0x350b, 0x7f},
++ {REG_OUT_TOTAL_WIDTH_HIGH, 0x0c},
++ {REG_OUT_TOTAL_WIDTH_LOW, 0x80},
++ {REG_OUT_TOTAL_HEIGHT_HIGH, 0x03}, // TIMING VTS Bit[3:0] Total vertical size high byte [11:8]
++ {REG_OUT_TOTAL_HEIGHT_LOW, 0xe8}, // TIMING VTS Bit[7:0] Total vertical size low byte [7:0]
++ // 0x3e8 => 1000
++ {0x3a0d, 0x04},
++ {0x3a0e, 0x03},
++ {0x3818, 0xc1},
++ {0x3705, 0xdb},
++ {0x370a, 0x81},
++ {REG_WINDOW_START_X_LOW, 0x80},
++ {0x3621, 0xc7},
++ {REG_WINDOW_START_X_LOW, 0x50},
++ {REG_WINDOW_START_Y_LOW, 0x08},
++ {0x3827, 0x08},
++ {0x3810, 0xc0},
++ {REG_WINDOW_WIDTH_HIGH, 0x05},
++ {REG_WINDOW_WIDTH_LOW, 0x00},
++ {REG_AVG_WINDOW_END_X_HIGH, 0x05},
++ {REG_AVG_WINDOW_END_X_LOW, 0x00},
++ {REG_WINDOW_HEIGHT_HIGH, 0x03},
++ {REG_WINDOW_HEIGHT_LOW, 0xc0},
++ {REG_AVG_WINDOW_END_Y_HIGH, 0x03},
++ {REG_AVG_WINDOW_END_Y_LOW, 0xc0},
++ {0x3a00, 0x78},
++ {0x3a1a, 0x04},
++ {0x3a13, 0x30},
++ {0x3a18, 0x00},
++ {0x3a19, 0x7c},
++ {0x3a08, 0x12},
++ {0x3a09, 0xc0},
++ {0x3a0a, 0x0f},
++ {0x3a0b, 0xa0},
++ {0x3004, 0xff},
++ {0x350c, 0x07},
++ {0x350d, 0xd0},
++ {0x3500, 0x00},
++ {0x3501, 0x00},
++ {0x3502, 0x00},
++ {0x350a, 0x00},
++ {0x350b, 0x00},
++ {0x3503, 0x00},
++ {0x528a, 0x02},
++ {0x528b, 0x04},
++ {0x528c, 0x08},
++ {0x528d, 0x08},
++ {0x528e, 0x08},
++ {0x528f, 0x10},
++ {0x5290, 0x10},
++ {0x5292, 0x00},
++ {0x5293, 0x02},
++ {0x5294, 0x00},
++ {0x5295, 0x02},
++ {0x5296, 0x00},
++ {0x5297, 0x02},
++ {0x5298, 0x00},
++ {0x5299, 0x02},
++ {0x529a, 0x00},
++ {0x529b, 0x02},
++ {0x529c, 0x00},
++ {0x529d, 0x02},
++ {0x529e, 0x00},
++ {0x529f, 0x02},
++ {0x3a0f, 0x3c},
++ {0x3a10, 0x30},
++ {0x3a1b, 0x3c},
++ {0x3a1e, 0x30},
++ {0x3a11, 0x70},
++ {0x3a1f, 0x10},
++ {0x3030, 0x0b},
++ {0x3a02, 0x00},
++ {0x3a03, 0x7d},
++ {0x3a04, 0x00},
++ {0x3a14, 0x00},
++ {0x3a15, 0x7d},
++ {0x3a16, 0x00},
++ {0x3a00, 0x78},
++ {0x3a08, 0x09},
++ {0x3a09, 0x60},
++ {0x3a0a, 0x07},
++ {0x3a0b, 0xd0},
++ {0x3a0d, 0x08},
++ {0x3a0e, 0x06},
++ {0x5193, 0x70},
++ {0x3620, 0x57},
++ {0x3703, 0x98},
++ {0x3704, 0x1c},
++ {0x589b, 0x04},
++ {0x589a, 0xc5},
++ {0x528a, 0x00},
++ {0x528b, 0x02},
++ {0x528c, 0x08},
++ {0x528d, 0x10},
++ {0x528e, 0x20},
++ {0x528f, 0x28},
++ {0x5290, 0x30},
++ {0x5292, 0x00},
++ {0x5293, 0x00},
++ {0x5294, 0x00},
++ {0x5295, 0x02},
++ {0x5296, 0x00},
++ {0x5297, 0x08},
++ {0x5298, 0x00},
++ {0x5299, 0x10},
++ {0x529a, 0x00},
++ {0x529b, 0x20},
++ {0x529c, 0x00},
++ {0x529d, 0x28},
++ {0x529e, 0x00},
++ {0x529f, 0x30},
++ {0x5282, 0x00},
++ {0x5300, 0x00},
++ {0x5301, 0x20},
++ {0x5302, 0x00},
++ {0x5303, 0x7c},
++ {0x530c, 0x00},
++ {0x530d, 0x0c},
++ {0x530e, 0x20},
++ {0x530f, 0x80},
++ {0x5310, 0x20},
++ {0x5311, 0x80},
++ {0x5308, 0x20},
++ {0x5309, 0x40},
++ {0x5304, 0x00},
++ {0x5305, 0x30},
++ {0x5306, 0x00},
++ {0x5307, 0x80},
++ {0x5314, 0x08},
++ {0x5315, 0x20},
++ {0x5319, 0x30},
++ {0x5316, 0x10},
++ {0x5317, 0x08},
++ {0x5318, 0x02},
++ {0x5380, 0x01},
++ {0x5381, 0x00},
++ {0x5382, 0x00},
++ {0x5383, 0x4e},
++ {0x5384, 0x00},
++ {0x5385, 0x0f},
++ {0x5386, 0x00},
++ {0x5387, 0x00},
++ {0x5388, 0x01},
++ {0x5389, 0x15},
++ {0x538a, 0x00},
++ {0x538b, 0x31},
++ {0x538c, 0x00},
++ {0x538d, 0x00},
++ {0x538e, 0x00},
++ {0x538f, 0x0f},
++ {0x5390, 0x00},
++ {0x5391, 0xab},
++ {0x5392, 0x00},
++ {0x5393, 0xa2},
++ {0x5394, 0x08},
++ {0x5480, 0x14},
++ {0x5481, 0x21},
++ {0x5482, 0x36},
++ {0x5483, 0x57},
++ {0x5484, 0x65},
++ {0x5485, 0x71},
++ {0x5486, 0x7d},
++ {0x5487, 0x87},
++ {0x5488, 0x91},
++ {0x5489, 0x9a},
++ {0x548a, 0xaa},
++ {0x548b, 0xb8},
++ {0x548c, 0xcd},
++ {0x548d, 0xdd},
++ {0x548e, 0xea},
++ {0x548f, 0x10},
++ {0x5490, 0x05},
++ {0x5491, 0x00},
++ {0x5492, 0x04},
++ {0x5493, 0x20},
++ {0x5494, 0x03},
++ {0x5495, 0x60},
++ {0x5496, 0x02},
++ {0x5497, 0xb8},
++ {0x5498, 0x02},
++ {0x5499, 0x86},
++ {0x549a, 0x02},
++ {0x549b, 0x5b},
++ {0x549c, 0x02},
++ {0x549d, 0x3b},
++ {0x549e, 0x02},
++ {0x549f, 0x1c},
++ {0x54a0, 0x02},
++ {0x54a1, 0x04},
++ {0x54a2, 0x01},
++ {0x54a3, 0xed},
++ {0x54a4, 0x01},
++ {0x54a5, 0xc5},
++ {0x54a6, 0x01},
++ {0x54a7, 0xa5},
++ {0x54a8, 0x01},
++ {0x54a9, 0x6c},
++ {0x54aa, 0x01},
++ {0x54ab, 0x41},
++ {0x54ac, 0x01},
++ {0x54ad, 0x20},
++ {0x54ae, 0x00},
++ {0x54af, 0x16},
++ {0x3406, 0x00},
++ {0x5192, 0x04},
++ {0x5191, 0xf8},
++ {0x5193, 0x70},
++ {0x5194, 0xf0},
++ {0x5195, 0xf0},
++ {0x518d, 0x3d},
++ {0x518f, 0x54},
++ {0x518e, 0x3d},
++ {0x5190, 0x54},
++ {0x518b, 0xc0},
++ {0x518c, 0xbd},
++ {0x5187, 0x18},
++ {0x5188, 0x18},
++ {0x5189, 0x6e},
++ {0x518a, 0x68},
++ {0x5186, 0x1c},
++ {0x5181, 0x50},
++ {0x5184, 0x25},
++ {0x5182, 0x11},
++ {0x5183, 0x14},
++ {0x5184, 0x25},
++ {0x5185, 0x24},
++ {0x5025, 0x82},
++ {0x3a0f, 0x7e},
++ {0x3a10, 0x72},
++ {0x3a1b, 0x80},
++ {0x3a1e, 0x70},
++ {0x3a11, 0xd0},
++ {0x3a1f, 0x40},
++ {0x5583, 0x40},
++ {0x5584, 0x40},
++ {0x5580, 0x02},
++ {0x3633, 0x07},
++ {0x3702, 0x10},
++ {0x3703, 0xb2},
++ {0x3704, 0x18},
++ {0x370b, 0x40},
++ {0x370d, 0x02},
++ {0x3620, 0x52},
++ {0x3c00, 0x04},
++
++ {REG_ISP_CTRL_01, 0xFF},
++ {0x5583, 0x50},
++ {0x5584, 0x50},
++ {0x5580, 0x02},
++ {0x3c01, 0x80},
++ {0x3c00, 0x04},
++ {0x5800, 0x27},
++ {0x5801, 0x22},
++ {0x5802, 0x1b},
++ {0x5803, 0x17},
++ {0x5804, 0x16},
++ {0x5805, 0x18},
++ {0x5806, 0x20},
++ {0x5807, 0x20},
++ {0x5808, 0x1b},
++ {0x5809, 0x15},
++ {0x580a, 0x0f},
++ {0x580b, 0x0d},
++ {0x580c, 0x0d},
++ {0x580d, 0x0e},
++ {0x580e, 0x11},
++ {0x580f, 0x18},
++ {0x5810, 0x10},
++ {0x5811, 0x0d},
++ {0x5812, 0x08},
++ {0x5813, 0x05},
++ {0x5814, 0x04},
++ {0x5815, 0x06},
++ {0x5816, 0x09},
++ {0x5817, 0x0e},
++ {0x5818, 0x0d},
++ {0x5819, 0x09},
++ {0x581a, 0x03},
++ {0x581b, 0x00},
++ {0x581c, 0x00},
++ {0x581d, 0x01},
++ {0x581e, 0x05},
++ {0x581f, 0x0b},
++ {0x5820, 0x0d},
++ {0x5821, 0x09},
++ {0x5822, 0x03},
++ {0x5823, 0x00},
++ {0x5824, 0x00},
++ {0x5825, 0x01},
++ {0x5826, 0x05},
++ {0x5827, 0x0b},
++ {0x5828, 0x10},
++ {0x5829, 0x0c},
++ {0x582a, 0x08},
++ {0x582b, 0x04},
++ {0x582c, 0x03},
++ {0x582d, 0x05},
++ {0x582e, 0x09},
++ {0x582f, 0x0e},
++ {0x5830, 0x1b},
++ {0x5831, 0x14},
++ {0x5832, 0x0f},
++ {0x5833, 0x0c},
++ {0x5834, 0x0c},
++ {0x5835, 0x0d},
++ {0x5836, 0x10},
++ {0x5837, 0x19},
++ {0x5838, 0x25},
++ {0x5839, 0x23},
++ {0x583a, 0x1a},
++ {0x583b, 0x16},
++ {0x583c, 0x15},
++ {0x583d, 0x18},
++ {0x583e, 0x1f},
++ {0x583f, 0x25},
++ {0x5840, 0x10},
++ {0x5841, 0x0e},
++ {0x5842, 0x0e},
++ {0x5843, 0x0e},
++ {0x5844, 0x0f},
++ {0x5845, 0x0a},
++ {0x5846, 0x08},
++ {0x5847, 0x0f},
++ {0x5848, 0x0f},
++ {0x5849, 0x0f},
++ {0x584a, 0x0c},
++ {0x584b, 0x0f},
++ {0x584c, 0x09},
++ {0x584d, 0x10},
++ {0x584e, 0x11},
++ {0x584f, 0x10},
++ {0x5850, 0x0f},
++ {0x5851, 0x0e},
++ {0x5852, 0x08},
++ {0x5853, 0x10},
++ {0x5854, 0x10},
++ {0x5855, 0x10},
++ {0x5856, 0x0e},
++ {0x5857, 0x0e},
++ {0x5858, 0x0a},
++ {0x5859, 0x0e},
++ {0x585a, 0x0e},
++ {0x585b, 0x0e},
++ {0x585c, 0x0e},
++ {0x585d, 0x0d},
++ {0x585e, 0x08},
++ {0x585f, 0x0b},
++ {0x5860, 0x0a},
++ {0x5861, 0x0a},
++ {0x5862, 0x09},
++ {0x5863, 0x0d},
++ {0x5864, 0x13},
++ {0x5865, 0x0e},
++ {0x5866, 0x10},
++ {0x5867, 0x10},
++ {0x5868, 0x0e},
++ {0x5869, 0x11},
++ {0x586a, 0x12},
++ {0x586b, 0x10},
++ {0x586c, 0x10},
++ {0x586d, 0x10},
++ {0x586e, 0x10},
++ {0x586f, 0x11},
++ {0x5870, 0x15},
++ {0x5871, 0x10},
++ {0x5872, 0x10},
++ {0x5873, 0x10},
++ {0x5874, 0x11},
++ {0x5875, 0x11},
++ {0x5876, 0x14},
++ {0x5877, 0x0f},
++ {0x5878, 0x10},
++ {0x5879, 0x10},
++ {0x587a, 0x10},
++ {0x587b, 0x11},
++ {0x587c, 0x12},
++ {0x587d, 0x0f},
++ {0x587e, 0x0f},
++ {0x587f, 0x10},
++ {0x5880, 0x10},
++ {0x5881, 0x0f},
++ {0x5882, 0x12},
++ {0x5883, 0x0e},
++ {0x5884, 0x10},
++ {0x5885, 0x10},
++ {0x5886, 0x0e},
++ {0x5887, 0x0e},
++ {0x5180, 0xff},
++ {0x5181, 0x52},
++ {0x5182, 0x11},
++ {0x5183, 0x14},
++ {0x5184, 0x25},
++ {0x5185, 0x24},
++ {0x5186, 0x14},
++ {0x5187, 0x14},
++ {0x5188, 0x14},
++ {0x5189, 0x6c},
++ {0x518a, 0x60},
++ {0x518b, 0xbd},
++ {0x518c, 0x9c},
++ {0x518d, 0x3d},
++ {0x518e, 0x34},
++ {0x518f, 0x57},
++ {0x5190, 0x4a},
++ {0x5191, 0xf8},
++ {0x5192, 0x04},
++ {0x5193, 0x70},
++ {0x5194, 0xf0},
++ {0x5195, 0xf0},
++ {0x5196, 0x03},
++ {0x5197, 0x01},
++ {0x5198, 0x04},
++ {0x5199, 0x00},
++ {0x519a, 0x04},
++ {0x519b, 0x35},
++ {0x519c, 0x08},
++ {0x519d, 0xb8},
++ {0x519e, 0xa0},
++ {0x528a, 0x00},
++ {0x528b, 0x01},
++ {0x528c, 0x04},
++ {0x528d, 0x08},
++ {0x528e, 0x10},
++ {0x528f, 0x20},
++ {0x5290, 0x30},
++ {0x5292, 0x00},
++ {0x5293, 0x00},
++ {0x5294, 0x00},
++ {0x5295, 0x01},
++ {0x5296, 0x00},
++ {0x5297, 0x04},
++ {0x5298, 0x00},
++ {0x5299, 0x08},
++ {0x529a, 0x00},
++ {0x529b, 0x10},
++ {0x529c, 0x00},
++ {0x529d, 0x20},
++ {0x529e, 0x00},
++ {0x529f, 0x30},
++ {0x5282, 0x00},
++ {0x5300, 0x00},
++ {0x5301, 0x20},
++ {0x5302, 0x00},
++ {0x5303, 0x7c},
++ {0x530c, 0x00},
++ {0x530d, 0x10},
++ {0x530e, 0x20},
++ {0x530f, 0x80},
++ {0x5310, 0x20},
++ {0x5311, 0x80},
++ {0x5308, 0x20},
++ {0x5309, 0x40},
++ {0x5304, 0x00},
++ {0x5305, 0x30},
++ {0x5306, 0x00},
++ {0x5307, 0x80},
++ {0x5314, 0x08},
++ {0x5315, 0x20},
++ {0x5319, 0x30},
++ {0x5316, 0x10},
++ {0x5317, 0x00},
++ {0x5318, 0x02},
++ {0x5380, 0x01},
++ {0x5381, 0x00},
++ {0x5382, 0x00},
++ {0x5383, 0x1f},
++ {0x5384, 0x00},
++ {0x5385, 0x06},
++ {0x5386, 0x00},
++ {0x5387, 0x00},
++ {0x5388, 0x00},
++ {0x5389, 0xE1},
++ {0x538A, 0x00},
++ {0x538B, 0x2B},
++ {0x538C, 0x00},
++ {0x538D, 0x00},
++ {0x538E, 0x00},
++ {0x538F, 0x10},
++ {0x5390, 0x00},
++ {0x5391, 0xB3},
++ {0x5392, 0x00},
++ {0x5393, 0xA6},
++ {0x5394, 0x08},
++ {0x5480, 0x14},
++ {0x5481, 0x21},
++ {0x5482, 0x36},
++ {0x5483, 0x57},
++ {0x5484, 0x65},
++ {0x5485, 0x71},
++ {0x5486, 0x7D},
++ {0x5487, 0x87},
++ {0x5488, 0x91},
++ {0x5489, 0x9A},
++ {0x548A, 0xAA},
++ {0x548B, 0xB8},
++ {0x548C, 0xCD},
++ {0x548D, 0xDD},
++ {0x548E, 0xEA},
++ {0x548F, 0x1d},
++ {0x5490, 0x05},
++ {0x5491, 0x00},
++ {0x5492, 0x04},
++ {0x5493, 0x20},
++ {0x5494, 0x03},
++ {0x5495, 0x60},
++ {0x5496, 0x02},
++ {0x5497, 0xB8},
++ {0x5498, 0x02},
++ {0x5499, 0x86},
++ {0x549A, 0x02},
++ {0x549B, 0x5B},
++ {0x549C, 0x02},
++ {0x549D, 0x3B},
++ {0x549E, 0x02},
++ {0x549F, 0x1C},
++ {0x54A0, 0x02},
++ {0x54A1, 0x04},
++ {0x54A2, 0x01},
++ {0x54A3, 0xED},
++ {0x54A4, 0x01},
++ {0x54A5, 0xC5},
++ {0x54A6, 0x01},
++ {0x54A7, 0xA5},
++ {0x54A8, 0x01},
++ {0x54A9, 0x6C},
++ {0x54AA, 0x01},
++ {0x54AB, 0x41},
++ {0x54AC, 0x01},
++ {0x54AD, 0x20},
++ {0x54AE, 0x00},
++ {0x54AF, 0x16},
++ {0x54B0, 0x01},
++ {0x54B1, 0x20},
++ {0x54B2, 0x00},
++ {0x54B3, 0x10},
++ {0x54B4, 0x00},
++ {0x54B5, 0xf0},
++ {0x54B6, 0x00},
++ {0x54B7, 0xDF},
++ {0x5402, 0x3f},
++ {0x5403, 0x00},
++ {0x5500, 0x10},
++ {0x5502, 0x00},
++ {0x5503, 0x06},
++ {0x5504, 0x00},
++ {0x5505, 0x7f},
++ {0x5025, 0x80},
++ {0x3a0f, 0x48}, //0x30
++ {0x3a10, 0x38}, //0x28
++ {0x3a1b, 0x50}, //0x30
++ {0x3a1e, 0x30}, //0x28
++ {0x3a11, 0x71}, //0x61
++ {0x3a1f, 0x10},
++ {0x5688, 0xfd},
++ {0x5689, 0xdf},
++ {0x568a, 0xfe},
++ {0x568b, 0xef},
++ {0x568c, 0xfe},
++ {0x568d, 0xef},
++ {0x568e, 0xaa},
++ {0x568f, 0xaa},
++
++ {REG_WINDOW_START_X_HIGH, 0x1 },
++ {REG_WINDOW_START_X_LOW, 0x50},
++ //0x150 = 336
++ {REG_WINDOW_START_Y_HIGH, 0x0 },
++ {REG_WINDOW_START_Y_LOW, 0x8 },
++ //0x8 = 8
++ {REG_WINDOW_WIDTH_HIGH, 0x5 },
++ {REG_WINDOW_WIDTH_LOW, 0x0 },
++ //0x500 = 1280
++ {REG_WINDOW_HEIGHT_HIGH, 0x3 },
++ {REG_WINDOW_HEIGHT_LOW, 0xc0},
++ //0x3c0 = 960
++ {REG_OUT_WIDTH_HIGH, 0x5 }, // TIMING DVPHO Bit[3:0] DVP output horizontal width high byte
++ {REG_OUT_WIDTH_LOW, 0x00}, // TIMING DVPHO Bit[7:0] DVP output horizontal width low byte
++ // 0x500 => 1280
++ {REG_OUT_HEIGHT_HIGH, 0x2 }, // TIMING DVPVO Bit[3:0] DVP output vertical height high byte
++// {REG_OUT_HEIGHT_LOW, 0xd0}, // TIMING DVPVO Bit[7:0] DVP output vertical height low byte
++ // 0x2d0 => 720
++ {REG_OUT_HEIGHT_LOW, 0xd5}, // TIMING DVPVO Bit[7:0] DVP output vertical height low byte
++ // 0x2d5 => 725
++ {REG_OUT_TOTAL_WIDTH_HIGH, 0xc }, // TIMING HTS Bit[3:0] Total horizontal size high byte [11:8]
++ {REG_OUT_TOTAL_WIDTH_LOW, 0x80}, // TIMING HTS Bit[7:0] Total horizontal size low byte [7:0]
++ // 0xc80 => 3200
++ {REG_OUT_TOTAL_HEIGHT_HIGH, 0x3 }, // TIMING VTS Bit[3:0] Total vertical size high byte [11:8]
++ {REG_OUT_TOTAL_HEIGHT_LOW, 0xe8}, // TIMING VTS Bit[7:0] Total vertical size low byte [7:0]
++ // 0x3e8 => 1000
++ {REG_ISP_CTRL_01, 0x7f},
++ {REG_AVG_WINDOW_START_X_HIGH, 0x0 },
++ {REG_AVG_WINDOW_START_X_LOW, 0x0 },
++ {REG_AVG_WINDOW_END_X_HIGH, 0x5 },
++ {REG_AVG_WINDOW_END_X_LOW, 0x0 },
++ {REG_AVG_WINDOW_START_Y_HIGH, 0x0 },
++ {REG_AVG_WINDOW_START_Y_LOW, 0x0 },
++ {REG_AVG_WINDOW_END_Y_HIGH, 0x3 },
++ //{REG_AVG_WINDOW_END_Y_LOW, 0xc0},
++ {REG_AVG_WINDOW_END_Y_LOW, 0xc0},
++ {0x3815, 0x02},
++ {0x3503, 0x00},
++ //{0x4730, 0x01},
++ {0x4730, 0x00},
++ {REG_OUTPUT_FORMAT, 0x32},
++
++ {0xffff, 0xff},
++};
+--
+1.9.1
+
diff --git a/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0033-media-soc-camera-fix-parallel-i-f-in-VIN.patch b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0033-media-soc-camera-fix-parallel-i-f-in-VIN.patch
new file mode 100644
index 0000000..c56049a
--- /dev/null
+++ b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0033-media-soc-camera-fix-parallel-i-f-in-VIN.patch
@@ -0,0 +1,69 @@
+From 112395ed601c67a6ba935cec0107335e966888dc Mon Sep 17 00:00:00 2001
+From: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+Date: Fri, 14 Jul 2017 21:55:20 +0300
+Subject: [PATCH] media: soc_camera: fix parallel i/f in VIN
+
+This fixes parallel interface in VIN
+
+Signed-off-by: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+---
+ drivers/media/platform/soc_camera/rcar_vin.c | 18 ++++++++++--------
+ 1 file changed, 10 insertions(+), 8 deletions(-)
+
+diff --git a/drivers/media/platform/soc_camera/rcar_vin.c b/drivers/media/platform/soc_camera/rcar_vin.c
+index f5c2528..a9cb72d 100644
+--- a/drivers/media/platform/soc_camera/rcar_vin.c
++++ b/drivers/media/platform/soc_camera/rcar_vin.c
+@@ -149,6 +149,9 @@
+ /* Video n Data Mode Register 2 bits */
+ #define VNDMR2_VPS (1 << 30)
+ #define VNDMR2_HPS (1 << 29)
++#define VNDMR2_CES (1 << 28)
++#define VNDMR2_DES (1 << 27)
++#define VNDMR2_CHS (1 << 23)
+ #define VNDMR2_FTEV (1 << 17)
+ #define VNDMR2_VLV(n) ((n & 0xf) << 12)
+
+@@ -1850,10 +1853,15 @@ static int rcar_vin_set_bus_param(struct soc_camera_device *icd)
+ val = VNDMR2_FTEV;
+ else
+ val = VNDMR2_FTEV | VNDMR2_VLV(1);
++
+ if (!(common_flags & V4L2_MBUS_VSYNC_ACTIVE_LOW))
+ val |= VNDMR2_VPS;
+ if (!(common_flags & V4L2_MBUS_HSYNC_ACTIVE_LOW))
+ val |= VNDMR2_HPS;
++
++ val |= VNDMR2_CES;
++ dev_dbg(icd->parent, "VNDMR2=0x%x\n", val);
++
+ iowrite32(val, priv->base + VNDMR2_REG);
+
+ ret = rcar_vin_set_rect(icd);
+@@ -2937,8 +2945,8 @@ static int rcar_vin_probe(struct platform_device *pdev)
+ priv->max_height = 2048;
+ }
+
+- if (priv->chip == RCAR_H3 || priv->chip == RCAR_M3 ||
+- priv->chip == RCAR_V3M) {
++ if ((priv->chip == RCAR_H3 || priv->chip == RCAR_M3 ||
++ priv->chip == RCAR_V3M) && !of_property_read_string(np, "csi,select", &str)) {
+ u32 ifmd = 0;
+ bool match_flag = false;
+ const struct vin_gen3_ifmd *gen3_ifmd_table = NULL;
+@@ -2973,12 +2981,6 @@ static int rcar_vin_probe(struct platform_device *pdev)
+ else
+ priv->index = RCAR_VIN_CH_NONE;
+
+- ret = of_property_read_string(np, "csi,select", &str);
+- if (ret) {
+- dev_err(&pdev->dev, "could not parse csi,select\n");
+- return ret;
+- }
+-
+ if (strcmp(str, "csi40") == 0)
+ priv->csi_ch = RCAR_CSI40;
+ else if (strcmp(str, "csi20") == 0)
+--
+1.9.1
+
diff --git a/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0034-media-soc_camera-Fix-VIDIOC_S_SELECTION-ioctl-miscal.patch b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0034-media-soc_camera-Fix-VIDIOC_S_SELECTION-ioctl-miscal.patch
new file mode 100644
index 0000000..fb15260
--- /dev/null
+++ b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0034-media-soc_camera-Fix-VIDIOC_S_SELECTION-ioctl-miscal.patch
@@ -0,0 +1,67 @@
+From 4b971606c7ef3e85be57b31d2583e169f983d91f Mon Sep 17 00:00:00 2001
+From: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+Date: Mon, 31 Jul 2017 19:26:05 +0300
+Subject: [PATCH] media: soc_camera: Fix VIDIOC_S_SELECTION ioctl
+ miscalculation
+
+This patch corrects the miscalculation of the capture buffer
+size and clipping data update in VIDIOC_S_SELECTION sequence.
+
+Patch isbased on work by: Koji Matsuoka <koji.matsuoka.xm@renesas.com>
+
+Signed-off-by: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+---
+ drivers/media/platform/soc_camera/soc_scale_crop.c | 10 +++++-----
+ 1 file changed, 5 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/media/platform/soc_camera/soc_scale_crop.c b/drivers/media/platform/soc_camera/soc_scale_crop.c
+index f77252d..79a7d95 100644
+--- a/drivers/media/platform/soc_camera/soc_scale_crop.c
++++ b/drivers/media/platform/soc_camera/soc_scale_crop.c
+@@ -72,14 +72,14 @@ static void update_subrect(struct v4l2_rect *rect, struct v4l2_rect *subrect)
+
+ if (rect->left > subrect->left)
+ subrect->left = rect->left;
+- else if (rect->left + rect->width >
++ else if (rect->left + rect->width <
+ subrect->left + subrect->width)
+ subrect->left = rect->left + rect->width -
+ subrect->width;
+
+ if (rect->top > subrect->top)
+ subrect->top = rect->top;
+- else if (rect->top + rect->height >
++ else if (rect->top + rect->height <
+ subrect->top + subrect->height)
+ subrect->top = rect->top + rect->height -
+ subrect->height;
+@@ -125,6 +125,7 @@ int soc_camera_client_s_selection(struct v4l2_subdev *sd,
+ dev_dbg(dev, "Camera S_SELECTION successful for %dx%d@%d:%d\n",
+ rect->width, rect->height, rect->left, rect->top);
+ *target_rect = *cam_rect;
++ *subrect = *rect;
+ return 0;
+ }
+
+@@ -216,6 +217,7 @@ int soc_camera_client_s_selection(struct v4l2_subdev *sd,
+
+ if (!ret) {
+ *target_rect = *cam_rect;
++ *subrect = *rect;
+ update_subrect(target_rect, subrect);
+ }
+
+@@ -296,9 +298,7 @@ static int client_set_fmt(struct soc_camera_device *icd,
+ if (ret < 0)
+ return ret;
+
+- if (host_1to1)
+- *subrect = *rect;
+- else
++ if (!host_1to1)
+ update_subrect(rect, subrect);
+
+ return 0;
+--
+1.9.1
+
diff --git a/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0040-arm64-dts-renesas-add-ADAS-boards.patch b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0040-arm64-dts-renesas-add-ADAS-boards.patch
new file mode 100644
index 0000000..b15a4fb
--- /dev/null
+++ b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0040-arm64-dts-renesas-add-ADAS-boards.patch
@@ -0,0 +1,17596 @@
+From 51718d8f768ba719a8a295e013e3456e13b70a98 Mon Sep 17 00:00:00 2001
+From: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+Date: Fri, 14 Jul 2017 15:05:42 +0300
+Subject: [PATCH] arm64: dts: renesas: add ADAS boards
+
+Salvator-X.View board on R8A7795 ES1.x SoC
+Salvator-X.View board on R8A7795 SoC
+Salvator-X.View board on R8A7796 SoC
+H3ULCB.View board on R8A7795 ES1.x SoC
+H3ULCB.View board on R8A7795 SoC
+M3ULCB.View board on R8A7796 SoC
+H3ULCB.HAD board on R8A7795 ES1.x SoC
+H3ULCB.HAD board on R8A7795 SoC
+Kingfisher board on R8A7795 ES1.x SoC
+Kingfisher board on R8A7795 SoC
+Kingfisher board on R8A7796 SoC
+Videobox board on R8A7795 ES1.x SoC
+Videobox board on R8A7795 SoC
+Eagle board on R8A7797 SoC
+V3MSK board on R8A7797 SoC
+Kingfisher board on R8A7797 SoC
+
+Signed-off-by: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+---
+ arch/arm64/boot/dts/renesas/Makefile | 16 +
+ arch/arm64/boot/dts/renesas/legacy/Makefile | 8 +
+ .../renesas/legacy/r8a7795-es1-h3ulcb-kf-v0.dts | 1717 +++++++++++++++++++
+ .../renesas/legacy/r8a7795-es1-h3ulcb-kf-v1.dts | 441 +++++
+ .../dts/renesas/legacy/r8a7795-h3ulcb-kf-v0.dts | 1724 +++++++++++++++++++
+ .../dts/renesas/legacy/r8a7795-h3ulcb-kf-v1.dts | 465 +++++
+ .../dts/renesas/legacy/r8a7796-m3ulcb-kf-v0.dts | 1214 +++++++++++++
+ .../dts/renesas/legacy/r8a7796-m3ulcb-kf-v1.dts | 465 +++++
+ .../dts/renesas/legacy/r8a7797-v3msk-kf-v0.dts | 20 +
+ .../boot/dts/renesas/legacy/ulcb-kf-cmos.dtsi | 75 +
+ .../arm64/boot/dts/renesas/legacy/ulcb-kf-rpi.dtsi | 77 +
+ .../dts/renesas/r8a7795-es1-h3ulcb-had-alfa.dts | 22 +
+ .../dts/renesas/r8a7795-es1-h3ulcb-had-beta.dts | 23 +
+ .../boot/dts/renesas/r8a7795-es1-h3ulcb-had.dtsi | 225 +++
+ .../boot/dts/renesas/r8a7795-es1-h3ulcb-kf.dts | 39 +
+ .../boot/dts/renesas/r8a7795-es1-h3ulcb-vb.dts | 1787 ++++++++++++++++++++
+ .../boot/dts/renesas/r8a7795-es1-h3ulcb-view.dts | 546 ++++++
+ .../dts/renesas/r8a7795-es1-salvator-x-view.dts | 552 ++++++
+ .../boot/dts/renesas/r8a7795-h3ulcb-had-alfa.dts | 22 +
+ .../boot/dts/renesas/r8a7795-h3ulcb-had-beta.dts | 23 +
+ .../arm64/boot/dts/renesas/r8a7795-h3ulcb-had.dtsi | 219 +++
+ arch/arm64/boot/dts/renesas/r8a7795-h3ulcb-kf.dts | 39 +
+ arch/arm64/boot/dts/renesas/r8a7795-h3ulcb-vb.dts | 1787 ++++++++++++++++++++
+ .../arm64/boot/dts/renesas/r8a7795-h3ulcb-view.dts | 546 ++++++
+ .../boot/dts/renesas/r8a7795-salvator-x-view.dts | 552 ++++++
+ arch/arm64/boot/dts/renesas/r8a7796-m3ulcb-kf.dts | 40 +
+ .../arm64/boot/dts/renesas/r8a7796-m3ulcb-view.dts | 287 ++++
+ .../boot/dts/renesas/r8a7796-salvator-x-view.dts | 318 ++++
+ arch/arm64/boot/dts/renesas/r8a7797-eagle.dts | 561 ++++++
+ arch/arm64/boot/dts/renesas/r8a7797-v3msk-kf.dts | 541 ++++++
+ arch/arm64/boot/dts/renesas/r8a7797-v3msk.dts | 294 ++++
+ arch/arm64/boot/dts/renesas/ulcb-kf-cn11.dtsi | 518 ++++++
+ arch/arm64/boot/dts/renesas/ulcb-kf-most.dtsi | 30 +
+ arch/arm64/boot/dts/renesas/ulcb-kf-sd3.dtsi | 46 +
+ arch/arm64/boot/dts/renesas/ulcb-kf.dtsi | 1531 +++++++++++++++++
+ arch/arm64/boot/dts/renesas/ulcb-vb-cn12.dtsi | 515 ++++++
+ 36 files changed, 17285 insertions(+)
+ create mode 100644 arch/arm64/boot/dts/renesas/legacy/Makefile
+ create mode 100644 arch/arm64/boot/dts/renesas/legacy/r8a7795-es1-h3ulcb-kf-v0.dts
+ create mode 100644 arch/arm64/boot/dts/renesas/legacy/r8a7795-es1-h3ulcb-kf-v1.dts
+ create mode 100644 arch/arm64/boot/dts/renesas/legacy/r8a7795-h3ulcb-kf-v0.dts
+ create mode 100644 arch/arm64/boot/dts/renesas/legacy/r8a7795-h3ulcb-kf-v1.dts
+ create mode 100644 arch/arm64/boot/dts/renesas/legacy/r8a7796-m3ulcb-kf-v0.dts
+ create mode 100644 arch/arm64/boot/dts/renesas/legacy/r8a7796-m3ulcb-kf-v1.dts
+ create mode 100644 arch/arm64/boot/dts/renesas/legacy/r8a7797-v3msk-kf-v0.dts
+ create mode 100644 arch/arm64/boot/dts/renesas/legacy/ulcb-kf-cmos.dtsi
+ create mode 100644 arch/arm64/boot/dts/renesas/legacy/ulcb-kf-rpi.dtsi
+ create mode 100644 arch/arm64/boot/dts/renesas/r8a7795-es1-h3ulcb-had-alfa.dts
+ create mode 100644 arch/arm64/boot/dts/renesas/r8a7795-es1-h3ulcb-had-beta.dts
+ create mode 100644 arch/arm64/boot/dts/renesas/r8a7795-es1-h3ulcb-had.dtsi
+ create mode 100644 arch/arm64/boot/dts/renesas/r8a7795-es1-h3ulcb-kf.dts
+ create mode 100644 arch/arm64/boot/dts/renesas/r8a7795-es1-h3ulcb-vb.dts
+ create mode 100644 arch/arm64/boot/dts/renesas/r8a7795-es1-h3ulcb-view.dts
+ create mode 100644 arch/arm64/boot/dts/renesas/r8a7795-es1-salvator-x-view.dts
+ create mode 100644 arch/arm64/boot/dts/renesas/r8a7795-h3ulcb-had-alfa.dts
+ create mode 100644 arch/arm64/boot/dts/renesas/r8a7795-h3ulcb-had-beta.dts
+ create mode 100644 arch/arm64/boot/dts/renesas/r8a7795-h3ulcb-had.dtsi
+ create mode 100644 arch/arm64/boot/dts/renesas/r8a7795-h3ulcb-kf.dts
+ create mode 100644 arch/arm64/boot/dts/renesas/r8a7795-h3ulcb-vb.dts
+ create mode 100644 arch/arm64/boot/dts/renesas/r8a7795-h3ulcb-view.dts
+ create mode 100644 arch/arm64/boot/dts/renesas/r8a7795-salvator-x-view.dts
+ create mode 100644 arch/arm64/boot/dts/renesas/r8a7796-m3ulcb-kf.dts
+ create mode 100644 arch/arm64/boot/dts/renesas/r8a7796-m3ulcb-view.dts
+ create mode 100644 arch/arm64/boot/dts/renesas/r8a7796-salvator-x-view.dts
+ create mode 100644 arch/arm64/boot/dts/renesas/r8a7797-eagle.dts
+ create mode 100644 arch/arm64/boot/dts/renesas/r8a7797-v3msk-kf.dts
+ create mode 100644 arch/arm64/boot/dts/renesas/r8a7797-v3msk.dts
+ create mode 100644 arch/arm64/boot/dts/renesas/ulcb-kf-cn11.dtsi
+ create mode 100644 arch/arm64/boot/dts/renesas/ulcb-kf-most.dtsi
+ create mode 100644 arch/arm64/boot/dts/renesas/ulcb-kf-sd3.dtsi
+ create mode 100644 arch/arm64/boot/dts/renesas/ulcb-kf.dtsi
+ create mode 100644 arch/arm64/boot/dts/renesas/ulcb-vb-cn12.dtsi
+
+diff --git a/arch/arm64/boot/dts/renesas/Makefile b/arch/arm64/boot/dts/renesas/Makefile
+index 32fb4d9..fd17456 100644
+--- a/arch/arm64/boot/dts/renesas/Makefile
++++ b/arch/arm64/boot/dts/renesas/Makefile
+@@ -4,5 +4,21 @@ dtb-$(CONFIG_ARCH_R8A7795) += r8a7795-es1-salvator-x.dtb r8a7795-es1-h3ulcb.dtb
+ dtb-$(CONFIG_ARCH_R8A7796) += r8a7796-salvator-x.dtb r8a7796-m3ulcb.dtb
+ dtb-$(CONFIG_ARCH_R8A7796) += r8a7796-salvator-xs.dtb
+
++# ADAS boards
++dtb-$(CONFIG_ARCH_R8A7796) += r8a7796-salvator-x-view.dtb
++dtb-$(CONFIG_ARCH_R8A7796) += r8a7796-m3ulcb-view.dtb
++dtb-$(CONFIG_ARCH_R8A7796) += r8a7796-m3ulcb-kf.dtb
++dtb-$(CONFIG_ARCH_R8A7795) += r8a7795-salvator-x-view.dtb r8a7795-es1-salvator-x-view.dtb
++dtb-$(CONFIG_ARCH_R8A7795) += r8a7795-h3ulcb-view.dtb r8a7795-es1-h3ulcb-view.dtb
++dtb-$(CONFIG_ARCH_R8A7795) += r8a7795-h3ulcb-had-alfa.dtb r8a7795-h3ulcb-had-beta.dtb r8a7795-es1-h3ulcb-had-alfa.dtb r8a7795-es1-h3ulcb-had-beta.dtb
++dtb-$(CONFIG_ARCH_R8A7795) += r8a7795-h3ulcb-kf.dtb r8a7795-es1-h3ulcb-kf.dtb
++dtb-$(CONFIG_ARCH_R8A7795) += r8a7795-h3ulcb-vb.dtb r8a7795-es1-h3ulcb-vb.dtb
++dtb-$(CONFIG_ARCH_R8A7797) += r8a7797-eagle.dtb
++dtb-$(CONFIG_ARCH_R8A7797) += r8a7797-v3msk.dtb
++dtb-$(CONFIG_ARCH_R8A7797) += r8a7797-v3msk-kf.dtb
++
++# ADAS legacy boards
++subdir-y := legacy
++
+ always := $(dtb-y)
+ clean-files := *.dtb
+diff --git a/arch/arm64/boot/dts/renesas/legacy/Makefile b/arch/arm64/boot/dts/renesas/legacy/Makefile
+new file mode 100644
+index 0000000..7f25079
+--- /dev/null
++++ b/arch/arm64/boot/dts/renesas/legacy/Makefile
+@@ -0,0 +1,8 @@
++# Legacy KF board: V0, V1 (V2 is the same as V1), V3 is latest and deployed in default directory
++dtb-$(CONFIG_ARCH_R8A7795) += r8a7795-es1-h3ulcb-kf-v0.dtb r8a7795-es1-h3ulcb-kf-v1.dtb
++dtb-$(CONFIG_ARCH_R8A7796) += r8a7796-m3ulcb-kf-v0.dtb r8a7796-m3ulcb-kf-v1.dtb
++dtb-$(CONFIG_ARCH_R8A7795) += r8a7795-h3ulcb-kf-v0.dtb r8a7795-h3ulcb-kf-v1.dtb
++dtb-$(CONFIG_ARCH_R8A7797) += r8a7797-v3msk-kf-v0.dtb
++
++always := $(dtb-y)
++clean-files := *.dtb
+diff --git a/arch/arm64/boot/dts/renesas/legacy/r8a7795-es1-h3ulcb-kf-v0.dts b/arch/arm64/boot/dts/renesas/legacy/r8a7795-es1-h3ulcb-kf-v0.dts
+new file mode 100644
+index 0000000..ec6d86d
+--- /dev/null
++++ b/arch/arm64/boot/dts/renesas/legacy/r8a7795-es1-h3ulcb-kf-v0.dts
+@@ -0,0 +1,1710 @@
++/*
++ * Device Tree Source for the H3ULCB Kingfisher V0 board on r8a7795 ES1.x
++ *
++ * Copyright (C) 2017 Renesas Electronics Corp.
++ * Copyright (C) 2017 Cogent Embedded, Inc.
++ *
++ * This file is licensed under the terms of the GNU General Public License
++ * version 2. This program is licensed "as is" without any warranty of any
++ * kind, whether express or implied.
++ */
++
++#include "../r8a7795-es1-h3ulcb.dts"
++
++/ {
++ model = "Renesas H3ULCB Kingfisher V0 board based on r8a7795";
++
++ aliases {
++ serial1 = &hscif4;
++ };
++
++ snd_clk: snd_clk {
++ compatible = "fixed-clock";
++ #clock-cells = <0>;
++ clock-frequency = <24576000>;
++ clock-output-names = "scki";
++ };
++
++ wlan_en: regulator@4 {
++ compatible = "regulator-fixed";
++ regulator-name = "wlan-en-regulator";
++
++ regulator-min-microvolt = <3300000>;
++ regulator-max-microvolt = <3300000>;
++
++ gpio = <&gpio_ext_20 4 GPIO_ACTIVE_HIGH>;
++ enable-active-high;
++ };
++
++ vcc_sdhi3: regulator@41 {
++ compatible = "regulator-fixed";
++
++ regulator-name = "SDHI3 Vcc";
++ regulator-min-microvolt = <3300000>;
++ regulator-max-microvolt = <3300000>;
++ regulator-always-on;
++ };
++
++ vccq_sdhi3: regulator@5 {
++ compatible = "regulator-fixed";
++
++ regulator-name = "SDHI3 VccQ";
++ regulator-min-microvolt = <3300000>;
++ regulator-max-microvolt = <3300000>;
++ };
++
++ codec_en_reg: regulator@6 {
++ compatible = "regulator-fixed";
++ regulator-name = "codec-en-regulator";
++ regulator-min-microvolt = <3300000>;
++ regulator-max-microvolt = <3300000>;
++
++ gpio = <&gpio_ext_20 15 0>;
++
++ /* delay - CHECK */
++ startup-delay-us = <70000>;
++ enable-active-high;
++ };
++
++ amp_en_reg: regulator@7 {
++ compatible = "regulator-fixed";
++ regulator-name = "amp-en-regulator";
++ regulator-min-microvolt = <3300000>;
++ regulator-max-microvolt = <3300000>;
++
++ gpio = <&gpio_ext_20 0 0>;
++
++ startup-delay-us = <0>;
++ enable-active-high;
++ };
++
++ lvds_switch: regulator@8 {
++ compatible = "regulator-fixed";
++ regulator-name = "lvds_on";
++ regulator-min-microvolt = <3300000>;
++ regulator-max-microvolt = <3300000>;
++ /* gpio = <&gpio1 24 0>; */
++ enable-active-high;
++ regulator-always-on;
++ };
++
++ sdio_switch: regulator@9 {
++ compatible = "regulator-fixed";
++ regulator-name = "wifi_on";
++ regulator-min-microvolt = <3300000>;
++ regulator-max-microvolt = <3300000>;
++ gpio = <&gpio_ext_20 5 0>;
++ enable-active-low;
++ regulator-always-on;
++ };
++
++ sound_switch: regulator@10 {
++ compatible = "regulator-fixed";
++ regulator-name = "pcm3168a_on";
++ regulator-min-microvolt = <3300000>;
++ regulator-max-microvolt = <3300000>;
++ gpio = <&gpio_ext_21 5 0>;
++ enable-active-low;
++ regulator-always-on;
++ };
++
++ radio_switch: regulator@11 {
++ compatible = "regulator-fixed";
++ regulator-name = "radio_on";
++ regulator-min-microvolt = <3300000>;
++ regulator-max-microvolt = <3300000>;
++ gpio = <&gpio_ext_20 13 GPIO_ACTIVE_HIGH>;
++ enable-active-high;
++ regulator-always-on;
++ };
++
++ kim {
++ compatible = "kim";
++ shutdown-gpios = <&gpio_ext_20 3 GPIO_ACTIVE_HIGH>;
++ /* serial1 */
++ dev_name = "/dev/ttySC1";
++ flow_cntrl = <1>;
++ /* int div 8 hscif@26.6666656MHz */
++ baud_rate = <3333332>;
++ };
++
++ btwilink {
++ compatible = "btwilink";
++ };
++
++ sound_ext: sound@0 {
++ pinctrl-0 = <&sound_0_pins>;
++ pinctrl-names = "default";
++ compatible = "simple-audio-card";
++
++ simple-audio-card,format = "left_j";
++ simple-audio-card,name = "pcm3168a";
++
++ simple-audio-card,bitclock-master = <&sound_ext_master>;
++ simple-audio-card,frame-master = <&sound_ext_master>;
++ sound_ext_master: simple-audio-card,cpu@0 {
++ sound-dai = <&rcar_sound 0>;
++ dai-tdm-slot-num = <8>;
++ dai-tdm-slot-width = <32>;
++ };
++
++ simple-audio-card,codec@0 {
++ sound-dai = <&pcm3168a>;
++ dai-tdm-slot-num = <8>;
++ dai-tdm-slot-width = <32>;
++ system-clock-frequency = <24576000>;
++ };
++ };
++
++ /delete-node/sound;
++
++ rsnd_ak4613: sound@1 {
++ pinctrl-0 = <&sound_1_pins>;
++ pinctrl-names = "default";
++ compatible = "simple-audio-card";
++
++ simple-audio-card,format = "left_j";
++ simple-audio-card,name = "ak4613";
++
++ simple-audio-card,bitclock-master = <&sndcpu>;
++ simple-audio-card,frame-master = <&sndcpu>;
++
++ sndcpu: simple-audio-card,cpu@1 {
++ sound-dai = <&rcar_sound 1>;
++ };
++
++ sndcodec: simple-audio-card,codec@1 {
++ sound-dai = <&ak4613>;
++ };
++ };
++
++ sound_radio: sound@2 {
++ pinctrl-0 = <&sound_2_pins>;
++ pinctrl-names = "default";
++ compatible = "simple-audio-card";
++
++ simple-audio-card,format = "i2s";
++ simple-audio-card,name = "radio";
++
++ simple-audio-card,bitclock-master = <&sound_radio_master>;
++ simple-audio-card,frame-master = <&sound_radio_master>;
++ simple-audio-card,cpu@2 {
++ sound-dai = <&rcar_sound 2>;
++ };
++
++ sound_radio_master: simple-audio-card,codec@2 {
++ sound-dai = <&radio>;
++ system-clock-frequency = <12288000>;
++ };
++ };
++
++ lvds-encoder {
++ compatible = "thine,thc63lvdm83d";
++
++ ports {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ port@0 {
++ reg = <0>;
++ lvds_enc_in: endpoint {
++ remote-endpoint = <&du_out_lvds0>;
++ };
++ };
++ port@1 {
++ reg = <1>;
++ lvds_enc_out: endpoint {
++ remote-endpoint = <&lvds_in>;
++ };
++ };
++ };
++ };
++
++ lvds {
++ compatible = "lvds-connector";
++
++ width-mm = <210>;
++ height-mm = <158>;
++
++ panel-timing {
++ /* 1280x800 @60Hz */
++ clock-frequency = <65000000>;
++ hactive = <1280>;
++ vactive = <800>;
++ hsync-len = <40>;
++ hfront-porch = <80>;
++ hback-porch = <40>;
++ vfront-porch = <14>;
++ vback-porch = <14>;
++ vsync-len = <4>;
++ };
++
++ port {
++ lvds_in: endpoint {
++ remote-endpoint = <&lvds_enc_out>;
++ };
++ };
++ };
++
++ radio: si468x@0 {
++ compatible = "si,si468x-pcm";
++ status = "okay";
++
++ #sound-dai-cells = <0>;
++ };
++};
++
++&pfc {
++ hscif4_pins: hscif4 {
++ groups = "hscif4_data_a", "hscif4_ctrl";
++ function = "hscif4";
++ };
++
++ sdhi3_pins_3v3: sd3_3v3 {
++ groups = "sdhi3_data4", "sdhi3_ctrl";
++ function = "sdhi3";
++ power-source = <3300>;
++ };
++
++ sound_0_pins: sound0 {
++ groups = "ssi78_ctrl", "ssi7_data", "ssi8_data";
++ function = "ssi";
++ };
++
++ sound_1_pins: sound1 {
++ groups = "ssi01239_ctrl", "ssi0_data", "ssi1_data_a";
++ function = "ssi";
++ };
++
++ sound_2_pins: sound2 {
++ groups = "ssi6_ctrl", "ssi6_data";
++ function = "ssi";
++ };
++
++ usb0_pins: usb0 {
++ groups = "usb0";
++ function = "usb0";
++ };
++
++ can0_pins: can0 {
++ groups = "can0_data_a";
++ function = "can0";
++ };
++
++ can1_pins: can1 {
++ groups = "can1_data";
++ function = "can1";
++ };
++
++ canfd0_pins: canfd0 {
++ groups = "canfd0_data_a";
++ function = "canfd0";
++ };
++
++ canfd1_pins: canfd1 {
++ groups = "canfd1_data";
++ function = "canfd1";
++ };
++};
++
++&du {
++ ports {
++ port@3 {
++ endpoint {
++ remote-endpoint = <&lvds_enc_in>;
++ };
++ };
++ };
++};
++
++&gpio0 {
++ video_a_irq {
++ gpio-hog;
++ gpios = <13 GPIO_ACTIVE_HIGH>;
++ input;
++ line-name = "Video-A irq";
++ };
++
++ video_b_irq {
++ gpio-hog;
++ gpios = <14 GPIO_ACTIVE_HIGH>;
++ input;
++ line-name = "Video-B irq";
++ };
++
++ gpioext_2_20_irq {
++ gpio-hog;
++ gpios = <15 GPIO_ACTIVE_HIGH>;
++ input;
++ line-name = "0x20@i2c2 irq";
++ };
++};
++
++&gpio1 {
++ gpioext_2_21_irq {
++ gpio-hog;
++ gpios = <15 GPIO_ACTIVE_HIGH>;
++ input;
++ line-name = "0x21@i2c2 irq";
++ };
++
++ wifi_irq {
++ gpio-hog;
++ gpios = <25 GPIO_ACTIVE_HIGH>;
++ input;
++ line-name = "wifi irq";
++ };
++};
++
++&gpio5 {
++ touch_irq {
++ gpio-hog;
++ gpios = <6 GPIO_ACTIVE_HIGH>;
++ input;
++ line-name = "touch irq";
++ };
++
++ /* From TI forum */
++ /* BT_AUD_OUT should be pulled low when WL_EN is activated. */
++ /* in case it isn't, wilink8 ends up in one of the test modes that introduces various issues */
++ bt_strap {
++ gpio-hog;
++ gpios = <14 GPIO_ACTIVE_HIGH>;
++ output-low;
++ line-name = "BT strap pin";
++ };
++};
++
++&gpio7 {
++ gpioext_2_21_irq {
++ gpio-hog;
++ gpios = <3 GPIO_ACTIVE_HIGH>;
++ input;
++ line-name = "0x21@i2c4 irq";
++ };
++};
++
++&hscif4 {
++ pinctrl-0 = <&hscif4_pins>;
++ pinctrl-names = "default";
++ uart-has-rtscts;
++
++ status = "okay";
++};
++
++&i2c2 {
++ clock-frequency = <400000>;
++
++ gpio_ext_20: pca9535@20 {
++ compatible = "nxp,pca9535";
++ reg = <0x20>;
++ gpio-controller;
++ #gpio-cells = <2>;
++ interrupt-controller;
++ interrupt-parent = <&gpio0>;
++ interrupts = <15 IRQ_TYPE_EDGE_FALLING>;
++ };
++
++ gpio_ext_21: pca9535@21 {
++ compatible = "nxp,pca9535";
++ reg = <0x21>;
++ gpio-controller;
++ #gpio-cells = <2>;
++ interrupt-controller;
++ interrupt-parent = <&gpio1>;
++ interrupts = <15 IRQ_TYPE_EDGE_FALLING>;
++ };
++
++ i2cswitch2: pca9548@74 {
++ compatible = "nxp,pca9548";
++ #address-cells = <1>;
++ #size-cells = <0>;
++ reg = <0x74>;
++ reset-gpios = <&gpio6 5 GPIO_ACTIVE_LOW>;
++
++ i2c@0 {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ reg = <0>;
++ /* BCM node(s) */
++ };
++
++ i2c@1 {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ reg = <1>;
++ /* USB3.0 HUB node(s) */
++ };
++
++ i2c@2 {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ reg = <2>;
++ /* Power amp node(s) */
++ };
++
++ i2c@3 {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ reg = <3>;
++ /* Radio node(s) */
++ };
++
++ i2c@4 {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ reg = <4>;
++ /* A2B node(s) */
++ };
++
++ i2c@5 {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ reg = <5>;
++ /* PCIe node(s) */
++ };
++
++ i2c@6 {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ reg = <6>;
++ /* LVDS display node(s) */
++
++ polytouch: edt-ft5x06@38 {
++ compatible = "edt,edt-ft5x06";
++ reg = <0x38>;
++ interrupt-parent = <&gpio5>;
++ interrupts = <6 IRQ_TYPE_EDGE_FALLING>;
++ };
++ };
++
++ i2c@7 {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ reg = <7>;
++ /* Audio, GPS and Gyro node(s) */
++
++ pcm3168a: audio-codec@44 {
++ #sound-dai-cells = <0>;
++ compatible = "ti,pcm3168a";
++ reg = <0x44>;
++ clocks = <&snd_clk>;
++ clock-names = "scki";
++ tdm;
++ VDD1-supply = <&codec_en_reg>;
++ VDD2-supply = <&codec_en_reg>;
++ VCCAD1-supply = <&codec_en_reg>;
++ VCCAD2-supply = <&codec_en_reg>;
++ VCCDA1-supply = <&amp_en_reg>;
++ VCCDA2-supply = <&amp_en_reg>;
++ };
++
++ lsm9ds0_acc_mag@1d {
++ compatible = "st,lsm9ds0_accel_magn";
++ reg = <0x1d>;
++ };
++
++ lsm9ds0_gyr@6b {
++ compatible = "st,lsm9ds0_gyro";
++ reg = <0x6b>;
++ };
++
++ /* GPS@ 0x42 */
++ };
++ };
++};
++
++&i2c4 {
++ gpio_ext_22: pca9535@21 {
++ compatible = "nxp,pca9535";
++ reg = <0x22>;
++ gpio-controller;
++ #gpio-cells = <2>;
++ interrupt-controller;
++ interrupt-parent = <&gpio7>;
++ interrupts = <3 IRQ_TYPE_EDGE_FALLING>;
++
++ cmos_pwdn {
++ gpio-hog;
++ gpios = <8 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "CMOS PWDN";
++ };
++ cmos_rst {
++ gpio-hog;
++ gpios = <9 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "CMOS RST";
++ };
++ /* pin 12 - CAM_CLK */
++ rpi_cam_io_1 {
++ gpio-hog;
++ gpios = <10 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "RaspB_IO1";
++ };
++ /* pin 11 - CAM_GPIO - assume pwdn */
++ rpi_cam_io_0 {
++ gpio-hog;
++ gpios = <11 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "RaspB_IO0";
++ };
++ };
++
++ i2cswitch4: pca9548@74 {
++ compatible = "nxp,pca9548";
++ #address-cells = <1>;
++ #size-cells = <0>;
++ reg = <0x74>;
++ reset-gpios= <&gpio6 21 GPIO_ACTIVE_LOW>;
++
++ i2c@0 {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ reg = <0>;
++ /* SAM node(s) */
++ };
++
++ i2c@1 {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ reg = <1>;
++ /* Slot A (CN10) */
++
++ ov106xx@0 {
++ compatible = "ovti,ov106xx";
++ reg = <0x60>;
++
++ port@0 {
++ ov106xx_in0: endpoint {
++ clock-lanes = <0>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&vin0ep0>;
++ };
++ };
++ port@1 {
++ ov106xx_max9286_des0ep0: endpoint@0 {
++ remote-endpoint = <&max9286_des0ep0>;
++ };
++ ov106xx_ti964_des0ep0: endpoint@1 {
++ remote-endpoint = <&ti964_des0ep0>;
++ };
++ ov106xx_ti954_des0ep0: endpoint@2 {
++ remote-endpoint = <&ti954_des0ep0>;
++ };
++ };
++ };
++
++ ov106xx@1 {
++ compatible = "ovti,ov106xx";
++ reg = <0x61>;
++
++ port@0 {
++ ov106xx_in1: endpoint {
++ clock-lanes = <0>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&vin1ep0>;
++ };
++ };
++ port@1 {
++ ov106xx_max9286_des0ep1: endpoint@0 {
++ remote-endpoint = <&max9286_des0ep1>;
++ };
++ ov106xx_ti964_des0ep1: endpoint@1 {
++ remote-endpoint = <&ti964_des0ep1>;
++ };
++ ov106xx_ti954_des0ep1: endpoint@2 {
++ remote-endpoint = <&ti954_des0ep1>;
++ };
++ };
++ };
++
++ ov106xx@2 {
++ compatible = "ovti,ov106xx";
++ reg = <0x62>;
++
++ port@0 {
++ ov106xx_in2: endpoint {
++ clock-lanes = <0>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&vin2ep0>;
++ };
++ };
++ port@1 {
++ ov106xx_max9286_des0ep2: endpoint@0 {
++ remote-endpoint = <&max9286_des0ep2>;
++ };
++ ov106xx_ti964_des0ep2: endpoint@1 {
++ remote-endpoint = <&ti964_des0ep2>;
++ };
++ };
++ };
++
++ ov106xx@3 {
++ compatible = "ovti,ov106xx";
++ reg = <0x63>;
++
++ port@0 {
++ ov106xx_in3: endpoint {
++ clock-lanes = <0>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&vin3ep0>;
++ };
++ };
++ port@1 {
++ ov106xx_max9286_des0ep3: endpoint@0 {
++ remote-endpoint = <&max9286_des0ep3>;
++ };
++ ov106xx_ti964_des0ep3: endpoint@1 {
++ remote-endpoint = <&ti964_des0ep3>;
++ };
++ };
++ };
++
++ /* DS90UB964 @ 0x3a */
++ ti964-ti9x3@0 {
++ compatible = "ti,ti964-ti9x3";
++ reg = <0x3a>;
++ ti,sensor_delay = <350>;
++ ti,links = <4>;
++ ti,lanes = <4>;
++ ti,forwarding-mode = "round-robin";
++ ti,cable-mode = "coax";
++
++ port@0 {
++ ti964_des0ep0: endpoint@0 {
++ ti9x3-addr = <0x0c>;
++ dvp-order = <0>;
++ remote-endpoint = <&ov106xx_in0>;
++ };
++ ti964_des0ep1: endpoint@1 {
++ ti9x3-addr = <0x0d>;
++ dvp-order = <0>;
++ remote-endpoint = <&ov106xx_in1>;
++ };
++ ti964_des0ep2: endpoint@2 {
++ ti9x3-addr = <0x0e>;
++ dvp-order = <0>;
++ remote-endpoint = <&ov106xx_in2>;
++ };
++ ti964_des0ep3: endpoint@3 {
++ ti9x3-addr = <0x0f>;
++ dvp-order = <0>;
++ remote-endpoint = <&ov106xx_in3>;
++ };
++ };
++ port@1 {
++ ti964_csi0ep0: endpoint {
++ csi-rate = <1450>;
++ remote-endpoint = <&csi2_40_ep>;
++ };
++ };
++ };
++
++ /* DS90UB954 @ 0x38 */
++ ti954-ti9x3@0 {
++ compatible = "ti,ti954-ti9x3";
++ reg = <0x38>;
++ /* gpios = <&video_a_ext1 10 GPIO_ACTIVE_HIGH>; */
++ ti,sensor_delay = <350>;
++ ti,links = <2>;
++ ti,lanes = <4>;
++ ti,forwarding-mode = "round-robin";
++ ti,cable-mode = "coax";
++
++ port@0 {
++ ti954_des0ep0: endpoint@0 {
++ ti9x3-addr = <0x0c>;
++ dvp-order = <0>;
++ remote-endpoint = <&ov106xx_in0>;
++ };
++ ti954_des0ep1: endpoint@1 {
++ ti9x3-addr = <0x0d>;
++ dvp-order = <0>;
++ remote-endpoint = <&ov106xx_in1>;
++ };
++ };
++ port@1 {
++ ti954_csi0ep0: endpoint {
++ csi-rate = <1450>;
++ remote-endpoint = <&csi2_40_ep>;
++ };
++ };
++ };
++
++ /* MAX9286 @ 0x2c */
++ max9286-max9271@0 {
++ compatible = "maxim,max9286-max9271";
++ reg = <0x2c>;
++ maxim,sensor_delay = <350>;
++ maxim,links = <4>;
++ maxim,lanes = <4>;
++ maxim,resetb-gpio = <1>;
++ maxim,fsync-mode = "automatic";
++ maxim,timeout = <100>;
++
++ port@0 {
++ max9286_des0ep0: endpoint@0 {
++ max9271-addr = <0x50>;
++ dvp-order = <1>;
++ remote-endpoint = <&ov106xx_in0>;
++ };
++ max9286_des0ep1: endpoint@1 {
++ max9271-addr = <0x51>;
++ dvp-order = <1>;
++ remote-endpoint = <&ov106xx_in1>;
++ };
++ max9286_des0ep2: endpoint@2 {
++ max9271-addr = <0x52>;
++ dvp-order = <1>;
++ remote-endpoint = <&ov106xx_in2>;
++ };
++ max9286_des0ep3: endpoint@3 {
++ max9271-addr = <0x53>;
++ dvp-order = <1>;
++ remote-endpoint = <&ov106xx_in3>;
++ };
++ };
++ port@1 {
++ max9286_csi0ep0: endpoint {
++ csi-rate = <700>;
++ remote-endpoint = <&csi2_40_ep>;
++ };
++ };
++ };
++ };
++
++ i2c@2 {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ reg = <2>;
++ /* Slot B (CN11) */
++
++ ov106xx@4 {
++ compatible = "ovti,ov106xx";
++ reg = <0x64>;
++
++ port@0 {
++ ov106xx_in4: endpoint {
++ clock-lanes = <0>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&vin4ep0>;
++ };
++ };
++ port@1 {
++ ov106xx_max9286_des1ep0: endpoint@0 {
++ remote-endpoint = <&max9286_des1ep0>;
++ };
++ ov106xx_ti964_des1ep0: endpoint@1 {
++ remote-endpoint = <&ti964_des1ep0>;
++ };
++ ov106xx_ti954_des1ep0: endpoint@2 {
++ remote-endpoint = <&ti954_des1ep0>;
++ };
++ };
++ };
++
++ ov106xx@5 {
++ compatible = "ovti,ov106xx";
++ reg = <0x65>;
++
++ port@0 {
++ ov106xx_in5: endpoint {
++ clock-lanes = <0>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&vin5ep0>;
++ };
++ };
++ port@1 {
++ ov106xx_max9286_des1ep1: endpoint@0 {
++ remote-endpoint = <&max9286_des1ep1>;
++ };
++ ov106xx_ti964_des1ep1: endpoint@1 {
++ remote-endpoint = <&ti964_des1ep1>;
++ };
++ ov106xx_ti954_des1ep1: endpoint@2 {
++ remote-endpoint = <&ti954_des1ep1>;
++ };
++ };
++ };
++
++ ov106xx@6 {
++ compatible = "ovti,ov106xx";
++ reg = <0x66>;
++
++ port@0 {
++ ov106xx_in6: endpoint {
++ clock-lanes = <0>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&vin6ep0>;
++ };
++ };
++ port@1 {
++ ov106xx_max9286_des1ep2: endpoint@0 {
++ remote-endpoint = <&max9286_des1ep2>;
++ };
++ ov106xx_ti964_des1ep2: endpoint@1 {
++ remote-endpoint = <&ti964_des1ep2>;
++ };
++ };
++ };
++
++ ov106xx@7 {
++ compatible = "ovti,ov106xx";
++ reg = <0x67>;
++
++ port@0 {
++ ov106xx_in7: endpoint {
++ clock-lanes = <0>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&vin7ep0>;
++ };
++ };
++ port@1 {
++ ov106xx_max9286_des1ep3: endpoint@0 {
++ remote-endpoint = <&max9286_des1ep3>;
++ };
++ ov106xx_ti964_des1ep3: endpoint@1 {
++ remote-endpoint = <&ti964_des1ep3>;
++ };
++ };
++ };
++
++ /* DS90UB964 @ 0x3a */
++ ti964-ti9x3@1 {
++ compatible = "ti,ti964-ti9x3";
++ reg = <0x3a>;
++ ti,sensor_delay = <350>;
++ ti,links = <4>;
++ ti,lanes = <4>;
++ ti,forwarding-mode = "round-robin";
++ ti,cable-mode = "coax";
++
++ port@0 {
++ ti964_des1ep0: endpoint@0 {
++ ti9x3-addr = <0x0c>;
++ dvp-order = <0>;
++ remote-endpoint = <&ov106xx_in4>;
++ };
++ ti964_des1ep1: endpoint@1 {
++ ti9x3-addr = <0x0d>;
++ dvp-order = <0>;
++ remote-endpoint = <&ov106xx_in5>;
++ };
++ ti964_des1ep2: endpoint@2 {
++ ti9x3-addr = <0x0e>;
++ dvp-order = <0>;
++ remote-endpoint = <&ov106xx_in6>;
++ };
++ ti964_des1ep3: endpoint@3 {
++ ti9x3-addr = <0x0f>;
++ dvp-order = <0>;
++ remote-endpoint = <&ov106xx_in7>;
++ };
++ };
++ port@1 {
++ ti964_csi2ep0: endpoint {
++ csi-rate = <1450>;
++ remote-endpoint = <&csi2_41_ep>;
++ };
++ };
++ };
++
++ /* DS90UB954 @ 0x38 */
++ ti954-ti9x3@1 {
++ compatible = "ti,ti954-ti9x3";
++ reg = <0x38>;
++ /* gpios = <&video_b_ext1 10 GPIO_ACTIVE_HIGH>; */
++ ti,sensor_delay = <350>;
++ ti,links = <2>;
++ ti,lanes = <4>;
++ ti,forwarding-mode = "round-robin";
++ ti,cable-mode = "coax";
++
++ port@0 {
++ ti954_des1ep0: endpoint@0 {
++ ti9x3-addr = <0x0c>;
++ dvp-order = <0>;
++ remote-endpoint = <&ov106xx_in4>;
++ };
++ ti954_des1ep1: endpoint@1 {
++ ti9x3-addr = <0x0d>;
++ dvp-order = <0>;
++ remote-endpoint = <&ov106xx_in5>;
++ };
++ };
++ port@1 {
++ ti954_csi2ep0: endpoint {
++ csi-rate = <1450>;
++ remote-endpoint = <&csi2_41_ep>;
++ };
++ };
++ };
++
++ /* MAX9286 @ 0x2c */
++ max9286-max9271@1 {
++ compatible = "maxim,max9286-max9271";
++ reg = <0x2c>;
++ maxim,sensor_delay = <350>;
++ maxim,links = <4>;
++ maxim,lanes = <4>;
++ maxim,resetb-gpio = <1>;
++ maxim,fsync-mode = "automatic";
++ maxim,timeout = <100>;
++
++ port@0 {
++ max9286_des1ep0: endpoint@0 {
++ max9271-addr = <0x50>;
++ dvp-order = <1>;
++ remote-endpoint = <&ov106xx_in4>;
++ };
++ max9286_des1ep1: endpoint@1 {
++ max9271-addr = <0x51>;
++ dvp-order = <1>;
++ remote-endpoint = <&ov106xx_in5>;
++ };
++ max9286_des1ep2: endpoint@2 {
++ max9271-addr = <0x52>;
++ dvp-order = <1>;
++ remote-endpoint = <&ov106xx_in6>;
++ };
++ max9286_des1ep3: endpoint@3 {
++ max9271-addr = <0x53>;
++ dvp-order = <1>;
++ remote-endpoint = <&ov106xx_in7>;
++ };
++ };
++ port@1 {
++ max9286_csi2ep0: endpoint {
++ csi-rate = <700>;
++ remote-endpoint = <&csi2_41_ep>;
++ };
++ };
++ };
++ };
++
++ i2c@6 {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ reg = <6>;
++ /* Slot B (CN11) */
++
++ video_b_ext0: pca9535@27 {
++ compatible = "nxp,pca9535";
++ reg = <0x27>;
++ gpio-controller;
++ #gpio-cells = <2>;
++
++ video_b_des_cfg1 {
++ gpio-hog;
++ gpios = <5 GPIO_ACTIVE_HIGH>;
++ input;
++ line-name = "Video-B cfg1";
++ };
++ video_b_des_cfg0 {
++ gpio-hog;
++ gpios = <6 GPIO_ACTIVE_HIGH>;
++ input;
++ line-name = "Video-B cfg0";
++ };
++ video_b_pwr_shdn {
++ gpio-hog;
++ gpios = <3 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "Video-B PWR_SHDN";
++ };
++ video_b_cam_pwr0 {
++ gpio-hog;
++ gpios = <12 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "Video-B PWR0";
++ };
++ video_b_cam_pwr1 {
++ gpio-hog;
++ gpios = <13 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "Video-B PWR1";
++ };
++ video_b_cam_pwr2 {
++ gpio-hog;
++ gpios = <14 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "Video-B PWR2";
++ };
++ video_b_cam_pwr3 {
++ gpio-hog;
++ gpios = <15 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "Video-B PWR3";
++ };
++ video_b_des_shdn {
++ gpio-hog;
++ gpios = <4 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "Video-B DES_SHDN";
++ };
++ video_b_des_led {
++ gpio-hog;
++ gpios = <7 GPIO_ACTIVE_HIGH>;
++ output-low;
++ line-name = "Video-B led";
++ };
++ };
++
++ video_b_ext1: max7325@5c {
++ compatible = "maxim,max7325";
++ reg = <0x5c>;
++ gpio-controller;
++ #gpio-cells = <2>;
++
++ video_b_des_cfg2 {
++ gpio-hog;
++ gpios = <4 GPIO_ACTIVE_HIGH>;
++ input;
++ line-name = "Video-B cfg2";
++ };
++ video_b_des_cfg1 {
++ gpio-hog;
++ gpios = <6 GPIO_ACTIVE_HIGH>;
++ input;
++ line-name = "Video-B cfg1";
++ };
++ video_b_des_cfg0 {
++ gpio-hog;
++ gpios = <7 GPIO_ACTIVE_HIGH>;
++ input;
++ line-name = "Video-B cfg0";
++ };
++ video_b_pwr_shdn {
++ gpio-hog;
++ gpios = <14 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "Video-B PWR_SHDN";
++ };
++ video_b_cam_pwr0 {
++ gpio-hog;
++ gpios = <8 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "Video-B PWR0";
++ };
++ video_b_cam_pwr1 {
++ gpio-hog;
++ gpios = <9 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "Video-B PWR1";
++ };
++ video_b_cam_pwr2 {
++ gpio-hog;
++ gpios = <10 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "Video-B PWR2";
++ };
++ video_b_cam_pwr3 {
++ gpio-hog;
++ gpios = <11 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "Video-B PWR3";
++ };
++ video_b_des_shdn {
++ gpio-hog;
++ gpios = <13 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "Video-B DES_SHDN";
++ };
++ video_b_led {
++ gpio-hog;
++ gpios = <12 GPIO_ACTIVE_HIGH>;
++ output-low;
++ line-name = "Video-B LED";
++ };
++ };
++ };
++
++ i2c@7 {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ reg = <7>;
++ /* Slot A (CN10) */
++
++ video_a_ext0: pca9535@26 {
++ compatible = "nxp,pca9535";
++ reg = <0x26>;
++ gpio-controller;
++ #gpio-cells = <2>;
++
++ video_a_des_cfg1 {
++ gpio-hog;
++ gpios = <5 GPIO_ACTIVE_HIGH>;
++ input;
++ line-name = "Video-A cfg1";
++ };
++ video_a_des_cfg0 {
++ gpio-hog;
++ gpios = <6 GPIO_ACTIVE_HIGH>;
++ input;
++ line-name = "Video-A cfg0";
++ };
++ video_a_pwr_shdn {
++ gpio-hog;
++ gpios = <3 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "Video-A PWR_SHDN";
++ };
++ video_a_cam_pwr0 {
++ gpio-hog;
++ gpios = <12 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "Video-A PWR0";
++ };
++ video_a_cam_pwr1 {
++ gpio-hog;
++ gpios = <13 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "Video-A PWR1";
++ };
++ video_a_cam_pwr2 {
++ gpio-hog;
++ gpios = <14 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "Video-A PWR2";
++ };
++ video_a_cam_pwr3 {
++ gpio-hog;
++ gpios = <15 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "Video-A PWR3";
++ };
++ video_a_des_shdn {
++ gpio-hog;
++ gpios = <4 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "Video-A DES_SHDN";
++ };
++ video_a_des_led {
++ gpio-hog;
++ gpios = <7 GPIO_ACTIVE_HIGH>;
++ output-low;
++ line-name = "Video-A led";
++ };
++ };
++
++ video_a_ext1: max7325@5c {
++ compatible = "maxim,max7325";
++ reg = <0x5c>;
++ gpio-controller;
++ #gpio-cells = <2>;
++
++ video_a_des_cfg2 {
++ gpio-hog;
++ gpios = <4 GPIO_ACTIVE_HIGH>;
++ input;
++ line-name = "Video-A cfg2";
++ };
++ video_a_des_cfg1 {
++ gpio-hog;
++ gpios = <6 GPIO_ACTIVE_HIGH>;
++ input;
++ line-name = "Video-A cfg1";
++ };
++ video_a_des_cfg0 {
++ gpio-hog;
++ gpios = <7 GPIO_ACTIVE_HIGH>;
++ input;
++ line-name = "Video-A cfg0";
++ };
++ video_a_pwr_shdn {
++ gpio-hog;
++ gpios = <14 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "Video-A PWR_SHDN";
++ };
++ video_a_cam_pwr0 {
++ gpio-hog;
++ gpios = <8 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "Video-A PWR0";
++ };
++ video_a_cam_pwr1 {
++ gpio-hog;
++ gpios = <9 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "Video-A PWR1";
++ };
++ video_a_cam_pwr2 {
++ gpio-hog;
++ gpios = <10 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "Video-A PWR2";
++ };
++ video_a_cam_pwr3 {
++ gpio-hog;
++ gpios = <11 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "Video-A PWR3";
++ };
++ video_a_des_shdn {
++ gpio-hog;
++ gpios = <13 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "Video-A DES_SHDN";
++ };
++ video_a_led {
++ gpio-hog;
++ gpios = <12 GPIO_ACTIVE_HIGH>;
++ output-low;
++ line-name = "Video-A LED";
++ };
++ };
++ };
++ };
++};
++
++&pcie_bus_clk {
++ clock-frequency = <100000000>;
++ status = "okay";
++};
++
++&pciec0 {
++ status = "okay";
++};
++
++&pciec1 {
++ status = "okay";
++};
++
++&vin0 {
++ status = "okay";
++
++ ports {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ port@0 {
++ vin0ep0: endpoint {
++ csi,select = "csi40";
++ virtual,channel = <0>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&ov106xx_in0>;
++ };
++ };
++ port@1 {
++ csi0ep0: endpoint {
++ remote-endpoint = <&csi2_40_ep>;
++ };
++ };
++ port@2 {
++ vin0_max9286_des0ep0: endpoint@0 {
++ remote-endpoint = <&max9286_des0ep0>;
++ };
++ vin0_ti964_des0ep0: endpoint@1 {
++ remote-endpoint = <&ti964_des0ep0>;
++ };
++ vin0_ti954_des0ep0: endpoint@2 {
++ remote-endpoint = <&ti954_des0ep0>;
++ };
++ };
++ };
++};
++
++&vin1 {
++ status = "okay";
++
++ ports {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ port@0 {
++ vin1ep0: endpoint {
++ csi,select = "csi40";
++ virtual,channel = <1>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&ov106xx_in1>;
++ };
++ };
++ port@1 {
++ csi0ep1: endpoint {
++ remote-endpoint = <&csi2_40_ep>;
++ };
++ };
++ port@2 {
++ vin1_max9286_des0ep1: endpoint@0 {
++ remote-endpoint = <&max9286_des0ep1>;
++ };
++ vin1_ti964_des0ep1: endpoint@1 {
++ remote-endpoint = <&ti964_des0ep1>;
++ };
++ vin1_ti954_des0ep1: endpoint@2 {
++ remote-endpoint = <&ti954_des0ep1>;
++ };
++ };
++ };
++};
++
++&vin2 {
++ status = "okay";
++
++ ports {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ port@0 {
++ vin2ep0: endpoint {
++ csi,select = "csi40";
++ virtual,channel = <2>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&ov106xx_in2>;
++ };
++ };
++ port@1 {
++ csi0ep2: endpoint {
++ remote-endpoint = <&csi2_40_ep>;
++ };
++ };
++ port@2 {
++ vin2_max9286_des0ep2: endpoint@0 {
++ remote-endpoint = <&max9286_des0ep2>;
++ };
++ vin2_ti964_des0ep2: endpoint@1 {
++ remote-endpoint = <&ti964_des0ep2>;
++ };
++ };
++ };
++};
++
++&vin3 {
++ status = "okay";
++
++ ports {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ port@0 {
++ vin3ep0: endpoint {
++ csi,select = "csi40";
++ virtual,channel = <3>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&ov106xx_in3>;
++ };
++ };
++ port@1 {
++ csi0ep3: endpoint {
++ remote-endpoint = <&csi2_40_ep>;
++ };
++ };
++ port@2 {
++ vin3_max9286_des0ep3: endpoint@0 {
++ remote-endpoint = <&max9286_des0ep3>;
++ };
++ vin3_ti964_des0ep3: endpoint@1 {
++ remote-endpoint = <&ti964_des0ep3>;
++ };
++ };
++ };
++};
++
++&vin4 {
++ status = "okay";
++
++ ports {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ port@0 {
++ vin4ep0: endpoint {
++ csi,select = "csi41";
++ virtual,channel = <0>;
++ remote-endpoint = <&ov106xx_in4>;
++ data-lanes = <1 2 3 4>;
++ };
++ };
++ port@1 {
++ csi2ep0: endpoint {
++ remote-endpoint = <&csi2_41_ep>;
++ };
++ };
++ port@2 {
++ vin4_max9286_des1ep0: endpoint@0 {
++ remote-endpoint = <&max9286_des1ep0>;
++ };
++ vin4_ti964_des1ep0: endpoint@1 {
++ remote-endpoint = <&ti964_des1ep0>;
++ };
++ vin4_ti954_des1ep0: endpoint@2 {
++ remote-endpoint = <&ti954_des1ep0>;
++ };
++ };
++ };
++};
++
++&vin5 {
++ status = "okay";
++
++ ports {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ port@0 {
++ vin5ep0: endpoint@0 {
++ csi,select = "csi41";
++ virtual,channel = <1>;
++ remote-endpoint = <&ov106xx_in5>;
++ data-lanes = <1 2 3 4>;
++ };
++ };
++ port@1 {
++ csi2ep1: endpoint {
++ remote-endpoint = <&csi2_41_ep>;
++ };
++ };
++ port@2 {
++ vin5_max9286_des1ep1: endpoint@0 {
++ remote-endpoint = <&max9286_des1ep1>;
++ };
++ vin5_ti964_des1ep1: endpoint@1 {
++ remote-endpoint = <&ti964_des1ep1>;
++ };
++ vin5_ti954_des1ep1: endpoint@2 {
++ remote-endpoint = <&ti954_des1ep1>;
++ };
++ };
++ };
++};
++
++&vin6 {
++ status = "okay";
++
++ ports {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ port@0 {
++ vin6ep0: endpoint@0 {
++ csi,select = "csi41";
++ virtual,channel = <2>;
++ remote-endpoint = <&ov106xx_in6>;
++ data-lanes = <1 2 3 4>;
++ };
++ };
++ port@1 {
++ csi2ep2: endpoint {
++ remote-endpoint = <&csi2_41_ep>;
++ };
++ };
++ port@2 {
++ vin6_max9286_des1ep2: endpoint@0 {
++ remote-endpoint = <&max9286_des1ep2>;
++ };
++ vin6_ti964_des1ep2: endpoint@1 {
++ remote-endpoint = <&ti964_des1ep2>;
++ };
++ };
++ };
++};
++
++&vin7 {
++ status = "okay";
++
++ ports {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ port@0 {
++ vin7ep0: endpoint@0 {
++ csi,select = "csi41";
++ virtual,channel = <3>;
++ remote-endpoint = <&ov106xx_in7>;
++ data-lanes = <1 2 3 4>;
++ };
++ };
++ port@1 {
++ csi2ep3: endpoint {
++ remote-endpoint = <&csi2_41_ep>;
++ };
++ };
++ port@2 {
++ vin7_max9286_des1ep3: endpoint@0 {
++ remote-endpoint = <&max9286_des1ep3>;
++ };
++ vin7_ti964_des1ep3: endpoint@1 {
++ remote-endpoint = <&ti964_des1ep3>;
++ };
++ };
++ };
++};
++
++&csi2_40 {
++ status = "okay";
++
++ virtual,channel {
++ csi2_vc0 {
++ data,type = "ycbcr422";
++ receive,vc = <0>;
++ };
++ csi2_vc1 {
++ data,type = "ycbcr422";
++ receive,vc = <1>;
++ };
++ csi2_vc2 {
++ data,type = "ycbcr422";
++ receive,vc = <2>;
++ };
++ csi2_vc3 {
++ data,type = "ycbcr422";
++ receive,vc = <3>;
++ };
++ };
++
++ port {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ csi2_40_ep: endpoint {
++ clock-lanes = <0>;
++ data-lanes = <1 2 3 4>;
++ csi-rate = <300>;
++ };
++ };
++};
++
++&csi2_41 {
++ status = "okay";
++
++ virtual,channel {
++ csi2_vc0 {
++ data,type = "ycbcr422";
++ receive,vc = <0>;
++ };
++ csi2_vc1 {
++ data,type = "ycbcr422";
++ receive,vc = <1>;
++ };
++ csi2_vc2 {
++ data,type = "ycbcr422";
++ receive,vc = <2>;
++ };
++ csi2_vc3 {
++ data,type = "ycbcr422";
++ receive,vc = <3>;
++ };
++ };
++
++ port {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ csi2_41_ep: endpoint {
++ clock-lanes = <0>;
++ data-lanes = <1 2 3 4>;
++ csi-rate = <300>;
++ };
++ };
++};
++
++&rcar_sound {
++ pinctrl-0 = <&sound_clk_pins>;
++
++ /* Multi DAI */
++ #sound-dai-cells = <1>;
++
++ rcar_sound,dai {
++ dai0 {
++ playback = <&ssi7>;
++ capture = <&ssi8>;
++ };
++
++ dai1 {
++ playback = <&ssi0 &src0 &dvc0>;
++ capture = <&ssi1 &src1 &dvc1>;
++ };
++
++ dai2 {
++ capture = <&ssi6>;
++ };
++ };
++};
++
++&sdhi3 {
++ pinctrl-0 = <&sdhi3_pins_3v3>;
++ pinctrl-names = "default";
++
++ vmmc-supply = <&wlan_en>;
++ vqmmc-supply = <&vccq_sdhi3>;
++ keep-power-in-suspend;
++ enable-sdio-wakeup;
++ bus-width = <4>;
++ no-1-8-v;
++ non-removable;
++ cap-power-off-card;
++ max-frequency = <26000000>;
++ status = "okay";
++
++ #address-cells = <1>;
++ #size-cells = <0>;
++ wlcore: wlcore@2 {
++ compatible = "ti,wl1837";
++ reg = <2>;
++ interrupt-parent = <&gpio1>;
++ interrupts = <25 IRQ_TYPE_EDGE_RISING>;
++ };
++};
++
++&usb2_phy0 {
++ pinctrl-0 = <&usb0_pins>;
++ pinctrl-names = "default";
++
++ status = "okay";
++};
++
++&hsusb {
++ status = "okay";
++};
++
++&ehci0 {
++ status = "okay";
++};
++
++&ohci0 {
++ status = "okay";
++};
++
++&xhci0 {
++ status = "okay";
++};
++
++&msiof1 {
++ status = "disabled";
++};
++
++&can0 {
++ pinctrl-0 = <&can0_pins>;
++ pinctrl-names = "default";
++ status = "okay";
++
++ renesas,can-clock-select = <0x0>;
++};
++
++&can1 {
++ pinctrl-0 = <&can1_pins>;
++ pinctrl-names = "default";
++ status = "okay";
++
++ renesas,can-clock-select = <0x0>;
++};
++
++&canfd {
++ pinctrl-0 = <&canfd0_pins &canfd1_pins>;
++ pinctrl-names = "default";
++ status = "disabled";
++
++ channel0 {
++ status = "okay";
++ };
++
++ channel1 {
++ status = "okay";
++ };
++};
++
++&ssi8 {
++ shared-pin;
++};
+diff --git a/arch/arm64/boot/dts/renesas/legacy/r8a7795-es1-h3ulcb-kf-v1.dts b/arch/arm64/boot/dts/renesas/legacy/r8a7795-es1-h3ulcb-kf-v1.dts
+new file mode 100644
+index 0000000..ac6a12b
+--- /dev/null
++++ b/arch/arm64/boot/dts/renesas/legacy/r8a7795-es1-h3ulcb-kf-v1.dts
+@@ -0,0 +1,441 @@
++/*
++ * Device Tree Source for the H3ULCB Kingfisher V1 board on r8a7795 ES1.x
++ *
++ * Copyright (C) 2017 Renesas Electronics Corp.
++ * Copyright (C) 2017 Cogent Embedded, Inc.
++ *
++ * This file is licensed under the terms of the GNU General Public License
++ * version 2. This program is licensed "as is" without any warranty of any
++ * kind, whether express or implied.
++ */
++
++#include "r8a7795-es1-h3ulcb-kf-v0.dts"
++
++/ {
++ model = "Renesas H3ULCB Kingfisher V1 board based on r8a7795";
++
++ aliases {
++ serial1 = &hscif0;
++ serial2 = &hscif1;
++ serial3 = &scif1;
++ };
++
++ wlan_en: regulator@4 {
++ compatible = "regulator-fixed";
++ regulator-name = "wlan-en-regulator";
++
++ regulator-min-microvolt = <3300000>;
++ regulator-max-microvolt = <3300000>;
++
++ gpio = <&gpio_ext_74 4 GPIO_ACTIVE_HIGH>;
++ enable-active-high;
++ };
++
++ codec_en_reg: regulator@6 {
++ compatible = "regulator-fixed";
++ regulator-name = "codec-en-regulator";
++ regulator-min-microvolt = <3300000>;
++ regulator-max-microvolt = <3300000>;
++
++ gpio = <&gpio_ext_74 15 0>;
++
++ /* delay - CHECK */
++ startup-delay-us = <70000>;
++ enable-active-high;
++ };
++
++ amp_en_reg: regulator@7 {
++ compatible = "regulator-fixed";
++ regulator-name = "amp-en-regulator";
++ regulator-min-microvolt = <3300000>;
++ regulator-max-microvolt = <3300000>;
++
++ gpio = <&gpio_ext_74 0 0>;
++
++ startup-delay-us = <0>;
++ enable-active-high;
++ };
++
++ /delete-node/regulator@8;
++
++ sdio_switch: regulator@9 {
++ compatible = "regulator-fixed";
++ regulator-name = "wifi_on";
++ regulator-min-microvolt = <3300000>;
++ regulator-max-microvolt = <3300000>;
++ gpio = <&gpio_ext_74 5 0>;
++ enable-active-low;
++ regulator-always-on;
++ };
++
++ /delete-node/regulator@10;
++
++ radio_switch: regulator@11 {
++ compatible = "regulator-fixed";
++ regulator-name = "radio_on";
++ regulator-min-microvolt = <3300000>;
++ regulator-max-microvolt = <3300000>;
++ gpio = <&gpio_ext_74 13 GPIO_ACTIVE_HIGH>;
++ enable-active-high;
++ regulator-always-on;
++ };
++
++ kim {
++ shutdown-gpios = <&gpio_ext_74 3 GPIO_ACTIVE_HIGH>;
++ };
++
++ hdmi-out {
++ compatible = "hdmi-connector";
++ type = "a";
++
++ port {
++ hdmi_con: endpoint {
++ remote-endpoint = <&adv7513_out>;
++ };
++ };
++ };
++};
++
++&pfc {
++ /delete-node/hscif4;
++
++ scif1_pins: scif1 {
++ groups = "scif1_data_b";
++ function = "scif1";
++ };
++
++ hscif0_pins: hscif0 {
++ groups = "hscif0_data", "hscif0_ctrl";
++ function = "hscif0";
++ };
++
++ hscif1_pins: hscif1 {
++ groups = "hscif1_data_a", "hscif1_ctrl_a";
++ function = "hscif1";
++ };
++
++ du_pins: du {
++ groups = "du_rgb888", "du_sync", "du_clk_out_0", "du_disp";
++ function = "du";
++ };
++};
++
++&du {
++ pinctrl-0 = <&du_pins>;
++ pinctrl-names = "default";
++
++ ports {
++ port@0 {
++ endpoint {
++ remote-endpoint = <&adv7513_in>;
++ };
++ };
++ };
++};
++
++&gpio0 {
++ /delete-node/video_a_irq;
++ /delete-node/video_b_irq;
++ /delete-node/gpioext_2_20_irq;
++};
++
++&gpio1 {
++ /delete-node/gpioext_2_21_irq;
++ /delete-node/wifi_irq;
++};
++
++&gpio2 {
++ bl_pwm {
++ gpio-hog;
++ gpios = <3 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "BL PWM 100%";
++ };
++};
++
++&gpio5 {
++ /delete-node/touch_irq;
++ /delete-node/bt_strap;
++};
++
++&gpio7 {
++ /delete-node/gpioext_2_21_irq;
++};
++
++&scif1 {
++ pinctrl-0 = <&scif1_pins>;
++ pinctrl-names = "default";
++
++ status = "okay";
++};
++
++&hscif0 {
++ pinctrl-0 = <&hscif0_pins>;
++ pinctrl-names = "default";
++ uart-has-rtscts;
++
++ status = "okay";
++};
++
++&hscif1 {
++ pinctrl-0 = <&hscif1_pins>;
++ pinctrl-names = "default";
++
++ status = "okay";
++};
++
++&hscif4 {
++ /delete-property/pinctrl-0;
++ /delete-property/pinctrl-names;
++
++ status = "disabled";
++};
++
++&i2c2 {
++ /delete-node/pca9535@20;
++ /delete-node/pca9535@21;
++
++ gpio_ext_74: pca9539@74 {
++ compatible = "nxp,pca9539";
++ reg = <0x74>;
++ gpio-controller;
++ #gpio-cells = <2>;
++ interrupt-controller;
++ interrupt-parent = <&gpio6>;
++ interrupts = <8 IRQ_TYPE_EDGE_FALLING>;
++
++ hub_pwen {
++ gpio-hog;
++ gpios = <6 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "HUB pwen";
++ };
++ hub_rst {
++ gpio-hog;
++ gpios = <7 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "HUB rst";
++ };
++ otg_offvbus {
++ gpio-hog;
++ gpios = <8 GPIO_ACTIVE_HIGH>;
++ output-low;
++ line-name = "OTG off VBUSn";
++ };
++ otg_extlpn {
++ gpio-hog;
++ gpios = <9 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "OTG EXTLPn";
++ };
++ otg_stat1 {
++ gpio-hog;
++ gpios = <10 GPIO_ACTIVE_HIGH>;
++ input;
++ line-name = "OTG Stat1";
++ };
++ otg_stat2 {
++ gpio-hog;
++ gpios = <11 GPIO_ACTIVE_HIGH>;
++ input;
++ line-name = "OTG Stat2";
++ };
++ };
++
++ gpio_ext_75: pca9539@75 {
++ compatible = "nxp,pca9539";
++ reg = <0x75>;
++ gpio-controller;
++ #gpio-cells = <2>;
++ interrupt-controller;
++ interrupt-parent = <&gpio6>;
++ interrupts = <4 IRQ_TYPE_EDGE_FALLING>;
++
++ gps_rst {
++ gpio-hog;
++ gpios = <6 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "GPS rst";
++ };
++ fpdl_shdn {
++ gpio-hog;
++ gpios = <9 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "FPDLink shdn";
++ };
++ };
++};
++
++&i2cswitch2 {
++ reg = <0x71>;
++ reset-gpios= <&gpio5 3 GPIO_ACTIVE_LOW>;
++
++ i2c@4 {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ reg = <4>;
++
++ hdmi@3d {
++ compatible = "adi,adv7511w";
++ reg = <0x3d>;
++// interrupt-parent = <&gpio2>;
++// interrupts = <0 IRQ_TYPE_EDGE_BOTH>;
++ pd-gpios = <&gpio_ext_75 5 GPIO_ACTIVE_LOW>;
++
++ adi,input-depth = <8>;
++ adi,input-colorspace = "rgb";
++ adi,input-clock = "1x";
++ adi,input-style = <1>;
++ adi,input-justification = "evenly";
++ adi,clock-delay = <1200>;
++ adi,clock-max-rate = <100000>;
++
++ ports {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ port@0 {
++ reg = <0>;
++ adv7513_in: endpoint {
++ remote-endpoint = <&du_out_rgb>;
++ };
++ };
++
++ port@1 {
++ reg = <1>;
++ adv7513_out: endpoint {
++ remote-endpoint = <&hdmi_con>;
++ };
++ };
++ };
++ };
++ };
++};
++
++&i2c4 {
++ /delete-node/pca9535@21;
++
++ gpio_ext_76: pca9539@76 {
++ compatible = "nxp,pca9539";
++ reg = <0x76>;
++ gpio-controller;
++ #gpio-cells = <2>;
++ interrupt-controller;
++ interrupt-parent = <&gpio7>;
++ interrupts = <3 IRQ_TYPE_EDGE_FALLING>;
++
++ port_b_a0 {
++ gpio-hog;
++ gpios = <0 GPIO_ACTIVE_HIGH>;
++ output-low;
++ line-name = "Video-B A0";
++ };
++ port_b_a1 {
++ gpio-hog;
++ gpios = <1 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "Video-B A1";
++ };
++ port_a_a0 {
++ gpio-hog;
++ gpios = <2 GPIO_ACTIVE_HIGH>;
++ output-low;
++ line-name = "Video-A A0";
++ };
++ port_a_a1 {
++ gpio-hog;
++ gpios = <3 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "Video-A A1";
++ };
++ cmos_pwdn {
++ gpio-hog;
++ gpios = <8 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "CMOS PWDN";
++ };
++ cmos_rst {
++ gpio-hog;
++ gpios = <9 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "CMOS RST";
++ };
++ /* pin 12 - CAM_CLK */
++ rpi_cam_io_1 {
++ gpio-hog;
++ gpios = <10 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "RaspB_IO1";
++ };
++ /* pin 11 - CAM_GPIO - assume pwdn */
++ rpi_cam_io_0 {
++ gpio-hog;
++ gpios = <11 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "RaspB_IO0";
++ };
++ sam_rst {
++ gpio-hog;
++ gpios = <4 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "SAM RST";
++ };
++ sam_pwr {
++ gpio-hog;
++ gpios = <5 GPIO_ACTIVE_HIGH>;
++ output-low;
++ line-name = "SAM PWR";
++ };
++ /* 0 - FPDLink output, 1 - LVDS output */
++ lvds_vs_fpdl {
++ gpio-hog;
++ gpios = <14 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "LVDS switch";
++ };
++ };
++
++ gpio_ext_77: pca9539@77 {
++ compatible = "nxp,pca9539";
++ reg = <0x77>;
++ gpio-controller;
++ #gpio-cells = <2>;
++ interrupt-controller;
++ interrupt-parent = <&gpio5>;
++ interrupts = <9 IRQ_TYPE_EDGE_FALLING>;
++
++ mpcie_wake {
++ gpio-hog;
++ gpios = <0 GPIO_ACTIVE_HIGH>;
++ output-low;
++ line-name = "mPCIe WAKE#";
++ };
++ mpcie_wdisable {
++ gpio-hog;
++ gpios = <1 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "mPCIe W_DISABLE";
++ };
++ mpcie_clreq {
++ gpio-hog;
++ gpios = <2 GPIO_ACTIVE_HIGH>;
++ input;
++ line-name = "mPCIe CLKREQ#";
++ };
++ mpcie_ovc {
++ gpio-hog;
++ gpios = <3 GPIO_ACTIVE_HIGH>;
++ input;
++ line-name = "mPCIe OVC";
++ };
++ };
++};
++
++&i2cswitch4 {
++ reg = <0x71>;
++ reset-gpios= <&gpio3 15 GPIO_ACTIVE_LOW>;
++};
++
++&wlcore {
++ interrupts = <25 IRQ_TYPE_EDGE_FALLING>;
++};
+diff --git a/arch/arm64/boot/dts/renesas/legacy/r8a7795-h3ulcb-kf-v0.dts b/arch/arm64/boot/dts/renesas/legacy/r8a7795-h3ulcb-kf-v0.dts
+new file mode 100644
+index 0000000..78c766b
+--- /dev/null
++++ b/arch/arm64/boot/dts/renesas/legacy/r8a7795-h3ulcb-kf-v0.dts
+@@ -0,0 +1,1724 @@
++/*
++ * Device Tree Source for the H3ULCB Kingfisher V0 board on r8a7795
++ *
++ * Copyright (C) 2017 Renesas Electronics Corp.
++ * Copyright (C) 2017 Cogent Embedded, Inc.
++ *
++ * This file is licensed under the terms of the GNU General Public License
++ * version 2. This program is licensed "as is" without any warranty of any
++ * kind, whether express or implied.
++ */
++
++#include "../r8a7795-h3ulcb.dts"
++
++/ {
++ model = "Renesas H3ULCB Kingfisher V0 board based on r8a7795";
++
++ aliases {
++ serial1 = &hscif4;
++ };
++
++ snd_clk: snd_clk {
++ compatible = "fixed-clock";
++ #clock-cells = <0>;
++ clock-frequency = <24576000>;
++ clock-output-names = "scki";
++ };
++
++ wlan_en: regulator@4 {
++ compatible = "regulator-fixed";
++ regulator-name = "wlan-en-regulator";
++
++ regulator-min-microvolt = <3300000>;
++ regulator-max-microvolt = <3300000>;
++
++ gpio = <&gpio_ext_20 4 GPIO_ACTIVE_HIGH>;
++ enable-active-high;
++ };
++
++ vcc_sdhi3: regulator@41 {
++ compatible = "regulator-fixed";
++
++ regulator-name = "SDHI3 Vcc";
++ regulator-min-microvolt = <3300000>;
++ regulator-max-microvolt = <3300000>;
++ regulator-always-on;
++ };
++
++ vccq_sdhi3: regulator@5 {
++ compatible = "regulator-fixed";
++
++ regulator-name = "SDHI3 VccQ";
++ regulator-min-microvolt = <3300000>;
++ regulator-max-microvolt = <3300000>;
++ };
++
++ codec_en_reg: regulator@6 {
++ compatible = "regulator-fixed";
++ regulator-name = "codec-en-regulator";
++ regulator-min-microvolt = <3300000>;
++ regulator-max-microvolt = <3300000>;
++
++ gpio = <&gpio_ext_20 15 0>;
++
++ /* delay - CHECK */
++ startup-delay-us = <70000>;
++ enable-active-high;
++ };
++
++ amp_en_reg: regulator@7 {
++ compatible = "regulator-fixed";
++ regulator-name = "amp-en-regulator";
++ regulator-min-microvolt = <3300000>;
++ regulator-max-microvolt = <3300000>;
++
++ gpio = <&gpio_ext_20 0 0>;
++
++ startup-delay-us = <0>;
++ enable-active-high;
++ };
++
++ lvds_switch: regulator@8 {
++ compatible = "regulator-fixed";
++ regulator-name = "lvds_on";
++ regulator-min-microvolt = <3300000>;
++ regulator-max-microvolt = <3300000>;
++ /* gpio = <&gpio1 24 0>; */
++ enable-active-high;
++ regulator-always-on;
++ };
++
++ sdio_switch: regulator@9 {
++ compatible = "regulator-fixed";
++ regulator-name = "wifi_on";
++ regulator-min-microvolt = <3300000>;
++ regulator-max-microvolt = <3300000>;
++ gpio = <&gpio_ext_20 5 0>;
++ enable-active-low;
++ regulator-always-on;
++ };
++
++ sound_switch: regulator@10 {
++ compatible = "regulator-fixed";
++ regulator-name = "pcm3168a_on";
++ regulator-min-microvolt = <3300000>;
++ regulator-max-microvolt = <3300000>;
++ gpio = <&gpio_ext_21 5 0>;
++ enable-active-low;
++ regulator-always-on;
++ };
++
++ radio_switch: regulator@11 {
++ compatible = "regulator-fixed";
++ regulator-name = "radio_on";
++ regulator-min-microvolt = <3300000>;
++ regulator-max-microvolt = <3300000>;
++ gpio = <&gpio_ext_20 13 GPIO_ACTIVE_HIGH>;
++ enable-active-high;
++ regulator-always-on;
++ };
++
++ kim {
++ compatible = "kim";
++ shutdown-gpios = <&gpio_ext_20 3 GPIO_ACTIVE_HIGH>;
++ /* serial1 */
++ dev_name = "/dev/ttySC1";
++ flow_cntrl = <1>;
++ /* int div 8 hscif@26.6666656MHz */
++ baud_rate = <3333332>;
++ };
++
++ btwilink {
++ compatible = "btwilink";
++ };
++
++ sound_ext: sound@0 {
++ pinctrl-0 = <&sound_0_pins>;
++ pinctrl-names = "default";
++ compatible = "simple-audio-card";
++
++ simple-audio-card,format = "left_j";
++ simple-audio-card,name = "pcm3168a";
++
++ simple-audio-card,bitclock-master = <&sound_ext_master>;
++ simple-audio-card,frame-master = <&sound_ext_master>;
++ sound_ext_master: simple-audio-card,cpu@0 {
++ sound-dai = <&rcar_sound 0>;
++ dai-tdm-slot-num = <8>;
++ dai-tdm-slot-width = <32>;
++ };
++
++ simple-audio-card,codec@0 {
++ sound-dai = <&pcm3168a>;
++ dai-tdm-slot-num = <8>;
++ dai-tdm-slot-width = <32>;
++ system-clock-frequency = <24576000>;
++ };
++ };
++
++ /delete-node/sound;
++
++ rsnd_ak4613: sound@1 {
++ pinctrl-0 = <&sound_1_pins>;
++ pinctrl-names = "default";
++ compatible = "simple-audio-card";
++
++ simple-audio-card,format = "left_j";
++ simple-audio-card,name = "ak4613";
++
++ simple-audio-card,bitclock-master = <&sndcpu>;
++ simple-audio-card,frame-master = <&sndcpu>;
++
++ sndcpu: simple-audio-card,cpu@1 {
++ sound-dai = <&rcar_sound 1>;
++ };
++
++ sndcodec: simple-audio-card,codec@1 {
++ sound-dai = <&ak4613>;
++ };
++ };
++
++ sound_radio: sound@2 {
++ pinctrl-0 = <&sound_2_pins>;
++ pinctrl-names = "default";
++ compatible = "simple-audio-card";
++
++ simple-audio-card,format = "i2s";
++ simple-audio-card,name = "radio";
++
++ simple-audio-card,bitclock-master = <&sound_radio_master>;
++ simple-audio-card,frame-master = <&sound_radio_master>;
++ simple-audio-card,cpu@2 {
++ sound-dai = <&rcar_sound 2>;
++ };
++
++ sound_radio_master: simple-audio-card,codec@2 {
++ sound-dai = <&radio>;
++ system-clock-frequency = <12288000>;
++ };
++ };
++
++ lvds-encoder {
++ compatible = "thine,thc63lvdm83d";
++
++ ports {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ port@0 {
++ reg = <0>;
++ lvds_enc_in: endpoint {
++ remote-endpoint = <&du_out_lvds0>;
++ };
++ };
++ port@1 {
++ reg = <1>;
++ lvds_enc_out: endpoint {
++ remote-endpoint = <&lvds_in>;
++ };
++ };
++ };
++ };
++
++ lvds {
++ compatible = "lvds-connector";
++
++ width-mm = <210>;
++ height-mm = <158>;
++
++ panel-timing {
++ /* 1280x800 @60Hz */
++ clock-frequency = <65000000>;
++ hactive = <1280>;
++ vactive = <800>;
++ hsync-len = <40>;
++ hfront-porch = <80>;
++ hback-porch = <40>;
++ vfront-porch = <14>;
++ vback-porch = <14>;
++ vsync-len = <4>;
++ };
++
++ port {
++ lvds_in: endpoint {
++ remote-endpoint = <&lvds_enc_out>;
++ };
++ };
++ };
++
++ radio: si468x@0 {
++ compatible = "si,si468x-pcm";
++ status = "okay";
++
++ #sound-dai-cells = <0>;
++ };
++};
++
++&pfc {
++ hscif4_pins: hscif4 {
++ groups = "hscif4_data_a", "hscif4_ctrl";
++ function = "hscif4";
++ };
++
++ sdhi3_pins_3v3: sd3_3v3 {
++ groups = "sdhi3_data4", "sdhi3_ctrl";
++ function = "sdhi3";
++ power-source = <3300>;
++ };
++
++ sound_0_pins: sound0 {
++ groups = "ssi78_ctrl", "ssi7_data", "ssi8_data";
++ function = "ssi";
++ };
++
++ sound_1_pins: sound1 {
++ groups = "ssi01239_ctrl", "ssi0_data", "ssi1_data_a";
++ function = "ssi";
++ };
++
++ sound_2_pins: sound2 {
++ groups = "ssi6_ctrl", "ssi6_data";
++ function = "ssi";
++ };
++
++ usb0_pins: usb0 {
++ groups = "usb0";
++ function = "usb0";
++ };
++
++ can0_pins: can0 {
++ groups = "can0_data_a";
++ function = "can0";
++ };
++
++ can1_pins: can1 {
++ groups = "can1_data";
++ function = "can1";
++ };
++
++ canfd0_pins: canfd0 {
++ groups = "canfd0_data_a";
++ function = "canfd0";
++ };
++
++ canfd1_pins: canfd1 {
++ groups = "canfd1_data";
++ function = "canfd1";
++ };
++};
++
++&du {
++ ports {
++ port@3 {
++ endpoint {
++ remote-endpoint = <&lvds_enc_in>;
++ };
++ };
++ };
++};
++
++&gpio0 {
++ video_a_irq {
++ gpio-hog;
++ gpios = <13 GPIO_ACTIVE_HIGH>;
++ input;
++ line-name = "Video-A irq";
++ };
++
++ video_b_irq {
++ gpio-hog;
++ gpios = <14 GPIO_ACTIVE_HIGH>;
++ input;
++ line-name = "Video-B irq";
++ };
++
++ gpioext_2_20_irq {
++ gpio-hog;
++ gpios = <15 GPIO_ACTIVE_HIGH>;
++ input;
++ line-name = "0x20@i2c2 irq";
++ };
++};
++
++&gpio1 {
++ gpioext_2_21_irq {
++ gpio-hog;
++ gpios = <15 GPIO_ACTIVE_HIGH>;
++ input;
++ line-name = "0x21@i2c2 irq";
++ };
++
++ wifi_irq {
++ gpio-hog;
++ gpios = <25 GPIO_ACTIVE_HIGH>;
++ input;
++ line-name = "wifi irq";
++ };
++};
++
++&gpio5 {
++ touch_irq {
++ gpio-hog;
++ gpios = <6 GPIO_ACTIVE_HIGH>;
++ input;
++ line-name = "touch irq";
++ };
++
++ /* From TI forum */
++ /* BT_AUD_OUT should be pulled low when WL_EN is activated. */
++ /* in case it isn't, wilink8 ends up in one of the test modes that introduces various issues */
++ bt_strap {
++ gpio-hog;
++ gpios = <14 GPIO_ACTIVE_HIGH>;
++ output-low;
++ line-name = "BT strap pin";
++ };
++};
++
++&gpio7 {
++ gpioext_2_21_irq {
++ gpio-hog;
++ gpios = <3 GPIO_ACTIVE_HIGH>;
++ input;
++ line-name = "0x21@i2c4 irq";
++ };
++};
++
++&hscif4 {
++ pinctrl-0 = <&hscif4_pins>;
++ pinctrl-names = "default";
++ uart-has-rtscts;
++
++ status = "okay";
++};
++
++&i2c2 {
++ clock-frequency = <400000>;
++
++ gpio_ext_20: pca9535@20 {
++ compatible = "nxp,pca9535";
++ reg = <0x20>;
++ gpio-controller;
++ #gpio-cells = <2>;
++ interrupt-controller;
++ interrupt-parent = <&gpio0>;
++ interrupts = <15 IRQ_TYPE_EDGE_FALLING>;
++ };
++
++ gpio_ext_21: pca9535@21 {
++ compatible = "nxp,pca9535";
++ reg = <0x21>;
++ gpio-controller;
++ #gpio-cells = <2>;
++ interrupt-controller;
++ interrupt-parent = <&gpio1>;
++ interrupts = <15 IRQ_TYPE_EDGE_FALLING>;
++ };
++
++ i2cswitch2: pca9548@74 {
++ compatible = "nxp,pca9548";
++ #address-cells = <1>;
++ #size-cells = <0>;
++ reg = <0x74>;
++ reset-gpios = <&gpio6 5 GPIO_ACTIVE_LOW>;
++
++ i2c@0 {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ reg = <0>;
++ /* BCM node(s) */
++ };
++
++ i2c@1 {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ reg = <1>;
++ /* USB3.0 HUB node(s) */
++ };
++
++ i2c@2 {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ reg = <2>;
++ /* Power amp node(s) */
++ };
++
++ i2c@3 {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ reg = <3>;
++ /* Radio node(s) */
++ };
++
++ i2c@4 {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ reg = <4>;
++ /* A2B node(s) */
++ };
++
++ i2c@5 {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ reg = <5>;
++ /* PCIe node(s) */
++ };
++
++ i2c@6 {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ reg = <6>;
++ /* LVDS display node(s) */
++
++ polytouch: edt-ft5x06@38 {
++ compatible = "edt,edt-ft5x06";
++ reg = <0x38>;
++ interrupt-parent = <&gpio5>;
++ interrupts = <6 IRQ_TYPE_EDGE_FALLING>;
++ };
++ };
++
++ i2c@7 {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ reg = <7>;
++ /* Audio, GPS and Gyro node(s) */
++
++ pcm3168a: audio-codec@44 {
++ #sound-dai-cells = <0>;
++ compatible = "ti,pcm3168a";
++ reg = <0x44>;
++ clocks = <&snd_clk>;
++ clock-names = "scki";
++ tdm;
++ VDD1-supply = <&codec_en_reg>;
++ VDD2-supply = <&codec_en_reg>;
++ VCCAD1-supply = <&codec_en_reg>;
++ VCCAD2-supply = <&codec_en_reg>;
++ VCCDA1-supply = <&amp_en_reg>;
++ VCCDA2-supply = <&amp_en_reg>;
++ };
++
++ lsm9ds0_acc_mag@1d {
++ compatible = "st,lsm9ds0_accel_magn";
++ reg = <0x1d>;
++ };
++
++ lsm9ds0_gyr@6b {
++ compatible = "st,lsm9ds0_gyro";
++ reg = <0x6b>;
++ };
++
++ /* GPS@ 0x42 */
++ };
++ };
++};
++
++&i2c4 {
++ gpio_ext_22: pca9535@21 {
++ compatible = "nxp,pca9535";
++ reg = <0x22>;
++ gpio-controller;
++ #gpio-cells = <2>;
++ interrupt-controller;
++ interrupt-parent = <&gpio7>;
++ interrupts = <3 IRQ_TYPE_EDGE_FALLING>;
++
++ cmos_pwdn {
++ gpio-hog;
++ gpios = <8 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "CMOS PWDN";
++ };
++ cmos_rst {
++ gpio-hog;
++ gpios = <9 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "CMOS RST";
++ };
++ /* pin 12 - CAM_CLK */
++ rpi_cam_io_1 {
++ gpio-hog;
++ gpios = <10 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "RaspB_IO1";
++ };
++ /* pin 11 - CAM_GPIO - assume pwdn */
++ rpi_cam_io_0 {
++ gpio-hog;
++ gpios = <11 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "RaspB_IO0";
++ };
++ };
++
++ i2cswitch4: pca9548@74 {
++ compatible = "nxp,pca9548";
++ #address-cells = <1>;
++ #size-cells = <0>;
++ reg = <0x74>;
++ reset-gpios= <&gpio6 21 GPIO_ACTIVE_LOW>;
++
++ i2c@0 {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ reg = <0>;
++ /* SAM node(s) */
++ };
++
++ i2c@1 {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ reg = <1>;
++ /* Slot A (CN10) */
++
++ ov106xx@0 {
++ compatible = "ovti,ov106xx";
++ reg = <0x60>;
++
++ port@0 {
++ ov106xx_in0: endpoint {
++ clock-lanes = <0>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&vin0ep0>;
++ };
++ };
++ port@1 {
++ ov106xx_max9286_des0ep0: endpoint@0 {
++ remote-endpoint = <&max9286_des0ep0>;
++ };
++ ov106xx_ti964_des0ep0: endpoint@1 {
++ remote-endpoint = <&ti964_des0ep0>;
++ };
++ ov106xx_ti954_des0ep0: endpoint@2 {
++ remote-endpoint = <&ti954_des0ep0>;
++ };
++ };
++ };
++
++ ov106xx@1 {
++ compatible = "ovti,ov106xx";
++ reg = <0x61>;
++
++ port@0 {
++ ov106xx_in1: endpoint {
++ clock-lanes = <0>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&vin1ep0>;
++ };
++ };
++ port@1 {
++ ov106xx_max9286_des0ep1: endpoint@0 {
++ remote-endpoint = <&max9286_des0ep1>;
++ };
++ ov106xx_ti964_des0ep1: endpoint@1 {
++ remote-endpoint = <&ti964_des0ep1>;
++ };
++ ov106xx_ti954_des0ep1: endpoint@2 {
++ remote-endpoint = <&ti954_des0ep1>;
++ };
++ };
++ };
++
++ ov106xx@2 {
++ compatible = "ovti,ov106xx";
++ reg = <0x62>;
++
++ port@0 {
++ ov106xx_in2: endpoint {
++ clock-lanes = <0>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&vin2ep0>;
++ };
++ };
++ port@1 {
++ ov106xx_max9286_des0ep2: endpoint@0 {
++ remote-endpoint = <&max9286_des0ep2>;
++ };
++ ov106xx_ti964_des0ep2: endpoint@1 {
++ remote-endpoint = <&ti964_des0ep2>;
++ };
++ };
++ };
++
++ ov106xx@3 {
++ compatible = "ovti,ov106xx";
++ reg = <0x63>;
++
++ port@0 {
++ ov106xx_in3: endpoint {
++ clock-lanes = <0>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&vin3ep0>;
++ };
++ };
++ port@1 {
++ ov106xx_max9286_des0ep3: endpoint@0 {
++ remote-endpoint = <&max9286_des0ep3>;
++ };
++ ov106xx_ti964_des0ep3: endpoint@1 {
++ remote-endpoint = <&ti964_des0ep3>;
++ };
++ };
++ };
++
++ /* DS90UB964 @ 0x3a */
++ ti964-ti9x3@0 {
++ compatible = "ti,ti964-ti9x3";
++ reg = <0x3a>;
++ ti,sensor_delay = <350>;
++ ti,links = <4>;
++ ti,lanes = <4>;
++ ti,forwarding-mode = "round-robin";
++ ti,cable-mode = "coax";
++
++ port@0 {
++ ti964_des0ep0: endpoint@0 {
++ ti9x3-addr = <0x0c>;
++ dvp-order = <0>;
++ remote-endpoint = <&ov106xx_in0>;
++ };
++ ti964_des0ep1: endpoint@1 {
++ ti9x3-addr = <0x0d>;
++ dvp-order = <0>;
++ remote-endpoint = <&ov106xx_in1>;
++ };
++ ti964_des0ep2: endpoint@2 {
++ ti9x3-addr = <0x0e>;
++ dvp-order = <0>;
++ remote-endpoint = <&ov106xx_in2>;
++ };
++ ti964_des0ep3: endpoint@3 {
++ ti9x3-addr = <0x0f>;
++ dvp-order = <0>;
++ remote-endpoint = <&ov106xx_in3>;
++ };
++ };
++ port@1 {
++ ti964_csi0ep0: endpoint {
++ csi-rate = <1450>;
++ remote-endpoint = <&csi2_40_ep>;
++ };
++ };
++ };
++
++ /* DS90UB954 @ 0x38 */
++ ti954-ti9x3@0 {
++ compatible = "ti,ti954-ti9x3";
++ reg = <0x38>;
++ /* gpios = <&video_a_ext1 10 GPIO_ACTIVE_HIGH>; */
++ ti,sensor_delay = <350>;
++ ti,links = <2>;
++ ti,lanes = <4>;
++ ti,forwarding-mode = "round-robin";
++ ti,cable-mode = "coax";
++
++ port@0 {
++ ti954_des0ep0: endpoint@0 {
++ ti9x3-addr = <0x0c>;
++ dvp-order = <0>;
++ remote-endpoint = <&ov106xx_in0>;
++ };
++ ti954_des0ep1: endpoint@1 {
++ ti9x3-addr = <0x0d>;
++ dvp-order = <0>;
++ remote-endpoint = <&ov106xx_in1>;
++ };
++ };
++ port@1 {
++ ti954_csi0ep0: endpoint {
++ csi-rate = <1450>;
++ remote-endpoint = <&csi2_40_ep>;
++ };
++ };
++ };
++
++ /* MAX9286 @ 0x2c */
++ max9286-max9271@0 {
++ compatible = "maxim,max9286-max9271";
++ reg = <0x2c>;
++ maxim,sensor_delay = <350>;
++ maxim,links = <4>;
++ maxim,lanes = <4>;
++ maxim,resetb-gpio = <1>;
++ maxim,fsync-mode = "automatic";
++ maxim,timeout = <100>;
++
++ port@0 {
++ max9286_des0ep0: endpoint@0 {
++ max9271-addr = <0x50>;
++ dvp-order = <1>;
++ remote-endpoint = <&ov106xx_in0>;
++ };
++ max9286_des0ep1: endpoint@1 {
++ max9271-addr = <0x51>;
++ dvp-order = <1>;
++ remote-endpoint = <&ov106xx_in1>;
++ };
++ max9286_des0ep2: endpoint@2 {
++ max9271-addr = <0x52>;
++ dvp-order = <1>;
++ remote-endpoint = <&ov106xx_in2>;
++ };
++ max9286_des0ep3: endpoint@3 {
++ max9271-addr = <0x53>;
++ dvp-order = <1>;
++ remote-endpoint = <&ov106xx_in3>;
++ };
++ };
++ port@1 {
++ max9286_csi0ep0: endpoint {
++ csi-rate = <700>;
++ remote-endpoint = <&csi2_40_ep>;
++ };
++ };
++ };
++ };
++
++ i2c@2 {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ reg = <2>;
++ /* Slot B (CN11) */
++
++ ov106xx@4 {
++ compatible = "ovti,ov106xx";
++ reg = <0x64>;
++
++ port@0 {
++ ov106xx_in4: endpoint {
++ clock-lanes = <0>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&vin4ep0>;
++ };
++ };
++ port@1 {
++ ov106xx_max9286_des1ep0: endpoint@0 {
++ remote-endpoint = <&max9286_des1ep0>;
++ };
++ ov106xx_ti964_des1ep0: endpoint@1 {
++ remote-endpoint = <&ti964_des1ep0>;
++ };
++ ov106xx_ti954_des1ep0: endpoint@2 {
++ remote-endpoint = <&ti954_des1ep0>;
++ };
++ };
++ };
++
++ ov106xx@5 {
++ compatible = "ovti,ov106xx";
++ reg = <0x65>;
++
++ port@0 {
++ ov106xx_in5: endpoint {
++ clock-lanes = <0>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&vin5ep0>;
++ };
++ };
++ port@1 {
++ ov106xx_max9286_des1ep1: endpoint@0 {
++ remote-endpoint = <&max9286_des1ep1>;
++ };
++ ov106xx_ti964_des1ep1: endpoint@1 {
++ remote-endpoint = <&ti964_des1ep1>;
++ };
++ ov106xx_ti954_des1ep1: endpoint@2 {
++ remote-endpoint = <&ti954_des1ep1>;
++ };
++ };
++ };
++
++ ov106xx@6 {
++ compatible = "ovti,ov106xx";
++ reg = <0x66>;
++
++ port@0 {
++ ov106xx_in6: endpoint {
++ clock-lanes = <0>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&vin6ep0>;
++ };
++ };
++ port@1 {
++ ov106xx_max9286_des1ep2: endpoint@0 {
++ remote-endpoint = <&max9286_des1ep2>;
++ };
++ ov106xx_ti964_des1ep2: endpoint@1 {
++ remote-endpoint = <&ti964_des1ep2>;
++ };
++ };
++ };
++
++ ov106xx@7 {
++ compatible = "ovti,ov106xx";
++ reg = <0x67>;
++
++ port@0 {
++ ov106xx_in7: endpoint {
++ clock-lanes = <0>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&vin7ep0>;
++ };
++ };
++ port@1 {
++ ov106xx_max9286_des1ep3: endpoint@0 {
++ remote-endpoint = <&max9286_des1ep3>;
++ };
++ ov106xx_ti964_des1ep3: endpoint@1 {
++ remote-endpoint = <&ti964_des1ep3>;
++ };
++ };
++ };
++
++ /* DS90UB964 @ 0x3a */
++ ti964-ti9x3@1 {
++ compatible = "ti,ti964-ti9x3";
++ reg = <0x3a>;
++ ti,sensor_delay = <350>;
++ ti,links = <4>;
++ ti,lanes = <4>;
++ ti,forwarding-mode = "round-robin";
++ ti,cable-mode = "coax";
++
++ port@0 {
++ ti964_des1ep0: endpoint@0 {
++ ti9x3-addr = <0x0c>;
++ dvp-order = <0>;
++ remote-endpoint = <&ov106xx_in4>;
++ };
++ ti964_des1ep1: endpoint@1 {
++ ti9x3-addr = <0x0d>;
++ dvp-order = <0>;
++ remote-endpoint = <&ov106xx_in5>;
++ };
++ ti964_des1ep2: endpoint@2 {
++ ti9x3-addr = <0x0e>;
++ dvp-order = <0>;
++ remote-endpoint = <&ov106xx_in6>;
++ };
++ ti964_des1ep3: endpoint@3 {
++ ti9x3-addr = <0x0f>;
++ dvp-order = <0>;
++ remote-endpoint = <&ov106xx_in7>;
++ };
++ };
++ port@1 {
++ ti964_csi2ep0: endpoint {
++ csi-rate = <1450>;
++ remote-endpoint = <&csi2_41_ep>;
++ };
++ };
++ };
++
++ /* DS90UB954 @ 0x38 */
++ ti954-ti9x3@1 {
++ compatible = "ti,ti954-ti9x3";
++ reg = <0x38>;
++ /* gpios = <&video_b_ext1 10 GPIO_ACTIVE_HIGH>; */
++ ti,sensor_delay = <350>;
++ ti,links = <2>;
++ ti,lanes = <4>;
++ ti,forwarding-mode = "round-robin";
++ ti,cable-mode = "coax";
++
++ port@0 {
++ ti954_des1ep0: endpoint@0 {
++ ti9x3-addr = <0x0c>;
++ dvp-order = <0>;
++ remote-endpoint = <&ov106xx_in4>;
++ };
++ ti954_des1ep1: endpoint@1 {
++ ti9x3-addr = <0x0d>;
++ dvp-order = <0>;
++ remote-endpoint = <&ov106xx_in5>;
++ };
++ };
++ port@1 {
++ ti954_csi2ep0: endpoint {
++ csi-rate = <1450>;
++ remote-endpoint = <&csi2_41_ep>;
++ };
++ };
++ };
++
++ /* MAX9286 @ 0x2c */
++ max9286-max9271@1 {
++ compatible = "maxim,max9286-max9271";
++ reg = <0x2c>;
++ maxim,sensor_delay = <350>;
++ maxim,links = <4>;
++ maxim,lanes = <4>;
++ maxim,resetb-gpio = <1>;
++ maxim,fsync-mode = "automatic";
++ maxim,timeout = <100>;
++
++ port@0 {
++ max9286_des1ep0: endpoint@0 {
++ max9271-addr = <0x50>;
++ dvp-order = <1>;
++ remote-endpoint = <&ov106xx_in4>;
++ };
++ max9286_des1ep1: endpoint@1 {
++ max9271-addr = <0x51>;
++ dvp-order = <1>;
++ remote-endpoint = <&ov106xx_in5>;
++ };
++ max9286_des1ep2: endpoint@2 {
++ max9271-addr = <0x52>;
++ dvp-order = <1>;
++ remote-endpoint = <&ov106xx_in6>;
++ };
++ max9286_des1ep3: endpoint@3 {
++ max9271-addr = <0x53>;
++ dvp-order = <1>;
++ remote-endpoint = <&ov106xx_in7>;
++ };
++ };
++ port@1 {
++ max9286_csi2ep0: endpoint {
++ csi-rate = <700>;
++ remote-endpoint = <&csi2_41_ep>;
++ };
++ };
++ };
++ };
++
++ i2c@3 {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ reg = <3>;
++ /* MOST node(s) */
++ };
++
++ i2c@6 {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ reg = <6>;
++ /* Slot B (CN11) */
++
++ video_b_ext0: pca9535@27 {
++ compatible = "nxp,pca9535";
++ reg = <0x27>;
++ gpio-controller;
++ #gpio-cells = <2>;
++
++ video_b_des_cfg1 {
++ gpio-hog;
++ gpios = <5 GPIO_ACTIVE_HIGH>;
++ input;
++ line-name = "Video-B cfg1";
++ };
++ video_b_des_cfg0 {
++ gpio-hog;
++ gpios = <6 GPIO_ACTIVE_HIGH>;
++ input;
++ line-name = "Video-B cfg0";
++ };
++ video_b_pwr_shdn {
++ gpio-hog;
++ gpios = <3 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "Video-B PWR_SHDN";
++ };
++ video_b_cam_pwr0 {
++ gpio-hog;
++ gpios = <12 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "Video-B PWR0";
++ };
++ video_b_cam_pwr1 {
++ gpio-hog;
++ gpios = <13 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "Video-B PWR1";
++ };
++ video_b_cam_pwr2 {
++ gpio-hog;
++ gpios = <14 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "Video-B PWR2";
++ };
++ video_b_cam_pwr3 {
++ gpio-hog;
++ gpios = <15 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "Video-B PWR3";
++ };
++ video_b_des_shdn {
++ gpio-hog;
++ gpios = <4 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "Video-B DES_SHDN";
++ };
++ video_b_des_led {
++ gpio-hog;
++ gpios = <7 GPIO_ACTIVE_HIGH>;
++ output-low;
++ line-name = "Video-B led";
++ };
++ };
++
++ video_b_ext1: max7325@5c {
++ compatible = "maxim,max7325";
++ reg = <0x5c>;
++ gpio-controller;
++ #gpio-cells = <2>;
++
++ video_b_des_cfg2 {
++ gpio-hog;
++ gpios = <4 GPIO_ACTIVE_HIGH>;
++ input;
++ line-name = "Video-B cfg2";
++ };
++ video_b_des_cfg1 {
++ gpio-hog;
++ gpios = <6 GPIO_ACTIVE_HIGH>;
++ input;
++ line-name = "Video-B cfg1";
++ };
++ video_b_des_cfg0 {
++ gpio-hog;
++ gpios = <7 GPIO_ACTIVE_HIGH>;
++ input;
++ line-name = "Video-B cfg0";
++ };
++ video_b_pwr_shdn {
++ gpio-hog;
++ gpios = <14 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "Video-B PWR_SHDN";
++ };
++ video_b_cam_pwr0 {
++ gpio-hog;
++ gpios = <8 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "Video-B PWR0";
++ };
++ video_b_cam_pwr1 {
++ gpio-hog;
++ gpios = <9 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "Video-B PWR1";
++ };
++ video_b_cam_pwr2 {
++ gpio-hog;
++ gpios = <10 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "Video-B PWR2";
++ };
++ video_b_cam_pwr3 {
++ gpio-hog;
++ gpios = <11 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "Video-B PWR3";
++ };
++ video_b_des_shdn {
++ gpio-hog;
++ gpios = <13 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "Video-B DES_SHDN";
++ };
++ video_b_led {
++ gpio-hog;
++ gpios = <12 GPIO_ACTIVE_HIGH>;
++ output-low;
++ line-name = "Video-B LED";
++ };
++ };
++ };
++
++ i2c@7 {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ reg = <7>;
++ /* Slot A (CN10) */
++
++ video_a_ext0: pca9535@26 {
++ compatible = "nxp,pca9535";
++ reg = <0x26>;
++ gpio-controller;
++ #gpio-cells = <2>;
++
++ video_a_des_cfg1 {
++ gpio-hog;
++ gpios = <5 GPIO_ACTIVE_HIGH>;
++ input;
++ line-name = "Video-A cfg1";
++ };
++ video_a_des_cfg0 {
++ gpio-hog;
++ gpios = <6 GPIO_ACTIVE_HIGH>;
++ input;
++ line-name = "Video-A cfg0";
++ };
++ video_a_pwr_shdn {
++ gpio-hog;
++ gpios = <3 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "Video-A PWR_SHDN";
++ };
++ video_a_cam_pwr0 {
++ gpio-hog;
++ gpios = <12 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "Video-A PWR0";
++ };
++ video_a_cam_pwr1 {
++ gpio-hog;
++ gpios = <13 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "Video-A PWR1";
++ };
++ video_a_cam_pwr2 {
++ gpio-hog;
++ gpios = <14 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "Video-A PWR2";
++ };
++ video_a_cam_pwr3 {
++ gpio-hog;
++ gpios = <15 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "Video-A PWR3";
++ };
++ video_a_des_shdn {
++ gpio-hog;
++ gpios = <4 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "Video-A DES_SHDN";
++ };
++ video_a_des_led {
++ gpio-hog;
++ gpios = <7 GPIO_ACTIVE_HIGH>;
++ output-low;
++ line-name = "Video-A led";
++ };
++ };
++
++ video_a_ext1: max7325@5c {
++ compatible = "maxim,max7325";
++ reg = <0x5c>;
++ gpio-controller;
++ #gpio-cells = <2>;
++
++ video_a_des_cfg2 {
++ gpio-hog;
++ gpios = <4 GPIO_ACTIVE_HIGH>;
++ input;
++ line-name = "Video-A cfg2";
++ };
++ video_a_des_cfg1 {
++ gpio-hog;
++ gpios = <6 GPIO_ACTIVE_HIGH>;
++ input;
++ line-name = "Video-A cfg1";
++ };
++ video_a_des_cfg0 {
++ gpio-hog;
++ gpios = <7 GPIO_ACTIVE_HIGH>;
++ input;
++ line-name = "Video-A cfg0";
++ };
++ video_a_pwr_shdn {
++ gpio-hog;
++ gpios = <14 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "Video-A PWR_SHDN";
++ };
++ video_a_cam_pwr0 {
++ gpio-hog;
++ gpios = <8 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "Video-A PWR0";
++ };
++ video_a_cam_pwr1 {
++ gpio-hog;
++ gpios = <9 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "Video-A PWR1";
++ };
++ video_a_cam_pwr2 {
++ gpio-hog;
++ gpios = <10 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "Video-A PWR2";
++ };
++ video_a_cam_pwr3 {
++ gpio-hog;
++ gpios = <11 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "Video-A PWR3";
++ };
++ video_a_des_shdn {
++ gpio-hog;
++ gpios = <13 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "Video-A DES_SHDN";
++ };
++ video_a_led {
++ gpio-hog;
++ gpios = <12 GPIO_ACTIVE_HIGH>;
++ output-low;
++ line-name = "Video-A LED";
++ };
++ };
++ };
++ };
++};
++
++&pcie_bus_clk {
++ clock-frequency = <100000000>;
++ status = "okay";
++};
++
++&pciec0 {
++ status = "okay";
++};
++
++&pciec1 {
++ status = "okay";
++};
++
++&vin0 {
++ status = "okay";
++
++ ports {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ port@0 {
++ vin0ep0: endpoint {
++ csi,select = "csi40";
++ virtual,channel = <0>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&ov106xx_in0>;
++ };
++ };
++ port@1 {
++ csi0ep0: endpoint {
++ remote-endpoint = <&csi2_40_ep>;
++ };
++ };
++ port@2 {
++ vin0_max9286_des0ep0: endpoint@0 {
++ remote-endpoint = <&max9286_des0ep0>;
++ };
++ vin0_ti964_des0ep0: endpoint@1 {
++ remote-endpoint = <&ti964_des0ep0>;
++ };
++ vin0_ti954_des0ep0: endpoint@2 {
++ remote-endpoint = <&ti954_des0ep0>;
++ };
++ };
++ };
++};
++
++&vin1 {
++ status = "okay";
++
++ ports {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ port@0 {
++ vin1ep0: endpoint {
++ csi,select = "csi40";
++ virtual,channel = <1>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&ov106xx_in1>;
++ };
++ };
++ port@1 {
++ csi0ep1: endpoint {
++ remote-endpoint = <&csi2_40_ep>;
++ };
++ };
++ port@2 {
++ vin1_max9286_des0ep1: endpoint@0 {
++ remote-endpoint = <&max9286_des0ep1>;
++ };
++ vin1_ti964_des0ep1: endpoint@1 {
++ remote-endpoint = <&ti964_des0ep1>;
++ };
++ vin1_ti954_des0ep1: endpoint@2 {
++ remote-endpoint = <&ti954_des0ep1>;
++ };
++ };
++ };
++};
++
++&vin2 {
++ status = "okay";
++
++ ports {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ port@0 {
++ vin2ep0: endpoint {
++ csi,select = "csi40";
++ virtual,channel = <2>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&ov106xx_in2>;
++ };
++ };
++ port@1 {
++ csi0ep2: endpoint {
++ remote-endpoint = <&csi2_40_ep>;
++ };
++ };
++ port@2 {
++ vin2_max9286_des0ep2: endpoint@0 {
++ remote-endpoint = <&max9286_des0ep2>;
++ };
++ vin2_ti964_des0ep2: endpoint@1 {
++ remote-endpoint = <&ti964_des0ep2>;
++ };
++ };
++ };
++};
++
++&vin3 {
++ status = "okay";
++
++ ports {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ port@0 {
++ vin3ep0: endpoint {
++ csi,select = "csi40";
++ virtual,channel = <3>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&ov106xx_in3>;
++ };
++ };
++ port@1 {
++ csi0ep3: endpoint {
++ remote-endpoint = <&csi2_40_ep>;
++ };
++ };
++ port@2 {
++ vin3_max9286_des0ep3: endpoint@0 {
++ remote-endpoint = <&max9286_des0ep3>;
++ };
++ vin3_ti964_des0ep3: endpoint@1 {
++ remote-endpoint = <&ti964_des0ep3>;
++ };
++ };
++ };
++};
++
++&vin4 {
++ status = "okay";
++
++ ports {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ port@0 {
++ vin4ep0: endpoint {
++ csi,select = "csi41";
++ virtual,channel = <0>;
++ remote-endpoint = <&ov106xx_in4>;
++ data-lanes = <1 2 3 4>;
++ };
++ };
++ port@1 {
++ csi2ep0: endpoint {
++ remote-endpoint = <&csi2_41_ep>;
++ };
++ };
++ port@2 {
++ vin4_max9286_des1ep0: endpoint@0 {
++ remote-endpoint = <&max9286_des1ep0>;
++ };
++ vin4_ti964_des1ep0: endpoint@1 {
++ remote-endpoint = <&ti964_des1ep0>;
++ };
++ vin4_ti954_des1ep0: endpoint@2 {
++ remote-endpoint = <&ti954_des1ep0>;
++ };
++ };
++ };
++};
++
++&vin5 {
++ status = "okay";
++
++ ports {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ port@0 {
++ vin5ep0: endpoint@0 {
++ csi,select = "csi41";
++ virtual,channel = <1>;
++ remote-endpoint = <&ov106xx_in5>;
++ data-lanes = <1 2 3 4>;
++ };
++ };
++ port@1 {
++ csi2ep1: endpoint {
++ remote-endpoint = <&csi2_41_ep>;
++ };
++ };
++ port@2 {
++ vin5_max9286_des1ep1: endpoint@0 {
++ remote-endpoint = <&max9286_des1ep1>;
++ };
++ vin5_ti964_des1ep1: endpoint@1 {
++ remote-endpoint = <&ti964_des1ep1>;
++ };
++ vin5_ti954_des1ep1: endpoint@2 {
++ remote-endpoint = <&ti954_des1ep1>;
++ };
++ };
++ };
++};
++
++&vin6 {
++ status = "okay";
++
++ ports {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ port@0 {
++ vin6ep0: endpoint@0 {
++ csi,select = "csi41";
++ virtual,channel = <2>;
++ remote-endpoint = <&ov106xx_in6>;
++ data-lanes = <1 2 3 4>;
++ };
++ };
++ port@1 {
++ csi2ep2: endpoint {
++ remote-endpoint = <&csi2_41_ep>;
++ };
++ };
++ port@2 {
++ vin6_max9286_des1ep2: endpoint@0 {
++ remote-endpoint = <&max9286_des1ep2>;
++ };
++ vin6_ti964_des1ep2: endpoint@1 {
++ remote-endpoint = <&ti964_des1ep2>;
++ };
++ };
++ };
++};
++
++&vin7 {
++ status = "okay";
++
++ ports {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ port@0 {
++ vin7ep0: endpoint@0 {
++ csi,select = "csi41";
++ virtual,channel = <3>;
++ remote-endpoint = <&ov106xx_in7>;
++ data-lanes = <1 2 3 4>;
++ };
++ };
++ port@1 {
++ csi2ep3: endpoint {
++ remote-endpoint = <&csi2_41_ep>;
++ };
++ };
++ port@2 {
++ vin7_max9286_des1ep3: endpoint@0 {
++ remote-endpoint = <&max9286_des1ep3>;
++ };
++ vin7_ti964_des1ep3: endpoint@1 {
++ remote-endpoint = <&ti964_des1ep3>;
++ };
++ };
++ };
++};
++
++&csi2_40 {
++ status = "okay";
++
++ virtual,channel {
++ csi2_vc0 {
++ data,type = "ycbcr422";
++ receive,vc = <0>;
++ };
++ csi2_vc1 {
++ data,type = "ycbcr422";
++ receive,vc = <1>;
++ };
++ csi2_vc2 {
++ data,type = "ycbcr422";
++ receive,vc = <2>;
++ };
++ csi2_vc3 {
++ data,type = "ycbcr422";
++ receive,vc = <3>;
++ };
++ };
++
++ port {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ csi2_40_ep: endpoint {
++ clock-lanes = <0>;
++ data-lanes = <1 2 3 4>;
++ csi-rate = <300>;
++ };
++ };
++};
++
++&csi2_41 {
++ status = "okay";
++
++ virtual,channel {
++ csi2_vc0 {
++ data,type = "ycbcr422";
++ receive,vc = <0>;
++ };
++ csi2_vc1 {
++ data,type = "ycbcr422";
++ receive,vc = <1>;
++ };
++ csi2_vc2 {
++ data,type = "ycbcr422";
++ receive,vc = <2>;
++ };
++ csi2_vc3 {
++ data,type = "ycbcr422";
++ receive,vc = <3>;
++ };
++ };
++
++ port {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ csi2_41_ep: endpoint {
++ clock-lanes = <0>;
++ data-lanes = <1 2 3 4>;
++ csi-rate = <300>;
++ };
++ };
++};
++
++&rcar_sound {
++ pinctrl-0 = <&sound_clk_pins>;
++
++ /* Multi DAI */
++ #sound-dai-cells = <1>;
++
++ rcar_sound,dai {
++ dai0 {
++ playback = <&ssi7>;
++ capture = <&ssi8>;
++ };
++
++ dai1 {
++ playback = <&ssi0 &src0 &dvc0>;
++ capture = <&ssi1 &src1 &dvc1>;
++ };
++
++ dai2 {
++ capture = <&ssi6>;
++ };
++ };
++};
++
++&sdhi3 {
++ pinctrl-0 = <&sdhi3_pins_3v3>;
++ pinctrl-names = "default";
++
++ vmmc-supply = <&wlan_en>;
++ vqmmc-supply = <&vccq_sdhi3>;
++ keep-power-in-suspend;
++ enable-sdio-wakeup;
++ bus-width = <4>;
++ no-1-8-v;
++ non-removable;
++ cap-power-off-card;
++ max-frequency = <26000000>;
++ status = "okay";
++
++ #address-cells = <1>;
++ #size-cells = <0>;
++ wlcore: wlcore@2 {
++ compatible = "ti,wl1837";
++ reg = <2>;
++ interrupt-parent = <&gpio1>;
++ interrupts = <25 IRQ_TYPE_EDGE_RISING>;
++ };
++};
++
++&usb2_phy0 {
++ pinctrl-0 = <&usb0_pins>;
++ pinctrl-names = "default";
++
++ status = "okay";
++};
++
++&hsusb0 {
++ status = "okay";
++};
++
++&ehci0 {
++ status = "okay";
++};
++
++&ohci0 {
++ status = "okay";
++};
++
++&xhci0 {
++ status = "okay";
++};
++
++&msiof1 {
++ status = "disabled";
++};
++
++&can0 {
++ pinctrl-0 = <&can0_pins>;
++ pinctrl-names = "default";
++ status = "okay";
++
++ renesas,can-clock-select = <0x0>;
++};
++
++&can1 {
++ pinctrl-0 = <&can1_pins>;
++ pinctrl-names = "default";
++ status = "okay";
++
++ renesas,can-clock-select = <0x0>;
++};
++
++&canfd {
++ pinctrl-0 = <&canfd0_pins &canfd1_pins>;
++ pinctrl-names = "default";
++ status = "disabled";
++
++ channel0 {
++ status = "okay";
++ };
++
++ channel1 {
++ status = "okay";
++ };
++};
++
++&ssi8 {
++ shared-pin;
++};
++
++/* uncomment to enable CN47: SD on SDHI3 */
++//#include "../ulcb-kf-sd3.dtsi"
++/* CN48 (Raspberry Pi) on VIN4 */
++//#include "ulcb-kf-rpi.dtsi"
++/* CN29: (CMOS camera) on VIN5 */
++//#include "ulcb-kf-cmos.dtsi"
+diff --git a/arch/arm64/boot/dts/renesas/legacy/r8a7795-h3ulcb-kf-v1.dts b/arch/arm64/boot/dts/renesas/legacy/r8a7795-h3ulcb-kf-v1.dts
+new file mode 100644
+index 0000000..14b6f52
+--- /dev/null
++++ b/arch/arm64/boot/dts/renesas/legacy/r8a7795-h3ulcb-kf-v1.dts
+@@ -0,0 +1,465 @@
++/*
++ * Device Tree Source for the H3ULCB Kingfisher V1 board
++ *
++ * Copyright (C) 2017 Renesas Electronics Corp.
++ * Copyright (C) 2017 Cogent Embedded, Inc.
++ *
++ * This file is licensed under the terms of the GNU General Public License
++ * version 2. This program is licensed "as is" without any warranty of any
++ * kind, whether express or implied.
++ */
++
++#include "r8a7795-h3ulcb-kf-v0.dts"
++
++/ {
++ model = "Renesas H3ULCB Kingfisher V1 board based on r8a7795";
++
++ aliases {
++ serial1 = &hscif0;
++ serial2 = &hscif1;
++ serial3 = &scif1;
++ };
++
++ wlan_en: regulator@4 {
++ compatible = "regulator-fixed";
++ regulator-name = "wlan-en-regulator";
++
++ regulator-min-microvolt = <3300000>;
++ regulator-max-microvolt = <3300000>;
++
++ gpio = <&gpio_ext_74 4 GPIO_ACTIVE_HIGH>;
++ enable-active-high;
++ };
++
++ codec_en_reg: regulator@6 {
++ compatible = "regulator-fixed";
++ regulator-name = "codec-en-regulator";
++ regulator-min-microvolt = <3300000>;
++ regulator-max-microvolt = <3300000>;
++
++ gpio = <&gpio_ext_74 15 0>;
++
++ /* delay - CHECK */
++ startup-delay-us = <70000>;
++ enable-active-high;
++ };
++
++ amp_en_reg: regulator@7 {
++ compatible = "regulator-fixed";
++ regulator-name = "amp-en-regulator";
++ regulator-min-microvolt = <3300000>;
++ regulator-max-microvolt = <3300000>;
++
++ gpio = <&gpio_ext_74 0 0>;
++
++ startup-delay-us = <0>;
++ enable-active-high;
++ };
++
++ /delete-node/regulator@8;
++
++ sdio_switch: regulator@9 {
++ compatible = "regulator-fixed";
++ regulator-name = "wifi_on";
++ regulator-min-microvolt = <3300000>;
++ regulator-max-microvolt = <3300000>;
++ gpio = <&gpio_ext_74 5 0>;
++ enable-active-low;
++ regulator-always-on;
++ };
++
++ /delete-node/regulator@10;
++
++ radio_switch: regulator@11 {
++ compatible = "regulator-fixed";
++ regulator-name = "radio_on";
++ regulator-min-microvolt = <3300000>;
++ regulator-max-microvolt = <3300000>;
++ gpio = <&gpio_ext_74 13 GPIO_ACTIVE_HIGH>;
++ enable-active-high;
++ regulator-always-on;
++ };
++
++ mpcie_3v3: regulator@12 {
++ compatible = "regulator-fixed";
++ regulator-name = "mPCIe 3v3";
++ regulator-min-microvolt = <3300000>;
++ regulator-max-microvolt = <3300000>;
++ gpio = <&gpio_ext_77 14 GPIO_ACTIVE_HIGH>;
++ enable-active-high;
++ };
++
++ mpcie_1v8: regulator@13 {
++ compatible = "regulator-fixed";
++ regulator-name = "mPCIe 1v8";
++ regulator-min-microvolt = <1800000>;
++ regulator-max-microvolt = <1800000>;
++ gpio = <&gpio_ext_77 15 GPIO_ACTIVE_HIGH>;
++ startup-delay-us = <200000>;
++ enable-active-high;
++ };
++
++ kim {
++ shutdown-gpios = <&gpio_ext_74 3 GPIO_ACTIVE_HIGH>;
++ };
++
++ hdmi-out {
++ compatible = "hdmi-connector";
++ type = "a";
++
++ port {
++ hdmi_con: endpoint {
++ remote-endpoint = <&adv7513_out>;
++ };
++ };
++ };
++};
++
++&pfc {
++ /delete-node/hscif4;
++
++ scif1_pins: scif1 {
++ groups = "scif1_data_b";
++ function = "scif1";
++ };
++
++ hscif0_pins: hscif0 {
++ groups = "hscif0_data", "hscif0_ctrl";
++ function = "hscif0";
++ };
++
++ hscif1_pins: hscif1 {
++ groups = "hscif1_data_a", "hscif1_ctrl_a";
++ function = "hscif1";
++ };
++
++ du_pins: du {
++ groups = "du_rgb888", "du_sync", "du_clk_out_0", "du_disp";
++ function = "du";
++ };
++};
++
++&du {
++ pinctrl-0 = <&du_pins>;
++ pinctrl-names = "default";
++
++ ports {
++ port@0 {
++ endpoint {
++ remote-endpoint = <&adv7513_in>;
++ };
++ };
++ };
++};
++
++&gpio0 {
++ /delete-node/video_a_irq;
++ /delete-node/video_b_irq;
++ /delete-node/gpioext_2_20_irq;
++};
++
++&gpio1 {
++ /delete-node/gpioext_2_21_irq;
++ /delete-node/wifi_irq;
++};
++
++&gpio2 {
++ bl_pwm {
++ gpio-hog;
++ gpios = <3 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "BL PWM 100%";
++ };
++};
++
++&gpio5 {
++ /delete-node/touch_irq;
++ /delete-node/bt_strap;
++};
++
++&gpio7 {
++ /delete-node/gpioext_2_21_irq;
++};
++
++&scif1 {
++ pinctrl-0 = <&scif1_pins>;
++ pinctrl-names = "default";
++
++ status = "okay";
++};
++
++&hscif0 {
++ pinctrl-0 = <&hscif0_pins>;
++ pinctrl-names = "default";
++ uart-has-rtscts;
++
++ status = "okay";
++};
++
++&hscif1 {
++ pinctrl-0 = <&hscif1_pins>;
++ pinctrl-names = "default";
++
++ status = "okay";
++};
++
++&hscif4 {
++ /delete-property/pinctrl-0;
++ /delete-property/pinctrl-names;
++
++ status = "disabled";
++};
++
++&i2c2 {
++ /delete-node/pca9535@20;
++ /delete-node/pca9535@21;
++
++ gpio_ext_74: pca9539@74 {
++ compatible = "nxp,pca9539";
++ reg = <0x74>;
++ gpio-controller;
++ #gpio-cells = <2>;
++ interrupt-controller;
++ interrupt-parent = <&gpio6>;
++ interrupts = <8 IRQ_TYPE_EDGE_FALLING>;
++
++ hub_pwen {
++ gpio-hog;
++ gpios = <6 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "HUB pwen";
++ };
++ hub_rst {
++ gpio-hog;
++ gpios = <7 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "HUB rst";
++ };
++ otg_offvbus {
++ gpio-hog;
++ gpios = <8 GPIO_ACTIVE_HIGH>;
++ output-low;
++ line-name = "OTG off VBUSn";
++ };
++ otg_extlpn {
++ gpio-hog;
++ gpios = <9 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "OTG EXTLPn";
++ };
++ otg_stat1 {
++ gpio-hog;
++ gpios = <10 GPIO_ACTIVE_HIGH>;
++ input;
++ line-name = "OTG Stat1";
++ };
++ otg_stat2 {
++ gpio-hog;
++ gpios = <11 GPIO_ACTIVE_HIGH>;
++ input;
++ line-name = "OTG Stat2";
++ };
++ };
++
++ gpio_ext_75: pca9539@75 {
++ compatible = "nxp,pca9539";
++ reg = <0x75>;
++ gpio-controller;
++ #gpio-cells = <2>;
++ interrupt-controller;
++ interrupt-parent = <&gpio6>;
++ interrupts = <4 IRQ_TYPE_EDGE_FALLING>;
++
++ gps_rst {
++ gpio-hog;
++ gpios = <6 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "GPS rst";
++ };
++ fpdl_shdn {
++ gpio-hog;
++ gpios = <9 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "FPDLink shdn";
++ };
++ };
++};
++
++&i2cswitch2 {
++ reg = <0x71>;
++ reset-gpios= <&gpio5 3 GPIO_ACTIVE_LOW>;
++
++ i2c@4 {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ reg = <4>;
++
++ hdmi@3d {
++ compatible = "adi,adv7511w";
++ reg = <0x3d>;
++// interrupt-parent = <&gpio2>;
++// interrupts = <0 IRQ_TYPE_EDGE_BOTH>;
++ pd-gpios = <&gpio_ext_75 5 GPIO_ACTIVE_LOW>;
++
++ adi,input-depth = <8>;
++ adi,input-colorspace = "rgb";
++ adi,input-clock = "1x";
++ adi,input-style = <1>;
++ adi,input-justification = "evenly";
++ adi,clock-delay = <1200>;
++ adi,clock-max-rate = <100000>;
++
++ ports {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ port@0 {
++ reg = <0>;
++ adv7513_in: endpoint {
++ remote-endpoint = <&du_out_rgb>;
++ };
++ };
++
++ port@1 {
++ reg = <1>;
++ adv7513_out: endpoint {
++ remote-endpoint = <&hdmi_con>;
++ };
++ };
++ };
++ };
++ };
++};
++
++&i2c4 {
++ /delete-node/pca9535@21;
++
++ gpio_ext_76: pca9539@76 {
++ compatible = "nxp,pca9539";
++ reg = <0x76>;
++ gpio-controller;
++ #gpio-cells = <2>;
++ interrupt-controller;
++ interrupt-parent = <&gpio7>;
++ interrupts = <3 IRQ_TYPE_EDGE_FALLING>;
++
++ port_b_a0 {
++ gpio-hog;
++ gpios = <0 GPIO_ACTIVE_HIGH>;
++ output-low;
++ line-name = "Video-B A0";
++ };
++ port_b_a1 {
++ gpio-hog;
++ gpios = <1 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "Video-B A1";
++ };
++ port_a_a0 {
++ gpio-hog;
++ gpios = <2 GPIO_ACTIVE_HIGH>;
++ output-low;
++ line-name = "Video-A A0";
++ };
++ port_a_a1 {
++ gpio-hog;
++ gpios = <3 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "Video-A A1";
++ };
++ cmos_pwdn {
++ gpio-hog;
++ gpios = <8 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "CMOS PWDN";
++ };
++ cmos_rst {
++ gpio-hog;
++ gpios = <9 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "CMOS RST";
++ };
++ /* pin 12 - CAM_CLK */
++ rpi_cam_io_1 {
++ gpio-hog;
++ gpios = <10 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "RaspB_IO1";
++ };
++ /* pin 11 - CAM_GPIO - assume pwdn */
++ rpi_cam_io_0 {
++ gpio-hog;
++ gpios = <11 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "RaspB_IO0";
++ };
++ sam_rst {
++ gpio-hog;
++ gpios = <4 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "SAM RST";
++ };
++ sam_pwr {
++ gpio-hog;
++ gpios = <5 GPIO_ACTIVE_HIGH>;
++ output-low;
++ line-name = "SAM PWR";
++ };
++ /* 0 - FPDLink output, 1 - LVDS output */
++ lvds_vs_fpdl {
++ gpio-hog;
++ gpios = <14 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "LVDS switch";
++ };
++ };
++
++ gpio_ext_77: pca9539@77 {
++ compatible = "nxp,pca9539";
++ reg = <0x77>;
++ gpio-controller;
++ #gpio-cells = <2>;
++ interrupt-controller;
++ interrupt-parent = <&gpio5>;
++ interrupts = <9 IRQ_TYPE_EDGE_FALLING>;
++
++ mpcie_wake {
++ gpio-hog;
++ gpios = <0 GPIO_ACTIVE_HIGH>;
++ output-low;
++ line-name = "mPCIe WAKE#";
++ };
++ mpcie_wdisable {
++ gpio-hog;
++ gpios = <1 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "mPCIe W_DISABLE";
++ };
++ mpcie_clreq {
++ gpio-hog;
++ gpios = <2 GPIO_ACTIVE_HIGH>;
++ input;
++ line-name = "mPCIe CLKREQ#";
++ };
++ mpcie_ovc {
++ gpio-hog;
++ gpios = <3 GPIO_ACTIVE_HIGH>;
++ input;
++ line-name = "mPCIe OVC";
++ };
++ };
++};
++
++&i2cswitch4 {
++ reg = <0x71>;
++ reset-gpios= <&gpio3 15 GPIO_ACTIVE_LOW>;
++};
++
++&wlcore {
++ interrupts = <25 IRQ_TYPE_EDGE_FALLING>;
++};
++
++&pciec1 {
++ pcie3v3-supply = <&mpcie_3v3>;
++ pcie1v8-supply = <&mpcie_1v8>;
++};
+diff --git a/arch/arm64/boot/dts/renesas/legacy/r8a7796-m3ulcb-kf-v0.dts b/arch/arm64/boot/dts/renesas/legacy/r8a7796-m3ulcb-kf-v0.dts
+new file mode 100644
+index 0000000..ffa1879
+--- /dev/null
++++ b/arch/arm64/boot/dts/renesas/legacy/r8a7796-m3ulcb-kf-v0.dts
+@@ -0,0 +1,1214 @@
++/*
++ * Device Tree Source for the M3ULCB Kingfisher V0 board on r8a7796
++ *
++ * Copyright (C) 2017 Renesas Electronics Corp.
++ * Copyright (C) 2017 Cogent Embedded, Inc.
++ *
++ * This file is licensed under the terms of the GNU General Public License
++ * version 2. This program is licensed "as is" without any warranty of any
++ * kind, whether express or implied.
++ */
++
++#include "../r8a7796-m3ulcb.dts"
++
++/ {
++ model = "Renesas M3ULCB Kingfisher V0 board based on r8a7796";
++
++ aliases {
++ serial1 = &hscif4;
++ };
++
++ snd_clk: snd_clk {
++ compatible = "fixed-clock";
++ #clock-cells = <0>;
++ clock-frequency = <24576000>;
++ clock-output-names = "scki";
++ };
++
++ wlan_en: regulator@4 {
++ compatible = "regulator-fixed";
++ regulator-name = "wlan-en-regulator";
++
++ regulator-min-microvolt = <3300000>;
++ regulator-max-microvolt = <3300000>;
++
++ gpio = <&gpio_ext_20 4 GPIO_ACTIVE_HIGH>;
++ enable-active-high;
++ };
++
++ vcc_sdhi3: regulator@41 {
++ compatible = "regulator-fixed";
++
++ regulator-name = "SDHI3 Vcc";
++ regulator-min-microvolt = <3300000>;
++ regulator-max-microvolt = <3300000>;
++ regulator-always-on;
++ };
++
++ vccq_sdhi3: regulator@5 {
++ compatible = "regulator-fixed";
++
++ regulator-name = "SDHI3 VccQ";
++ regulator-min-microvolt = <3300000>;
++ regulator-max-microvolt = <3300000>;
++ };
++
++ codec_en_reg: regulator@6 {
++ compatible = "regulator-fixed";
++ regulator-name = "codec-en-regulator";
++ regulator-min-microvolt = <3300000>;
++ regulator-max-microvolt = <3300000>;
++
++ gpio = <&gpio_ext_20 15 0>;
++
++ /* delay - CHECK */
++ startup-delay-us = <70000>;
++ enable-active-high;
++ };
++
++ amp_en_reg: regulator@7 {
++ compatible = "regulator-fixed";
++ regulator-name = "amp-en-regulator";
++ regulator-min-microvolt = <3300000>;
++ regulator-max-microvolt = <3300000>;
++
++ gpio = <&gpio_ext_20 0 0>;
++
++ startup-delay-us = <0>;
++ enable-active-high;
++ };
++
++ lvds_switch: regulator@8 {
++ compatible = "regulator-fixed";
++ regulator-name = "lvds_on";
++ regulator-min-microvolt = <3300000>;
++ regulator-max-microvolt = <3300000>;
++ /* gpio = <&gpio1 24 0>; */
++ enable-active-high;
++ regulator-always-on;
++ };
++
++ sdio_switch: regulator@9 {
++ compatible = "regulator-fixed";
++ regulator-name = "wifi_on";
++ regulator-min-microvolt = <3300000>;
++ regulator-max-microvolt = <3300000>;
++ gpio = <&gpio_ext_20 5 0>;
++ enable-active-low;
++ regulator-always-on;
++ };
++
++ sound_switch: regulator@10 {
++ compatible = "regulator-fixed";
++ regulator-name = "pcm3168a_on";
++ regulator-min-microvolt = <3300000>;
++ regulator-max-microvolt = <3300000>;
++ gpio = <&gpio_ext_21 5 0>;
++ enable-active-low;
++ regulator-always-on;
++ };
++
++ radio_switch: regulator@11 {
++ compatible = "regulator-fixed";
++ regulator-name = "radio_on";
++ regulator-min-microvolt = <3300000>;
++ regulator-max-microvolt = <3300000>;
++ gpio = <&gpio_ext_20 13 GPIO_ACTIVE_HIGH>;
++ enable-active-high;
++ regulator-always-on;
++ };
++
++ kim {
++ compatible = "kim";
++ shutdown-gpios = <&gpio_ext_20 3 GPIO_ACTIVE_HIGH>;
++ /* serial1 */
++ dev_name = "/dev/ttySC1";
++ flow_cntrl = <1>;
++ /* int div 8 hscif@26.6666656MHz */
++ baud_rate = <3333332>;
++ };
++
++ btwilink {
++ compatible = "btwilink";
++ };
++
++ sound_ext: sound@0 {
++ pinctrl-0 = <&sound_0_pins>;
++ pinctrl-names = "default";
++ compatible = "simple-audio-card";
++
++ simple-audio-card,format = "left_j";
++ simple-audio-card,name = "pcm3168a";
++
++ simple-audio-card,bitclock-master = <&sound_ext_master>;
++ simple-audio-card,frame-master = <&sound_ext_master>;
++ sound_ext_master: simple-audio-card,cpu@0 {
++ sound-dai = <&rcar_sound 0>;
++ dai-tdm-slot-num = <8>;
++ dai-tdm-slot-width = <32>;
++ };
++
++ simple-audio-card,codec@0 {
++ sound-dai = <&pcm3168a>;
++ dai-tdm-slot-num = <8>;
++ dai-tdm-slot-width = <32>;
++ system-clock-frequency = <24576000>;
++ };
++ };
++
++ /delete-node/sound;
++
++ rsnd_ak4613: sound@1 {
++ pinctrl-0 = <&sound_1_pins>;
++ pinctrl-names = "default";
++ compatible = "simple-audio-card";
++
++ simple-audio-card,format = "left_j";
++ simple-audio-card,name = "ak4613";
++
++ simple-audio-card,bitclock-master = <&sndcpu>;
++ simple-audio-card,frame-master = <&sndcpu>;
++
++ sndcpu: simple-audio-card,cpu@1 {
++ sound-dai = <&rcar_sound 1>;
++ };
++
++ sndcodec: simple-audio-card,codec@1 {
++ sound-dai = <&ak4613>;
++ };
++ };
++
++ sound_radio: sound@2 {
++ pinctrl-0 = <&sound_2_pins>;
++ pinctrl-names = "default";
++ compatible = "simple-audio-card";
++
++ simple-audio-card,format = "i2s";
++ simple-audio-card,name = "radio";
++
++ simple-audio-card,bitclock-master = <&sound_radio_master>;
++ simple-audio-card,frame-master = <&sound_radio_master>;
++ simple-audio-card,cpu@2 {
++ sound-dai = <&rcar_sound 2>;
++ };
++
++ sound_radio_master: simple-audio-card,codec@2 {
++ sound-dai = <&radio>;
++ system-clock-frequency = <12288000>;
++ };
++ };
++
++ lvds-encoder {
++ compatible = "thine,thc63lvdm83d";
++
++ ports {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ port@0 {
++ reg = <0>;
++ lvds_enc_in: endpoint {
++ remote-endpoint = <&du_out_lvds0>;
++ };
++ };
++ port@1 {
++ reg = <1>;
++ lvds_enc_out: endpoint {
++ remote-endpoint = <&lvds_in>;
++ };
++ };
++ };
++ };
++
++ lvds {
++ compatible = "lvds-connector";
++
++ width-mm = <210>;
++ height-mm = <158>;
++
++ panel-timing {
++ /* 1280x800 @60Hz */
++ clock-frequency = <65000000>;
++ hactive = <1280>;
++ vactive = <800>;
++ hsync-len = <40>;
++ hfront-porch = <80>;
++ hback-porch = <40>;
++ vfront-porch = <14>;
++ vback-porch = <14>;
++ vsync-len = <4>;
++ };
++
++ port {
++ lvds_in: endpoint {
++ remote-endpoint = <&lvds_enc_out>;
++ };
++ };
++ };
++
++ radio: si468x@0 {
++ compatible = "si,si468x-pcm";
++ status = "okay";
++
++ #sound-dai-cells = <0>;
++ };
++};
++
++&pfc {
++ hscif4_pins: hscif4 {
++ groups = "hscif4_data_a", "hscif4_ctrl";
++ function = "hscif4";
++ };
++
++ sdhi3_pins_3v3: sd3_3v3 {
++ groups = "sdhi3_data4", "sdhi3_ctrl";
++ function = "sdhi3";
++ power-source = <3300>;
++ };
++
++ sound_0_pins: sound0 {
++ groups = "ssi78_ctrl", "ssi7_data", "ssi8_data";
++ function = "ssi";
++ };
++
++ sound_1_pins: sound1 {
++ groups = "ssi0129_ctrl", "ssi0_data", "ssi1_data_a";
++ function = "ssi";
++ };
++
++ sound_2_pins: sound2 {
++ groups = "ssi6_ctrl", "ssi6_data";
++ function = "ssi";
++ };
++
++ usb0_pins: usb0 {
++ groups = "usb0";
++ function = "usb0";
++ };
++
++ can0_pins: can0 {
++ groups = "can0_data_a";
++ function = "can0";
++ };
++
++ can1_pins: can1 {
++ groups = "can1_data";
++ function = "can1";
++ };
++
++ canfd0_pins: canfd0 {
++ groups = "canfd0_data_a";
++ function = "canfd0";
++ };
++
++ canfd1_pins: canfd1 {
++ groups = "canfd1_data";
++ function = "canfd1";
++ };
++};
++
++&du {
++ ports {
++ port@2 {
++ endpoint {
++ remote-endpoint = <&lvds_enc_in>;
++ };
++ };
++ };
++};
++
++&gpio0 {
++ video_a_irq {
++ gpio-hog;
++ gpios = <13 GPIO_ACTIVE_HIGH>;
++ input;
++ line-name = "Video-A irq";
++ };
++
++ video_b_irq {
++ gpio-hog;
++ gpios = <14 GPIO_ACTIVE_HIGH>;
++ input;
++ line-name = "Video-B irq";
++ };
++
++ gpioext_2_20_irq {
++ gpio-hog;
++ gpios = <15 GPIO_ACTIVE_HIGH>;
++ input;
++ line-name = "0x20@i2c2 irq";
++ };
++};
++
++&gpio1 {
++ gpioext_2_21_irq {
++ gpio-hog;
++ gpios = <15 GPIO_ACTIVE_HIGH>;
++ input;
++ line-name = "0x21@i2c2 irq";
++ };
++
++ wifi_irq {
++ gpio-hog;
++ gpios = <25 GPIO_ACTIVE_HIGH>;
++ input;
++ line-name = "wifi irq";
++ };
++};
++
++&gpio5 {
++ touch_irq {
++ gpio-hog;
++ gpios = <6 GPIO_ACTIVE_HIGH>;
++ input;
++ line-name = "touch irq";
++ };
++
++ /* From TI forum */
++ /* BT_AUD_OUT should be pulled low when WL_EN is activated. */
++ /* in case it isn't, wilink8 ends up in one of the test modes that introduces various issues */
++ bt_strap {
++ gpio-hog;
++ gpios = <14 GPIO_ACTIVE_HIGH>;
++ output-low;
++ line-name = "BT strap pin";
++ };
++};
++
++&gpio7 {
++ gpioext_2_21_irq {
++ gpio-hog;
++ gpios = <3 GPIO_ACTIVE_HIGH>;
++ input;
++ line-name = "0x21@i2c4 irq";
++ };
++};
++
++&hscif4 {
++ pinctrl-0 = <&hscif4_pins>;
++ pinctrl-names = "default";
++ uart-has-rtscts;
++
++ status = "okay";
++};
++
++&i2c2 {
++ clock-frequency = <400000>;
++
++ gpio_ext_20: pca9535@20 {
++ compatible = "nxp,pca9535";
++ reg = <0x20>;
++ gpio-controller;
++ #gpio-cells = <2>;
++ interrupt-controller;
++ interrupt-parent = <&gpio0>;
++ interrupts = <15 IRQ_TYPE_EDGE_FALLING>;
++ };
++
++ gpio_ext_21: pca9535@21 {
++ compatible = "nxp,pca9535";
++ reg = <0x21>;
++ gpio-controller;
++ #gpio-cells = <2>;
++ interrupt-controller;
++ interrupt-parent = <&gpio1>;
++ interrupts = <15 IRQ_TYPE_EDGE_FALLING>;
++ };
++
++ i2cswitch2: pca9548@74 {
++ compatible = "nxp,pca9548";
++ #address-cells = <1>;
++ #size-cells = <0>;
++ reg = <0x74>;
++ reset-gpios = <&gpio6 5 GPIO_ACTIVE_LOW>;
++
++ i2c@0 {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ reg = <0>;
++ /* BCM node(s) */
++ };
++
++ i2c@1 {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ reg = <1>;
++ /* USB3.0 HUB node(s) */
++ };
++
++ i2c@2 {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ reg = <2>;
++ /* Power amp node(s) */
++ };
++
++ i2c@3 {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ reg = <3>;
++ /* Radio node(s) */
++ };
++
++ i2c@4 {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ reg = <4>;
++ /* A2B node(s) */
++ };
++
++ i2c@5 {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ reg = <5>;
++ /* PCIe node(s) */
++ };
++
++ i2c@6 {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ reg = <6>;
++ /* LVDS display node(s) */
++
++ polytouch: edt-ft5x06@38 {
++ compatible = "edt,edt-ft5x06";
++ reg = <0x38>;
++ interrupt-parent = <&gpio5>;
++ interrupts = <6 IRQ_TYPE_EDGE_FALLING>;
++ };
++ };
++
++ i2c@7 {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ reg = <7>;
++ /* Audio, GPS and Gyro node(s) */
++
++ pcm3168a: audio-codec@44 {
++ #sound-dai-cells = <0>;
++ compatible = "ti,pcm3168a";
++ reg = <0x44>;
++ clocks = <&snd_clk>;
++ clock-names = "scki";
++ tdm;
++ VDD1-supply = <&codec_en_reg>;
++ VDD2-supply = <&codec_en_reg>;
++ VCCAD1-supply = <&codec_en_reg>;
++ VCCAD2-supply = <&codec_en_reg>;
++ VCCDA1-supply = <&amp_en_reg>;
++ VCCDA2-supply = <&amp_en_reg>;
++ };
++
++ lsm9ds0_acc_mag@1d {
++ compatible = "st,lsm9ds0_accel_magn";
++ reg = <0x1d>;
++ };
++
++ lsm9ds0_gyr@6b {
++ compatible = "st,lsm9ds0_gyro";
++ reg = <0x6b>;
++ };
++
++ /* GPS@ 0x42 */
++ };
++ };
++};
++
++&i2c4 {
++ gpio_ext_22: pca9535@21 {
++ compatible = "nxp,pca9535";
++ reg = <0x22>;
++ gpio-controller;
++ #gpio-cells = <2>;
++ interrupt-controller;
++ interrupt-parent = <&gpio7>;
++ interrupts = <3 IRQ_TYPE_EDGE_FALLING>;
++
++ cmos_pwdn {
++ gpio-hog;
++ gpios = <8 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "CMOS PWDN";
++ };
++ cmos_rst {
++ gpio-hog;
++ gpios = <9 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "CMOS RST";
++ };
++ /* pin 12 - CAM_CLK */
++ rpi_cam_io_1 {
++ gpio-hog;
++ gpios = <10 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "RaspB_IO1";
++ };
++ /* pin 11 - CAM_GPIO - assume pwdn */
++ rpi_cam_io_0 {
++ gpio-hog;
++ gpios = <11 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "RaspB_IO0";
++ };
++ };
++
++ i2cswitch4: pca9548@74 {
++ compatible = "nxp,pca9548";
++ #address-cells = <1>;
++ #size-cells = <0>;
++ reg = <0x74>;
++ reset-gpios= <&gpio6 21 GPIO_ACTIVE_LOW>;
++
++ i2c@0 {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ reg = <0>;
++ /* SAM node(s) */
++ };
++
++ i2c@1 {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ reg = <1>;
++ /* Slot A (CN10) */
++
++ ov106xx@0 {
++ compatible = "ovti,ov106xx";
++ reg = <0x60>;
++
++ port@0 {
++ ov106xx_in0: endpoint {
++ clock-lanes = <0>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&vin0ep0>;
++ };
++ };
++ port@1 {
++ ov106xx_max9286_des0ep0: endpoint@0 {
++ remote-endpoint = <&max9286_des0ep0>;
++ };
++ ov106xx_ti964_des0ep0: endpoint@1 {
++ remote-endpoint = <&ti964_des0ep0>;
++ };
++ ov106xx_ti954_des0ep0: endpoint@2 {
++ remote-endpoint = <&ti954_des0ep0>;
++ };
++ };
++ };
++
++ ov106xx@1 {
++ compatible = "ovti,ov106xx";
++ reg = <0x61>;
++
++ port@0 {
++ ov106xx_in1: endpoint {
++ clock-lanes = <0>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&vin1ep0>;
++ };
++ };
++ port@1 {
++ ov106xx_max9286_des0ep1: endpoint@0 {
++ remote-endpoint = <&max9286_des0ep1>;
++ };
++ ov106xx_ti964_des0ep1: endpoint@1 {
++ remote-endpoint = <&ti964_des0ep1>;
++ };
++ ov106xx_ti954_des0ep1: endpoint@2 {
++ remote-endpoint = <&ti954_des0ep1>;
++ };
++ };
++ };
++
++ ov106xx@2 {
++ compatible = "ovti,ov106xx";
++ reg = <0x62>;
++
++ port@0 {
++ ov106xx_in2: endpoint {
++ clock-lanes = <0>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&vin2ep0>;
++ };
++ };
++ port@1 {
++ ov106xx_max9286_des0ep2: endpoint@0 {
++ remote-endpoint = <&max9286_des0ep2>;
++ };
++ ov106xx_ti964_des0ep2: endpoint@1 {
++ remote-endpoint = <&ti964_des0ep2>;
++ };
++ };
++ };
++
++ ov106xx@3 {
++ compatible = "ovti,ov106xx";
++ reg = <0x63>;
++
++ port@0 {
++ ov106xx_in3: endpoint {
++ clock-lanes = <0>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&vin3ep0>;
++ };
++ };
++ port@1 {
++ ov106xx_max9286_des0ep3: endpoint@0 {
++ remote-endpoint = <&max9286_des0ep3>;
++ };
++ ov106xx_ti964_des0ep3: endpoint@1 {
++ remote-endpoint = <&ti964_des0ep3>;
++ };
++ };
++ };
++
++ /* DS90UB964 @ 0x3a */
++ ti964-ti9x3@0 {
++ compatible = "ti,ti964-ti9x3";
++ reg = <0x3a>;
++ ti,sensor_delay = <350>;
++ ti,links = <4>;
++ ti,lanes = <4>;
++ ti,forwarding-mode = "round-robin";
++ ti,cable-mode = "coax";
++
++ port@0 {
++ ti964_des0ep0: endpoint@0 {
++ ti9x3-addr = <0x0c>;
++ dvp-order = <0>;
++ remote-endpoint = <&ov106xx_in0>;
++ };
++ ti964_des0ep1: endpoint@1 {
++ ti9x3-addr = <0x0d>;
++ dvp-order = <0>;
++ remote-endpoint = <&ov106xx_in1>;
++ };
++ ti964_des0ep2: endpoint@2 {
++ ti9x3-addr = <0x0e>;
++ dvp-order = <0>;
++ remote-endpoint = <&ov106xx_in2>;
++ };
++ ti964_des0ep3: endpoint@3 {
++ ti9x3-addr = <0x0f>;
++ dvp-order = <0>;
++ remote-endpoint = <&ov106xx_in3>;
++ };
++ };
++ port@1 {
++ ti964_csi0ep0: endpoint {
++ csi-rate = <1450>;
++ remote-endpoint = <&csi2_40_ep>;
++ };
++ };
++ };
++
++ /* DS90UB954 @ 0x38 */
++ ti954-ti9x3@0 {
++ compatible = "ti,ti954-ti9x3";
++ reg = <0x38>;
++ /* gpios = <&video_a_ext1 10 GPIO_ACTIVE_HIGH>; */
++ ti,sensor_delay = <350>;
++ ti,links = <2>;
++ ti,lanes = <4>;
++ ti,forwarding-mode = "round-robin";
++ ti,cable-mode = "coax";
++
++ port@0 {
++ ti954_des0ep0: endpoint@0 {
++ ti9x3-addr = <0x0c>;
++ dvp-order = <0>;
++ remote-endpoint = <&ov106xx_in0>;
++ };
++ ti954_des0ep1: endpoint@1 {
++ ti9x3-addr = <0x0d>;
++ dvp-order = <0>;
++ remote-endpoint = <&ov106xx_in1>;
++ };
++ };
++ port@1 {
++ ti954_csi0ep0: endpoint {
++ csi-rate = <1450>;
++ remote-endpoint = <&csi2_40_ep>;
++ };
++ };
++ };
++
++ /* MAX9286 @ 0x2c */
++ max9286-max9271@0 {
++ compatible = "maxim,max9286-max9271";
++ reg = <0x2c>;
++ maxim,sensor_delay = <350>;
++ maxim,links = <4>;
++ maxim,lanes = <4>;
++ maxim,resetb-gpio = <1>;
++ maxim,fsync-mode = "automatic";
++ maxim,timeout = <100>;
++
++ port@0 {
++ max9286_des0ep0: endpoint@0 {
++ max9271-addr = <0x50>;
++ dvp-order = <1>;
++ remote-endpoint = <&ov106xx_in0>;
++ };
++ max9286_des0ep1: endpoint@1 {
++ max9271-addr = <0x51>;
++ dvp-order = <1>;
++ remote-endpoint = <&ov106xx_in1>;
++ };
++ max9286_des0ep2: endpoint@2 {
++ max9271-addr = <0x52>;
++ dvp-order = <1>;
++ remote-endpoint = <&ov106xx_in2>;
++ };
++ max9286_des0ep3: endpoint@3 {
++ max9271-addr = <0x53>;
++ dvp-order = <1>;
++ remote-endpoint = <&ov106xx_in3>;
++ };
++ };
++ port@1 {
++ max9286_csi0ep0: endpoint {
++ csi-rate = <700>;
++ remote-endpoint = <&csi2_40_ep>;
++ };
++ };
++ };
++ };
++
++ i2c@3 {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ reg = <3>;
++ /* MOST node(s) */
++ };
++
++ i2c@7 {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ reg = <7>;
++ /* Slot A (CN10) */
++
++ video_a_ext0: pca9535@26 {
++ compatible = "nxp,pca9535";
++ reg = <0x26>;
++ gpio-controller;
++ #gpio-cells = <2>;
++
++ video_a_des_cfg1 {
++ gpio-hog;
++ gpios = <5 GPIO_ACTIVE_HIGH>;
++ input;
++ line-name = "Video-A cfg1";
++ };
++ video_a_des_cfg0 {
++ gpio-hog;
++ gpios = <6 GPIO_ACTIVE_HIGH>;
++ input;
++ line-name = "Video-A cfg0";
++ };
++ video_a_pwr_shdn {
++ gpio-hog;
++ gpios = <3 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "Video-A PWR_SHDN";
++ };
++ video_a_cam_pwr0 {
++ gpio-hog;
++ gpios = <12 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "Video-A PWR0";
++ };
++ video_a_cam_pwr1 {
++ gpio-hog;
++ gpios = <13 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "Video-A PWR1";
++ };
++ video_a_cam_pwr2 {
++ gpio-hog;
++ gpios = <14 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "Video-A PWR2";
++ };
++ video_a_cam_pwr3 {
++ gpio-hog;
++ gpios = <15 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "Video-A PWR3";
++ };
++ video_a_des_shdn {
++ gpio-hog;
++ gpios = <4 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "Video-A DES_SHDN";
++ };
++ video_a_des_led {
++ gpio-hog;
++ gpios = <7 GPIO_ACTIVE_HIGH>;
++ output-low;
++ line-name = "Video-A led";
++ };
++ };
++
++ video_a_ext1: max7325@5c {
++ compatible = "maxim,max7325";
++ reg = <0x5c>;
++ gpio-controller;
++ #gpio-cells = <2>;
++
++ video_a_des_cfg2 {
++ gpio-hog;
++ gpios = <4 GPIO_ACTIVE_HIGH>;
++ input;
++ line-name = "Video-A cfg2";
++ };
++ video_a_des_cfg1 {
++ gpio-hog;
++ gpios = <6 GPIO_ACTIVE_HIGH>;
++ input;
++ line-name = "Video-A cfg1";
++ };
++ video_a_des_cfg0 {
++ gpio-hog;
++ gpios = <7 GPIO_ACTIVE_HIGH>;
++ input;
++ line-name = "Video-A cfg0";
++ };
++ video_a_pwr_shdn {
++ gpio-hog;
++ gpios = <14 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "Video-A PWR_SHDN";
++ };
++ video_a_cam_pwr0 {
++ gpio-hog;
++ gpios = <8 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "Video-A PWR0";
++ };
++ video_a_cam_pwr1 {
++ gpio-hog;
++ gpios = <9 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "Video-A PWR1";
++ };
++ video_a_cam_pwr2 {
++ gpio-hog;
++ gpios = <10 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "Video-A PWR2";
++ };
++ video_a_cam_pwr3 {
++ gpio-hog;
++ gpios = <11 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "Video-A PWR3";
++ };
++ video_a_des_shdn {
++ gpio-hog;
++ gpios = <13 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "Video-A DES_SHDN";
++ };
++ video_a_led {
++ gpio-hog;
++ gpios = <12 GPIO_ACTIVE_HIGH>;
++ output-low;
++ line-name = "Video-A LED";
++ };
++ };
++ };
++ };
++};
++
++&pcie_bus_clk {
++ clock-frequency = <100000000>;
++ status = "okay";
++};
++
++&pciec0 {
++ status = "okay";
++};
++
++&pciec1 {
++ status = "okay";
++};
++
++&vin0 {
++ status = "okay";
++
++ ports {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ port@0 {
++ vin0ep0: endpoint {
++ csi,select = "csi40";
++ virtual,channel = <0>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&ov106xx_in0>;
++ };
++ };
++ port@1 {
++ csi0ep0: endpoint {
++ remote-endpoint = <&csi2_40_ep>;
++ };
++ };
++ port@2 {
++ vin0_max9286_des0ep0: endpoint@0 {
++ remote-endpoint = <&max9286_des0ep0>;
++ };
++ vin0_ti964_des0ep0: endpoint@1 {
++ remote-endpoint = <&ti964_des0ep0>;
++ };
++ vin0_ti954_des0ep0: endpoint@2 {
++ remote-endpoint = <&ti954_des0ep0>;
++ };
++ };
++ };
++};
++
++&vin1 {
++ status = "okay";
++
++ ports {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ port@0 {
++ vin1ep0: endpoint {
++ csi,select = "csi40";
++ virtual,channel = <1>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&ov106xx_in1>;
++ };
++ };
++ port@1 {
++ csi0ep1: endpoint {
++ remote-endpoint = <&csi2_40_ep>;
++ };
++ };
++ port@2 {
++ vin1_max9286_des0ep1: endpoint@0 {
++ remote-endpoint = <&max9286_des0ep1>;
++ };
++ vin1_ti964_des0ep1: endpoint@1 {
++ remote-endpoint = <&ti964_des0ep1>;
++ };
++ vin1_ti954_des0ep1: endpoint@2 {
++ remote-endpoint = <&ti954_des0ep1>;
++ };
++ };
++ };
++};
++
++&vin2 {
++ status = "okay";
++
++ ports {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ port@0 {
++ vin2ep0: endpoint {
++ csi,select = "csi40";
++ virtual,channel = <2>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&ov106xx_in2>;
++ };
++ };
++ port@1 {
++ csi0ep2: endpoint {
++ remote-endpoint = <&csi2_40_ep>;
++ };
++ };
++ port@2 {
++ vin2_max9286_des0ep2: endpoint@0 {
++ remote-endpoint = <&max9286_des0ep2>;
++ };
++ vin2_ti964_des0ep2: endpoint@1 {
++ remote-endpoint = <&ti964_des0ep2>;
++ };
++ };
++ };
++};
++
++&vin3 {
++ status = "okay";
++
++ ports {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ port@0 {
++ vin3ep0: endpoint {
++ csi,select = "csi40";
++ virtual,channel = <3>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&ov106xx_in3>;
++ };
++ };
++ port@1 {
++ csi0ep3: endpoint {
++ remote-endpoint = <&csi2_40_ep>;
++ };
++ };
++ port@2 {
++ vin3_max9286_des0ep3: endpoint@0 {
++ remote-endpoint = <&max9286_des0ep3>;
++ };
++ vin3_ti964_des0ep3: endpoint@1 {
++ remote-endpoint = <&ti964_des0ep3>;
++ };
++ };
++ };
++};
++
++&csi2_40 {
++ status = "okay";
++
++ virtual,channel {
++ csi2_vc0 {
++ data,type = "ycbcr422";
++ receive,vc = <0>;
++ };
++ csi2_vc1 {
++ data,type = "ycbcr422";
++ receive,vc = <1>;
++ };
++ csi2_vc2 {
++ data,type = "ycbcr422";
++ receive,vc = <2>;
++ };
++ csi2_vc3 {
++ data,type = "ycbcr422";
++ receive,vc = <3>;
++ };
++ };
++
++ port {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ csi2_40_ep: endpoint {
++ clock-lanes = <0>;
++ data-lanes = <1 2 3 4>;
++ csi-rate = <300>;
++ };
++ };
++};
++
++&rcar_sound {
++ pinctrl-0 = <&sound_clk_pins>;
++
++ /* Multi DAI */
++ #sound-dai-cells = <1>;
++
++ rcar_sound,dai {
++ dai0 {
++ playback = <&ssi7>;
++ capture = <&ssi8>;
++ };
++
++ dai1 {
++ playback = <&ssi0 &src0 &dvc0>;
++ capture = <&ssi1 &src1 &dvc1>;
++ };
++
++ dai2 {
++ capture = <&ssi6>;
++ };
++ };
++};
++
++&sdhi3 {
++ pinctrl-0 = <&sdhi3_pins_3v3>;
++ pinctrl-names = "default";
++
++ vmmc-supply = <&wlan_en>;
++ vqmmc-supply = <&vccq_sdhi3>;
++ keep-power-in-suspend;
++ enable-sdio-wakeup;
++ bus-width = <4>;
++ no-1-8-v;
++ non-removable;
++ cap-power-off-card;
++ max-frequency = <26000000>;
++ status = "okay";
++
++ #address-cells = <1>;
++ #size-cells = <0>;
++ wlcore: wlcore@2 {
++ compatible = "ti,wl1837";
++ reg = <2>;
++ interrupt-parent = <&gpio1>;
++ interrupts = <25 IRQ_TYPE_EDGE_RISING>;
++ };
++};
++
++&usb2_phy0 {
++ pinctrl-0 = <&usb0_pins>;
++ pinctrl-names = "default";
++
++ status = "okay";
++};
++
++&hsusb {
++ status = "okay";
++};
++
++&ehci0 {
++ status = "okay";
++};
++
++&ohci0 {
++ status = "okay";
++};
++
++&xhci0 {
++ status = "okay";
++};
++
++&msiof1 {
++ status = "disabled";
++};
++
++&can0 {
++ pinctrl-0 = <&can0_pins>;
++ pinctrl-names = "default";
++ status = "okay";
++
++ renesas,can-clock-select = <0x0>;
++};
++
++&can1 {
++ pinctrl-0 = <&can1_pins>;
++ pinctrl-names = "default";
++ status = "okay";
++
++ renesas,can-clock-select = <0x0>;
++};
++
++&canfd {
++ pinctrl-0 = <&canfd0_pins &canfd1_pins>;
++ pinctrl-names = "default";
++ status = "disabled";
++
++ channel0 {
++ status = "okay";
++ };
++
++ channel1 {
++ status = "okay";
++ };
++};
++
++&ssi8 {
++ shared-pin;
++};
++
++/* uncomment to enable CN47: SD on SDHI3 */
++//#include "../ulcb-kf-sd3.dtsi"
++/* CN48 (Raspberry Pi) on VIN4 */
++#include "ulcb-kf-rpi.dtsi"
++/* CN29: (CMOS camera) on VIN5 */
++#include "ulcb-kf-cmos.dtsi"
+diff --git a/arch/arm64/boot/dts/renesas/legacy/r8a7796-m3ulcb-kf-v1.dts b/arch/arm64/boot/dts/renesas/legacy/r8a7796-m3ulcb-kf-v1.dts
+new file mode 100644
+index 0000000..637c840
+--- /dev/null
++++ b/arch/arm64/boot/dts/renesas/legacy/r8a7796-m3ulcb-kf-v1.dts
+@@ -0,0 +1,465 @@
++/*
++ * Device Tree Source for the M3ULCB Kingfisher V1 board
++ *
++ * Copyright (C) 2017 Renesas Electronics Corp.
++ * Copyright (C) 2017 Cogent Embedded, Inc.
++ *
++ * This file is licensed under the terms of the GNU General Public License
++ * version 2. This program is licensed "as is" without any warranty of any
++ * kind, whether express or implied.
++ */
++
++#include "r8a7796-m3ulcb-kf-v0.dts"
++
++/ {
++ model = "Renesas M3ULCB Kingfisher V1 board based on r8a7796";
++
++ aliases {
++ serial1 = &hscif0;
++ serial2 = &hscif1;
++ serial3 = &scif1;
++ };
++
++ wlan_en: regulator@4 {
++ compatible = "regulator-fixed";
++ regulator-name = "wlan-en-regulator";
++
++ regulator-min-microvolt = <3300000>;
++ regulator-max-microvolt = <3300000>;
++
++ gpio = <&gpio_ext_74 4 GPIO_ACTIVE_HIGH>;
++ enable-active-high;
++ };
++
++ codec_en_reg: regulator@6 {
++ compatible = "regulator-fixed";
++ regulator-name = "codec-en-regulator";
++ regulator-min-microvolt = <3300000>;
++ regulator-max-microvolt = <3300000>;
++
++ gpio = <&gpio_ext_74 15 0>;
++
++ /* delay - CHECK */
++ startup-delay-us = <70000>;
++ enable-active-high;
++ };
++
++ amp_en_reg: regulator@7 {
++ compatible = "regulator-fixed";
++ regulator-name = "amp-en-regulator";
++ regulator-min-microvolt = <3300000>;
++ regulator-max-microvolt = <3300000>;
++
++ gpio = <&gpio_ext_74 0 0>;
++
++ startup-delay-us = <0>;
++ enable-active-high;
++ };
++
++ /delete-node/regulator@8;
++
++ sdio_switch: regulator@9 {
++ compatible = "regulator-fixed";
++ regulator-name = "wifi_on";
++ regulator-min-microvolt = <3300000>;
++ regulator-max-microvolt = <3300000>;
++ gpio = <&gpio_ext_74 5 0>;
++ enable-active-low;
++ regulator-always-on;
++ };
++
++ /delete-node/regulator@10;
++
++ radio_switch: regulator@11 {
++ compatible = "regulator-fixed";
++ regulator-name = "radio_on";
++ regulator-min-microvolt = <3300000>;
++ regulator-max-microvolt = <3300000>;
++ gpio = <&gpio_ext_74 13 GPIO_ACTIVE_HIGH>;
++ enable-active-high;
++ regulator-always-on;
++ };
++
++ mpcie_3v3: regulator@12 {
++ compatible = "regulator-fixed";
++ regulator-name = "mPCIe 3v3";
++ regulator-min-microvolt = <3300000>;
++ regulator-max-microvolt = <3300000>;
++ gpio = <&gpio_ext_77 14 GPIO_ACTIVE_HIGH>;
++ enable-active-high;
++ };
++
++ mpcie_1v8: regulator@13 {
++ compatible = "regulator-fixed";
++ regulator-name = "mPCIe 1v8";
++ regulator-min-microvolt = <1800000>;
++ regulator-max-microvolt = <1800000>;
++ gpio = <&gpio_ext_77 15 GPIO_ACTIVE_HIGH>;
++ startup-delay-us = <200000>;
++ enable-active-high;
++ };
++
++ kim {
++ shutdown-gpios = <&gpio_ext_74 3 GPIO_ACTIVE_HIGH>;
++ };
++
++ hdmi-out {
++ compatible = "hdmi-connector";
++ type = "a";
++
++ port {
++ hdmi_con: endpoint {
++ remote-endpoint = <&adv7513_out>;
++ };
++ };
++ };
++};
++
++&pfc {
++ /delete-node/hscif4;
++
++ scif1_pins: scif1 {
++ groups = "scif1_data_b";
++ function = "scif1";
++ };
++
++ hscif0_pins: hscif0 {
++ groups = "hscif0_data", "hscif0_ctrl";
++ function = "hscif0";
++ };
++
++ hscif1_pins: hscif1 {
++ groups = "hscif1_data_a", "hscif1_ctrl_a";
++ function = "hscif1";
++ };
++
++ du_pins: du {
++ groups = "du_rgb888", "du_sync", "du_clk_out_0", "du_disp";
++ function = "du";
++ };
++};
++
++&du {
++ pinctrl-0 = <&du_pins>;
++ pinctrl-names = "default";
++
++ ports {
++ port@0 {
++ endpoint {
++ remote-endpoint = <&adv7513_in>;
++ };
++ };
++ };
++};
++
++&gpio0 {
++ /delete-node/video_a_irq;
++ /delete-node/video_b_irq;
++ /delete-node/gpioext_2_20_irq;
++};
++
++&gpio1 {
++ /delete-node/gpioext_2_21_irq;
++ /delete-node/wifi_irq;
++};
++
++&gpio2 {
++ bl_pwm {
++ gpio-hog;
++ gpios = <3 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "BL PWM 100%";
++ };
++};
++
++&gpio5 {
++ /delete-node/touch_irq;
++ /delete-node/bt_strap;
++};
++
++&gpio7 {
++ /delete-node/gpioext_2_21_irq;
++};
++
++&scif1 {
++ pinctrl-0 = <&scif1_pins>;
++ pinctrl-names = "default";
++
++ status = "okay";
++};
++
++&hscif0 {
++ pinctrl-0 = <&hscif0_pins>;
++ pinctrl-names = "default";
++ uart-has-rtscts;
++
++ status = "okay";
++};
++
++&hscif1 {
++ pinctrl-0 = <&hscif1_pins>;
++ pinctrl-names = "default";
++
++ status = "okay";
++};
++
++&hscif4 {
++ /delete-property/pinctrl-0;
++ /delete-property/pinctrl-names;
++
++ status = "disabled";
++};
++
++&i2c2 {
++ /delete-node/pca9535@20;
++ /delete-node/pca9535@21;
++
++ gpio_ext_74: pca9539@74 {
++ compatible = "nxp,pca9539";
++ reg = <0x74>;
++ gpio-controller;
++ #gpio-cells = <2>;
++ interrupt-controller;
++ interrupt-parent = <&gpio6>;
++ interrupts = <8 IRQ_TYPE_EDGE_FALLING>;
++
++ hub_pwen {
++ gpio-hog;
++ gpios = <6 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "HUB pwen";
++ };
++ hub_rst {
++ gpio-hog;
++ gpios = <7 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "HUB rst";
++ };
++ otg_offvbus {
++ gpio-hog;
++ gpios = <8 GPIO_ACTIVE_HIGH>;
++ output-low;
++ line-name = "OTG off VBUSn";
++ };
++ otg_extlpn {
++ gpio-hog;
++ gpios = <9 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "OTG EXTLPn";
++ };
++ otg_stat1 {
++ gpio-hog;
++ gpios = <10 GPIO_ACTIVE_HIGH>;
++ input;
++ line-name = "OTG Stat1";
++ };
++ otg_stat2 {
++ gpio-hog;
++ gpios = <11 GPIO_ACTIVE_HIGH>;
++ input;
++ line-name = "OTG Stat2";
++ };
++ };
++
++ gpio_ext_75: pca9539@75 {
++ compatible = "nxp,pca9539";
++ reg = <0x75>;
++ gpio-controller;
++ #gpio-cells = <2>;
++ interrupt-controller;
++ interrupt-parent = <&gpio6>;
++ interrupts = <4 IRQ_TYPE_EDGE_FALLING>;
++
++ gps_rst {
++ gpio-hog;
++ gpios = <6 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "GPS rst";
++ };
++ fpdl_shdn {
++ gpio-hog;
++ gpios = <9 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "FPDLink shdn";
++ };
++ };
++};
++
++&i2cswitch2 {
++ reg = <0x71>;
++ reset-gpios= <&gpio5 3 GPIO_ACTIVE_LOW>;
++
++ i2c@4 {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ reg = <4>;
++
++ hdmi@3d {
++ compatible = "adi,adv7511w";
++ reg = <0x3d>;
++// interrupt-parent = <&gpio2>;
++// interrupts = <0 IRQ_TYPE_EDGE_BOTH>;
++ pd-gpios = <&gpio_ext_75 5 GPIO_ACTIVE_LOW>;
++
++ adi,input-depth = <8>;
++ adi,input-colorspace = "rgb";
++ adi,input-clock = "1x";
++ adi,input-style = <1>;
++ adi,input-justification = "evenly";
++ adi,clock-delay = <1200>;
++ adi,clock-max-rate = <100000>;
++
++ ports {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ port@0 {
++ reg = <0>;
++ adv7513_in: endpoint {
++ remote-endpoint = <&du_out_rgb>;
++ };
++ };
++
++ port@1 {
++ reg = <1>;
++ adv7513_out: endpoint {
++ remote-endpoint = <&hdmi_con>;
++ };
++ };
++ };
++ };
++ };
++};
++
++&i2c4 {
++ /delete-node/pca9535@21;
++
++ gpio_ext_76: pca9539@76 {
++ compatible = "nxp,pca9539";
++ reg = <0x76>;
++ gpio-controller;
++ #gpio-cells = <2>;
++ interrupt-controller;
++ interrupt-parent = <&gpio7>;
++ interrupts = <3 IRQ_TYPE_EDGE_FALLING>;
++
++ port_b_a0 {
++ gpio-hog;
++ gpios = <0 GPIO_ACTIVE_HIGH>;
++ output-low;
++ line-name = "Video-B A0";
++ };
++ port_b_a1 {
++ gpio-hog;
++ gpios = <1 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "Video-B A1";
++ };
++ port_a_a0 {
++ gpio-hog;
++ gpios = <2 GPIO_ACTIVE_HIGH>;
++ output-low;
++ line-name = "Video-A A0";
++ };
++ port_a_a1 {
++ gpio-hog;
++ gpios = <3 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "Video-A A1";
++ };
++ cmos_pwdn {
++ gpio-hog;
++ gpios = <8 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "CMOS PWDN";
++ };
++ cmos_rst {
++ gpio-hog;
++ gpios = <9 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "CMOS RST";
++ };
++ /* pin 12 - CAM_CLK */
++ rpi_cam_io_1 {
++ gpio-hog;
++ gpios = <10 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "RaspB_IO1";
++ };
++ /* pin 11 - CAM_GPIO - assume pwdn */
++ rpi_cam_io_0 {
++ gpio-hog;
++ gpios = <11 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "RaspB_IO0";
++ };
++ sam_rst {
++ gpio-hog;
++ gpios = <4 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "SAM RST";
++ };
++ sam_pwr {
++ gpio-hog;
++ gpios = <5 GPIO_ACTIVE_HIGH>;
++ output-low;
++ line-name = "SAM PWR";
++ };
++ /* 0 - FPDLink output, 1 - LVDS output */
++ lvds_vs_fpdl {
++ gpio-hog;
++ gpios = <14 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "LVDS switch";
++ };
++ };
++
++ gpio_ext_77: pca9539@77 {
++ compatible = "nxp,pca9539";
++ reg = <0x77>;
++ gpio-controller;
++ #gpio-cells = <2>;
++ interrupt-controller;
++ interrupt-parent = <&gpio5>;
++ interrupts = <9 IRQ_TYPE_EDGE_FALLING>;
++
++ mpcie_wake {
++ gpio-hog;
++ gpios = <0 GPIO_ACTIVE_HIGH>;
++ output-low;
++ line-name = "mPCIe WAKE#";
++ };
++ mpcie_wdisable {
++ gpio-hog;
++ gpios = <1 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "mPCIe W_DISABLE";
++ };
++ mpcie_clreq {
++ gpio-hog;
++ gpios = <2 GPIO_ACTIVE_HIGH>;
++ input;
++ line-name = "mPCIe CLKREQ#";
++ };
++ mpcie_ovc {
++ gpio-hog;
++ gpios = <3 GPIO_ACTIVE_HIGH>;
++ input;
++ line-name = "mPCIe OVC";
++ };
++ };
++};
++
++&i2cswitch4 {
++ reg = <0x71>;
++ reset-gpios= <&gpio3 15 GPIO_ACTIVE_LOW>;
++};
++
++&wlcore {
++ interrupts = <25 IRQ_TYPE_EDGE_FALLING>;
++};
++
++&pciec1 {
++ pcie3v3-supply = <&mpcie_3v3>;
++ pcie1v8-supply = <&mpcie_1v8>;
++};
+diff --git a/arch/arm64/boot/dts/renesas/legacy/r8a7797-v3msk-kf-v0.dts b/arch/arm64/boot/dts/renesas/legacy/r8a7797-v3msk-kf-v0.dts
+new file mode 100644
+index 0000000..cc04429
+--- /dev/null
++++ b/arch/arm64/boot/dts/renesas/legacy/r8a7797-v3msk-kf-v0.dts
+@@ -0,0 +1,20 @@
++/*
++ * Device Tree Source for the V3MSK Kingfisher V0 board on r8a7797
++ *
++ * Copyright (C) 2017 Renesas Electronics Corp.
++ * Copyright (C) 2017 Cogent Embedded, Inc.
++ *
++ * This file is licensed under the terms of the GNU General Public License
++ * version 2. This program is licensed "as is" without any warranty of any
++ * kind, whether express or implied.
++ */
++
++#include "../r8a7797-v3msk-kf.dts"
++
++/ {
++ model = "Renesas V3MSK Kingfisher V0 board based on r8a7797";
++};
++
++&i2cswitch4 {
++ reg = <0x74>;
++};
+diff --git a/arch/arm64/boot/dts/renesas/legacy/ulcb-kf-cmos.dtsi b/arch/arm64/boot/dts/renesas/legacy/ulcb-kf-cmos.dtsi
+new file mode 100644
+index 0000000..2145f5e
+--- /dev/null
++++ b/arch/arm64/boot/dts/renesas/legacy/ulcb-kf-cmos.dtsi
+@@ -0,0 +1,75 @@
++/*
++ * Device Tree Source for the H3ULCB Kingfisher board:
++ * this adding conflicting resource on VIN5 for CMOS camera
++ *
++ * Copyright (C) 2017 Renesas Electronics Corp.
++ * Copyright (C) 2017 Cogent Embedded, Inc.
++ *
++ * This file is licensed under the terms of the GNU General Public License
++ * version 2. This program is licensed "as is" without any warranty of any
++ * kind, whether express or implied.
++ */
++
++/ {
++ camera_clk: camera_clk {
++ compatible = "fixed-clock";
++ #clock-cells = <0>;
++ clock-frequency = <24000000>;
++ clock-output-names = "mclk";
++ };
++};
++
++&pfc {
++ vin5_pins: vin5 {
++ groups = "vin5_data8", "vin5_sync", "vin5_clk";
++ function = "vin5";
++ };
++};
++
++&i2cswitch4 {
++ i2c@5 {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ reg = <5>;
++
++ cmos_camera: ov5642@3c {
++ compatible = "ovti,ov5642";
++ reg = <0x3c>;
++ clocks = <&camera_clk>;
++ clock-names = "mclk";
++
++ port@0 {
++ cmos_camera_in: endpoint {
++ remote-endpoint = <&vin5ep0>;
++ };
++ };
++ };
++ };
++};
++
++&vin5 {
++ pinctrl-0 = <&vin5_pins>;
++ pinctrl-names = "default";
++ status = "okay";
++
++ ports {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ port@0 {
++ vin5ep0: endpoint@0 {
++ /delete-property/csi,select;
++ /delete-property/virtual,channel;
++ /delete-property/data-lanes;
++ bus-width = <8>;
++ /* #HSYNC, #VSYNC */
++ vsync-active = <1>;
++ hsync-active = <0>;
++ remote-endpoint = <&cmos_camera_in>;
++ };
++ };
++ port@1 {
++ /delete-node/endpoint;
++ };
++ };
++};
+diff --git a/arch/arm64/boot/dts/renesas/legacy/ulcb-kf-rpi.dtsi b/arch/arm64/boot/dts/renesas/legacy/ulcb-kf-rpi.dtsi
+new file mode 100644
+index 0000000..bcd9865
+--- /dev/null
++++ b/arch/arm64/boot/dts/renesas/legacy/ulcb-kf-rpi.dtsi
+@@ -0,0 +1,77 @@
++/*
++ * Device Tree Source for the H3ULCB Kingfisher board:
++ * this adding conflicting resource on VIN4 for Raspberry Pi camera
++ *
++ * Copyright (C) 2017 Renesas Electronics Corp.
++ * Copyright (C) 2017 Cogent Embedded, Inc.
++ *
++ * This file is licensed under the terms of the GNU General Public License
++ * version 2. This program is licensed "as is" without any warranty of any
++ * kind, whether express or implied.
++ */
++
++&i2cswitch4 {
++ i2c@4 {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ reg = <4>;
++
++ rpi_camera: ov5647@36 {
++ compatible = "ovti,ov5647";
++ reg = <0x36>;
++
++ port@0 {
++ rpi_camera_in: endpoint {
++ clock-lanes = <0>;
++ data-lanes = <1 2>;
++ remote-endpoint = <&vin4ep0>;
++ };
++ };
++ };
++ };
++};
++
++&vin4 {
++ status = "okay";
++
++ ports {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ port@0 {
++ vin4ep0: endpoint {
++ csi,select = "csi20";
++ virtual,channel = <0>;
++ remote-endpoint = <&rpi_camera_in>;
++ data-lanes = <1 2>;
++ };
++ };
++ port@1 {
++ csi2ep0: endpoint {
++ remote-endpoint = <&csi2_20_ep>;
++ };
++ };
++ };
++};
++
++&csi2_20 {
++ status = "okay";
++
++ virtual,channel {
++ csi2_vc0 {
++ data,type = "raw8";
++ receive,vc = <0>;
++ };
++ };
++
++ port {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ csi2_20_ep: endpoint {
++ clock-lanes = <0>;
++ data-lanes = <1 2>;
++ csi-rate = <280>;
++ };
++ };
++};
+diff --git a/arch/arm64/boot/dts/renesas/r8a7795-es1-h3ulcb-had-alfa.dts b/arch/arm64/boot/dts/renesas/r8a7795-es1-h3ulcb-had-alfa.dts
+new file mode 100644
+index 0000000..6b13f07
+--- /dev/null
++++ b/arch/arm64/boot/dts/renesas/r8a7795-es1-h3ulcb-had-alfa.dts
+@@ -0,0 +1,22 @@
++/*
++ * Device Tree Source for the H3ULCB.HAD board Alfa side on r8a7795 ES1.x
++ *
++ * Copyright (C) 2017 Renesas Electronics Corp.
++ * Copyright (C) 2017 Cogent Embedded, Inc.
++ *
++ * This file is licensed under the terms of the GNU General Public License
++ * version 2. This program is licensed "as is" without any warranty of any
++ * kind, whether express or implied.
++ */
++
++#include "r8a7795-es1-h3ulcb-had.dtsi"
++
++/ {
++ model = "Renesas H3ULCB.HAD board Alfa side based on r8a7795";
++};
++
++&pciec0 {
++ status = "okay";
++
++ /* Root complex */
++};
+diff --git a/arch/arm64/boot/dts/renesas/r8a7795-es1-h3ulcb-had-beta.dts b/arch/arm64/boot/dts/renesas/r8a7795-es1-h3ulcb-had-beta.dts
+new file mode 100644
+index 0000000..2f8b274
+--- /dev/null
++++ b/arch/arm64/boot/dts/renesas/r8a7795-es1-h3ulcb-had-beta.dts
+@@ -0,0 +1,23 @@
++/*
++ * Device Tree Source for the H3ULCB.HAD board Beta side on r8a7795 ES1.x
++ *
++ * Copyright (C) 2017 Renesas Electronics Corp.
++ * Copyright (C) 2017 Cogent Embedded, Inc.
++ *
++ * This file is licensed under the terms of the GNU General Public License
++ * version 2. This program is licensed "as is" without any warranty of any
++ * kind, whether express or implied.
++ */
++
++#include "r8a7795-es1-h3ulcb-had.dtsi"
++
++/ {
++ model = "Renesas H3ULCB.HAD board Beta side based on r8a7795";
++};
++
++&pciec0 {
++ status = "okay";
++
++ /* Endpoint */
++ endpoint;
++};
+diff --git a/arch/arm64/boot/dts/renesas/r8a7795-es1-h3ulcb-had.dtsi b/arch/arm64/boot/dts/renesas/r8a7795-es1-h3ulcb-had.dtsi
+new file mode 100644
+index 0000000..d50ff7a
+--- /dev/null
++++ b/arch/arm64/boot/dts/renesas/r8a7795-es1-h3ulcb-had.dtsi
+@@ -0,0 +1,225 @@
++/*
++ * Device Tree Source for the H3ULCB.HAD board on r8a7795 ES1.x
++ *
++ * Copyright (C) 2016-2017 Renesas Electronics Corp.
++ * Copyright (C) 2016-2017 Cogent Embedded, Inc.
++ *
++ * This file is licensed under the terms of the GNU General Public License
++ * version 2. This program is licensed "as is" without any warranty of any
++ * kind, whether express or implied.
++ */
++
++/*
++ * MSIOF0 - /dev/spidev1.0 connected to FPGA ethernet switch (both sides)
++ * MSIOF1 - /dev/spidev2.0 connected to RH850 (sideA to CSIH1, sideB to CSIH0)
++ */
++
++#include "r8a7795-es1-h3ulcb-view.dts"
++
++/ {
++ model = "Renesas H3ULCB.HAD board based on r8a7795";
++
++ aliases {
++ serial1 = &scif1;
++ spi1 = &spi0_gpio;
++ spi2 = &spi1_gpio;
++ };
++
++ chosen {
++ stdout-path = "serial1:115200n8";
++ };
++
++ spi0_gpio: spi_gpio@0 {
++ compatible = "spi-gpio";
++ num-chipselects = <1>;
++ gpio-sck = <&gpio5 17 0>;
++ gpio-mosi = <&gpio5 20 0>;
++ gpio-miso = <&gpio5 22 0>;
++ cs-gpios = <&gpio5 19 0>;
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ spidev@0 {
++ compatible = "spi-gpio";
++ reg = <0>;
++ spi-max-frequency = <2000000>;
++ spi-cpha;
++ spi-cpol;
++ };
++ };
++
++ spi1_gpio: spi_gpio@1 {
++ compatible = "spi-gpio";
++ num-chipselects = <1>;
++ gpio-sck = <&gpio6 8 0>;
++ gpio-mosi = <&gpio6 7 0>;
++ gpio-miso = <&gpio6 10 0>;
++ cs-gpios = <&gpio6 5 0>;
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ spidev@0 {
++ compatible = "spi-gpio";
++ reg = <0>;
++ spi-max-frequency = <2000000>;
++ spi-cpha;
++ spi-cpol;
++ };
++ };
++
++ hdmi1-out {
++ compatible = "hdmi-connector";
++ type = "a";
++
++ port {
++ hdmi1_con: endpoint {
++ remote-endpoint = <&rcar_dw_hdmi1_out>;
++ };
++ };
++ };
++};
++
++&du {
++ ports {
++ port@1 {
++ endpoint {
++ remote-endpoint = <&rcar_dw_hdmi0_in>;
++ };
++ };
++ port@2 {
++ endpoint {
++ remote-endpoint = <&rcar_dw_hdmi1_in>;
++ };
++ };
++ };
++};
++
++&hdmi1 {
++ status = "okay";
++
++ ports {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ port@0 {
++ reg = <0>;
++ rcar_dw_hdmi1_in: endpoint {
++ remote-endpoint = <&du_out_hdmi1>;
++ };
++ };
++ port@1 {
++ reg = <1>;
++ rcar_dw_hdmi1_out: endpoint {
++ remote-endpoint = <&hdmi1_con>;
++ };
++ };
++ };
++};
++
++&pfc {
++ scif1_pins: scif1 {
++ groups = "scif1_data_a";
++ function = "scif1";
++ };
++
++ msiof0_pins: spi1 {
++ groups = "msiof0_clk", "msiof0_rxd", "msiof0_txd",
++ "msiof0_ss1";
++ function = "msiof0";
++ };
++
++ msiof1_pins: spi2 {
++ groups = "msiof1_clk_a", "msiof1_rxd_a", "msiof1_txd_a",
++ "msiof1_ss1_a";
++ function = "msiof1";
++ };
++
++ sound_clk_pins: sound-clk {
++ groups = "audio_clk_a_a", "audio_clk_b_a", "audio_clk_c_a",
++ "audio_clkout_a" /*, "audio_clkout3_a"*/;
++ function = "audio_clk";
++ };
++
++ usb31_pins: usb31 {
++ groups = "usb31";
++ function = "usb31";
++ };
++
++ can0_pins: can0 {
++ groups = "can0_data_a";
++ function = "can0";
++ };
++
++ canfd0_pins: canfd0 {
++ groups = "canfd0_data_a";
++ function = "canfd0";
++ };
++};
++
++&scif1 {
++ pinctrl-0 = <&scif1_pins>;
++ pinctrl-names = "default";
++ status = "okay";
++};
++
++&avb {
++ /delete-property/phy-handle;
++ /delete-property/phy-gpios;
++ /delete-node/ethernet-phy@0;
++
++ fixed-link {
++ speed = <1000>;
++ full-duplex;
++ };
++};
++
++&msiof0 {
++ pinctrl-0 = <&msiof0_pins>;
++ pinctrl-names = "default";
++ status = "disabled";
++ cs-gpios = <&gpio5 19 0>;
++
++ spidev@0 {
++ compatible = "renesas,sh-msiof";
++ reg = <0>;
++ spi-max-frequency = <66666666>;
++ spi-cpha;
++ spi-cpol;
++ };
++};
++
++&msiof1 {
++ status = "disabled";
++ cs-gpios = <&gpio6 5 0>;
++};
++
++&can0 {
++ pinctrl-0 = <&can0_pins>;
++ pinctrl-names = "default";
++ status = "disabled";
++
++ renesas,can-clock-select = <0x0>;
++ gpios = <&gpio2 6 GPIO_ACTIVE_HIGH /* enable - shared with camera board */
++ &gpio2 7 GPIO_ACTIVE_LOW /* standby */
++ >;
++};
++
++&canfd {
++ pinctrl-0 = <&canfd0_pins>;
++ pinctrl-names = "default";
++ status = "okay";
++
++ renesas,can-clock-select = <0x0>;
++ gpios = <&gpio2 6 GPIO_ACTIVE_HIGH /* enable - shared with camera board */
++ &gpio2 7 GPIO_ACTIVE_LOW /* standby */
++ >;
++
++ channel0 {
++ status = "okay";
++ };
++};
++
++&xhci1 {
++ status = "okay";
++ pinctrl-0 = <&usb31_pins>;
++ pinctrl-names = "default";
++};
+diff --git a/arch/arm64/boot/dts/renesas/r8a7795-es1-h3ulcb-kf.dts b/arch/arm64/boot/dts/renesas/r8a7795-es1-h3ulcb-kf.dts
+new file mode 100644
+index 0000000..849afae
+--- /dev/null
++++ b/arch/arm64/boot/dts/renesas/r8a7795-es1-h3ulcb-kf.dts
+@@ -0,0 +1,39 @@
++/*
++ * Device Tree Source for the H3ULCB Kingfisher board on r8a7795 ES1.x
++ *
++ * Copyright (C) 2017 Renesas Electronics Corp.
++ * Copyright (C) 2017 Cogent Embedded, Inc.
++ *
++ * This file is licensed under the terms of the GNU General Public License
++ * version 2. This program is licensed "as is" without any warranty of any
++ * kind, whether express or implied.
++ */
++
++#include "r8a7795-es1-h3ulcb.dts"
++#include "ulcb-kf.dtsi"
++
++/ {
++ model = "Renesas H3ULCB Kingfisher board based on r8a7795";
++};
++
++&du {
++ ports {
++ port@0 {
++ endpoint {
++ remote-endpoint = <&adv7513_in>;
++ };
++ };
++ port@3 {
++ endpoint {
++ remote-endpoint = <&lvds_enc_in>;
++ };
++ };
++ };
++};
++
++&hsusb {
++ status = "okay";
++};
++
++/* use CN11 instead default CN29/CN48 (H3 only) */
++//#include "ulcb-kf-cn11.dtsi"
+diff --git a/arch/arm64/boot/dts/renesas/r8a7795-es1-h3ulcb-vb.dts b/arch/arm64/boot/dts/renesas/r8a7795-es1-h3ulcb-vb.dts
+new file mode 100644
+index 0000000..e5734aa
+--- /dev/null
++++ b/arch/arm64/boot/dts/renesas/r8a7795-es1-h3ulcb-vb.dts
+@@ -0,0 +1,1787 @@
++/*
++ * Device Tree Source for the H3ULCB Videobox board on r8a7795 ES1.x
++ *
++ * Copyright (C) 2017 Renesas Electronics Corp.
++ * Copyright (C) 2017 Cogent Embedded, Inc.
++ *
++ * This file is licensed under the terms of the GNU General Public License
++ * version 2. This program is licensed "as is" without any warranty of any
++ * kind, whether express or implied.
++ */
++
++#include "r8a7795-es1-h3ulcb.dts"
++
++/ {
++ model = "Renesas H3ULCB Videobox board based on r8a7795";
++
++ leds {
++ compatible = "gpio-leds";
++
++ led5 {
++ gpios = <&gpio6 12 GPIO_ACTIVE_HIGH>;
++ };
++ led6 {
++ gpios = <&gpio6 13 GPIO_ACTIVE_HIGH>;
++ };
++ /* D13 - status 0 */
++ led_ext00 {
++ gpios = <&gpio_ext_led 0 GPIO_ACTIVE_LOW>;
++ /* linux,default-trigger = "heartbeat"; */
++ };
++ /* D14 - status 1 */
++ led_ext01 {
++ gpios = <&gpio_ext_led 1 GPIO_ACTIVE_LOW>;
++ /* linux,default-trigger = "mmc1"; */
++ };
++ /* D16 - HDMI1 */
++ led_ext02 {
++ gpios = <&gpio_ext_led 2 GPIO_ACTIVE_LOW>;
++ };
++ /* D18 - HDMI0 */
++ led_ext03 {
++ gpios = <&gpio_ext_led 3 GPIO_ACTIVE_LOW>;
++ };
++ /* D20 - USB3.0 - 0.1 */
++ led_ext04 {
++ gpios = <&gpio_ext_led 4 GPIO_ACTIVE_LOW>;
++ };
++ /* D21 - USB3.0 - 0.2 */
++ led_ext05 {
++ gpios = <&gpio_ext_led 5 GPIO_ACTIVE_LOW>;
++ };
++ /* D24 - USB3.0 - 1.1 */
++ led6_ext06 {
++ gpios = <&gpio_ext_led 6 GPIO_ACTIVE_LOW>;
++ };
++ /* D25 - USB3.0 - 1.2 */
++ led_ext07 {
++ gpios = <&gpio_ext_led 7 GPIO_ACTIVE_LOW>;
++ };
++ };
++
++ snd_clk: snd_clk {
++ compatible = "fixed-clock";
++ #clock-cells = <0>;
++ clock-frequency = <24576000>;
++ clock-output-names = "scki";
++ };
++
++ vccq_sdhi3: regulator@5 {
++ compatible = "regulator-fixed";
++
++ regulator-name = "SDHI3 VccQ";
++ /* external voltage translator to 1.8V */
++ regulator-min-microvolt = <3300000>;
++ regulator-max-microvolt = <3300000>;
++ };
++
++ fpdlink_switch: regulator@8 {
++ compatible = "regulator-fixed";
++ regulator-name = "fpdlink_on";
++ regulator-min-microvolt = <3300000>;
++ regulator-max-microvolt = <3300000>;
++ gpio = <&gpio1 20 0>;
++ enable-active-high;
++ regulator-always-on;
++ };
++
++ hub_reset: regulator@9 {
++ compatible = "regulator-fixed";
++ regulator-name = "hub_reset";
++ regulator-min-microvolt = <3300000>;
++ regulator-max-microvolt = <3300000>;
++ gpio = <&gpio5 5 0>;
++ enable-active-high;
++ regulator-always-on;
++ };
++
++ hub_power: regulator@10 {
++ compatible = "regulator-fixed";
++ regulator-name = "hub_power";
++ regulator-min-microvolt = <5000000>;
++ regulator-max-microvolt = <5000000>;
++ gpio = <&gpio6 28 0>;
++ enable-active-high;
++ regulator-always-on;
++ };
++
++ /delete-node/sound;
++
++ rsnd_ak4613: sound@0 {
++ pinctrl-0 = <&sound_0_pins>;
++ pinctrl-names = "default";
++ compatible = "simple-audio-card";
++
++ simple-audio-card,format = "left_j";
++ simple-audio-card,name = "ak4613";
++
++ simple-audio-card,bitclock-master = <&sndcpu>;
++ simple-audio-card,frame-master = <&sndcpu>;
++
++ sndcpu: simple-audio-card,cpu@1 {
++ sound-dai = <&rcar_sound>;
++ };
++
++ sndcodec: simple-audio-card,codec@1 {
++ sound-dai = <&ak4613>;
++ };
++ };
++
++ lvds-encoder {
++ compatible = "thine,thc63lvdm83d";
++
++ ports {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ port@0 {
++ reg = <0>;
++ lvds_enc_in: endpoint {
++ remote-endpoint = <&du_out_lvds0>;
++ };
++ };
++ port@1 {
++ reg = <1>;
++ lvds_enc_out: endpoint {
++ remote-endpoint = <&lvds_in>;
++ };
++ };
++ };
++ };
++
++ lvds {
++ compatible = "lvds-connector";
++
++ width-mm = <210>;
++ height-mm = <158>;
++
++ panel-timing {
++ /* 1280x800 @60Hz */
++ clock-frequency = <65000000>;
++ hactive = <1280>;
++ vactive = <800>;
++ hsync-len = <40>;
++ hfront-porch = <80>;
++ hback-porch = <40>;
++ vfront-porch = <14>;
++ vback-porch = <14>;
++ vsync-len = <4>;
++ };
++
++ port {
++ lvds_in: endpoint {
++ remote-endpoint = <&lvds_enc_out>;
++ };
++ };
++ };
++
++ hdmi1-out {
++ compatible = "hdmi-connector";
++ type = "a";
++
++ port {
++ hdmi1_con: endpoint {
++ remote-endpoint = <&rcar_dw_hdmi1_out>;
++ };
++ };
++ };
++
++ excan_ref_clk: excan-ref-clock {
++ compatible = "fixed-clock";
++ #clock-cells = <0>;
++ clock-frequency = <16000000>;
++ };
++
++ radio: si468x@0 {
++ compatible = "si,si468x-pcm";
++ status = "okay";
++
++ #sound-dai-cells = <0>;
++ };
++
++ spi_gpio_sw {
++ compatible = "spi-gpio";
++ #address-cells = <0x1>;
++ #size-cells = <0x0>;
++ gpio-sck = <&gpio0 8 GPIO_ACTIVE_HIGH>;
++ gpio-miso = <&gpio0 10 GPIO_ACTIVE_HIGH>;
++ gpio-mosi = <&gpio0 11 GPIO_ACTIVE_HIGH>;
++ cs-gpios = <&gpio0 9 GPIO_ACTIVE_HIGH>;
++ num-chipselects = <1>;
++
++ spidev: spidev@0 {
++ compatible = "spidev", "spi-gpio";
++ reg = <0>;
++ spi-max-frequency = <25000000>;
++ spi-cpha;
++ spi-cpol;
++ };
++ };
++
++ spi_gpio_can {
++ compatible = "spi-gpio";
++ #address-cells = <0x1>;
++ #size-cells = <0x0>;
++ gpio-sck = <&gpio1 2 GPIO_ACTIVE_HIGH>;
++ gpio-miso = <&gpio1 3 GPIO_ACTIVE_HIGH>;
++ gpio-mosi = <&gpio1 1 GPIO_ACTIVE_HIGH>;
++ cs-gpios = <&gpio1 0 GPIO_ACTIVE_HIGH
++ &gpio1 4 GPIO_ACTIVE_HIGH>;
++ num-chipselects = <2>;
++
++ spican0: spidev@0 {
++ compatible = "microchip,mcp2515";
++ reg = <0>;
++ clocks = <&excan_ref_clk>;
++ interrupt-parent = <&gpio0>;
++ interrupts = <15 GPIO_ACTIVE_LOW>;
++ spi-max-frequency = <10000000>;
++ };
++ spican1: spidev@1 {
++ compatible = "microchip,mcp2515";
++ reg = <1>;
++ clocks = <&excan_ref_clk>;
++ interrupt-parent = <&gpio1>;
++ interrupts = <5 GPIO_ACTIVE_LOW>;
++ spi-max-frequency = <10000000>;
++ };
++ };
++};
++
++&du {
++ ports {
++ port@1 {
++ endpoint {
++ remote-endpoint = <&rcar_dw_hdmi0_in>;
++ };
++ };
++ port@2 {
++ endpoint {
++ remote-endpoint = <&rcar_dw_hdmi1_in>;
++ };
++ };
++ port@3 {
++ endpoint {
++ remote-endpoint = <&lvds_enc_in>;
++ };
++ };
++ };
++};
++
++&hdmi1 {
++ status = "okay";
++
++ ports {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ port@0 {
++ reg = <0>;
++ rcar_dw_hdmi1_in: endpoint {
++ remote-endpoint = <&du_out_hdmi1>;
++ };
++ };
++ port@1 {
++ reg = <1>;
++ rcar_dw_hdmi1_out: endpoint {
++ remote-endpoint = <&hdmi1_con>;
++ };
++ };
++ };
++};
++
++&pfc {
++ hscif4_pins: hscif4 {
++ groups = "hscif4_data_a", "hscif4_ctrl";
++ function = "hscif4";
++ };
++
++ sdhi3_pins_3v3: sd3_3v3 {
++ groups = "sdhi3_data4", "sdhi3_ctrl";
++ function = "sdhi3";
++ power-source = <3300>;
++ };
++
++ /delete-node/sound;
++
++ sound_0_pins: sound1 {
++ groups = "ssi01239_ctrl", "ssi0_data", "ssi1_data_a";
++ function = "ssi";
++ };
++
++ usb0_pins: usb0 {
++ groups = "usb0";
++ function = "usb0";
++ };
++
++ can0_pins: can0 {
++ groups = "can0_data_a";
++ function = "can0";
++ };
++
++ can1_pins: can1 {
++ groups = "can1_data";
++ function = "can1";
++ };
++
++ canfd0_pins: canfd0 {
++ groups = "canfd0_data_a";
++ function = "canfd0";
++ };
++
++ canfd1_pins: canfd1 {
++ groups = "canfd1_data";
++ function = "canfd1";
++ };
++};
++
++&gpio0 {
++ video_a_irq {
++ gpio-hog;
++ gpios = <12 GPIO_ACTIVE_HIGH>;
++ input;
++ line-name = "Video-A irq";
++ };
++
++ video_b_irq {
++ gpio-hog;
++ gpios = <13 GPIO_ACTIVE_HIGH>;
++ input;
++ line-name = "Video-B irq";
++ };
++
++ video_c_irq {
++ gpio-hog;
++ gpios = <14 GPIO_ACTIVE_HIGH>;
++ input;
++ line-name = "Video-C irq";
++ };
++};
++
++&gpio1 {
++ gpioext_4_22_irq {
++ gpio-hog;
++ gpios = <25 GPIO_ACTIVE_HIGH>;
++ input;
++ line-name = "0x22@i2c4 irq";
++ };
++ pcie_disable {
++ gpio-hog;
++ gpios = <11 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "mPCIe W_DISABLE";
++ };
++ m2_sleep {
++ gpio-hog;
++ gpios = <6 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "M.2 SLEEP#";
++ };
++ m2_pres {
++ gpio-hog;
++ gpios = <7 GPIO_ACTIVE_HIGH>;
++ input;
++ line-name = "M.2 Present";
++ };
++ m2_pcie_det {
++ gpio-hog;
++ gpios = <18 GPIO_ACTIVE_HIGH>;
++ input;
++ line-name = "M.2 PCIe detected";
++ };
++ m2_usb_det {
++ gpio-hog;
++ gpios = <19 GPIO_ACTIVE_HIGH>;
++ input;
++ line-name = "M.2 USB30 detected";
++ };
++ m2_usb_det {
++ gpio-hog;
++ gpios = <27 GPIO_ACTIVE_HIGH>;
++ input;
++ line-name = "M.2 SSD detected";
++ };
++ eth_phy_reset {
++ gpio-hog;
++ gpios = <16 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "BR phy reset";
++ };
++ eth_sw_reset {
++ gpio-hog;
++ gpios = <17 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "BR switch reset";
++ };
++};
++
++&gpio2 {
++ m2_wake {
++ gpio-hog;
++ gpios = <1 GPIO_ACTIVE_HIGH>;
++ input;
++ line-name = "M.2 WAKE#";
++ };
++ m2_pcie_en {
++ gpio-hog;
++ gpios = <4 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "M.2 PCIe enable";
++ };
++};
++
++&gpio3 {
++ m2_power_off {
++ gpio-hog;
++ gpios = <15 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "M.2 FULL_CARD_POWER_OFF#";
++ };
++};
++
++&gpio6 {
++ pcie_wake {
++ gpio-hog;
++ gpios = <4 GPIO_ACTIVE_HIGH>;
++ input;
++ line-name = "mPCIe WAKE#";
++ };
++ pcie_clkreq {
++ gpio-hog;
++ gpios = <10 GPIO_ACTIVE_HIGH>;
++ input;
++ line-name = "mPCIe CLKREQ#";
++ };
++ m2_rst {
++ gpio-hog;
++ gpios = <21 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "M.2 RESET#";
++ };
++};
++
++&hscif4 {
++ pinctrl-0 = <&hscif4_pins>;
++ pinctrl-names = "default";
++ uart-has-rtscts;
++
++ status = "okay";
++};
++
++&i2c2 {
++ clock-frequency = <400000>;
++
++ i2cswitch2: pca9548@74 {
++ compatible = "nxp,pca9548";
++ #address-cells = <1>;
++ #size-cells = <0>;
++ reg = <0x74>;
++ reset-gpios = <&gpio6 5 GPIO_ACTIVE_LOW>;
++
++ i2c@0 {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ reg = <0>;
++ /* USB3.0 HUB node(s) */
++ };
++
++ i2c@6 {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ reg = <6>;
++ /* PCIe node(s) */
++ };
++
++ i2c@7 {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ reg = <7>;
++ /* Slot A (CN10) */
++
++ ov106xx@0 {
++ compatible = "ovti,ov106xx";
++ reg = <0x60>;
++
++ port@0 {
++ ov106xx_in0: endpoint {
++ clock-lanes = <0>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&vin0ep0>;
++ };
++ };
++ port@1 {
++ ov106xx_max9286_des0ep0: endpoint@0 {
++ remote-endpoint = <&max9286_des0ep0>;
++ };
++ ov106xx_ti964_des0ep0: endpoint@1 {
++ remote-endpoint = <&ti964_des0ep0>;
++ };
++ ov106xx_ti954_des0ep0: endpoint@2 {
++ remote-endpoint = <&ti954_des0ep0>;
++ };
++ };
++ };
++
++ ov106xx@1 {
++ compatible = "ovti,ov106xx";
++ reg = <0x61>;
++
++ port@0 {
++ ov106xx_in1: endpoint {
++ clock-lanes = <0>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&vin1ep0>;
++ };
++ };
++ port@1 {
++ ov106xx_max9286_des0ep1: endpoint@0 {
++ remote-endpoint = <&max9286_des0ep1>;
++ };
++ ov106xx_ti964_des0ep1: endpoint@1 {
++ remote-endpoint = <&ti964_des0ep1>;
++ };
++ ov106xx_ti954_des0ep1: endpoint@2 {
++ remote-endpoint = <&ti954_des0ep1>;
++ };
++ };
++ };
++
++ ov106xx@2 {
++ compatible = "ovti,ov106xx";
++ reg = <0x62>;
++
++ port@0 {
++ ov106xx_in2: endpoint {
++ clock-lanes = <0>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&vin2ep0>;
++ };
++ };
++ port@1 {
++ ov106xx_max9286_des0ep2: endpoint@0 {
++ remote-endpoint = <&max9286_des0ep2>;
++ };
++ ov106xx_ti964_des0ep2: endpoint@1 {
++ remote-endpoint = <&ti964_des0ep2>;
++ };
++ };
++ };
++
++ ov106xx@3 {
++ compatible = "ovti,ov106xx";
++ reg = <0x63>;
++
++ port@0 {
++ ov106xx_in3: endpoint {
++ clock-lanes = <0>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&vin3ep0>;
++ };
++ };
++ port@1 {
++ ov106xx_max9286_des0ep3: endpoint@0 {
++ remote-endpoint = <&max9286_des0ep3>;
++ };
++ ov106xx_ti964_des0ep3: endpoint@1 {
++ remote-endpoint = <&ti964_des0ep3>;
++ };
++ };
++ };
++
++ /* DS90UB964 @ 0x3a */
++ ti964-ti9x3@0 {
++ compatible = "ti,ti964-ti9x3";
++ reg = <0x3a>;
++ ti,sensor_delay = <350>;
++ ti,links = <4>;
++ ti,lanes = <4>;
++ ti,forwarding-mode = "round-robin";
++ ti,cable-mode = "stp";
++
++ port@0 {
++ ti964_des0ep0: endpoint@0 {
++ ti9x3-addr = <0x0c>;
++ dvp-order = <0>;
++ remote-endpoint = <&ov106xx_in0>;
++ };
++ ti964_des0ep1: endpoint@1 {
++ ti9x3-addr = <0x0d>;
++ dvp-order = <0>;
++ remote-endpoint = <&ov106xx_in1>;
++ };
++ ti964_des0ep2: endpoint@2 {
++ ti9x3-addr = <0x0e>;
++ dvp-order = <0>;
++ remote-endpoint = <&ov106xx_in2>;
++ };
++ ti964_des0ep3: endpoint@3 {
++ ti9x3-addr = <0x0f>;
++ dvp-order = <0>;
++ remote-endpoint = <&ov106xx_in3>;
++ };
++ };
++ port@1 {
++ ti964_csi0ep0: endpoint {
++ csi-rate = <1450>;
++ remote-endpoint = <&csi2_40_ep>;
++ };
++ };
++ };
++
++ /* DS90UB954 @ 0x38 */
++ ti954-ti9x3@0 {
++ compatible = "ti,ti954-ti9x3";
++ reg = <0x38>;
++ /* gpios = <&video_a_ext1 10 GPIO_ACTIVE_HIGH>; */
++ ti,sensor_delay = <350>;
++ ti,links = <2>;
++ ti,lanes = <4>;
++ ti,forwarding-mode = "round-robin";
++ ti,cable-mode = "stp";
++
++ port@0 {
++ ti954_des0ep0: endpoint@0 {
++ ti9x3-addr = <0x0c>;
++ dvp-order = <0>;
++ remote-endpoint = <&ov106xx_in0>;
++ };
++ ti954_des0ep1: endpoint@1 {
++ ti9x3-addr = <0x0d>;
++ dvp-order = <0>;
++ remote-endpoint = <&ov106xx_in1>;
++ };
++ };
++ port@1 {
++ ti954_csi0ep0: endpoint {
++ csi-rate = <1450>;
++ remote-endpoint = <&csi2_40_ep>;
++ };
++ };
++ };
++
++ /* MAX9286 @ 0x2c */
++ max9286-max9271@0 {
++ compatible = "maxim,max9286-max9271";
++ reg = <0x2c>;
++ maxim,sensor_delay = <350>;
++ maxim,links = <4>;
++ maxim,lanes = <4>;
++ maxim,resetb-gpio = <1>;
++ maxim,fsync-mode = "automatic";
++ maxim,timeout = <100>;
++
++ port@0 {
++ max9286_des0ep0: endpoint@0 {
++ max9271-addr = <0x50>;
++ dvp-order = <1>;
++ remote-endpoint = <&ov106xx_in0>;
++ };
++ max9286_des0ep1: endpoint@1 {
++ max9271-addr = <0x51>;
++ dvp-order = <1>;
++ remote-endpoint = <&ov106xx_in1>;
++ };
++ max9286_des0ep2: endpoint@2 {
++ max9271-addr = <0x52>;
++ dvp-order = <1>;
++ remote-endpoint = <&ov106xx_in2>;
++ };
++ max9286_des0ep3: endpoint@3 {
++ max9271-addr = <0x53>;
++ dvp-order = <1>;
++ remote-endpoint = <&ov106xx_in3>;
++ };
++ };
++ port@1 {
++ max9286_csi0ep0: endpoint {
++ csi-rate = <700>;
++ remote-endpoint = <&csi2_40_ep>;
++ };
++ };
++ };
++ };
++
++ i2c@2 {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ reg = <2>;
++ /* Slot B (CN11) */
++
++ ov106xx@4 {
++ compatible = "ovti,ov106xx";
++ reg = <0x64>;
++
++ port@0 {
++ ov106xx_in4: endpoint {
++ clock-lanes = <0>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&vin4ep0>;
++ };
++ };
++ port@1 {
++ ov106xx_max9286_des1ep0: endpoint@0 {
++ remote-endpoint = <&max9286_des1ep0>;
++ };
++ ov106xx_ti964_des1ep0: endpoint@1 {
++ remote-endpoint = <&ti964_des1ep0>;
++ };
++ ov106xx_ti954_des1ep0: endpoint@2 {
++ remote-endpoint = <&ti954_des1ep0>;
++ };
++ };
++ };
++
++ ov106xx@5 {
++ compatible = "ovti,ov106xx";
++ reg = <0x65>;
++
++ port@0 {
++ ov106xx_in5: endpoint {
++ clock-lanes = <0>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&vin5ep0>;
++ };
++ };
++ port@1 {
++ ov106xx_max9286_des1ep1: endpoint@0 {
++ remote-endpoint = <&max9286_des1ep1>;
++ };
++ ov106xx_ti964_des1ep1: endpoint@1 {
++ remote-endpoint = <&ti964_des1ep1>;
++ };
++ ov106xx_ti954_des1ep1: endpoint@2 {
++ remote-endpoint = <&ti954_des1ep1>;
++ };
++ };
++ };
++
++ ov106xx@6 {
++ compatible = "ovti,ov106xx";
++ reg = <0x66>;
++
++ port@0 {
++ ov106xx_in6: endpoint {
++ clock-lanes = <0>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&vin6ep0>;
++ };
++ };
++ port@1 {
++ ov106xx_max9286_des1ep2: endpoint@0 {
++ remote-endpoint = <&max9286_des1ep2>;
++ };
++ ov106xx_ti964_des1ep2: endpoint@1 {
++ remote-endpoint = <&ti964_des1ep2>;
++ };
++ };
++ };
++
++ ov106xx@7 {
++ compatible = "ovti,ov106xx";
++ reg = <0x67>;
++
++ port@0 {
++ ov106xx_in7: endpoint {
++ clock-lanes = <0>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&vin7ep0>;
++ };
++ };
++ port@1 {
++ ov106xx_max9286_des1ep3: endpoint@0 {
++ remote-endpoint = <&max9286_des1ep3>;
++ };
++ ov106xx_ti964_des1ep3: endpoint@1 {
++ remote-endpoint = <&ti964_des1ep3>;
++ };
++ };
++ };
++
++ /* DS90UB964 @ 0x3a */
++ ti964-ti9x3@1 {
++ compatible = "ti,ti964-ti9x3";
++ reg = <0x3a>;
++ ti,sensor_delay = <350>;
++ ti,links = <4>;
++ ti,lanes = <4>;
++ ti,forwarding-mode = "round-robin";
++ ti,cable-mode = "stp";
++
++ port@0 {
++ ti964_des1ep0: endpoint@0 {
++ ti9x3-addr = <0x0c>;
++ dvp-order = <0>;
++ remote-endpoint = <&ov106xx_in4>;
++ };
++ ti964_des1ep1: endpoint@1 {
++ ti9x3-addr = <0x0d>;
++ dvp-order = <0>;
++ remote-endpoint = <&ov106xx_in5>;
++ };
++ ti964_des1ep2: endpoint@2 {
++ ti9x3-addr = <0x0e>;
++ dvp-order = <0>;
++ remote-endpoint = <&ov106xx_in6>;
++ };
++ ti964_des1ep3: endpoint@3 {
++ ti9x3-addr = <0x0f>;
++ dvp-order = <0>;
++ remote-endpoint = <&ov106xx_in7>;
++ };
++ };
++ port@1 {
++ ti964_csi2ep0: endpoint {
++ csi-rate = <1450>;
++ remote-endpoint = <&csi2_41_ep>;
++ };
++ };
++ };
++
++ /* DS90UB954 @ 0x38 */
++ ti954-ti9x3@1 {
++ compatible = "ti,ti954-ti9x3";
++ reg = <0x38>;
++ /* gpios = <&video_b_ext1 10 GPIO_ACTIVE_HIGH>; */
++ ti,sensor_delay = <350>;
++ ti,links = <2>;
++ ti,lanes = <4>;
++ ti,forwarding-mode = "round-robin";
++ ti,cable-mode = "stp";
++
++ port@0 {
++ ti954_des1ep0: endpoint@0 {
++ ti9x3-addr = <0x0c>;
++ dvp-order = <0>;
++ remote-endpoint = <&ov106xx_in4>;
++ };
++ ti954_des1ep1: endpoint@1 {
++ ti9x3-addr = <0x0d>;
++ dvp-order = <0>;
++ remote-endpoint = <&ov106xx_in5>;
++ };
++ };
++ port@1 {
++ ti954_csi2ep0: endpoint {
++ csi-rate = <1450>;
++ remote-endpoint = <&csi2_41_ep>;
++ };
++ };
++ };
++
++ /* MAX9286 @ 0x2c */
++ max9286-max9271@1 {
++ compatible = "maxim,max9286-max9271";
++ reg = <0x2c>;
++ maxim,sensor_delay = <350>;
++ maxim,links = <4>;
++ maxim,lanes = <4>;
++ maxim,resetb-gpio = <1>;
++ maxim,fsync-mode = "automatic";
++ maxim,timeout = <100>;
++
++ port@0 {
++ max9286_des1ep0: endpoint@0 {
++ max9271-addr = <0x50>;
++ dvp-order = <1>;
++ remote-endpoint = <&ov106xx_in4>;
++ };
++ max9286_des1ep1: endpoint@1 {
++ max9271-addr = <0x51>;
++ dvp-order = <1>;
++ remote-endpoint = <&ov106xx_in5>;
++ };
++ max9286_des1ep2: endpoint@2 {
++ max9271-addr = <0x52>;
++ dvp-order = <1>;
++ remote-endpoint = <&ov106xx_in6>;
++ };
++ max9286_des1ep3: endpoint@3 {
++ max9271-addr = <0x53>;
++ dvp-order = <1>;
++ remote-endpoint = <&ov106xx_in7>;
++ };
++ };
++ port@1 {
++ max9286_csi2ep0: endpoint {
++ csi-rate = <700>;
++ remote-endpoint = <&csi2_41_ep>;
++ };
++ };
++ };
++ };
++
++ i2c@3 {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ reg = <3>;
++ /* Slot C (CN12) */
++ };
++
++ i2c@1 {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ reg = <1>;
++ /* Slot A (CN10) */
++
++ video_a_ext0: pca9535@26 {
++ compatible = "nxp,pca9535";
++ reg = <0x26>;
++ gpio-controller;
++ #gpio-cells = <2>;
++
++ video_a_des_cfg1 {
++ gpio-hog;
++ gpios = <5 GPIO_ACTIVE_HIGH>;
++ input;
++ line-name = "Video-A cfg1";
++ };
++ video_a_des_cfg0 {
++ gpio-hog;
++ gpios = <6 GPIO_ACTIVE_HIGH>;
++ input;
++ line-name = "Video-A cfg0";
++ };
++ video_a_pwr_shdn {
++ gpio-hog;
++ gpios = <3 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "Video-A PWR_SHDN";
++ };
++ video_a_cam_pwr0 {
++ gpio-hog;
++ gpios = <12 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "Video-A PWR0";
++ };
++ video_a_cam_pwr1 {
++ gpio-hog;
++ gpios = <13 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "Video-A PWR1";
++ };
++ video_a_cam_pwr2 {
++ gpio-hog;
++ gpios = <14 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "Video-A PWR2";
++ };
++ video_a_cam_pwr3 {
++ gpio-hog;
++ gpios = <15 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "Video-A PWR3";
++ };
++ video_a_des_shdn {
++ gpio-hog;
++ gpios = <4 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "Video-A DES_SHDN";
++ };
++ video_a_des_led {
++ gpio-hog;
++ gpios = <7 GPIO_ACTIVE_HIGH>;
++ output-low;
++ line-name = "Video-A led";
++ };
++ };
++
++ video_a_ext1: max7325@5c {
++ compatible = "maxim,max7325";
++ reg = <0x5c>;
++ gpio-controller;
++ #gpio-cells = <2>;
++
++ video_a_des_cfg2 {
++ gpio-hog;
++ gpios = <4 GPIO_ACTIVE_HIGH>;
++ input;
++ line-name = "Video-A cfg2";
++ };
++ video_a_des_cfg1 {
++ gpio-hog;
++ gpios = <6 GPIO_ACTIVE_HIGH>;
++ input;
++ line-name = "Video-A cfg1";
++ };
++ video_a_des_cfg0 {
++ gpio-hog;
++ gpios = <7 GPIO_ACTIVE_HIGH>;
++ input;
++ line-name = "Video-A cfg0";
++ };
++ video_a_pwr_shdn {
++ gpio-hog;
++ gpios = <14 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "Video-A PWR_SHDN";
++ };
++ video_a_cam_pwr0 {
++ gpio-hog;
++ gpios = <8 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "Video-A PWR0";
++ };
++ video_a_cam_pwr1 {
++ gpio-hog;
++ gpios = <9 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "Video-A PWR1";
++ };
++ video_a_cam_pwr2 {
++ gpio-hog;
++ gpios = <10 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "Video-A PWR2";
++ };
++ video_a_cam_pwr3 {
++ gpio-hog;
++ gpios = <11 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "Video-A PWR3";
++ };
++ video_a_des_shdn {
++ gpio-hog;
++ gpios = <13 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "Video-A DES_SHDN";
++ };
++ video_a_led {
++ gpio-hog;
++ gpios = <12 GPIO_ACTIVE_HIGH>;
++ output-low;
++ line-name = "Video-A LED";
++ };
++ };
++ };
++
++ i2c@5 {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ reg = <5>;
++ /* Slot B (CN11) */
++
++ video_b_ext0: pca9535@26 {
++ compatible = "nxp,pca9535";
++ reg = <0x26>;
++ gpio-controller;
++ #gpio-cells = <2>;
++
++ video_b_des_cfg1 {
++ gpio-hog;
++ gpios = <5 GPIO_ACTIVE_HIGH>;
++ input;
++ line-name = "Video-B cfg1";
++ };
++ video_b_des_cfg0 {
++ gpio-hog;
++ gpios = <6 GPIO_ACTIVE_HIGH>;
++ input;
++ line-name = "Video-B cfg0";
++ };
++ video_b_pwr_shdn {
++ gpio-hog;
++ gpios = <3 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "Video-B PWR_SHDN";
++ };
++ video_b_cam_pwr0 {
++ gpio-hog;
++ gpios = <12 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "Video-B PWR0";
++ };
++ video_b_cam_pwr1 {
++ gpio-hog;
++ gpios = <13 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "Video-B PWR1";
++ };
++ video_b_cam_pwr2 {
++ gpio-hog;
++ gpios = <14 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "Video-B PWR2";
++ };
++ video_b_cam_pwr3 {
++ gpio-hog;
++ gpios = <15 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "Video-B PWR3";
++ };
++ video_b_des_shdn {
++ gpio-hog;
++ gpios = <4 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "Video-B DES_SHDN";
++ };
++ video_b_des_led {
++ gpio-hog;
++ gpios = <7 GPIO_ACTIVE_HIGH>;
++ output-low;
++ line-name = "Video-B led";
++ };
++ };
++
++ video_b_ext1: max7325@5c {
++ compatible = "maxim,max7325";
++ reg = <0x5c>;
++ gpio-controller;
++ #gpio-cells = <2>;
++
++ video_b_des_cfg2 {
++ gpio-hog;
++ gpios = <4 GPIO_ACTIVE_HIGH>;
++ input;
++ line-name = "Video-B cfg2";
++ };
++ video_b_des_cfg1 {
++ gpio-hog;
++ gpios = <6 GPIO_ACTIVE_HIGH>;
++ input;
++ line-name = "Video-B cfg1";
++ };
++ video_b_des_cfg0 {
++ gpio-hog;
++ gpios = <7 GPIO_ACTIVE_HIGH>;
++ input;
++ line-name = "Video-B cfg0";
++ };
++ video_b_pwr_shdn {
++ gpio-hog;
++ gpios = <14 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "Video-B PWR_SHDN";
++ };
++ video_b_cam_pwr0 {
++ gpio-hog;
++ gpios = <8 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "Video-B PWR0";
++ };
++ video_b_cam_pwr1 {
++ gpio-hog;
++ gpios = <9 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "Video-B PWR1";
++ };
++ video_b_cam_pwr2 {
++ gpio-hog;
++ gpios = <10 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "Video-B PWR2";
++ };
++ video_b_cam_pwr3 {
++ gpio-hog;
++ gpios = <11 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "Video-B PWR3";
++ };
++ video_b_des_shdn {
++ gpio-hog;
++ gpios = <13 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "Video-B DES_SHDN";
++ };
++ video_b_led {
++ gpio-hog;
++ gpios = <12 GPIO_ACTIVE_HIGH>;
++ output-low;
++ line-name = "Video-B LED";
++ };
++ };
++ };
++
++ i2c@4 {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ reg = <4>;
++ /* Slot C (CN12) */
++ };
++ };
++};
++
++&i2c4 {
++ i2cswitch4: pca9548@74 {
++ compatible = "nxp,pca9548";
++ #address-cells = <1>;
++ #size-cells = <0>;
++ reg = <0x74>;
++ reset-gpios= <&gpio5 15 GPIO_ACTIVE_LOW>;
++
++ i2c@0 {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ reg = <0>;
++ /* FAN node - EMC2103 */
++ fan_ctrl:ecm2103@2e {
++ compatible = "emc2103";
++ reg = <0x2e>;
++ };
++ };
++
++ i2c@1 {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ reg = <1>;
++ /* Power nodes - 2 x TPS544x20 */
++ };
++
++ i2c@2 {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ reg = <2>;
++ /* CAN and power board nodes */
++
++ gpio_ext_pwr: pca9535@22 {
++ compatible = "nxp,pca9535";
++ reg = <0x22>;
++ gpio-controller;
++ #gpio-cells = <2>;
++ interrupt-controller;
++ interrupt-parent = <&gpio1>;
++ interrupts = <25 IRQ_TYPE_EDGE_FALLING>;
++
++ /* enable input DCDC after wake-up signal released */
++ pwr_hold {
++ gpio-hog;
++ gpios = <11 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "pwr_hold";
++ };
++
++ /* CAN0 */
++ can0_stby {
++ gpio-hog;
++ gpios = <4 GPIO_ACTIVE_HIGH>;
++ output-low;
++ line-name = "can0_stby";
++ };
++ can0_load {
++ gpio-hog;
++ gpios = <0 GPIO_ACTIVE_HIGH>;
++ output-low;
++ line-name = "can0_120R_load";
++ };
++ /* CAN1 */
++ can1_stby {
++ gpio-hog;
++ gpios = <5 GPIO_ACTIVE_HIGH>;
++ output-low;
++ line-name = "can1_stby";
++ };
++ can1_load {
++ gpio-hog;
++ gpios = <1 GPIO_ACTIVE_HIGH>;
++ output-low;
++ line-name = "can1_120R_load";
++ };
++ /* CAN2 */
++ can2_stby {
++ gpio-hog;
++ gpios = <6 GPIO_ACTIVE_HIGH>;
++ output-low;
++ line-name = "can2_stby";
++ };
++ can2_load {
++ gpio-hog;
++ gpios = <2 GPIO_ACTIVE_HIGH>;
++ output-low;
++ line-name = "can2_120R_load";
++ };
++ can2_rst {
++ gpio-hog;
++ gpios = <8 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "can2_rst";
++ };
++ /* CAN3 */
++ can3_stby {
++ gpio-hog;
++ gpios = <7 GPIO_ACTIVE_HIGH>;
++ output-low;
++ line-name = "can3_stby";
++ };
++ can3_load {
++ gpio-hog;
++ gpios = <3 GPIO_ACTIVE_HIGH>;
++ output-low;
++ line-name = "can3_120R_load";
++ };
++ can3_rst {
++ gpio-hog;
++ gpios = <9 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "can3_rst";
++ };
++ };
++ };
++
++ i2c@3 {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ reg = <3>;
++ /* FPDLink output node - DS90UH947 */
++ };
++
++ i2c@4 {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ reg = <4>;
++ /* BCM switch node */
++ };
++
++ i2c@5 {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ reg = <5>;
++ /* LED board node(s) */
++
++ gpio_ext_led: pca9535@22 {
++ compatible = "nxp,pca9535";
++ reg = <0x22>;
++ gpio-controller;
++ #gpio-cells = <2>;
++
++ /* gpios 0..7 are used for indication LEDs, low-active */
++ };
++ };
++
++ i2c@6 {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ reg = <6>;
++ /* M2 connector i2c node(s) */
++ };
++
++ /* port 7 is not used */
++ };
++};
++
++&pcie_bus_clk {
++ clock-frequency = <100000000>;
++ status = "okay";
++};
++
++&pciec0 {
++ status = "okay";
++};
++
++&pciec1 {
++ status = "okay";
++};
++
++&vin0 {
++ status = "okay";
++
++ ports {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ port@0 {
++ vin0ep0: endpoint {
++ csi,select = "csi40";
++ virtual,channel = <0>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&ov106xx_in0>;
++ };
++ };
++ port@1 {
++ csi0ep0: endpoint {
++ remote-endpoint = <&csi2_40_ep>;
++ };
++ };
++ port@2 {
++ vin0_max9286_des0ep0: endpoint@0 {
++ remote-endpoint = <&max9286_des0ep0>;
++ };
++ vin0_ti964_des0ep0: endpoint@1 {
++ remote-endpoint = <&ti964_des0ep0>;
++ };
++ vin0_ti954_des0ep0: endpoint@2 {
++ remote-endpoint = <&ti954_des0ep0>;
++ };
++ };
++ };
++};
++
++&vin1 {
++ status = "okay";
++
++ ports {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ port@0 {
++ vin1ep0: endpoint {
++ csi,select = "csi40";
++ virtual,channel = <1>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&ov106xx_in1>;
++ };
++ };
++ port@1 {
++ csi0ep1: endpoint {
++ remote-endpoint = <&csi2_40_ep>;
++ };
++ };
++ port@2 {
++ vin1_max9286_des0ep1: endpoint@0 {
++ remote-endpoint = <&max9286_des0ep1>;
++ };
++ vin1_ti964_des0ep1: endpoint@1 {
++ remote-endpoint = <&ti964_des0ep1>;
++ };
++ vin1_ti954_des0ep1: endpoint@2 {
++ remote-endpoint = <&ti954_des0ep1>;
++ };
++ };
++ };
++};
++
++&vin2 {
++ status = "okay";
++
++ ports {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ port@0 {
++ vin2ep0: endpoint {
++ csi,select = "csi40";
++ virtual,channel = <2>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&ov106xx_in2>;
++ };
++ };
++ port@1 {
++ csi0ep2: endpoint {
++ remote-endpoint = <&csi2_40_ep>;
++ };
++ };
++ port@2 {
++ vin2_max9286_des0ep2: endpoint@0 {
++ remote-endpoint = <&max9286_des0ep2>;
++ };
++ vin2_ti964_des0ep2: endpoint@1 {
++ remote-endpoint = <&ti964_des0ep2>;
++ };
++ };
++ };
++};
++
++&vin3 {
++ status = "okay";
++
++ ports {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ port@0 {
++ vin3ep0: endpoint {
++ csi,select = "csi40";
++ virtual,channel = <3>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&ov106xx_in3>;
++ };
++ };
++ port@1 {
++ csi0ep3: endpoint {
++ remote-endpoint = <&csi2_40_ep>;
++ };
++ };
++ port@2 {
++ vin3_max9286_des0ep3: endpoint@0 {
++ remote-endpoint = <&max9286_des0ep3>;
++ };
++ vin3_ti964_des0ep3: endpoint@1 {
++ remote-endpoint = <&ti964_des0ep3>;
++ };
++ };
++ };
++};
++
++&vin4 {
++ status = "okay";
++
++ ports {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ port@0 {
++ vin4ep0: endpoint {
++ csi,select = "csi41";
++ virtual,channel = <0>;
++ remote-endpoint = <&ov106xx_in4>;
++ data-lanes = <1 2 3 4>;
++ };
++ };
++ port@1 {
++ csi2ep0: endpoint {
++ remote-endpoint = <&csi2_41_ep>;
++ };
++ };
++ port@2 {
++ vin4_max9286_des1ep0: endpoint@0 {
++ remote-endpoint = <&max9286_des1ep0>;
++ };
++ vin4_ti964_des1ep0: endpoint@1 {
++ remote-endpoint = <&ti964_des1ep0>;
++ };
++ vin4_ti954_des1ep0: endpoint@2 {
++ remote-endpoint = <&ti954_des1ep0>;
++ };
++ };
++ };
++};
++
++&vin5 {
++ status = "okay";
++
++ ports {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ port@0 {
++ vin5ep0: endpoint@0 {
++ csi,select = "csi41";
++ virtual,channel = <1>;
++ remote-endpoint = <&ov106xx_in5>;
++ data-lanes = <1 2 3 4>;
++ };
++ };
++ port@1 {
++ csi2ep1: endpoint {
++ remote-endpoint = <&csi2_41_ep>;
++ };
++ };
++ port@2 {
++ vin5_max9286_des1ep1: endpoint@0 {
++ remote-endpoint = <&max9286_des1ep1>;
++ };
++ vin5_ti964_des1ep1: endpoint@1 {
++ remote-endpoint = <&ti964_des1ep1>;
++ };
++ vin5_ti954_des1ep1: endpoint@2 {
++ remote-endpoint = <&ti954_des1ep1>;
++ };
++ };
++ };
++};
++
++&vin6 {
++ status = "okay";
++
++ ports {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ port@0 {
++ vin6ep0: endpoint@0 {
++ csi,select = "csi41";
++ virtual,channel = <2>;
++ remote-endpoint = <&ov106xx_in6>;
++ data-lanes = <1 2 3 4>;
++ };
++ };
++ port@1 {
++ csi2ep2: endpoint {
++ remote-endpoint = <&csi2_41_ep>;
++ };
++ };
++ port@2 {
++ vin6_max9286_des1ep2: endpoint@0 {
++ remote-endpoint = <&max9286_des1ep2>;
++ };
++ vin6_ti964_des1ep2: endpoint@1 {
++ remote-endpoint = <&ti964_des1ep2>;
++ };
++ };
++ };
++};
++
++&vin7 {
++ status = "okay";
++
++ ports {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ port@0 {
++ vin7ep0: endpoint@0 {
++ csi,select = "csi41";
++ virtual,channel = <3>;
++ remote-endpoint = <&ov106xx_in7>;
++ data-lanes = <1 2 3 4>;
++ };
++ };
++ port@1 {
++ csi2ep3: endpoint {
++ remote-endpoint = <&csi2_41_ep>;
++ };
++ };
++ port@2 {
++ vin7_max9286_des1ep3: endpoint@0 {
++ remote-endpoint = <&max9286_des1ep3>;
++ };
++ vin7_ti964_des1ep3: endpoint@1 {
++ remote-endpoint = <&ti964_des1ep3>;
++ };
++ };
++ };
++};
++
++&csi2_40 {
++ status = "okay";
++
++ virtual,channel {
++ csi2_vc0 {
++ data,type = "ycbcr422";
++ receive,vc = <0>;
++ };
++ csi2_vc1 {
++ data,type = "ycbcr422";
++ receive,vc = <1>;
++ };
++ csi2_vc2 {
++ data,type = "ycbcr422";
++ receive,vc = <2>;
++ };
++ csi2_vc3 {
++ data,type = "ycbcr422";
++ receive,vc = <3>;
++ };
++ };
++
++ port {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ csi2_40_ep: endpoint {
++ clock-lanes = <0>;
++ data-lanes = <1 2 3 4>;
++ csi-rate = <300>;
++ };
++ };
++};
++
++&csi2_41 {
++ status = "okay";
++
++ virtual,channel {
++ csi2_vc0 {
++ data,type = "ycbcr422";
++ receive,vc = <0>;
++ };
++ csi2_vc1 {
++ data,type = "ycbcr422";
++ receive,vc = <1>;
++ };
++ csi2_vc2 {
++ data,type = "ycbcr422";
++ receive,vc = <2>;
++ };
++ csi2_vc3 {
++ data,type = "ycbcr422";
++ receive,vc = <3>;
++ };
++ };
++
++ port {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ csi2_41_ep: endpoint {
++ clock-lanes = <0>;
++ data-lanes = <1 2 3 4>;
++ csi-rate = <300>;
++ };
++ };
++};
++
++&rcar_sound {
++ pinctrl-0 = <&sound_clk_pins>;
++
++ /* Multi DAI */
++ #sound-dai-cells = <1>;
++};
++
++&sata {
++ status = "okay";
++};
++
++&ssi1 {
++ /delete-property/shared-pin;
++};
++
++&avb {
++ /delete-property/phy-handle;
++ /delete-property/phy-gpios;
++ phy-mode = "rgmii";
++
++ /delete-node/ethernet-phy@0;
++
++ fixed-link {
++ speed = <100>;
++ full-duplex;
++ };
++};
++
++&msiof1 {
++ status = "disabled";
++};
++
++&usb2_phy0 {
++ pinctrl-0 = <&usb0_pins>;
++ pinctrl-names = "default";
++
++ status = "okay";
++};
++
++&xhci0 {
++ status = "okay";
++};
++
++&hsusb {
++ status = "okay";
++};
++
++&ehci0 {
++ status = "okay";
++};
++
++&ohci0 {
++ status = "okay";
++};
++
++&can0 {
++ pinctrl-0 = <&can0_pins>;
++ pinctrl-names = "default";
++ status = "okay";
++
++ renesas,can-clock-select = <0x0>;
++};
++
++&can1 {
++ pinctrl-0 = <&can1_pins>;
++ pinctrl-names = "default";
++ status = "okay";
++
++ renesas,can-clock-select = <0x0>;
++};
++
++&canfd {
++ pinctrl-0 = <&canfd0_pins &canfd1_pins>;
++ pinctrl-names = "default";
++ status = "disabled";
++
++ renesas,can-clock-select = <0x0>;
++
++ channel0 {
++ status = "okay";
++ };
++
++ channel1 {
++ status = "okay";
++ };
++};
++
++/* uncomment to enable CN12 on VIN4-7 */
++//#include "ulcb-vb-cn12.dtsi"
+diff --git a/arch/arm64/boot/dts/renesas/r8a7795-es1-h3ulcb-view.dts b/arch/arm64/boot/dts/renesas/r8a7795-es1-h3ulcb-view.dts
+new file mode 100644
+index 0000000..de56fa4
+--- /dev/null
++++ b/arch/arm64/boot/dts/renesas/r8a7795-es1-h3ulcb-view.dts
+@@ -0,0 +1,546 @@
++/*
++ * Device Tree Source for the H3ULCB.View board on r8a7795 ES1.x
++ *
++ * Copyright (C) 2016-2017 Renesas Electronics Corp.
++ * Copyright (C) 2016-2017 Cogent Embedded, Inc.
++ *
++ * This file is licensed under the terms of the GNU General Public License
++ * version 2. This program is licensed "as is" without any warranty of any
++ * kind, whether express or implied.
++ */
++
++#include "r8a7795-es1-h3ulcb.dts"
++
++/ {
++ model = "Renesas H3ULCB.View board based on r8a7795";
++};
++
++&i2c4 {
++ ov106xx@0 {
++ compatible = "ovti,ov106xx";
++ reg = <0x60>;
++
++ port@0 {
++ ov106xx_in0: endpoint {
++ clock-lanes = <0>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&vin0ep0>;
++ };
++ };
++ port@1 {
++ ov106xx_max9286_des0ep0: endpoint@0 {
++ remote-endpoint = <&max9286_des0ep0>;
++ };
++ };
++ };
++
++ ov106xx@1 {
++ compatible = "ovti,ov106xx";
++ reg = <0x61>;
++
++ port@0 {
++ ov106xx_in1: endpoint {
++ clock-lanes = <0>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&vin1ep0>;
++ };
++ };
++ port@1 {
++ ov106xx_max9286_des0ep1: endpoint@0 {
++ remote-endpoint = <&max9286_des0ep1>;
++ };
++ };
++ };
++
++ ov106xx@2 {
++ compatible = "ovti,ov106xx";
++ reg = <0x62>;
++
++ port@0 {
++ ov106xx_in2: endpoint {
++ clock-lanes = <0>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&vin2ep0>;
++ };
++ };
++ port@1 {
++ ov106xx_max9286_des0ep2: endpoint@0 {
++ remote-endpoint = <&max9286_des0ep2>;
++ };
++ };
++ };
++
++ ov106xx@3 {
++ compatible = "ovti,ov106xx";
++ reg = <0x63>;
++
++ port@0 {
++ ov106xx_in3: endpoint {
++ clock-lanes = <0>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&vin3ep0>;
++ };
++ };
++ port@1 {
++ ov106xx_des0ep3: endpoint {
++ remote-endpoint = <&max9286_des0ep3>;
++ };
++ };
++ };
++
++ ov106xx@4 {
++ compatible = "ovti,ov106xx";
++ reg = <0x64>;
++
++ port@0 {
++ ov106xx_in4: endpoint {
++ clock-lanes = <0>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&vin4ep0>;
++ };
++ };
++ port@1 {
++ ov106xx_max9286_des1ep0: endpoint@0 {
++ remote-endpoint = <&max9286_des1ep0>;
++ };
++ };
++ };
++
++ ov106xx@5 {
++ compatible = "ovti,ov106xx";
++ reg = <0x65>;
++
++ port@0 {
++ ov106xx_in5: endpoint {
++ clock-lanes = <0>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&vin5ep0>;
++ };
++ };
++ port@1 {
++ ov106xx_max9286_des1ep1: endpoint@0 {
++ remote-endpoint = <&max9286_des1ep1>;
++ };
++ };
++ };
++
++ ov106xx@6 {
++ compatible = "ovti,ov106xx";
++ reg = <0x66>;
++
++ port@0 {
++ ov106xx_in6: endpoint {
++ clock-lanes = <0>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&vin6ep0>;
++ };
++ };
++ port@1 {
++ ov106xx_max9286_des1ep2: endpoint@0 {
++ remote-endpoint = <&max9286_des1ep2>;
++ };
++ };
++ };
++
++ ov106xx@7 {
++ compatible = "ovti,ov106xx";
++ reg = <0x67>;
++
++ port@0 {
++ ov106xx_in7: endpoint {
++ clock-lanes = <0>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&vin7ep0>;
++ };
++ };
++ port@1 {
++ ov106xx_des1ep3: endpoint {
++ remote-endpoint = <&max9286_des1ep3>;
++ };
++ };
++ };
++
++ max9286-max9271@0 {
++ compatible = "maxim,max9286-max9271";
++ reg = <0x4c>;
++ gpios = <&gpio2 6 GPIO_ACTIVE_HIGH>;
++ maxim,sensor_delay = <0>;
++ maxim,links = <4>;
++ maxim,lanes = <4>;
++ maxim,resetb-gpio = <1>;
++ maxim,fsync-mode = "automatic";
++ maxim,timeout = <100>;
++ maxim,i2c-quirk = <0x6c>;
++
++ port@0 {
++ max9286_des0ep0: endpoint@0 {
++ max9271-addr = <0x50>;
++ dvp-order = <1>;
++ remote-endpoint = <&ov106xx_in0>;
++ };
++ max9286_des0ep1: endpoint@1 {
++ max9271-addr = <0x51>;
++ dvp-order = <1>;
++ remote-endpoint = <&ov106xx_in1>;
++ };
++ max9286_des0ep2: endpoint@2 {
++ max9271-addr = <0x52>;
++ dvp-order = <1>;
++ remote-endpoint = <&ov106xx_in2>;
++ };
++ max9286_des0ep3: endpoint@3 {
++ max9271-addr = <0x53>;
++ dvp-order = <1>;
++ remote-endpoint = <&ov106xx_in3>;
++ };
++ };
++ port@1 {
++ max9286_csi0ep0: endpoint {
++ csi-rate = <700>;
++ remote-endpoint = <&csi2_40_ep>;
++ };
++ };
++ };
++
++ max9286-max9271@1 {
++ compatible = "maxim,max9286-max9271";
++ reg = <0x6c>;
++ gpios = <&gpio5 25 GPIO_ACTIVE_HIGH>;
++ maxim,sensor_delay = <0>;
++ maxim,links = <4>;
++ maxim,lanes = <4>;
++ maxim,resetb-gpio = <1>;
++ maxim,fsync-mode = "automatic";
++ maxim,timeout = <100>;
++
++ port@0 {
++ max9286_des1ep0: endpoint@0 {
++ max9271-addr = <0x54>;
++ dvp-order = <1>;
++ remote-endpoint = <&ov106xx_in4>;
++ };
++ max9286_des1ep1: endpoint@1 {
++ max9271-addr = <0x55>;
++ dvp-order = <1>;
++ remote-endpoint = <&ov106xx_in5>;
++ };
++ max9286_des1ep2: endpoint@2 {
++ max9271-addr = <0x56>;
++ dvp-order = <1>;
++ remote-endpoint = <&ov106xx_in6>;
++ };
++ max9286_des1ep3: endpoint@3 {
++ max9271-addr = <0x57>;
++ dvp-order = <1>;
++ remote-endpoint = <&ov106xx_in7>;
++ };
++ };
++ port@1 {
++ max9286_csi2ep0: endpoint {
++ csi-rate = <700>;
++ remote-endpoint = <&csi2_41_ep>;
++ };
++ };
++ };
++};
++
++&pcie_bus_clk {
++ clock-frequency = <100000000>;
++ status = "okay";
++};
++
++&pciec1 {
++ status = "okay";
++};
++
++&vin0 {
++ status = "okay";
++
++ ports {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ port@0 {
++ vin0ep0: endpoint {
++ csi,select = "csi40";
++ virtual,channel = <0>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&ov106xx_in0>;
++ };
++ };
++ port@1 {
++ csi0ep0: endpoint {
++ remote-endpoint = <&csi2_40_ep>;
++ };
++ };
++ port@2 {
++ vin0_max9286_des0ep0: endpoint@0 {
++ remote-endpoint = <&max9286_des0ep0>;
++ };
++ };
++ };
++};
++
++&vin1 {
++ status = "okay";
++
++ ports {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ port@0 {
++ vin1ep0: endpoint {
++ csi,select = "csi40";
++ virtual,channel = <1>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&ov106xx_in1>;
++ };
++ };
++ port@1 {
++ csi0ep1: endpoint {
++ remote-endpoint = <&csi2_40_ep>;
++ };
++ };
++ port@2 {
++ vin1_max9286_des0ep1: endpoint@0 {
++ remote-endpoint = <&max9286_des0ep1>;
++ };
++ };
++ };
++};
++
++&vin2 {
++ status = "okay";
++
++ ports {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ port@0 {
++ vin2ep0: endpoint {
++ csi,select = "csi40";
++ virtual,channel = <2>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&ov106xx_in2>;
++ };
++ };
++ port@1 {
++ csi0ep2: endpoint {
++ remote-endpoint = <&csi2_40_ep>;
++ };
++ };
++ port@2 {
++ vin2_max9286_des0ep2: endpoint@0 {
++ remote-endpoint = <&max9286_des0ep2>;
++ };
++ };
++ };
++};
++
++&vin3 {
++ status = "okay";
++
++ ports {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ port@0 {
++ vin3ep0: endpoint {
++ csi,select = "csi40";
++ virtual,channel = <3>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&ov106xx_in3>;
++ };
++ };
++ port@1 {
++ csi0ep3: endpoint {
++ remote-endpoint = <&csi2_40_ep>;
++ };
++ };
++ port@2 {
++ vin3_max9286_des0ep3: endpoint@0 {
++ remote-endpoint = <&max9286_des0ep3>;
++ };
++ };
++ };
++};
++
++&vin4 {
++ status = "okay";
++
++ ports {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ port@0 {
++ vin4ep0: endpoint {
++ csi,select = "csi41";
++ virtual,channel = <0>;
++ remote-endpoint = <&ov106xx_in4>;
++ data-lanes = <1 2 3 4>;
++ };
++ };
++ port@1 {
++ csi2ep0: endpoint {
++ remote-endpoint = <&csi2_41_ep>;
++ };
++ };
++ port@2 {
++ vin4_max9286_des1ep0: endpoint@0 {
++ remote-endpoint = <&max9286_des1ep0>;
++ };
++ };
++ };
++};
++
++&vin5 {
++ status = "okay";
++
++ ports {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ port@0 {
++ vin5ep0: endpoint@0 {
++ csi,select = "csi41";
++ virtual,channel = <1>;
++ remote-endpoint = <&ov106xx_in5>;
++ data-lanes = <1 2 3 4>;
++ };
++ };
++ port@1 {
++ csi2ep1: endpoint {
++ remote-endpoint = <&csi2_41_ep>;
++ };
++ };
++ port@2 {
++ vin5_max9286_des1ep1: endpoint@0 {
++ remote-endpoint = <&max9286_des1ep1>;
++ };
++ };
++ };
++};
++
++&vin6 {
++ status = "okay";
++
++ ports {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ port@0 {
++ vin6ep0: endpoint@0 {
++ csi,select = "csi41";
++ virtual,channel = <2>;
++ remote-endpoint = <&ov106xx_in6>;
++ data-lanes = <1 2 3 4>;
++ };
++ };
++ port@1 {
++ csi2ep2: endpoint {
++ remote-endpoint = <&csi2_41_ep>;
++ };
++ };
++ port@2 {
++ vin6_max9286_des1ep2: endpoint@0 {
++ remote-endpoint = <&max9286_des1ep2>;
++ };
++ };
++ };
++};
++
++&vin7 {
++ status = "okay";
++
++ ports {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ port@0 {
++ vin7ep0: endpoint@0 {
++ csi,select = "csi41";
++ virtual,channel = <3>;
++ remote-endpoint = <&ov106xx_in7>;
++ data-lanes = <1 2 3 4>;
++ };
++ };
++ port@1 {
++ csi2ep3: endpoint {
++ remote-endpoint = <&csi2_41_ep>;
++ };
++ };
++ port@2 {
++ vin7_max9286_des1ep3: endpoint@0 {
++ remote-endpoint = <&max9286_des1ep3>;
++ };
++ };
++ };
++};
++
++&csi2_40 {
++ status = "okay";
++
++ virtual,channel {
++ csi2_vc0 {
++ data,type = "ycbcr422";
++ receive,vc = <0>;
++ };
++ csi2_vc1 {
++ data,type = "ycbcr422";
++ receive,vc = <1>;
++ };
++ csi2_vc2 {
++ data,type = "ycbcr422";
++ receive,vc = <2>;
++ };
++ csi2_vc3 {
++ data,type = "ycbcr422";
++ receive,vc = <3>;
++ };
++ };
++
++ port {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ csi2_40_ep: endpoint {
++ clock-lanes = <0>;
++ data-lanes = <1 2 3 4>;
++ csi-rate = <300>;
++ };
++ };
++};
++
++&csi2_41 {
++ status = "okay";
++
++ virtual,channel {
++ csi2_vc0 {
++ data,type = "ycbcr422";
++ receive,vc = <0>;
++ };
++ csi2_vc1 {
++ data,type = "ycbcr422";
++ receive,vc = <1>;
++ };
++ csi2_vc2 {
++ data,type = "ycbcr422";
++ receive,vc = <2>;
++ };
++ csi2_vc3 {
++ data,type = "ycbcr422";
++ receive,vc = <3>;
++ };
++ };
++
++ port {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ csi2_41_ep: endpoint {
++ clock-lanes = <0>;
++ data-lanes = <1 2 3 4>;
++ csi-rate = <300>;
++ };
++ };
++};
+diff --git a/arch/arm64/boot/dts/renesas/r8a7795-es1-salvator-x-view.dts b/arch/arm64/boot/dts/renesas/r8a7795-es1-salvator-x-view.dts
+new file mode 100644
+index 0000000..3f3d66a
+--- /dev/null
++++ b/arch/arm64/boot/dts/renesas/r8a7795-es1-salvator-x-view.dts
+@@ -0,0 +1,552 @@
++/*
++ * Device Tree Source for the Salvator-X.View board on r8a7795 ES1.x
++ *
++ * Copyright (C) 2016-2017 Renesas Electronics Corp.
++ * Copyright (C) 2015-2017 Cogent Embedded, Inc
++ *
++ * This file is licensed under the terms of the GNU General Public License
++ * version 2. This program is licensed "as is" without any warranty of any
++ * kind, whether express or implied.
++ */
++
++#include "r8a7795-es1-salvator-x.dts"
++
++/ {
++ model = "Renesas Salvator-X.View board based on r8a7795";
++};
++
++&pfc {
++ can0_pins: can0 {
++ groups = "can0_data_a";
++ function = "can0";
++ };
++
++ can1_pins: can1 {
++ groups = "can1_data";
++ function = "can1";
++ };
++};
++
++&i2c4 {
++ /delete-node/hdmi-in@34;
++ /delete-node/composite-in@70;
++
++ ov106xx@0 {
++ compatible = "ovti,ov106xx";
++ reg = <0x60>;
++
++ port@0 {
++ ov106xx_in0: endpoint {
++ clock-lanes = <0>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&vin0ep0>;
++ };
++ };
++ port@1 {
++ ov106xx_max9286_des0ep0: endpoint@0 {
++ remote-endpoint = <&max9286_des0ep0>;
++ };
++ };
++ };
++
++ ov106xx@1 {
++ compatible = "ovti,ov106xx";
++ reg = <0x61>;
++
++ port@0 {
++ ov106xx_in1: endpoint {
++ clock-lanes = <0>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&vin1ep0>;
++ };
++ };
++ port@1 {
++ ov106xx_max9286_des0ep1: endpoint@0 {
++ remote-endpoint = <&max9286_des0ep1>;
++ };
++ };
++ };
++
++ ov106xx@2 {
++ compatible = "ovti,ov106xx";
++ reg = <0x62>;
++
++ port@0 {
++ ov106xx_in2: endpoint {
++ clock-lanes = <0>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&vin2ep0>;
++ };
++ };
++ port@1 {
++ ov106xx_max9286_des0ep2: endpoint@0 {
++ remote-endpoint = <&max9286_des0ep2>;
++ };
++ };
++ };
++
++ ov106xx@3 {
++ compatible = "ovti,ov106xx";
++ reg = <0x63>;
++
++ port@0 {
++ ov106xx_in3: endpoint {
++ clock-lanes = <0>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&vin3ep0>;
++ };
++ };
++ port@1 {
++ ov106xx_des0ep3: endpoint {
++ remote-endpoint = <&max9286_des0ep3>;
++ };
++ };
++ };
++
++ ov106xx@4 {
++ compatible = "ovti,ov106xx";
++ reg = <0x64>;
++
++ port@0 {
++ ov106xx_in4: endpoint {
++ clock-lanes = <0>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&vin4ep0>;
++ };
++ };
++ port@1 {
++ ov106xx_max9286_des1ep0: endpoint@0 {
++ remote-endpoint = <&max9286_des1ep0>;
++ };
++ };
++ };
++
++ ov106xx@5 {
++ compatible = "ovti,ov106xx";
++ reg = <0x65>;
++
++ port@0 {
++ ov106xx_in5: endpoint {
++ clock-lanes = <0>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&vin5ep0>;
++ };
++ };
++ port@1 {
++ ov106xx_max9286_des1ep1: endpoint@0 {
++ remote-endpoint = <&max9286_des1ep1>;
++ };
++ };
++ };
++
++ ov106xx@6 {
++ compatible = "ovti,ov106xx";
++ reg = <0x66>;
++
++ port@0 {
++ ov106xx_in6: endpoint {
++ clock-lanes = <0>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&vin6ep0>;
++ };
++ };
++ port@1 {
++ ov106xx_max9286_des1ep2: endpoint@0 {
++ remote-endpoint = <&max9286_des1ep2>;
++ };
++ };
++ };
++
++ ov106xx@7 {
++ compatible = "ovti,ov106xx";
++ reg = <0x67>;
++
++ port@0 {
++ ov106xx_in7: endpoint {
++ clock-lanes = <0>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&vin7ep0>;
++ };
++ };
++ port@1 {
++ ov106xx_des1ep3: endpoint {
++ remote-endpoint = <&max9286_des1ep3>;
++ };
++ };
++ };
++
++ max9286-max9271@0 {
++ compatible = "maxim,max9286-max9271";
++ reg = <0x4c>;
++ gpios = <&gpio6 30 GPIO_ACTIVE_LOW>;
++ maxim,sensor_delay = <0>;
++ maxim,links = <4>;
++ maxim,lanes = <4>;
++ maxim,resetb-gpio = <1>;
++ maxim,fsync-mode = "automatic";
++ maxim,timeout = <100>;
++ maxim,i2c-quirk = <0x6c>;
++
++ port@0 {
++ max9286_des0ep0: endpoint@0 {
++ max9271-addr = <0x50>;
++ dvp-order = <1>;
++ remote-endpoint = <&ov106xx_in0>;
++ };
++ max9286_des0ep1: endpoint@1 {
++ max9271-addr = <0x51>;
++ dvp-order = <1>;
++ remote-endpoint = <&ov106xx_in1>;
++ };
++ max9286_des0ep2: endpoint@2 {
++ max9271-addr = <0x52>;
++ dvp-order = <1>;
++ remote-endpoint = <&ov106xx_in2>;
++ };
++ max9286_des0ep3: endpoint@3 {
++ max9271-addr = <0x53>;
++ dvp-order = <1>;
++ remote-endpoint = <&ov106xx_in3>;
++ };
++ };
++ port@1 {
++ max9286_csi0ep0: endpoint {
++ csi-rate = <700>;
++ remote-endpoint = <&csi2_40_ep>;
++ };
++ };
++ };
++
++ max9286-max9271@1 {
++ compatible = "maxim,max9286-max9271";
++ reg = <0x6c>;
++ maxim,sensor_delay = <0>;
++ maxim,links = <4>;
++ maxim,lanes = <4>;
++ maxim,resetb-gpio = <1>;
++ maxim,fsync-mode = "automatic";
++ maxim,timeout = <100>;
++
++ port@0 {
++ max9286_des1ep0: endpoint@0 {
++ max9271-addr = <0x54>;
++ dvp-order = <1>;
++ remote-endpoint = <&ov106xx_in4>;
++ };
++ max9286_des1ep1: endpoint@1 {
++ max9271-addr = <0x55>;
++ dvp-order = <1>;
++ remote-endpoint = <&ov106xx_in5>;
++ };
++ max9286_des1ep2: endpoint@2 {
++ max9271-addr = <0x56>;
++ dvp-order = <1>;
++ remote-endpoint = <&ov106xx_in6>;
++ };
++ max9286_des1ep3: endpoint@3 {
++ max9271-addr = <0x57>;
++ dvp-order = <1>;
++ remote-endpoint = <&ov106xx_in7>;
++ };
++ };
++ port@1 {
++ max9286_csi2ep0: endpoint {
++ csi-rate = <700>;
++ remote-endpoint = <&csi2_41_ep>;
++ };
++ };
++ };
++};
++
++&vin0 {
++ ports {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ port@0 {
++ vin0ep0: endpoint {
++ csi,select = "csi40";
++ virtual,channel = <0>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&ov106xx_in0>;
++ };
++ };
++ port@1 {
++ csi0ep0: endpoint {
++ remote-endpoint = <&csi2_40_ep>;
++ };
++ };
++ port@2 {
++ vin0_max9286_des0ep0: endpoint@0 {
++ remote-endpoint = <&max9286_des0ep0>;
++ };
++ };
++ };
++};
++
++&vin1 {
++ ports {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ port@0 {
++ vin1ep0: endpoint {
++ csi,select = "csi40";
++ virtual,channel = <1>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&ov106xx_in1>;
++ };
++ };
++ port@1 {
++ csi0ep1: endpoint {
++ remote-endpoint = <&csi2_40_ep>;
++ };
++ };
++ port@2 {
++ vin1_max9286_des0ep1: endpoint@0 {
++ remote-endpoint = <&max9286_des0ep1>;
++ };
++ };
++ };
++};
++
++&vin2 {
++ ports {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ port@0 {
++ vin2ep0: endpoint {
++ csi,select = "csi40";
++ virtual,channel = <2>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&ov106xx_in2>;
++ };
++ };
++ port@1 {
++ csi0ep2: endpoint {
++ remote-endpoint = <&csi2_40_ep>;
++ };
++ };
++ port@2 {
++ vin2_max9286_des0ep2: endpoint@0 {
++ remote-endpoint = <&max9286_des0ep2>;
++ };
++ };
++ };
++};
++
++&vin3 {
++ ports {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ port@0 {
++ vin3ep0: endpoint {
++ csi,select = "csi40";
++ virtual,channel = <3>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&ov106xx_in3>;
++ };
++ };
++ port@1 {
++ csi0ep3: endpoint {
++ remote-endpoint = <&csi2_40_ep>;
++ };
++ };
++ port@2 {
++ vin3_max9286_des0ep3: endpoint@0 {
++ remote-endpoint = <&max9286_des0ep3>;
++ };
++ };
++ };
++};
++
++&vin4 {
++ ports {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ port@0 {
++ vin4ep0: endpoint {
++ csi,select = "csi41";
++ virtual,channel = <0>;
++ remote-endpoint = <&ov106xx_in4>;
++ data-lanes = <1 2 3 4>;
++ };
++ };
++ port@1 {
++ csi2ep0: endpoint {
++ remote-endpoint = <&csi2_41_ep>;
++ };
++ };
++ port@2 {
++ vin4_max9286_des1ep0: endpoint@0 {
++ remote-endpoint = <&max9286_des1ep0>;
++ };
++ };
++ };
++};
++
++&vin5 {
++ ports {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ port@0 {
++ vin5ep0: endpoint@0 {
++ csi,select = "csi41";
++ virtual,channel = <1>;
++ remote-endpoint = <&ov106xx_in5>;
++ data-lanes = <1 2 3 4>;
++ };
++ };
++ port@1 {
++ csi2ep1: endpoint {
++ remote-endpoint = <&csi2_41_ep>;
++ };
++ };
++ port@2 {
++ vin5_max9286_des1ep1: endpoint@0 {
++ remote-endpoint = <&max9286_des1ep1>;
++ };
++ };
++ };
++};
++
++&vin6 {
++ ports {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ port@0 {
++ vin6ep0: endpoint@0 {
++ csi,select = "csi41";
++ virtual,channel = <2>;
++ remote-endpoint = <&ov106xx_in6>;
++ data-lanes = <1 2 3 4>;
++ };
++ };
++ port@1 {
++ csi2ep2: endpoint {
++ remote-endpoint = <&csi2_41_ep>;
++ };
++ };
++ port@2 {
++ vin6_max9286_des1ep2: endpoint@0 {
++ remote-endpoint = <&max9286_des1ep2>;
++ };
++ };
++ };
++};
++
++&vin7 {
++ ports {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ port@0 {
++ vin7ep0: endpoint@0 {
++ csi,select = "csi41";
++ virtual,channel = <3>;
++ remote-endpoint = <&ov106xx_in7>;
++ data-lanes = <1 2 3 4>;
++ };
++ };
++ port@1 {
++ csi2ep3: endpoint {
++ remote-endpoint = <&csi2_41_ep>;
++ };
++ };
++ port@2 {
++ vin7_max9286_des1ep3: endpoint@0 {
++ remote-endpoint = <&max9286_des1ep3>;
++ };
++ };
++ };
++};
++
++&csi2_20 {
++ status = "disabled";
++ /delete-node/ports;
++};
++
++&csi2_40 {
++ /delete-node/ports;
++
++ virtual,channel {
++ csi2_vc0 {
++ data,type = "ycbcr422";
++ receive,vc = <0>;
++ };
++ csi2_vc1 {
++ data,type = "ycbcr422";
++ receive,vc = <1>;
++ };
++ csi2_vc2 {
++ data,type = "ycbcr422";
++ receive,vc = <2>;
++ };
++ csi2_vc3 {
++ data,type = "ycbcr422";
++ receive,vc = <3>;
++ };
++ };
++
++ port {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ csi2_40_ep: endpoint {
++ clock-lanes = <0>;
++ data-lanes = <1 2 3 4>;
++ csi-rate = <300>;
++ };
++ };
++};
++
++&csi2_41 {
++ status = "okay";
++
++ virtual,channel {
++ csi2_vc0 {
++ data,type = "ycbcr422";
++ receive,vc = <0>;
++ };
++ csi2_vc1 {
++ data,type = "ycbcr422";
++ receive,vc = <1>;
++ };
++ csi2_vc2 {
++ data,type = "ycbcr422";
++ receive,vc = <2>;
++ };
++ csi2_vc3 {
++ data,type = "ycbcr422";
++ receive,vc = <3>;
++ };
++ };
++
++ port {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ csi2_41_ep: endpoint {
++ clock-lanes = <0>;
++ data-lanes = <1 2 3 4>;
++ csi-rate = <300>;
++ };
++ };
++};
++
++&can0 {
++ pinctrl-0 = <&can0_pins>;
++ pinctrl-names = "default";
++ status = "okay";
++};
++
++&can1 {
++ pinctrl-0 = <&can1_pins>;
++ pinctrl-names = "default";
++ status = "okay";
++};
+diff --git a/arch/arm64/boot/dts/renesas/r8a7795-h3ulcb-had-alfa.dts b/arch/arm64/boot/dts/renesas/r8a7795-h3ulcb-had-alfa.dts
+new file mode 100644
+index 0000000..ae115bd
+--- /dev/null
++++ b/arch/arm64/boot/dts/renesas/r8a7795-h3ulcb-had-alfa.dts
+@@ -0,0 +1,22 @@
++/*
++ * Device Tree Source for the H3ULCB.HAD board Alfa side
++ *
++ * Copyright (C) 2017 Renesas Electronics Corp.
++ * Copyright (C) 2017 Cogent Embedded, Inc.
++ *
++ * This file is licensed under the terms of the GNU General Public License
++ * version 2. This program is licensed "as is" without any warranty of any
++ * kind, whether express or implied.
++ */
++
++#include "r8a7795-h3ulcb-had.dtsi"
++
++/ {
++ model = "Renesas H3ULCB.HAD board Alfa side based on r8a7795";
++};
++
++&pciec0 {
++ status = "okay";
++
++ /* Root complex */
++};
+diff --git a/arch/arm64/boot/dts/renesas/r8a7795-h3ulcb-had-beta.dts b/arch/arm64/boot/dts/renesas/r8a7795-h3ulcb-had-beta.dts
+new file mode 100644
+index 0000000..805067e
+--- /dev/null
++++ b/arch/arm64/boot/dts/renesas/r8a7795-h3ulcb-had-beta.dts
+@@ -0,0 +1,23 @@
++/*
++ * Device Tree Source for the H3ULCB.HAD board Beta side
++ *
++ * Copyright (C) 2017 Renesas Electronics Corp.
++ * Copyright (C) 2017 Cogent Embedded, Inc.
++ *
++ * This file is licensed under the terms of the GNU General Public License
++ * version 2. This program is licensed "as is" without any warranty of any
++ * kind, whether express or implied.
++ */
++
++#include "r8a7795-h3ulcb-had.dtsi"
++
++/ {
++ model = "Renesas H3ULCB.HAD board Beta side based on r8a7795";
++};
++
++&pciec0 {
++ status = "okay";
++
++ /* Endpoint */
++ endpoint;
++};
+diff --git a/arch/arm64/boot/dts/renesas/r8a7795-h3ulcb-had.dtsi b/arch/arm64/boot/dts/renesas/r8a7795-h3ulcb-had.dtsi
+new file mode 100644
+index 0000000..4a00426
+--- /dev/null
++++ b/arch/arm64/boot/dts/renesas/r8a7795-h3ulcb-had.dtsi
+@@ -0,0 +1,219 @@
++/*
++ * Device Tree Source for the H3ULCB.HAD board on r8a7795
++ *
++ * Copyright (C) 2016-2017 Renesas Electronics Corp.
++ * Copyright (C) 2016-2017 Cogent Embedded, Inc.
++ *
++ * This file is licensed under the terms of the GNU General Public License
++ * version 2. This program is licensed "as is" without any warranty of any
++ * kind, whether express or implied.
++ */
++
++/*
++ * MSIOF0 - /dev/spidev1.0 connected to FPGA ethernet switch (both sides)
++ * MSIOF1 - /dev/spidev2.0 connected to RH850 (sideA to CSIH1, sideB to CSIH0)
++ */
++
++#include "r8a7795-h3ulcb-view.dts"
++
++/ {
++ model = "Renesas H3ULCB.HAD board based on r8a7795";
++
++ aliases {
++ serial1 = &scif1;
++ spi1 = &spi0_gpio;
++ spi2 = &spi1_gpio;
++ };
++
++ chosen {
++ stdout-path = "serial1:115200n8";
++ };
++
++ spi0_gpio: spi_gpio@0 {
++ compatible = "spi-gpio";
++ num-chipselects = <1>;
++ gpio-sck = <&gpio5 17 0>;
++ gpio-mosi = <&gpio5 20 0>;
++ gpio-miso = <&gpio5 22 0>;
++ cs-gpios = <&gpio5 19 0>;
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ spidev@0 {
++ compatible = "spi-gpio";
++ reg = <0>;
++ spi-max-frequency = <2000000>;
++ spi-cpha;
++ spi-cpol;
++ };
++ };
++
++ spi1_gpio: spi_gpio@1 {
++ compatible = "spi-gpio";
++ num-chipselects = <1>;
++ gpio-sck = <&gpio6 8 0>;
++ gpio-mosi = <&gpio6 7 0>;
++ gpio-miso = <&gpio6 10 0>;
++ cs-gpios = <&gpio6 5 0>;
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ spidev@0 {
++ compatible = "spi-gpio";
++ reg = <0>;
++ spi-max-frequency = <2000000>;
++ spi-cpha;
++ spi-cpol;
++ };
++ };
++
++ hdmi1-out {
++ compatible = "hdmi-connector";
++ type = "a";
++
++ port {
++ hdmi1_con: endpoint {
++ remote-endpoint = <&rcar_dw_hdmi1_out>;
++ };
++ };
++ };
++};
++
++&du {
++ ports {
++ port@1 {
++ endpoint {
++ remote-endpoint = <&rcar_dw_hdmi0_in>;
++ };
++ };
++ port@2 {
++ endpoint {
++ remote-endpoint = <&rcar_dw_hdmi1_in>;
++ };
++ };
++ };
++};
++
++&hdmi1 {
++ status = "okay";
++
++ ports {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ port@0 {
++ reg = <0>;
++ rcar_dw_hdmi1_in: endpoint {
++ remote-endpoint = <&du_out_hdmi1>;
++ };
++ };
++ port@1 {
++ reg = <1>;
++ rcar_dw_hdmi1_out: endpoint {
++ remote-endpoint = <&hdmi1_con>;
++ };
++ };
++ };
++};
++
++&pfc {
++ scif1_pins: scif1 {
++ groups = "scif1_data_a";
++ function = "scif1";
++ };
++
++ msiof0_pins: spi1 {
++ groups = "msiof0_clk", "msiof0_rxd", "msiof0_txd",
++ "msiof0_ss1";
++ function = "msiof0";
++ };
++
++ msiof1_pins: spi2 {
++ groups = "msiof1_clk_a", "msiof1_rxd_a", "msiof1_txd_a",
++ "msiof1_ss1_a";
++ function = "msiof1";
++ };
++
++ sound_clk_pins: sound-clk {
++ groups = "audio_clk_a_a", "audio_clk_b_a", "audio_clk_c_a",
++ "audio_clkout_a" /*, "audio_clkout3_a"*/;
++ function = "audio_clk";
++ };
++
++ usb31_pins: usb31 {
++ groups = "usb31";
++ function = "usb31";
++ };
++
++ can0_pins: can0 {
++ groups = "can0_data_a";
++ function = "can0";
++ };
++
++ canfd0_pins: canfd0 {
++ groups = "canfd0_data_a";
++ function = "canfd0";
++ };
++};
++
++&scif1 {
++ pinctrl-0 = <&scif1_pins>;
++ pinctrl-names = "default";
++ status = "okay";
++};
++
++&avb {
++ /delete-property/phy-handle;
++ /delete-property/phy-gpios;
++ /delete-node/ethernet-phy@0;
++
++ fixed-link {
++ speed = <1000>;
++ full-duplex;
++ };
++};
++
++&msiof0 {
++ pinctrl-0 = <&msiof0_pins>;
++ pinctrl-names = "default";
++ status = "disabled";
++ cs-gpios = <&gpio5 19 0>;
++
++ spidev@0 {
++ compatible = "renesas,sh-msiof";
++ reg = <0>;
++ spi-max-frequency = <66666666>;
++ spi-cpha;
++ spi-cpol;
++ };
++};
++
++&msiof1 {
++ status = "disabled";
++ cs-gpios = <&gpio6 5 0>;
++};
++
++&can0 {
++ pinctrl-0 = <&can0_pins>;
++ pinctrl-names = "default";
++ status = "disabled";
++
++ renesas,can-clock-select = <0x0>;
++ gpios = <&gpio2 6 GPIO_ACTIVE_HIGH /* enable - shared with camera board */
++ &gpio2 7 GPIO_ACTIVE_LOW /* standby */
++ >;
++};
++
++&canfd {
++ pinctrl-0 = <&canfd0_pins>;
++ pinctrl-names = "default";
++ status = "okay";
++
++ renesas,can-clock-select = <0x0>;
++ gpios = <&gpio2 6 GPIO_ACTIVE_HIGH /* enable - shared with camera board */
++ &gpio2 7 GPIO_ACTIVE_LOW /* standby */
++ >;
++
++ channel0 {
++ status = "okay";
++ };
++};
+diff --git a/arch/arm64/boot/dts/renesas/r8a7795-h3ulcb-kf.dts b/arch/arm64/boot/dts/renesas/r8a7795-h3ulcb-kf.dts
+new file mode 100644
+index 0000000..4fe67f8
+--- /dev/null
++++ b/arch/arm64/boot/dts/renesas/r8a7795-h3ulcb-kf.dts
+@@ -0,0 +1,39 @@
++/*
++ * Device Tree Source for the H3ULCB Kingfisher board on r8a7795
++ *
++ * Copyright (C) 2017 Renesas Electronics Corp.
++ * Copyright (C) 2017 Cogent Embedded, Inc.
++ *
++ * This file is licensed under the terms of the GNU General Public License
++ * version 2. This program is licensed "as is" without any warranty of any
++ * kind, whether express or implied.
++ */
++
++#include "r8a7795-h3ulcb.dts"
++#include "ulcb-kf.dtsi"
++
++/ {
++ model = "Renesas H3ULCB Kingfisher board based on r8a7795";
++};
++
++&du {
++ ports {
++ port@0 {
++ endpoint {
++ remote-endpoint = <&adv7513_in>;
++ };
++ };
++ port@3 {
++ endpoint {
++ remote-endpoint = <&lvds_enc_in>;
++ };
++ };
++ };
++};
++
++&hsusb0 {
++ status = "okay";
++};
++
++/* use CN11 instead default CN29/CN48 (H3 only) */
++//#include "ulcb-kf-cn11.dtsi"
+diff --git a/arch/arm64/boot/dts/renesas/r8a7795-h3ulcb-vb.dts b/arch/arm64/boot/dts/renesas/r8a7795-h3ulcb-vb.dts
+new file mode 100644
+index 0000000..98b6a08
+--- /dev/null
++++ b/arch/arm64/boot/dts/renesas/r8a7795-h3ulcb-vb.dts
+@@ -0,0 +1,1787 @@
++/*
++ * Device Tree Source for the H3ULCB Videobox board
++ *
++ * Copyright (C) 2017 Renesas Electronics Corp.
++ * Copyright (C) 2017 Cogent Embedded, Inc.
++ *
++ * This file is licensed under the terms of the GNU General Public License
++ * version 2. This program is licensed "as is" without any warranty of any
++ * kind, whether express or implied.
++ */
++
++#include "r8a7795-h3ulcb.dts"
++
++/ {
++ model = "Renesas H3ULCB Videobox board based on r8a7795";
++
++ leds {
++ compatible = "gpio-leds";
++
++ led5 {
++ gpios = <&gpio6 12 GPIO_ACTIVE_HIGH>;
++ };
++ led6 {
++ gpios = <&gpio6 13 GPIO_ACTIVE_HIGH>;
++ };
++ /* D13 - status 0 */
++ led_ext00 {
++ gpios = <&gpio_ext_led 0 GPIO_ACTIVE_LOW>;
++ /* linux,default-trigger = "heartbeat"; */
++ };
++ /* D14 - status 1 */
++ led_ext01 {
++ gpios = <&gpio_ext_led 1 GPIO_ACTIVE_LOW>;
++ /* linux,default-trigger = "mmc1"; */
++ };
++ /* D16 - HDMI1 */
++ led_ext02 {
++ gpios = <&gpio_ext_led 2 GPIO_ACTIVE_LOW>;
++ };
++ /* D18 - HDMI0 */
++ led_ext03 {
++ gpios = <&gpio_ext_led 3 GPIO_ACTIVE_LOW>;
++ };
++ /* D20 - USB3.0 - 0.1 */
++ led_ext04 {
++ gpios = <&gpio_ext_led 4 GPIO_ACTIVE_LOW>;
++ };
++ /* D21 - USB3.0 - 0.2 */
++ led_ext05 {
++ gpios = <&gpio_ext_led 5 GPIO_ACTIVE_LOW>;
++ };
++ /* D24 - USB3.0 - 1.1 */
++ led6_ext06 {
++ gpios = <&gpio_ext_led 6 GPIO_ACTIVE_LOW>;
++ };
++ /* D25 - USB3.0 - 1.2 */
++ led_ext07 {
++ gpios = <&gpio_ext_led 7 GPIO_ACTIVE_LOW>;
++ };
++ };
++
++ snd_clk: snd_clk {
++ compatible = "fixed-clock";
++ #clock-cells = <0>;
++ clock-frequency = <24576000>;
++ clock-output-names = "scki";
++ };
++
++ vccq_sdhi3: regulator@5 {
++ compatible = "regulator-fixed";
++
++ regulator-name = "SDHI3 VccQ";
++ /* external voltage translator to 1.8V */
++ regulator-min-microvolt = <3300000>;
++ regulator-max-microvolt = <3300000>;
++ };
++
++ fpdlink_switch: regulator@8 {
++ compatible = "regulator-fixed";
++ regulator-name = "fpdlink_on";
++ regulator-min-microvolt = <3300000>;
++ regulator-max-microvolt = <3300000>;
++ gpio = <&gpio1 20 0>;
++ enable-active-high;
++ regulator-always-on;
++ };
++
++ hub_reset: regulator@9 {
++ compatible = "regulator-fixed";
++ regulator-name = "hub_reset";
++ regulator-min-microvolt = <3300000>;
++ regulator-max-microvolt = <3300000>;
++ gpio = <&gpio5 5 0>;
++ enable-active-high;
++ regulator-always-on;
++ };
++
++ hub_power: regulator@10 {
++ compatible = "regulator-fixed";
++ regulator-name = "hub_power";
++ regulator-min-microvolt = <5000000>;
++ regulator-max-microvolt = <5000000>;
++ gpio = <&gpio6 28 0>;
++ enable-active-high;
++ regulator-always-on;
++ };
++
++ /delete-node/sound;
++
++ rsnd_ak4613: sound@0 {
++ pinctrl-0 = <&sound_0_pins>;
++ pinctrl-names = "default";
++ compatible = "simple-audio-card";
++
++ simple-audio-card,format = "left_j";
++ simple-audio-card,name = "ak4613";
++
++ simple-audio-card,bitclock-master = <&sndcpu>;
++ simple-audio-card,frame-master = <&sndcpu>;
++
++ sndcpu: simple-audio-card,cpu@1 {
++ sound-dai = <&rcar_sound>;
++ };
++
++ sndcodec: simple-audio-card,codec@1 {
++ sound-dai = <&ak4613>;
++ };
++ };
++
++ lvds-encoder {
++ compatible = "thine,thc63lvdm83d";
++
++ ports {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ port@0 {
++ reg = <0>;
++ lvds_enc_in: endpoint {
++ remote-endpoint = <&du_out_lvds0>;
++ };
++ };
++ port@1 {
++ reg = <1>;
++ lvds_enc_out: endpoint {
++ remote-endpoint = <&lvds_in>;
++ };
++ };
++ };
++ };
++
++ lvds {
++ compatible = "lvds-connector";
++
++ width-mm = <210>;
++ height-mm = <158>;
++
++ panel-timing {
++ /* 1280x800 @60Hz */
++ clock-frequency = <65000000>;
++ hactive = <1280>;
++ vactive = <800>;
++ hsync-len = <40>;
++ hfront-porch = <80>;
++ hback-porch = <40>;
++ vfront-porch = <14>;
++ vback-porch = <14>;
++ vsync-len = <4>;
++ };
++
++ port {
++ lvds_in: endpoint {
++ remote-endpoint = <&lvds_enc_out>;
++ };
++ };
++ };
++
++ hdmi1-out {
++ compatible = "hdmi-connector";
++ type = "a";
++
++ port {
++ hdmi1_con: endpoint {
++ remote-endpoint = <&rcar_dw_hdmi1_out>;
++ };
++ };
++ };
++
++ excan_ref_clk: excan-ref-clock {
++ compatible = "fixed-clock";
++ #clock-cells = <0>;
++ clock-frequency = <16000000>;
++ };
++
++ radio: si468x@0 {
++ compatible = "si,si468x-pcm";
++ status = "okay";
++
++ #sound-dai-cells = <0>;
++ };
++
++ spi_gpio_sw {
++ compatible = "spi-gpio";
++ #address-cells = <0x1>;
++ #size-cells = <0x0>;
++ gpio-sck = <&gpio0 8 GPIO_ACTIVE_HIGH>;
++ gpio-miso = <&gpio0 10 GPIO_ACTIVE_HIGH>;
++ gpio-mosi = <&gpio0 11 GPIO_ACTIVE_HIGH>;
++ cs-gpios = <&gpio0 9 GPIO_ACTIVE_HIGH>;
++ num-chipselects = <1>;
++
++ spidev: spidev@0 {
++ compatible = "spidev", "spi-gpio";
++ reg = <0>;
++ spi-max-frequency = <25000000>;
++ spi-cpha;
++ spi-cpol;
++ };
++ };
++
++ spi_gpio_can {
++ compatible = "spi-gpio";
++ #address-cells = <0x1>;
++ #size-cells = <0x0>;
++ gpio-sck = <&gpio1 2 GPIO_ACTIVE_HIGH>;
++ gpio-miso = <&gpio1 3 GPIO_ACTIVE_HIGH>;
++ gpio-mosi = <&gpio1 1 GPIO_ACTIVE_HIGH>;
++ cs-gpios = <&gpio1 0 GPIO_ACTIVE_HIGH
++ &gpio1 4 GPIO_ACTIVE_HIGH>;
++ num-chipselects = <2>;
++
++ spican0: spidev@0 {
++ compatible = "microchip,mcp2515";
++ reg = <0>;
++ clocks = <&excan_ref_clk>;
++ interrupt-parent = <&gpio0>;
++ interrupts = <15 GPIO_ACTIVE_LOW>;
++ spi-max-frequency = <10000000>;
++ };
++ spican1: spidev@1 {
++ compatible = "microchip,mcp2515";
++ reg = <1>;
++ clocks = <&excan_ref_clk>;
++ interrupt-parent = <&gpio1>;
++ interrupts = <5 GPIO_ACTIVE_LOW>;
++ spi-max-frequency = <10000000>;
++ };
++ };
++};
++
++&du {
++ ports {
++ port@1 {
++ endpoint {
++ remote-endpoint = <&rcar_dw_hdmi0_in>;
++ };
++ };
++ port@2 {
++ endpoint {
++ remote-endpoint = <&rcar_dw_hdmi1_in>;
++ };
++ };
++ port@3 {
++ endpoint {
++ remote-endpoint = <&lvds_enc_in>;
++ };
++ };
++ };
++};
++
++&hdmi1 {
++ status = "okay";
++
++ ports {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ port@0 {
++ reg = <0>;
++ rcar_dw_hdmi1_in: endpoint {
++ remote-endpoint = <&du_out_hdmi1>;
++ };
++ };
++ port@1 {
++ reg = <1>;
++ rcar_dw_hdmi1_out: endpoint {
++ remote-endpoint = <&hdmi1_con>;
++ };
++ };
++ };
++};
++
++&pfc {
++ hscif4_pins: hscif4 {
++ groups = "hscif4_data_a", "hscif4_ctrl";
++ function = "hscif4";
++ };
++
++ sdhi3_pins_3v3: sd3_3v3 {
++ groups = "sdhi3_data4", "sdhi3_ctrl";
++ function = "sdhi3";
++ power-source = <3300>;
++ };
++
++ /delete-node/sound;
++
++ sound_0_pins: sound1 {
++ groups = "ssi01239_ctrl", "ssi0_data", "ssi1_data_a";
++ function = "ssi";
++ };
++
++ usb0_pins: usb0 {
++ groups = "usb0";
++ function = "usb0";
++ };
++
++ can0_pins: can0 {
++ groups = "can0_data_a";
++ function = "can0";
++ };
++
++ can1_pins: can1 {
++ groups = "can1_data";
++ function = "can1";
++ };
++
++ canfd0_pins: canfd0 {
++ groups = "canfd0_data_a";
++ function = "canfd0";
++ };
++
++ canfd1_pins: canfd1 {
++ groups = "canfd1_data";
++ function = "canfd1";
++ };
++};
++
++&gpio0 {
++ video_a_irq {
++ gpio-hog;
++ gpios = <12 GPIO_ACTIVE_HIGH>;
++ input;
++ line-name = "Video-A irq";
++ };
++
++ video_b_irq {
++ gpio-hog;
++ gpios = <13 GPIO_ACTIVE_HIGH>;
++ input;
++ line-name = "Video-B irq";
++ };
++
++ video_c_irq {
++ gpio-hog;
++ gpios = <14 GPIO_ACTIVE_HIGH>;
++ input;
++ line-name = "Video-C irq";
++ };
++};
++
++&gpio1 {
++ gpioext_4_22_irq {
++ gpio-hog;
++ gpios = <25 GPIO_ACTIVE_HIGH>;
++ input;
++ line-name = "0x22@i2c4 irq";
++ };
++ pcie_disable {
++ gpio-hog;
++ gpios = <11 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "mPCIe W_DISABLE";
++ };
++ m2_sleep {
++ gpio-hog;
++ gpios = <6 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "M.2 SLEEP#";
++ };
++ m2_pres {
++ gpio-hog;
++ gpios = <7 GPIO_ACTIVE_HIGH>;
++ input;
++ line-name = "M.2 Present";
++ };
++ m2_pcie_det {
++ gpio-hog;
++ gpios = <18 GPIO_ACTIVE_HIGH>;
++ input;
++ line-name = "M.2 PCIe detected";
++ };
++ m2_usb_det {
++ gpio-hog;
++ gpios = <19 GPIO_ACTIVE_HIGH>;
++ input;
++ line-name = "M.2 USB30 detected";
++ };
++ m2_usb_det {
++ gpio-hog;
++ gpios = <27 GPIO_ACTIVE_HIGH>;
++ input;
++ line-name = "M.2 SSD detected";
++ };
++ eth_phy_reset {
++ gpio-hog;
++ gpios = <16 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "BR phy reset";
++ };
++ eth_sw_reset {
++ gpio-hog;
++ gpios = <17 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "BR switch reset";
++ };
++};
++
++&gpio2 {
++ m2_wake {
++ gpio-hog;
++ gpios = <1 GPIO_ACTIVE_HIGH>;
++ input;
++ line-name = "M.2 WAKE#";
++ };
++ m2_pcie_en {
++ gpio-hog;
++ gpios = <4 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "M.2 PCIe enable";
++ };
++};
++
++&gpio3 {
++ m2_power_off {
++ gpio-hog;
++ gpios = <15 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "M.2 FULL_CARD_POWER_OFF#";
++ };
++};
++
++&gpio6 {
++ pcie_wake {
++ gpio-hog;
++ gpios = <4 GPIO_ACTIVE_HIGH>;
++ input;
++ line-name = "mPCIe WAKE#";
++ };
++ pcie_clkreq {
++ gpio-hog;
++ gpios = <10 GPIO_ACTIVE_HIGH>;
++ input;
++ line-name = "mPCIe CLKREQ#";
++ };
++ m2_rst {
++ gpio-hog;
++ gpios = <21 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "M.2 RESET#";
++ };
++};
++
++&hscif4 {
++ pinctrl-0 = <&hscif4_pins>;
++ pinctrl-names = "default";
++ uart-has-rtscts;
++
++ status = "okay";
++};
++
++&i2c2 {
++ clock-frequency = <400000>;
++
++ i2cswitch2: pca9548@74 {
++ compatible = "nxp,pca9548";
++ #address-cells = <1>;
++ #size-cells = <0>;
++ reg = <0x74>;
++ reset-gpios = <&gpio6 5 GPIO_ACTIVE_LOW>;
++
++ i2c@0 {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ reg = <0>;
++ /* USB3.0 HUB node(s) */
++ };
++
++ i2c@6 {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ reg = <6>;
++ /* PCIe node(s) */
++ };
++
++ i2c@7 {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ reg = <7>;
++ /* Slot A (CN10) */
++
++ ov106xx@0 {
++ compatible = "ovti,ov106xx";
++ reg = <0x60>;
++
++ port@0 {
++ ov106xx_in0: endpoint {
++ clock-lanes = <0>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&vin0ep0>;
++ };
++ };
++ port@1 {
++ ov106xx_max9286_des0ep0: endpoint@0 {
++ remote-endpoint = <&max9286_des0ep0>;
++ };
++ ov106xx_ti964_des0ep0: endpoint@1 {
++ remote-endpoint = <&ti964_des0ep0>;
++ };
++ ov106xx_ti954_des0ep0: endpoint@2 {
++ remote-endpoint = <&ti954_des0ep0>;
++ };
++ };
++ };
++
++ ov106xx@1 {
++ compatible = "ovti,ov106xx";
++ reg = <0x61>;
++
++ port@0 {
++ ov106xx_in1: endpoint {
++ clock-lanes = <0>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&vin1ep0>;
++ };
++ };
++ port@1 {
++ ov106xx_max9286_des0ep1: endpoint@0 {
++ remote-endpoint = <&max9286_des0ep1>;
++ };
++ ov106xx_ti964_des0ep1: endpoint@1 {
++ remote-endpoint = <&ti964_des0ep1>;
++ };
++ ov106xx_ti954_des0ep1: endpoint@2 {
++ remote-endpoint = <&ti954_des0ep1>;
++ };
++ };
++ };
++
++ ov106xx@2 {
++ compatible = "ovti,ov106xx";
++ reg = <0x62>;
++
++ port@0 {
++ ov106xx_in2: endpoint {
++ clock-lanes = <0>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&vin2ep0>;
++ };
++ };
++ port@1 {
++ ov106xx_max9286_des0ep2: endpoint@0 {
++ remote-endpoint = <&max9286_des0ep2>;
++ };
++ ov106xx_ti964_des0ep2: endpoint@1 {
++ remote-endpoint = <&ti964_des0ep2>;
++ };
++ };
++ };
++
++ ov106xx@3 {
++ compatible = "ovti,ov106xx";
++ reg = <0x63>;
++
++ port@0 {
++ ov106xx_in3: endpoint {
++ clock-lanes = <0>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&vin3ep0>;
++ };
++ };
++ port@1 {
++ ov106xx_max9286_des0ep3: endpoint@0 {
++ remote-endpoint = <&max9286_des0ep3>;
++ };
++ ov106xx_ti964_des0ep3: endpoint@1 {
++ remote-endpoint = <&ti964_des0ep3>;
++ };
++ };
++ };
++
++ /* DS90UB964 @ 0x3a */
++ ti964-ti9x3@0 {
++ compatible = "ti,ti964-ti9x3";
++ reg = <0x3a>;
++ ti,sensor_delay = <350>;
++ ti,links = <4>;
++ ti,lanes = <4>;
++ ti,forwarding-mode = "round-robin";
++ ti,cable-mode = "stp";
++
++ port@0 {
++ ti964_des0ep0: endpoint@0 {
++ ti9x3-addr = <0x0c>;
++ dvp-order = <0>;
++ remote-endpoint = <&ov106xx_in0>;
++ };
++ ti964_des0ep1: endpoint@1 {
++ ti9x3-addr = <0x0d>;
++ dvp-order = <0>;
++ remote-endpoint = <&ov106xx_in1>;
++ };
++ ti964_des0ep2: endpoint@2 {
++ ti9x3-addr = <0x0e>;
++ dvp-order = <0>;
++ remote-endpoint = <&ov106xx_in2>;
++ };
++ ti964_des0ep3: endpoint@3 {
++ ti9x3-addr = <0x0f>;
++ dvp-order = <0>;
++ remote-endpoint = <&ov106xx_in3>;
++ };
++ };
++ port@1 {
++ ti964_csi0ep0: endpoint {
++ csi-rate = <1450>;
++ remote-endpoint = <&csi2_40_ep>;
++ };
++ };
++ };
++
++ /* DS90UB954 @ 0x38 */
++ ti954-ti9x3@0 {
++ compatible = "ti,ti954-ti9x3";
++ reg = <0x38>;
++ /* gpios = <&video_a_ext1 10 GPIO_ACTIVE_HIGH>; */
++ ti,sensor_delay = <350>;
++ ti,links = <2>;
++ ti,lanes = <4>;
++ ti,forwarding-mode = "round-robin";
++ ti,cable-mode = "stp";
++
++ port@0 {
++ ti954_des0ep0: endpoint@0 {
++ ti9x3-addr = <0x0c>;
++ dvp-order = <0>;
++ remote-endpoint = <&ov106xx_in0>;
++ };
++ ti954_des0ep1: endpoint@1 {
++ ti9x3-addr = <0x0d>;
++ dvp-order = <0>;
++ remote-endpoint = <&ov106xx_in1>;
++ };
++ };
++ port@1 {
++ ti954_csi0ep0: endpoint {
++ csi-rate = <1450>;
++ remote-endpoint = <&csi2_40_ep>;
++ };
++ };
++ };
++
++ /* MAX9286 @ 0x2c */
++ max9286-max9271@0 {
++ compatible = "maxim,max9286-max9271";
++ reg = <0x2c>;
++ maxim,sensor_delay = <350>;
++ maxim,links = <4>;
++ maxim,lanes = <4>;
++ maxim,resetb-gpio = <1>;
++ maxim,fsync-mode = "automatic";
++ maxim,timeout = <100>;
++
++ port@0 {
++ max9286_des0ep0: endpoint@0 {
++ max9271-addr = <0x50>;
++ dvp-order = <1>;
++ remote-endpoint = <&ov106xx_in0>;
++ };
++ max9286_des0ep1: endpoint@1 {
++ max9271-addr = <0x51>;
++ dvp-order = <1>;
++ remote-endpoint = <&ov106xx_in1>;
++ };
++ max9286_des0ep2: endpoint@2 {
++ max9271-addr = <0x52>;
++ dvp-order = <1>;
++ remote-endpoint = <&ov106xx_in2>;
++ };
++ max9286_des0ep3: endpoint@3 {
++ max9271-addr = <0x53>;
++ dvp-order = <1>;
++ remote-endpoint = <&ov106xx_in3>;
++ };
++ };
++ port@1 {
++ max9286_csi0ep0: endpoint {
++ csi-rate = <700>;
++ remote-endpoint = <&csi2_40_ep>;
++ };
++ };
++ };
++ };
++
++ i2c@2 {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ reg = <2>;
++ /* Slot B (CN11) */
++
++ ov106xx@4 {
++ compatible = "ovti,ov106xx";
++ reg = <0x64>;
++
++ port@0 {
++ ov106xx_in4: endpoint {
++ clock-lanes = <0>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&vin4ep0>;
++ };
++ };
++ port@1 {
++ ov106xx_max9286_des1ep0: endpoint@0 {
++ remote-endpoint = <&max9286_des1ep0>;
++ };
++ ov106xx_ti964_des1ep0: endpoint@1 {
++ remote-endpoint = <&ti964_des1ep0>;
++ };
++ ov106xx_ti954_des1ep0: endpoint@2 {
++ remote-endpoint = <&ti954_des1ep0>;
++ };
++ };
++ };
++
++ ov106xx@5 {
++ compatible = "ovti,ov106xx";
++ reg = <0x65>;
++
++ port@0 {
++ ov106xx_in5: endpoint {
++ clock-lanes = <0>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&vin5ep0>;
++ };
++ };
++ port@1 {
++ ov106xx_max9286_des1ep1: endpoint@0 {
++ remote-endpoint = <&max9286_des1ep1>;
++ };
++ ov106xx_ti964_des1ep1: endpoint@1 {
++ remote-endpoint = <&ti964_des1ep1>;
++ };
++ ov106xx_ti954_des1ep1: endpoint@2 {
++ remote-endpoint = <&ti954_des1ep1>;
++ };
++ };
++ };
++
++ ov106xx@6 {
++ compatible = "ovti,ov106xx";
++ reg = <0x66>;
++
++ port@0 {
++ ov106xx_in6: endpoint {
++ clock-lanes = <0>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&vin6ep0>;
++ };
++ };
++ port@1 {
++ ov106xx_max9286_des1ep2: endpoint@0 {
++ remote-endpoint = <&max9286_des1ep2>;
++ };
++ ov106xx_ti964_des1ep2: endpoint@1 {
++ remote-endpoint = <&ti964_des1ep2>;
++ };
++ };
++ };
++
++ ov106xx@7 {
++ compatible = "ovti,ov106xx";
++ reg = <0x67>;
++
++ port@0 {
++ ov106xx_in7: endpoint {
++ clock-lanes = <0>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&vin7ep0>;
++ };
++ };
++ port@1 {
++ ov106xx_max9286_des1ep3: endpoint@0 {
++ remote-endpoint = <&max9286_des1ep3>;
++ };
++ ov106xx_ti964_des1ep3: endpoint@1 {
++ remote-endpoint = <&ti964_des1ep3>;
++ };
++ };
++ };
++
++ /* DS90UB964 @ 0x3a */
++ ti964-ti9x3@1 {
++ compatible = "ti,ti964-ti9x3";
++ reg = <0x3a>;
++ ti,sensor_delay = <350>;
++ ti,links = <4>;
++ ti,lanes = <4>;
++ ti,forwarding-mode = "round-robin";
++ ti,cable-mode = "stp";
++
++ port@0 {
++ ti964_des1ep0: endpoint@0 {
++ ti9x3-addr = <0x0c>;
++ dvp-order = <0>;
++ remote-endpoint = <&ov106xx_in4>;
++ };
++ ti964_des1ep1: endpoint@1 {
++ ti9x3-addr = <0x0d>;
++ dvp-order = <0>;
++ remote-endpoint = <&ov106xx_in5>;
++ };
++ ti964_des1ep2: endpoint@2 {
++ ti9x3-addr = <0x0e>;
++ dvp-order = <0>;
++ remote-endpoint = <&ov106xx_in6>;
++ };
++ ti964_des1ep3: endpoint@3 {
++ ti9x3-addr = <0x0f>;
++ dvp-order = <0>;
++ remote-endpoint = <&ov106xx_in7>;
++ };
++ };
++ port@1 {
++ ti964_csi2ep0: endpoint {
++ csi-rate = <1450>;
++ remote-endpoint = <&csi2_41_ep>;
++ };
++ };
++ };
++
++ /* DS90UB954 @ 0x38 */
++ ti954-ti9x3@1 {
++ compatible = "ti,ti954-ti9x3";
++ reg = <0x38>;
++ /* gpios = <&video_b_ext1 10 GPIO_ACTIVE_HIGH>; */
++ ti,sensor_delay = <350>;
++ ti,links = <2>;
++ ti,lanes = <4>;
++ ti,forwarding-mode = "round-robin";
++ ti,cable-mode = "stp";
++
++ port@0 {
++ ti954_des1ep0: endpoint@0 {
++ ti9x3-addr = <0x0c>;
++ dvp-order = <0>;
++ remote-endpoint = <&ov106xx_in4>;
++ };
++ ti954_des1ep1: endpoint@1 {
++ ti9x3-addr = <0x0d>;
++ dvp-order = <0>;
++ remote-endpoint = <&ov106xx_in5>;
++ };
++ };
++ port@1 {
++ ti954_csi2ep0: endpoint {
++ csi-rate = <1450>;
++ remote-endpoint = <&csi2_41_ep>;
++ };
++ };
++ };
++
++ /* MAX9286 @ 0x2c */
++ max9286-max9271@1 {
++ compatible = "maxim,max9286-max9271";
++ reg = <0x2c>;
++ maxim,sensor_delay = <350>;
++ maxim,links = <4>;
++ maxim,lanes = <4>;
++ maxim,resetb-gpio = <1>;
++ maxim,fsync-mode = "automatic";
++ maxim,timeout = <100>;
++
++ port@0 {
++ max9286_des1ep0: endpoint@0 {
++ max9271-addr = <0x50>;
++ dvp-order = <1>;
++ remote-endpoint = <&ov106xx_in4>;
++ };
++ max9286_des1ep1: endpoint@1 {
++ max9271-addr = <0x51>;
++ dvp-order = <1>;
++ remote-endpoint = <&ov106xx_in5>;
++ };
++ max9286_des1ep2: endpoint@2 {
++ max9271-addr = <0x52>;
++ dvp-order = <1>;
++ remote-endpoint = <&ov106xx_in6>;
++ };
++ max9286_des1ep3: endpoint@3 {
++ max9271-addr = <0x53>;
++ dvp-order = <1>;
++ remote-endpoint = <&ov106xx_in7>;
++ };
++ };
++ port@1 {
++ max9286_csi2ep0: endpoint {
++ csi-rate = <700>;
++ remote-endpoint = <&csi2_41_ep>;
++ };
++ };
++ };
++ };
++
++ i2c@3 {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ reg = <3>;
++ /* Slot C (CN12) */
++ };
++
++ i2c@1 {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ reg = <1>;
++ /* Slot A (CN10) */
++
++ video_a_ext0: pca9535@26 {
++ compatible = "nxp,pca9535";
++ reg = <0x26>;
++ gpio-controller;
++ #gpio-cells = <2>;
++
++ video_a_des_cfg1 {
++ gpio-hog;
++ gpios = <5 GPIO_ACTIVE_HIGH>;
++ input;
++ line-name = "Video-A cfg1";
++ };
++ video_a_des_cfg0 {
++ gpio-hog;
++ gpios = <6 GPIO_ACTIVE_HIGH>;
++ input;
++ line-name = "Video-A cfg0";
++ };
++ video_a_pwr_shdn {
++ gpio-hog;
++ gpios = <3 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "Video-A PWR_SHDN";
++ };
++ video_a_cam_pwr0 {
++ gpio-hog;
++ gpios = <12 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "Video-A PWR0";
++ };
++ video_a_cam_pwr1 {
++ gpio-hog;
++ gpios = <13 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "Video-A PWR1";
++ };
++ video_a_cam_pwr2 {
++ gpio-hog;
++ gpios = <14 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "Video-A PWR2";
++ };
++ video_a_cam_pwr3 {
++ gpio-hog;
++ gpios = <15 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "Video-A PWR3";
++ };
++ video_a_des_shdn {
++ gpio-hog;
++ gpios = <4 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "Video-A DES_SHDN";
++ };
++ video_a_des_led {
++ gpio-hog;
++ gpios = <7 GPIO_ACTIVE_HIGH>;
++ output-low;
++ line-name = "Video-A led";
++ };
++ };
++
++ video_a_ext1: max7325@5c {
++ compatible = "maxim,max7325";
++ reg = <0x5c>;
++ gpio-controller;
++ #gpio-cells = <2>;
++
++ video_a_des_cfg2 {
++ gpio-hog;
++ gpios = <4 GPIO_ACTIVE_HIGH>;
++ input;
++ line-name = "Video-A cfg2";
++ };
++ video_a_des_cfg1 {
++ gpio-hog;
++ gpios = <6 GPIO_ACTIVE_HIGH>;
++ input;
++ line-name = "Video-A cfg1";
++ };
++ video_a_des_cfg0 {
++ gpio-hog;
++ gpios = <7 GPIO_ACTIVE_HIGH>;
++ input;
++ line-name = "Video-A cfg0";
++ };
++ video_a_pwr_shdn {
++ gpio-hog;
++ gpios = <14 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "Video-A PWR_SHDN";
++ };
++ video_a_cam_pwr0 {
++ gpio-hog;
++ gpios = <8 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "Video-A PWR0";
++ };
++ video_a_cam_pwr1 {
++ gpio-hog;
++ gpios = <9 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "Video-A PWR1";
++ };
++ video_a_cam_pwr2 {
++ gpio-hog;
++ gpios = <10 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "Video-A PWR2";
++ };
++ video_a_cam_pwr3 {
++ gpio-hog;
++ gpios = <11 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "Video-A PWR3";
++ };
++ video_a_des_shdn {
++ gpio-hog;
++ gpios = <13 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "Video-A DES_SHDN";
++ };
++ video_a_led {
++ gpio-hog;
++ gpios = <12 GPIO_ACTIVE_HIGH>;
++ output-low;
++ line-name = "Video-A LED";
++ };
++ };
++ };
++
++ i2c@5 {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ reg = <5>;
++ /* Slot B (CN11) */
++
++ video_b_ext0: pca9535@26 {
++ compatible = "nxp,pca9535";
++ reg = <0x26>;
++ gpio-controller;
++ #gpio-cells = <2>;
++
++ video_b_des_cfg1 {
++ gpio-hog;
++ gpios = <5 GPIO_ACTIVE_HIGH>;
++ input;
++ line-name = "Video-B cfg1";
++ };
++ video_b_des_cfg0 {
++ gpio-hog;
++ gpios = <6 GPIO_ACTIVE_HIGH>;
++ input;
++ line-name = "Video-B cfg0";
++ };
++ video_b_pwr_shdn {
++ gpio-hog;
++ gpios = <3 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "Video-B PWR_SHDN";
++ };
++ video_b_cam_pwr0 {
++ gpio-hog;
++ gpios = <12 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "Video-B PWR0";
++ };
++ video_b_cam_pwr1 {
++ gpio-hog;
++ gpios = <13 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "Video-B PWR1";
++ };
++ video_b_cam_pwr2 {
++ gpio-hog;
++ gpios = <14 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "Video-B PWR2";
++ };
++ video_b_cam_pwr3 {
++ gpio-hog;
++ gpios = <15 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "Video-B PWR3";
++ };
++ video_b_des_shdn {
++ gpio-hog;
++ gpios = <4 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "Video-B DES_SHDN";
++ };
++ video_b_des_led {
++ gpio-hog;
++ gpios = <7 GPIO_ACTIVE_HIGH>;
++ output-low;
++ line-name = "Video-B led";
++ };
++ };
++
++ video_b_ext1: max7325@5c {
++ compatible = "maxim,max7325";
++ reg = <0x5c>;
++ gpio-controller;
++ #gpio-cells = <2>;
++
++ video_b_des_cfg2 {
++ gpio-hog;
++ gpios = <4 GPIO_ACTIVE_HIGH>;
++ input;
++ line-name = "Video-B cfg2";
++ };
++ video_b_des_cfg1 {
++ gpio-hog;
++ gpios = <6 GPIO_ACTIVE_HIGH>;
++ input;
++ line-name = "Video-B cfg1";
++ };
++ video_b_des_cfg0 {
++ gpio-hog;
++ gpios = <7 GPIO_ACTIVE_HIGH>;
++ input;
++ line-name = "Video-B cfg0";
++ };
++ video_b_pwr_shdn {
++ gpio-hog;
++ gpios = <14 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "Video-B PWR_SHDN";
++ };
++ video_b_cam_pwr0 {
++ gpio-hog;
++ gpios = <8 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "Video-B PWR0";
++ };
++ video_b_cam_pwr1 {
++ gpio-hog;
++ gpios = <9 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "Video-B PWR1";
++ };
++ video_b_cam_pwr2 {
++ gpio-hog;
++ gpios = <10 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "Video-B PWR2";
++ };
++ video_b_cam_pwr3 {
++ gpio-hog;
++ gpios = <11 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "Video-B PWR3";
++ };
++ video_b_des_shdn {
++ gpio-hog;
++ gpios = <13 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "Video-B DES_SHDN";
++ };
++ video_b_led {
++ gpio-hog;
++ gpios = <12 GPIO_ACTIVE_HIGH>;
++ output-low;
++ line-name = "Video-B LED";
++ };
++ };
++ };
++
++ i2c@4 {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ reg = <4>;
++ /* Slot C (CN12) */
++ };
++ };
++};
++
++&i2c4 {
++ i2cswitch4: pca9548@74 {
++ compatible = "nxp,pca9548";
++ #address-cells = <1>;
++ #size-cells = <0>;
++ reg = <0x74>;
++ reset-gpios= <&gpio5 15 GPIO_ACTIVE_LOW>;
++
++ i2c@0 {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ reg = <0>;
++ /* FAN node - EMC2103 */
++ fan_ctrl:ecm2103@2e {
++ compatible = "emc2103";
++ reg = <0x2e>;
++ };
++ };
++
++ i2c@1 {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ reg = <1>;
++ /* Power nodes - 2 x TPS544x20 */
++ };
++
++ i2c@2 {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ reg = <2>;
++ /* CAN and power board nodes */
++
++ gpio_ext_pwr: pca9535@22 {
++ compatible = "nxp,pca9535";
++ reg = <0x22>;
++ gpio-controller;
++ #gpio-cells = <2>;
++ interrupt-controller;
++ interrupt-parent = <&gpio1>;
++ interrupts = <25 IRQ_TYPE_EDGE_FALLING>;
++
++ /* enable input DCDC after wake-up signal released */
++ pwr_hold {
++ gpio-hog;
++ gpios = <11 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "pwr_hold";
++ };
++
++ /* CAN0 */
++ can0_stby {
++ gpio-hog;
++ gpios = <4 GPIO_ACTIVE_HIGH>;
++ output-low;
++ line-name = "can0_stby";
++ };
++ can0_load {
++ gpio-hog;
++ gpios = <0 GPIO_ACTIVE_HIGH>;
++ output-low;
++ line-name = "can0_120R_load";
++ };
++ /* CAN1 */
++ can1_stby {
++ gpio-hog;
++ gpios = <5 GPIO_ACTIVE_HIGH>;
++ output-low;
++ line-name = "can1_stby";
++ };
++ can1_load {
++ gpio-hog;
++ gpios = <1 GPIO_ACTIVE_HIGH>;
++ output-low;
++ line-name = "can1_120R_load";
++ };
++ /* CAN2 */
++ can2_stby {
++ gpio-hog;
++ gpios = <6 GPIO_ACTIVE_HIGH>;
++ output-low;
++ line-name = "can2_stby";
++ };
++ can2_load {
++ gpio-hog;
++ gpios = <2 GPIO_ACTIVE_HIGH>;
++ output-low;
++ line-name = "can2_120R_load";
++ };
++ can2_rst {
++ gpio-hog;
++ gpios = <8 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "can2_rst";
++ };
++ /* CAN3 */
++ can3_stby {
++ gpio-hog;
++ gpios = <7 GPIO_ACTIVE_HIGH>;
++ output-low;
++ line-name = "can3_stby";
++ };
++ can3_load {
++ gpio-hog;
++ gpios = <3 GPIO_ACTIVE_HIGH>;
++ output-low;
++ line-name = "can3_120R_load";
++ };
++ can3_rst {
++ gpio-hog;
++ gpios = <9 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "can3_rst";
++ };
++ };
++ };
++
++ i2c@3 {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ reg = <3>;
++ /* FPDLink output node - DS90UH947 */
++ };
++
++ i2c@4 {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ reg = <4>;
++ /* BCM switch node */
++ };
++
++ i2c@5 {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ reg = <5>;
++ /* LED board node(s) */
++
++ gpio_ext_led: pca9535@22 {
++ compatible = "nxp,pca9535";
++ reg = <0x22>;
++ gpio-controller;
++ #gpio-cells = <2>;
++
++ /* gpios 0..7 are used for indication LEDs, low-active */
++ };
++ };
++
++ i2c@6 {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ reg = <6>;
++ /* M2 connector i2c node(s) */
++ };
++
++ /* port 7 is not used */
++ };
++};
++
++&pcie_bus_clk {
++ clock-frequency = <100000000>;
++ status = "okay";
++};
++
++&pciec0 {
++ status = "okay";
++};
++
++&pciec1 {
++ status = "okay";
++};
++
++&vin0 {
++ status = "okay";
++
++ ports {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ port@0 {
++ vin0ep0: endpoint {
++ csi,select = "csi40";
++ virtual,channel = <0>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&ov106xx_in0>;
++ };
++ };
++ port@1 {
++ csi0ep0: endpoint {
++ remote-endpoint = <&csi2_40_ep>;
++ };
++ };
++ port@2 {
++ vin0_max9286_des0ep0: endpoint@0 {
++ remote-endpoint = <&max9286_des0ep0>;
++ };
++ vin0_ti964_des0ep0: endpoint@1 {
++ remote-endpoint = <&ti964_des0ep0>;
++ };
++ vin0_ti954_des0ep0: endpoint@2 {
++ remote-endpoint = <&ti954_des0ep0>;
++ };
++ };
++ };
++};
++
++&vin1 {
++ status = "okay";
++
++ ports {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ port@0 {
++ vin1ep0: endpoint {
++ csi,select = "csi40";
++ virtual,channel = <1>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&ov106xx_in1>;
++ };
++ };
++ port@1 {
++ csi0ep1: endpoint {
++ remote-endpoint = <&csi2_40_ep>;
++ };
++ };
++ port@2 {
++ vin1_max9286_des0ep1: endpoint@0 {
++ remote-endpoint = <&max9286_des0ep1>;
++ };
++ vin1_ti964_des0ep1: endpoint@1 {
++ remote-endpoint = <&ti964_des0ep1>;
++ };
++ vin1_ti954_des0ep1: endpoint@2 {
++ remote-endpoint = <&ti954_des0ep1>;
++ };
++ };
++ };
++};
++
++&vin2 {
++ status = "okay";
++
++ ports {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ port@0 {
++ vin2ep0: endpoint {
++ csi,select = "csi40";
++ virtual,channel = <2>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&ov106xx_in2>;
++ };
++ };
++ port@1 {
++ csi0ep2: endpoint {
++ remote-endpoint = <&csi2_40_ep>;
++ };
++ };
++ port@2 {
++ vin2_max9286_des0ep2: endpoint@0 {
++ remote-endpoint = <&max9286_des0ep2>;
++ };
++ vin2_ti964_des0ep2: endpoint@1 {
++ remote-endpoint = <&ti964_des0ep2>;
++ };
++ };
++ };
++};
++
++&vin3 {
++ status = "okay";
++
++ ports {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ port@0 {
++ vin3ep0: endpoint {
++ csi,select = "csi40";
++ virtual,channel = <3>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&ov106xx_in3>;
++ };
++ };
++ port@1 {
++ csi0ep3: endpoint {
++ remote-endpoint = <&csi2_40_ep>;
++ };
++ };
++ port@2 {
++ vin3_max9286_des0ep3: endpoint@0 {
++ remote-endpoint = <&max9286_des0ep3>;
++ };
++ vin3_ti964_des0ep3: endpoint@1 {
++ remote-endpoint = <&ti964_des0ep3>;
++ };
++ };
++ };
++};
++
++&vin4 {
++ status = "okay";
++
++ ports {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ port@0 {
++ vin4ep0: endpoint {
++ csi,select = "csi41";
++ virtual,channel = <0>;
++ remote-endpoint = <&ov106xx_in4>;
++ data-lanes = <1 2 3 4>;
++ };
++ };
++ port@1 {
++ csi2ep0: endpoint {
++ remote-endpoint = <&csi2_41_ep>;
++ };
++ };
++ port@2 {
++ vin4_max9286_des1ep0: endpoint@0 {
++ remote-endpoint = <&max9286_des1ep0>;
++ };
++ vin4_ti964_des1ep0: endpoint@1 {
++ remote-endpoint = <&ti964_des1ep0>;
++ };
++ vin4_ti954_des1ep0: endpoint@2 {
++ remote-endpoint = <&ti954_des1ep0>;
++ };
++ };
++ };
++};
++
++&vin5 {
++ status = "okay";
++
++ ports {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ port@0 {
++ vin5ep0: endpoint@0 {
++ csi,select = "csi41";
++ virtual,channel = <1>;
++ remote-endpoint = <&ov106xx_in5>;
++ data-lanes = <1 2 3 4>;
++ };
++ };
++ port@1 {
++ csi2ep1: endpoint {
++ remote-endpoint = <&csi2_41_ep>;
++ };
++ };
++ port@2 {
++ vin5_max9286_des1ep1: endpoint@0 {
++ remote-endpoint = <&max9286_des1ep1>;
++ };
++ vin5_ti964_des1ep1: endpoint@1 {
++ remote-endpoint = <&ti964_des1ep1>;
++ };
++ vin5_ti954_des1ep1: endpoint@2 {
++ remote-endpoint = <&ti954_des1ep1>;
++ };
++ };
++ };
++};
++
++&vin6 {
++ status = "okay";
++
++ ports {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ port@0 {
++ vin6ep0: endpoint@0 {
++ csi,select = "csi41";
++ virtual,channel = <2>;
++ remote-endpoint = <&ov106xx_in6>;
++ data-lanes = <1 2 3 4>;
++ };
++ };
++ port@1 {
++ csi2ep2: endpoint {
++ remote-endpoint = <&csi2_41_ep>;
++ };
++ };
++ port@2 {
++ vin6_max9286_des1ep2: endpoint@0 {
++ remote-endpoint = <&max9286_des1ep2>;
++ };
++ vin6_ti964_des1ep2: endpoint@1 {
++ remote-endpoint = <&ti964_des1ep2>;
++ };
++ };
++ };
++};
++
++&vin7 {
++ status = "okay";
++
++ ports {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ port@0 {
++ vin7ep0: endpoint@0 {
++ csi,select = "csi41";
++ virtual,channel = <3>;
++ remote-endpoint = <&ov106xx_in7>;
++ data-lanes = <1 2 3 4>;
++ };
++ };
++ port@1 {
++ csi2ep3: endpoint {
++ remote-endpoint = <&csi2_41_ep>;
++ };
++ };
++ port@2 {
++ vin7_max9286_des1ep3: endpoint@0 {
++ remote-endpoint = <&max9286_des1ep3>;
++ };
++ vin7_ti964_des1ep3: endpoint@1 {
++ remote-endpoint = <&ti964_des1ep3>;
++ };
++ };
++ };
++};
++
++&csi2_40 {
++ status = "okay";
++
++ virtual,channel {
++ csi2_vc0 {
++ data,type = "ycbcr422";
++ receive,vc = <0>;
++ };
++ csi2_vc1 {
++ data,type = "ycbcr422";
++ receive,vc = <1>;
++ };
++ csi2_vc2 {
++ data,type = "ycbcr422";
++ receive,vc = <2>;
++ };
++ csi2_vc3 {
++ data,type = "ycbcr422";
++ receive,vc = <3>;
++ };
++ };
++
++ port {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ csi2_40_ep: endpoint {
++ clock-lanes = <0>;
++ data-lanes = <1 2 3 4>;
++ csi-rate = <300>;
++ };
++ };
++};
++
++&csi2_41 {
++ status = "okay";
++
++ virtual,channel {
++ csi2_vc0 {
++ data,type = "ycbcr422";
++ receive,vc = <0>;
++ };
++ csi2_vc1 {
++ data,type = "ycbcr422";
++ receive,vc = <1>;
++ };
++ csi2_vc2 {
++ data,type = "ycbcr422";
++ receive,vc = <2>;
++ };
++ csi2_vc3 {
++ data,type = "ycbcr422";
++ receive,vc = <3>;
++ };
++ };
++
++ port {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ csi2_41_ep: endpoint {
++ clock-lanes = <0>;
++ data-lanes = <1 2 3 4>;
++ csi-rate = <300>;
++ };
++ };
++};
++
++&rcar_sound {
++ pinctrl-0 = <&sound_clk_pins>;
++
++ /* Multi DAI */
++ #sound-dai-cells = <1>;
++};
++
++&sata {
++ status = "okay";
++};
++
++&ssi1 {
++ /delete-property/shared-pin;
++};
++
++&avb {
++ /delete-property/phy-handle;
++ /delete-property/phy-gpios;
++ phy-mode = "rgmii";
++
++ /delete-node/ethernet-phy@0;
++
++ fixed-link {
++ speed = <100>;
++ full-duplex;
++ };
++};
++
++&msiof1 {
++ status = "disabled";
++};
++
++&usb2_phy0 {
++ pinctrl-0 = <&usb0_pins>;
++ pinctrl-names = "default";
++
++ status = "okay";
++};
++
++&xhci0 {
++ status = "okay";
++};
++
++&hsusb0 {
++ status = "okay";
++};
++
++&ehci0 {
++ status = "okay";
++};
++
++&ohci0 {
++ status = "okay";
++};
++
++&can0 {
++ pinctrl-0 = <&can0_pins>;
++ pinctrl-names = "default";
++ status = "okay";
++
++ renesas,can-clock-select = <0x0>;
++};
++
++&can1 {
++ pinctrl-0 = <&can1_pins>;
++ pinctrl-names = "default";
++ status = "okay";
++
++ renesas,can-clock-select = <0x0>;
++};
++
++&canfd {
++ pinctrl-0 = <&canfd0_pins &canfd1_pins>;
++ pinctrl-names = "default";
++ status = "disabled";
++
++ renesas,can-clock-select = <0x0>;
++
++ channel0 {
++ status = "okay";
++ };
++
++ channel1 {
++ status = "okay";
++ };
++};
++
++/* uncomment to enable CN12 on VIN4-7 */
++//#include "ulcb-vb-cn12.dtsi"
+diff --git a/arch/arm64/boot/dts/renesas/r8a7795-h3ulcb-view.dts b/arch/arm64/boot/dts/renesas/r8a7795-h3ulcb-view.dts
+new file mode 100644
+index 0000000..2c24b85
+--- /dev/null
++++ b/arch/arm64/boot/dts/renesas/r8a7795-h3ulcb-view.dts
+@@ -0,0 +1,546 @@
++/*
++ * Device Tree Source for the H3ULCB.View board
++ *
++ * Copyright (C) 2016-2017 Renesas Electronics Corp.
++ * Copyright (C) 2016-2017 Cogent Embedded, Inc.
++ *
++ * This file is licensed under the terms of the GNU General Public License
++ * version 2. This program is licensed "as is" without any warranty of any
++ * kind, whether express or implied.
++ */
++
++#include "r8a7795-h3ulcb.dts"
++
++/ {
++ model = "Renesas H3ULCB.View board based on r8a7795";
++};
++
++&i2c4 {
++ ov106xx@0 {
++ compatible = "ovti,ov106xx";
++ reg = <0x60>;
++
++ port@0 {
++ ov106xx_in0: endpoint {
++ clock-lanes = <0>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&vin0ep0>;
++ };
++ };
++ port@1 {
++ ov106xx_max9286_des0ep0: endpoint@0 {
++ remote-endpoint = <&max9286_des0ep0>;
++ };
++ };
++ };
++
++ ov106xx@1 {
++ compatible = "ovti,ov106xx";
++ reg = <0x61>;
++
++ port@0 {
++ ov106xx_in1: endpoint {
++ clock-lanes = <0>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&vin1ep0>;
++ };
++ };
++ port@1 {
++ ov106xx_max9286_des0ep1: endpoint@0 {
++ remote-endpoint = <&max9286_des0ep1>;
++ };
++ };
++ };
++
++ ov106xx@2 {
++ compatible = "ovti,ov106xx";
++ reg = <0x62>;
++
++ port@0 {
++ ov106xx_in2: endpoint {
++ clock-lanes = <0>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&vin2ep0>;
++ };
++ };
++ port@1 {
++ ov106xx_max9286_des0ep2: endpoint@0 {
++ remote-endpoint = <&max9286_des0ep2>;
++ };
++ };
++ };
++
++ ov106xx@3 {
++ compatible = "ovti,ov106xx";
++ reg = <0x63>;
++
++ port@0 {
++ ov106xx_in3: endpoint {
++ clock-lanes = <0>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&vin3ep0>;
++ };
++ };
++ port@1 {
++ ov106xx_des0ep3: endpoint {
++ remote-endpoint = <&max9286_des0ep3>;
++ };
++ };
++ };
++
++ ov106xx@4 {
++ compatible = "ovti,ov106xx";
++ reg = <0x64>;
++
++ port@0 {
++ ov106xx_in4: endpoint {
++ clock-lanes = <0>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&vin4ep0>;
++ };
++ };
++ port@1 {
++ ov106xx_max9286_des1ep0: endpoint@0 {
++ remote-endpoint = <&max9286_des1ep0>;
++ };
++ };
++ };
++
++ ov106xx@5 {
++ compatible = "ovti,ov106xx";
++ reg = <0x65>;
++
++ port@0 {
++ ov106xx_in5: endpoint {
++ clock-lanes = <0>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&vin5ep0>;
++ };
++ };
++ port@1 {
++ ov106xx_max9286_des1ep1: endpoint@0 {
++ remote-endpoint = <&max9286_des1ep1>;
++ };
++ };
++ };
++
++ ov106xx@6 {
++ compatible = "ovti,ov106xx";
++ reg = <0x66>;
++
++ port@0 {
++ ov106xx_in6: endpoint {
++ clock-lanes = <0>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&vin6ep0>;
++ };
++ };
++ port@1 {
++ ov106xx_max9286_des1ep2: endpoint@0 {
++ remote-endpoint = <&max9286_des1ep2>;
++ };
++ };
++ };
++
++ ov106xx@7 {
++ compatible = "ovti,ov106xx";
++ reg = <0x67>;
++
++ port@0 {
++ ov106xx_in7: endpoint {
++ clock-lanes = <0>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&vin7ep0>;
++ };
++ };
++ port@1 {
++ ov106xx_des1ep3: endpoint {
++ remote-endpoint = <&max9286_des1ep3>;
++ };
++ };
++ };
++
++ max9286-max9271@0 {
++ compatible = "maxim,max9286-max9271";
++ reg = <0x4c>;
++ gpios = <&gpio2 6 GPIO_ACTIVE_HIGH>;
++ maxim,sensor_delay = <0>;
++ maxim,links = <4>;
++ maxim,lanes = <4>;
++ maxim,resetb-gpio = <1>;
++ maxim,fsync-mode = "automatic";
++ maxim,timeout = <100>;
++ maxim,i2c-quirk = <0x6c>;
++
++ port@0 {
++ max9286_des0ep0: endpoint@0 {
++ max9271-addr = <0x50>;
++ dvp-order = <1>;
++ remote-endpoint = <&ov106xx_in0>;
++ };
++ max9286_des0ep1: endpoint@1 {
++ max9271-addr = <0x51>;
++ dvp-order = <1>;
++ remote-endpoint = <&ov106xx_in1>;
++ };
++ max9286_des0ep2: endpoint@2 {
++ max9271-addr = <0x52>;
++ dvp-order = <1>;
++ remote-endpoint = <&ov106xx_in2>;
++ };
++ max9286_des0ep3: endpoint@3 {
++ max9271-addr = <0x53>;
++ dvp-order = <1>;
++ remote-endpoint = <&ov106xx_in3>;
++ };
++ };
++ port@1 {
++ max9286_csi0ep0: endpoint {
++ csi-rate = <700>;
++ remote-endpoint = <&csi2_40_ep>;
++ };
++ };
++ };
++
++ max9286-max9271@1 {
++ compatible = "maxim,max9286-max9271";
++ reg = <0x6c>;
++ gpios = <&gpio5 25 GPIO_ACTIVE_HIGH>;
++ maxim,sensor_delay = <0>;
++ maxim,links = <4>;
++ maxim,lanes = <4>;
++ maxim,resetb-gpio = <1>;
++ maxim,fsync-mode = "automatic";
++ maxim,timeout = <100>;
++
++ port@0 {
++ max9286_des1ep0: endpoint@0 {
++ max9271-addr = <0x54>;
++ dvp-order = <1>;
++ remote-endpoint = <&ov106xx_in4>;
++ };
++ max9286_des1ep1: endpoint@1 {
++ max9271-addr = <0x55>;
++ dvp-order = <1>;
++ remote-endpoint = <&ov106xx_in5>;
++ };
++ max9286_des1ep2: endpoint@2 {
++ max9271-addr = <0x56>;
++ dvp-order = <1>;
++ remote-endpoint = <&ov106xx_in6>;
++ };
++ max9286_des1ep3: endpoint@3 {
++ max9271-addr = <0x57>;
++ dvp-order = <1>;
++ remote-endpoint = <&ov106xx_in7>;
++ };
++ };
++ port@1 {
++ max9286_csi2ep0: endpoint {
++ csi-rate = <700>;
++ remote-endpoint = <&csi2_41_ep>;
++ };
++ };
++ };
++};
++
++&pcie_bus_clk {
++ clock-frequency = <100000000>;
++ status = "okay";
++};
++
++&pciec1 {
++ status = "okay";
++};
++
++&vin0 {
++ status = "okay";
++
++ ports {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ port@0 {
++ vin0ep0: endpoint {
++ csi,select = "csi40";
++ virtual,channel = <0>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&ov106xx_in0>;
++ };
++ };
++ port@1 {
++ csi0ep0: endpoint {
++ remote-endpoint = <&csi2_40_ep>;
++ };
++ };
++ port@2 {
++ vin0_max9286_des0ep0: endpoint@0 {
++ remote-endpoint = <&max9286_des0ep0>;
++ };
++ };
++ };
++};
++
++&vin1 {
++ status = "okay";
++
++ ports {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ port@0 {
++ vin1ep0: endpoint {
++ csi,select = "csi40";
++ virtual,channel = <1>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&ov106xx_in1>;
++ };
++ };
++ port@1 {
++ csi0ep1: endpoint {
++ remote-endpoint = <&csi2_40_ep>;
++ };
++ };
++ port@2 {
++ vin1_max9286_des0ep1: endpoint@0 {
++ remote-endpoint = <&max9286_des0ep1>;
++ };
++ };
++ };
++};
++
++&vin2 {
++ status = "okay";
++
++ ports {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ port@0 {
++ vin2ep0: endpoint {
++ csi,select = "csi40";
++ virtual,channel = <2>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&ov106xx_in2>;
++ };
++ };
++ port@1 {
++ csi0ep2: endpoint {
++ remote-endpoint = <&csi2_40_ep>;
++ };
++ };
++ port@2 {
++ vin2_max9286_des0ep2: endpoint@0 {
++ remote-endpoint = <&max9286_des0ep2>;
++ };
++ };
++ };
++};
++
++&vin3 {
++ status = "okay";
++
++ ports {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ port@0 {
++ vin3ep0: endpoint {
++ csi,select = "csi40";
++ virtual,channel = <3>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&ov106xx_in3>;
++ };
++ };
++ port@1 {
++ csi0ep3: endpoint {
++ remote-endpoint = <&csi2_40_ep>;
++ };
++ };
++ port@2 {
++ vin3_max9286_des0ep3: endpoint@0 {
++ remote-endpoint = <&max9286_des0ep3>;
++ };
++ };
++ };
++};
++
++&vin4 {
++ status = "okay";
++
++ ports {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ port@0 {
++ vin4ep0: endpoint {
++ csi,select = "csi41";
++ virtual,channel = <0>;
++ remote-endpoint = <&ov106xx_in4>;
++ data-lanes = <1 2 3 4>;
++ };
++ };
++ port@1 {
++ csi2ep0: endpoint {
++ remote-endpoint = <&csi2_41_ep>;
++ };
++ };
++ port@2 {
++ vin4_max9286_des1ep0: endpoint@0 {
++ remote-endpoint = <&max9286_des1ep0>;
++ };
++ };
++ };
++};
++
++&vin5 {
++ status = "okay";
++
++ ports {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ port@0 {
++ vin5ep0: endpoint@0 {
++ csi,select = "csi41";
++ virtual,channel = <1>;
++ remote-endpoint = <&ov106xx_in5>;
++ data-lanes = <1 2 3 4>;
++ };
++ };
++ port@1 {
++ csi2ep1: endpoint {
++ remote-endpoint = <&csi2_41_ep>;
++ };
++ };
++ port@2 {
++ vin5_max9286_des1ep1: endpoint@0 {
++ remote-endpoint = <&max9286_des1ep1>;
++ };
++ };
++ };
++};
++
++&vin6 {
++ status = "okay";
++
++ ports {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ port@0 {
++ vin6ep0: endpoint@0 {
++ csi,select = "csi41";
++ virtual,channel = <2>;
++ remote-endpoint = <&ov106xx_in6>;
++ data-lanes = <1 2 3 4>;
++ };
++ };
++ port@1 {
++ csi2ep2: endpoint {
++ remote-endpoint = <&csi2_41_ep>;
++ };
++ };
++ port@2 {
++ vin6_max9286_des1ep2: endpoint@0 {
++ remote-endpoint = <&max9286_des1ep2>;
++ };
++ };
++ };
++};
++
++&vin7 {
++ status = "okay";
++
++ ports {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ port@0 {
++ vin7ep0: endpoint@0 {
++ csi,select = "csi41";
++ virtual,channel = <3>;
++ remote-endpoint = <&ov106xx_in7>;
++ data-lanes = <1 2 3 4>;
++ };
++ };
++ port@1 {
++ csi2ep3: endpoint {
++ remote-endpoint = <&csi2_41_ep>;
++ };
++ };
++ port@2 {
++ vin7_max9286_des1ep3: endpoint@0 {
++ remote-endpoint = <&max9286_des1ep3>;
++ };
++ };
++ };
++};
++
++&csi2_40 {
++ status = "okay";
++
++ virtual,channel {
++ csi2_vc0 {
++ data,type = "ycbcr422";
++ receive,vc = <0>;
++ };
++ csi2_vc1 {
++ data,type = "ycbcr422";
++ receive,vc = <1>;
++ };
++ csi2_vc2 {
++ data,type = "ycbcr422";
++ receive,vc = <2>;
++ };
++ csi2_vc3 {
++ data,type = "ycbcr422";
++ receive,vc = <3>;
++ };
++ };
++
++ port {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ csi2_40_ep: endpoint {
++ clock-lanes = <0>;
++ data-lanes = <1 2 3 4>;
++ csi-rate = <300>;
++ };
++ };
++};
++
++&csi2_41 {
++ status = "okay";
++
++ virtual,channel {
++ csi2_vc0 {
++ data,type = "ycbcr422";
++ receive,vc = <0>;
++ };
++ csi2_vc1 {
++ data,type = "ycbcr422";
++ receive,vc = <1>;
++ };
++ csi2_vc2 {
++ data,type = "ycbcr422";
++ receive,vc = <2>;
++ };
++ csi2_vc3 {
++ data,type = "ycbcr422";
++ receive,vc = <3>;
++ };
++ };
++
++ port {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ csi2_41_ep: endpoint {
++ clock-lanes = <0>;
++ data-lanes = <1 2 3 4>;
++ csi-rate = <300>;
++ };
++ };
++};
+diff --git a/arch/arm64/boot/dts/renesas/r8a7795-salvator-x-view.dts b/arch/arm64/boot/dts/renesas/r8a7795-salvator-x-view.dts
+new file mode 100644
+index 0000000..fb12a39f3
+--- /dev/null
++++ b/arch/arm64/boot/dts/renesas/r8a7795-salvator-x-view.dts
+@@ -0,0 +1,552 @@
++/*
++ * Device Tree Source for the Salvator-X.View board
++ *
++ * Copyright (C) 2016-2017 Renesas Electronics Corp.
++ * Copyright (C) 2015-2017 Cogent Embedded, Inc
++ *
++ * This file is licensed under the terms of the GNU General Public License
++ * version 2. This program is licensed "as is" without any warranty of any
++ * kind, whether express or implied.
++ */
++
++#include "r8a7795-salvator-x.dts"
++
++/ {
++ model = "Renesas Salvator-X.View board based on r8a7795";
++};
++
++&pfc {
++ can0_pins: can0 {
++ groups = "can0_data_a";
++ function = "can0";
++ };
++
++ can1_pins: can1 {
++ groups = "can1_data";
++ function = "can1";
++ };
++};
++
++&i2c4 {
++ /delete-node/hdmi-in@34;
++ /delete-node/composite-in@70;
++
++ ov106xx@0 {
++ compatible = "ovti,ov106xx";
++ reg = <0x60>;
++
++ port@0 {
++ ov106xx_in0: endpoint {
++ clock-lanes = <0>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&vin0ep0>;
++ };
++ };
++ port@1 {
++ ov106xx_max9286_des0ep0: endpoint@0 {
++ remote-endpoint = <&max9286_des0ep0>;
++ };
++ };
++ };
++
++ ov106xx@1 {
++ compatible = "ovti,ov106xx";
++ reg = <0x61>;
++
++ port@0 {
++ ov106xx_in1: endpoint {
++ clock-lanes = <0>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&vin1ep0>;
++ };
++ };
++ port@1 {
++ ov106xx_max9286_des0ep1: endpoint@0 {
++ remote-endpoint = <&max9286_des0ep1>;
++ };
++ };
++ };
++
++ ov106xx@2 {
++ compatible = "ovti,ov106xx";
++ reg = <0x62>;
++
++ port@0 {
++ ov106xx_in2: endpoint {
++ clock-lanes = <0>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&vin2ep0>;
++ };
++ };
++ port@1 {
++ ov106xx_max9286_des0ep2: endpoint@0 {
++ remote-endpoint = <&max9286_des0ep2>;
++ };
++ };
++ };
++
++ ov106xx@3 {
++ compatible = "ovti,ov106xx";
++ reg = <0x63>;
++
++ port@0 {
++ ov106xx_in3: endpoint {
++ clock-lanes = <0>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&vin3ep0>;
++ };
++ };
++ port@1 {
++ ov106xx_des0ep3: endpoint {
++ remote-endpoint = <&max9286_des0ep3>;
++ };
++ };
++ };
++
++ ov106xx@4 {
++ compatible = "ovti,ov106xx";
++ reg = <0x64>;
++
++ port@0 {
++ ov106xx_in4: endpoint {
++ clock-lanes = <0>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&vin4ep0>;
++ };
++ };
++ port@1 {
++ ov106xx_max9286_des1ep0: endpoint@0 {
++ remote-endpoint = <&max9286_des1ep0>;
++ };
++ };
++ };
++
++ ov106xx@5 {
++ compatible = "ovti,ov106xx";
++ reg = <0x65>;
++
++ port@0 {
++ ov106xx_in5: endpoint {
++ clock-lanes = <0>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&vin5ep0>;
++ };
++ };
++ port@1 {
++ ov106xx_max9286_des1ep1: endpoint@0 {
++ remote-endpoint = <&max9286_des1ep1>;
++ };
++ };
++ };
++
++ ov106xx@6 {
++ compatible = "ovti,ov106xx";
++ reg = <0x66>;
++
++ port@0 {
++ ov106xx_in6: endpoint {
++ clock-lanes = <0>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&vin6ep0>;
++ };
++ };
++ port@1 {
++ ov106xx_max9286_des1ep2: endpoint@0 {
++ remote-endpoint = <&max9286_des1ep2>;
++ };
++ };
++ };
++
++ ov106xx@7 {
++ compatible = "ovti,ov106xx";
++ reg = <0x67>;
++
++ port@0 {
++ ov106xx_in7: endpoint {
++ clock-lanes = <0>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&vin7ep0>;
++ };
++ };
++ port@1 {
++ ov106xx_des1ep3: endpoint {
++ remote-endpoint = <&max9286_des1ep3>;
++ };
++ };
++ };
++
++ max9286-max9271@0 {
++ compatible = "maxim,max9286-max9271";
++ reg = <0x4c>;
++ gpios = <&gpio6 30 GPIO_ACTIVE_LOW>;
++ maxim,sensor_delay = <0>;
++ maxim,links = <4>;
++ maxim,lanes = <4>;
++ maxim,resetb-gpio = <1>;
++ maxim,fsync-mode = "automatic";
++ maxim,timeout = <100>;
++ maxim,i2c-quirk = <0x6c>;
++
++ port@0 {
++ max9286_des0ep0: endpoint@0 {
++ max9271-addr = <0x50>;
++ dvp-order = <1>;
++ remote-endpoint = <&ov106xx_in0>;
++ };
++ max9286_des0ep1: endpoint@1 {
++ max9271-addr = <0x51>;
++ dvp-order = <1>;
++ remote-endpoint = <&ov106xx_in1>;
++ };
++ max9286_des0ep2: endpoint@2 {
++ max9271-addr = <0x52>;
++ dvp-order = <1>;
++ remote-endpoint = <&ov106xx_in2>;
++ };
++ max9286_des0ep3: endpoint@3 {
++ max9271-addr = <0x53>;
++ dvp-order = <1>;
++ remote-endpoint = <&ov106xx_in3>;
++ };
++ };
++ port@1 {
++ max9286_csi0ep0: endpoint {
++ csi-rate = <700>;
++ remote-endpoint = <&csi2_40_ep>;
++ };
++ };
++ };
++
++ max9286-max9271@1 {
++ compatible = "maxim,max9286-max9271";
++ reg = <0x6c>;
++ maxim,sensor_delay = <0>;
++ maxim,links = <4>;
++ maxim,lanes = <4>;
++ maxim,resetb-gpio = <1>;
++ maxim,fsync-mode = "automatic";
++ maxim,timeout = <100>;
++
++ port@0 {
++ max9286_des1ep0: endpoint@0 {
++ max9271-addr = <0x54>;
++ dvp-order = <1>;
++ remote-endpoint = <&ov106xx_in4>;
++ };
++ max9286_des1ep1: endpoint@1 {
++ max9271-addr = <0x55>;
++ dvp-order = <1>;
++ remote-endpoint = <&ov106xx_in5>;
++ };
++ max9286_des1ep2: endpoint@2 {
++ max9271-addr = <0x56>;
++ dvp-order = <1>;
++ remote-endpoint = <&ov106xx_in6>;
++ };
++ max9286_des1ep3: endpoint@3 {
++ max9271-addr = <0x57>;
++ dvp-order = <1>;
++ remote-endpoint = <&ov106xx_in7>;
++ };
++ };
++ port@1 {
++ max9286_csi2ep0: endpoint {
++ csi-rate = <700>;
++ remote-endpoint = <&csi2_41_ep>;
++ };
++ };
++ };
++};
++
++&vin0 {
++ ports {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ port@0 {
++ vin0ep0: endpoint {
++ csi,select = "csi40";
++ virtual,channel = <0>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&ov106xx_in0>;
++ };
++ };
++ port@1 {
++ csi0ep0: endpoint {
++ remote-endpoint = <&csi2_40_ep>;
++ };
++ };
++ port@2 {
++ vin0_max9286_des0ep0: endpoint@0 {
++ remote-endpoint = <&max9286_des0ep0>;
++ };
++ };
++ };
++};
++
++&vin1 {
++ ports {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ port@0 {
++ vin1ep0: endpoint {
++ csi,select = "csi40";
++ virtual,channel = <1>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&ov106xx_in1>;
++ };
++ };
++ port@1 {
++ csi0ep1: endpoint {
++ remote-endpoint = <&csi2_40_ep>;
++ };
++ };
++ port@2 {
++ vin1_max9286_des0ep1: endpoint@0 {
++ remote-endpoint = <&max9286_des0ep1>;
++ };
++ };
++ };
++};
++
++&vin2 {
++ ports {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ port@0 {
++ vin2ep0: endpoint {
++ csi,select = "csi40";
++ virtual,channel = <2>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&ov106xx_in2>;
++ };
++ };
++ port@1 {
++ csi0ep2: endpoint {
++ remote-endpoint = <&csi2_40_ep>;
++ };
++ };
++ port@2 {
++ vin2_max9286_des0ep2: endpoint@0 {
++ remote-endpoint = <&max9286_des0ep2>;
++ };
++ };
++ };
++};
++
++&vin3 {
++ ports {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ port@0 {
++ vin3ep0: endpoint {
++ csi,select = "csi40";
++ virtual,channel = <3>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&ov106xx_in3>;
++ };
++ };
++ port@1 {
++ csi0ep3: endpoint {
++ remote-endpoint = <&csi2_40_ep>;
++ };
++ };
++ port@2 {
++ vin3_max9286_des0ep3: endpoint@0 {
++ remote-endpoint = <&max9286_des0ep3>;
++ };
++ };
++ };
++};
++
++&vin4 {
++ ports {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ port@0 {
++ vin4ep0: endpoint {
++ csi,select = "csi41";
++ virtual,channel = <0>;
++ remote-endpoint = <&ov106xx_in4>;
++ data-lanes = <1 2 3 4>;
++ };
++ };
++ port@1 {
++ csi2ep0: endpoint {
++ remote-endpoint = <&csi2_41_ep>;
++ };
++ };
++ port@2 {
++ vin4_max9286_des1ep0: endpoint@0 {
++ remote-endpoint = <&max9286_des1ep0>;
++ };
++ };
++ };
++};
++
++&vin5 {
++ ports {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ port@0 {
++ vin5ep0: endpoint@0 {
++ csi,select = "csi41";
++ virtual,channel = <1>;
++ remote-endpoint = <&ov106xx_in5>;
++ data-lanes = <1 2 3 4>;
++ };
++ };
++ port@1 {
++ csi2ep1: endpoint {
++ remote-endpoint = <&csi2_41_ep>;
++ };
++ };
++ port@2 {
++ vin5_max9286_des1ep1: endpoint@0 {
++ remote-endpoint = <&max9286_des1ep1>;
++ };
++ };
++ };
++};
++
++&vin6 {
++ ports {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ port@0 {
++ vin6ep0: endpoint@0 {
++ csi,select = "csi41";
++ virtual,channel = <2>;
++ remote-endpoint = <&ov106xx_in6>;
++ data-lanes = <1 2 3 4>;
++ };
++ };
++ port@1 {
++ csi2ep2: endpoint {
++ remote-endpoint = <&csi2_41_ep>;
++ };
++ };
++ port@2 {
++ vin6_max9286_des1ep2: endpoint@0 {
++ remote-endpoint = <&max9286_des1ep2>;
++ };
++ };
++ };
++};
++
++&vin7 {
++ ports {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ port@0 {
++ vin7ep0: endpoint@0 {
++ csi,select = "csi41";
++ virtual,channel = <3>;
++ remote-endpoint = <&ov106xx_in7>;
++ data-lanes = <1 2 3 4>;
++ };
++ };
++ port@1 {
++ csi2ep3: endpoint {
++ remote-endpoint = <&csi2_41_ep>;
++ };
++ };
++ port@2 {
++ vin7_max9286_des1ep3: endpoint@0 {
++ remote-endpoint = <&max9286_des1ep3>;
++ };
++ };
++ };
++};
++
++&csi2_20 {
++ status = "disabled";
++ /delete-node/ports;
++};
++
++&csi2_40 {
++ /delete-node/ports;
++
++ virtual,channel {
++ csi2_vc0 {
++ data,type = "ycbcr422";
++ receive,vc = <0>;
++ };
++ csi2_vc1 {
++ data,type = "ycbcr422";
++ receive,vc = <1>;
++ };
++ csi2_vc2 {
++ data,type = "ycbcr422";
++ receive,vc = <2>;
++ };
++ csi2_vc3 {
++ data,type = "ycbcr422";
++ receive,vc = <3>;
++ };
++ };
++
++ port {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ csi2_40_ep: endpoint {
++ clock-lanes = <0>;
++ data-lanes = <1 2 3 4>;
++ csi-rate = <300>;
++ };
++ };
++};
++
++&csi2_41 {
++ status = "okay";
++
++ virtual,channel {
++ csi2_vc0 {
++ data,type = "ycbcr422";
++ receive,vc = <0>;
++ };
++ csi2_vc1 {
++ data,type = "ycbcr422";
++ receive,vc = <1>;
++ };
++ csi2_vc2 {
++ data,type = "ycbcr422";
++ receive,vc = <2>;
++ };
++ csi2_vc3 {
++ data,type = "ycbcr422";
++ receive,vc = <3>;
++ };
++ };
++
++ port {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ csi2_41_ep: endpoint {
++ clock-lanes = <0>;
++ data-lanes = <1 2 3 4>;
++ csi-rate = <300>;
++ };
++ };
++};
++
++&can0 {
++ pinctrl-0 = <&can0_pins>;
++ pinctrl-names = "default";
++ status = "okay";
++};
++
++&can1 {
++ pinctrl-0 = <&can1_pins>;
++ pinctrl-names = "default";
++ status = "okay";
++};
+diff --git a/arch/arm64/boot/dts/renesas/r8a7796-m3ulcb-kf.dts b/arch/arm64/boot/dts/renesas/r8a7796-m3ulcb-kf.dts
+new file mode 100644
+index 0000000..a409402
+--- /dev/null
++++ b/arch/arm64/boot/dts/renesas/r8a7796-m3ulcb-kf.dts
+@@ -0,0 +1,40 @@
++/*
++ * Device Tree Source for the M3ULCB Kingfisher board on r8a7796
++ *
++ * Copyright (C) 2017 Renesas Electronics Corp.
++ * Copyright (C) 2017 Cogent Embedded, Inc.
++ *
++ * This file is licensed under the terms of the GNU General Public License
++ * version 2. This program is licensed "as is" without any warranty of any
++ * kind, whether express or implied.
++ */
++
++#include "r8a7796-m3ulcb.dts"
++#include "ulcb-kf.dtsi"
++
++/ {
++ model = "Renesas M3ULCB Kingfisher board based on r8a7796";
++};
++
++&du {
++ ports {
++ port@0 {
++ endpoint {
++ remote-endpoint = <&adv7513_in>;
++ };
++ };
++ port@2 {
++ endpoint {
++ remote-endpoint = <&lvds_enc_in>;
++ };
++ };
++ };
++};
++
++&hsusb {
++ status = "okay";
++};
++
++&xhci0 {
++ status = "disabled";
++};
+diff --git a/arch/arm64/boot/dts/renesas/r8a7796-m3ulcb-view.dts b/arch/arm64/boot/dts/renesas/r8a7796-m3ulcb-view.dts
+new file mode 100644
+index 0000000..1ac0041
+--- /dev/null
++++ b/arch/arm64/boot/dts/renesas/r8a7796-m3ulcb-view.dts
+@@ -0,0 +1,287 @@
++/*
++ * Device Tree Source for the M3ULCB.View board on r8a7796
++ *
++ * Copyright (C) 2016-2017 Renesas Electronics Corp.
++ * Copyright (C) 2016-2017 Cogent Embedded, Inc.
++ *
++ * This file is licensed under the terms of the GNU General Public License
++ * version 2. This program is licensed "as is" without any warranty of any
++ * kind, whether express or implied.
++ */
++
++#include "r8a7796-m3ulcb.dts"
++
++/ {
++ model = "Renesas M3ULCB.View board based on r8a7796";
++};
++
++&i2c4 {
++ ov106xx@0 {
++ compatible = "ovti,ov106xx";
++ reg = <0x60>;
++
++ port@0 {
++ ov106xx_in0: endpoint {
++ clock-lanes = <0>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&vin0ep0>;
++ };
++ };
++ port@1 {
++ ov106xx_max9286_des0ep0: endpoint@0 {
++ remote-endpoint = <&max9286_des0ep0>;
++ };
++ };
++ };
++
++ ov106xx@1 {
++ compatible = "ovti,ov106xx";
++ reg = <0x61>;
++
++ port@0 {
++ ov106xx_in1: endpoint {
++ clock-lanes = <0>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&vin1ep0>;
++ };
++ };
++ port@1 {
++ ov106xx_max9286_des0ep1: endpoint@0 {
++ remote-endpoint = <&max9286_des0ep1>;
++ };
++ };
++ };
++
++ ov106xx@2 {
++ compatible = "ovti,ov106xx";
++ reg = <0x62>;
++
++ port@0 {
++ ov106xx_in2: endpoint {
++ clock-lanes = <0>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&vin2ep0>;
++ };
++ };
++ port@1 {
++ ov106xx_max9286_des0ep2: endpoint@0 {
++ remote-endpoint = <&max9286_des0ep2>;
++ };
++ };
++ };
++
++ ov106xx@3 {
++ compatible = "ovti,ov106xx";
++ reg = <0x63>;
++
++ port@0 {
++ ov106xx_in3: endpoint {
++ clock-lanes = <0>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&vin3ep0>;
++ };
++ };
++ port@1 {
++ ov106xx_des0ep3: endpoint {
++ remote-endpoint = <&max9286_des0ep3>;
++ };
++ };
++ };
++
++ max9286-max9271@0 {
++ compatible = "maxim,max9286-max9271";
++ reg = <0x4c>;
++ gpios = <&gpio2 6 GPIO_ACTIVE_HIGH>;
++ maxim,sensor_delay = <0>;
++ maxim,links = <4>;
++ maxim,lanes = <4>;
++ maxim,resetb-gpio = <1>;
++ maxim,fsync-mode = "automatic";
++ maxim,timeout = <100>;
++ maxim,i2c-quirk = <0x6c>;
++
++ port@0 {
++ max9286_des0ep0: endpoint@0 {
++ max9271-addr = <0x50>;
++ dvp-order = <1>;
++ remote-endpoint = <&ov106xx_in0>;
++ };
++ max9286_des0ep1: endpoint@1 {
++ max9271-addr = <0x51>;
++ dvp-order = <1>;
++ remote-endpoint = <&ov106xx_in1>;
++ };
++ max9286_des0ep2: endpoint@2 {
++ max9271-addr = <0x52>;
++ dvp-order = <1>;
++ remote-endpoint = <&ov106xx_in2>;
++ };
++ max9286_des0ep3: endpoint@3 {
++ max9271-addr = <0x53>;
++ dvp-order = <1>;
++ remote-endpoint = <&ov106xx_in3>;
++ };
++ };
++ port@1 {
++ max9286_csi0ep0: endpoint {
++ csi-rate = <700>;
++ remote-endpoint = <&csi2_40_ep>;
++ };
++ };
++ };
++};
++
++&pcie_bus_clk {
++ clock-frequency = <100000000>;
++ status = "okay";
++};
++
++&pciec1 {
++ status = "okay";
++};
++
++&vin0 {
++ status = "okay";
++
++ ports {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ port@0 {
++ vin0ep0: endpoint {
++ csi,select = "csi40";
++ virtual,channel = <0>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&ov106xx_in0>;
++ };
++ };
++ port@1 {
++ csi0ep0: endpoint {
++ remote-endpoint = <&csi2_40_ep>;
++ };
++ };
++ port@2 {
++ vin0_max9286_des0ep0: endpoint@0 {
++ remote-endpoint = <&max9286_des0ep0>;
++ };
++ };
++ };
++};
++
++&vin1 {
++ status = "okay";
++
++ ports {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ port@0 {
++ vin1ep0: endpoint {
++ csi,select = "csi40";
++ virtual,channel = <1>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&ov106xx_in1>;
++ };
++ };
++ port@1 {
++ csi0ep1: endpoint {
++ remote-endpoint = <&csi2_40_ep>;
++ };
++ };
++ port@2 {
++ vin1_max9286_des0ep1: endpoint@0 {
++ remote-endpoint = <&max9286_des0ep1>;
++ };
++ };
++ };
++};
++
++&vin2 {
++ status = "okay";
++
++ ports {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ port@0 {
++ vin2ep0: endpoint {
++ csi,select = "csi40";
++ virtual,channel = <2>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&ov106xx_in2>;
++ };
++ };
++ port@1 {
++ csi0ep2: endpoint {
++ remote-endpoint = <&csi2_40_ep>;
++ };
++ };
++ port@2 {
++ vin2_max9286_des0ep2: endpoint@0 {
++ remote-endpoint = <&max9286_des0ep2>;
++ };
++ };
++ };
++};
++
++&vin3 {
++ status = "okay";
++
++ ports {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ port@0 {
++ vin3ep0: endpoint {
++ csi,select = "csi40";
++ virtual,channel = <3>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&ov106xx_in3>;
++ };
++ };
++ port@1 {
++ csi0ep3: endpoint {
++ remote-endpoint = <&csi2_40_ep>;
++ };
++ };
++ port@2 {
++ vin3_max9286_des0ep3: endpoint@0 {
++ remote-endpoint = <&max9286_des0ep3>;
++ };
++ };
++ };
++};
++
++&csi2_40 {
++ status = "okay";
++
++ virtual,channel {
++ csi2_vc0 {
++ data,type = "ycbcr422";
++ receive,vc = <0>;
++ };
++ csi2_vc1 {
++ data,type = "ycbcr422";
++ receive,vc = <1>;
++ };
++ csi2_vc2 {
++ data,type = "ycbcr422";
++ receive,vc = <2>;
++ };
++ csi2_vc3 {
++ data,type = "ycbcr422";
++ receive,vc = <3>;
++ };
++ };
++
++ port {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ csi2_40_ep: endpoint {
++ clock-lanes = <0>;
++ data-lanes = <1 2 3 4>;
++ csi-rate = <300>;
++ };
++ };
++};
+diff --git a/arch/arm64/boot/dts/renesas/r8a7796-salvator-x-view.dts b/arch/arm64/boot/dts/renesas/r8a7796-salvator-x-view.dts
+new file mode 100644
+index 0000000..cc6866c
+--- /dev/null
++++ b/arch/arm64/boot/dts/renesas/r8a7796-salvator-x-view.dts
+@@ -0,0 +1,318 @@
++/*
++ * Device Tree Source for the Salvator-X.View board
++ *
++ * Copyright (C) 2016-2017 Renesas Electronics Corp.
++ * Copyright (C) 2016-2017 Cogent Embedded, Inc
++ *
++ * This file is licensed under the terms of the GNU General Public License
++ * version 2. This program is licensed "as is" without any warranty of any
++ * kind, whether express or implied.
++ */
++
++#include "r8a7796-salvator-x.dts"
++
++/ {
++ model = "Renesas Salvator-X.View board based on r8a7796";
++};
++
++&pfc {
++ can0_pins: can0 {
++ groups = "can0_data_a";
++ function = "can0";
++ };
++
++ can1_pins: can1 {
++ groups = "can1_data";
++ function = "can1";
++ };
++};
++
++&i2c4 {
++ /delete-node/hdmi-in@34;
++ /delete-node/composite-in@70;
++
++ ov106xx@0 {
++ compatible = "ovti,ov106xx";
++ reg = <0x60>;
++
++ port@0 {
++ ov106xx_in0: endpoint {
++ clock-lanes = <0>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&vin0ep0>;
++ };
++ };
++ port@1 {
++ ov106xx_max9286_des0ep0: endpoint@0 {
++ remote-endpoint = <&max9286_des0ep0>;
++ };
++ };
++ };
++
++ ov106xx@1 {
++ compatible = "ovti,ov106xx";
++ reg = <0x61>;
++
++ port@0 {
++ ov106xx_in1: endpoint {
++ clock-lanes = <0>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&vin1ep0>;
++ };
++ };
++ port@1 {
++ ov106xx_max9286_des0ep1: endpoint@0 {
++ remote-endpoint = <&max9286_des0ep1>;
++ };
++ };
++ };
++
++ ov106xx@2 {
++ compatible = "ovti,ov106xx";
++ reg = <0x62>;
++
++ port@0 {
++ ov106xx_in2: endpoint {
++ clock-lanes = <0>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&vin2ep0>;
++ };
++ };
++ port@1 {
++ ov106xx_max9286_des0ep2: endpoint@0 {
++ remote-endpoint = <&max9286_des0ep2>;
++ };
++ };
++ };
++
++ ov106xx@3 {
++ compatible = "ovti,ov106xx";
++ reg = <0x63>;
++
++ port@0 {
++ ov106xx_in3: endpoint {
++ clock-lanes = <0>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&vin3ep0>;
++ };
++ };
++ port@1 {
++ ov106xx_des0ep3: endpoint {
++ remote-endpoint = <&max9286_des0ep3>;
++ };
++ };
++ };
++
++ max9286-max9271@0 {
++ compatible = "maxim,max9286-max9271";
++ reg = <0x4c>;
++ gpios = <&gpio6 30 GPIO_ACTIVE_LOW>;
++ maxim,sensor_delay = <0>;
++ maxim,links = <4>;
++ maxim,lanes = <4>;
++ maxim,resetb-gpio = <1>;
++ maxim,fsync-mode = "automatic";
++ maxim,timeout = <100>;
++ maxim,i2c-quirk = <0x6c>;
++
++ port@0 {
++ max9286_des0ep0: endpoint@0 {
++ max9271-addr = <0x50>;
++ dvp-order = <1>;
++ remote-endpoint = <&ov106xx_in0>;
++ };
++ max9286_des0ep1: endpoint@1 {
++ max9271-addr = <0x51>;
++ dvp-order = <1>;
++ remote-endpoint = <&ov106xx_in1>;
++ };
++ max9286_des0ep2: endpoint@2 {
++ max9271-addr = <0x52>;
++ dvp-order = <1>;
++ remote-endpoint = <&ov106xx_in2>;
++ };
++ max9286_des0ep3: endpoint@3 {
++ max9271-addr = <0x53>;
++ dvp-order = <1>;
++ remote-endpoint = <&ov106xx_in3>;
++ };
++ };
++ port@1 {
++ max9286_csi0ep0: endpoint {
++ csi-rate = <700>;
++ remote-endpoint = <&csi2_40_ep>;
++ };
++ };
++ };
++};
++
++&vin0 {
++ ports {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ port@0 {
++ vin0ep0: endpoint {
++ csi,select = "csi40";
++ virtual,channel = <0>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&ov106xx_in0>;
++ };
++ };
++ port@1 {
++ csi0ep0: endpoint {
++ remote-endpoint = <&csi2_40_ep>;
++ };
++ };
++ port@2 {
++ vin0_max9286_des0ep0: endpoint@0 {
++ remote-endpoint = <&max9286_des0ep0>;
++ };
++ };
++ };
++};
++
++&vin1 {
++ ports {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ port@0 {
++ vin1ep0: endpoint {
++ csi,select = "csi40";
++ virtual,channel = <1>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&ov106xx_in1>;
++ };
++ };
++ port@1 {
++ csi0ep1: endpoint {
++ remote-endpoint = <&csi2_40_ep>;
++ };
++ };
++ port@2 {
++ vin1_max9286_des0ep1: endpoint@0 {
++ remote-endpoint = <&max9286_des0ep1>;
++ };
++ };
++ };
++};
++
++&vin2 {
++ ports {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ port@0 {
++ vin2ep0: endpoint {
++ csi,select = "csi40";
++ virtual,channel = <2>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&ov106xx_in2>;
++ };
++ };
++ port@1 {
++ csi0ep2: endpoint {
++ remote-endpoint = <&csi2_40_ep>;
++ };
++ };
++ port@2 {
++ vin2_max9286_des0ep2: endpoint@0 {
++ remote-endpoint = <&max9286_des0ep2>;
++ };
++ };
++ };
++};
++
++&vin3 {
++ ports {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ port@0 {
++ vin3ep0: endpoint {
++ csi,select = "csi40";
++ virtual,channel = <3>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&ov106xx_in3>;
++ };
++ };
++ port@1 {
++ csi0ep3: endpoint {
++ remote-endpoint = <&csi2_40_ep>;
++ };
++ };
++ port@2 {
++ vin3_max9286_des0ep3: endpoint@0 {
++ remote-endpoint = <&max9286_des0ep3>;
++ };
++ };
++ };
++};
++
++&vin4 {
++ status = "disabled";
++};
++
++&vin5 {
++ status = "disabled";
++};
++
++&vin6 {
++ status = "disabled";
++};
++
++&vin7 {
++ status = "disabled";
++};
++
++&csi2_20 {
++ status = "disabled";
++ /delete-node/ports;
++};
++
++&csi2_40 {
++ /delete-node/ports;
++
++ virtual,channel {
++ csi2_vc0 {
++ data,type = "ycbcr422";
++ receive,vc = <0>;
++ };
++ csi2_vc1 {
++ data,type = "ycbcr422";
++ receive,vc = <1>;
++ };
++ csi2_vc2 {
++ data,type = "ycbcr422";
++ receive,vc = <2>;
++ };
++ csi2_vc3 {
++ data,type = "ycbcr422";
++ receive,vc = <3>;
++ };
++ };
++
++ port {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ csi2_40_ep: endpoint {
++ clock-lanes = <0>;
++ data-lanes = <1 2 3 4>;
++ csi-rate = <300>;
++ };
++ };
++};
++
++&can0 {
++ pinctrl-0 = <&can0_pins>;
++ pinctrl-names = "default";
++ status = "okay";
++};
++
++&can1 {
++ pinctrl-0 = <&can1_pins>;
++ pinctrl-names = "default";
++ status = "okay";
++};
+diff --git a/arch/arm64/boot/dts/renesas/r8a7797-eagle.dts b/arch/arm64/boot/dts/renesas/r8a7797-eagle.dts
+new file mode 100644
+index 0000000..f71addf
+--- /dev/null
++++ b/arch/arm64/boot/dts/renesas/r8a7797-eagle.dts
+@@ -0,0 +1,561 @@
++/*
++ * Device Tree Source for the Eagle board
++ *
++ * Copyright (C) 2016-2017 Renesas Electronics Corp.
++ *
++ * This file is licensed under the terms of the GNU General Public License
++ * version 2. This program is licensed "as is" without any warranty of any
++ * kind, whether express or implied.
++ */
++
++/dts-v1/;
++#include "r8a7797.dtsi"
++#include <dt-bindings/gpio/gpio.h>
++
++/ {
++ model = "Renesas Eagle board based on r8a7797";
++ compatible = "renesas,eagle", "renesas,r8a7797";
++
++ aliases {
++ serial0 = &scif0;
++ ethernet0 = &avb;
++ };
++
++ chosen {
++ bootargs = "ignore_loglevel rw root=/dev/nfs ip=dhcp";
++ stdout-path = "serial0:115200n8";
++ };
++
++ memory@48000000 {
++ device_type = "memory";
++ /* first 128MB is reserved for secure area. */
++ reg = <0x0 0x48000000 0x0 0x38000000>;
++ };
++
++ reserved-memory {
++ #address-cells = <2>;
++ #size-cells = <2>;
++ ranges;
++
++ /* device specific region for Lossy Decompression */
++ lossy_decompress: linux,lossy_decompress {
++ no-map;
++ reg = <0x00000000 0x64000000 0x0 0x03000000>;
++ };
++
++ /* global autoconfigured region for contiguous allocations */
++ linux,cma {
++ compatible = "shared-dma-pool";
++ reusable;
++ reg = <0x00000000 0x67000000 0x0 0x09000000>;
++ linux,cma-default;
++ };
++
++ /* device specific region for contiguous allocations */
++ linux,multimedia {
++ compatible = "shared-dma-pool";
++ reusable;
++ reg = <0x00000000 0x70000000 0x0 0x10000000>;
++ };
++ };
++
++ mmngr {
++ compatible = "renesas,mmngr";
++ memory-region = <&lossy_decompress>;
++ };
++
++ mmngrbuf {
++ compatible = "renesas,mmngrbuf";
++ };
++
++ vspm_if {
++ compatible = "renesas,vspm_if";
++ };
++
++ lvds-encoder {
++ compatible = "thine,thc63lvdm83d";
++
++ ports {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ port@0 {
++ reg = <0>;
++ lvds_enc_in: endpoint {
++ remote-endpoint = <&du_out_lvds0>;
++ };
++ };
++ port@1 {
++ reg = <1>;
++ lvds_enc_out: endpoint {
++ remote-endpoint = <&lvds_in>;
++ };
++ };
++ };
++ };
++
++ lvds {
++ compatible = "lvds-connector";
++
++ width-mm = <210>;
++ height-mm = <158>;
++
++ panel-timing {
++ clock-frequency = <133000000>;
++ hactive = <1024>;
++ vactive = <768>;
++ hsync-len = <136>;
++ hfront-porch = <20>;
++ hback-porch = <160>;
++ vfront-porch = <3>;
++ vback-porch = <29>;
++ vsync-len = <6>;
++ };
++
++ port {
++ lvds_in: endpoint {
++ remote-endpoint = <&lvds_enc_out>;
++ };
++ };
++ };
++
++ hdmi-out {
++ compatible = "hdmi-connector";
++ type = "a";
++
++ port {
++ hdmi_con: endpoint {
++ remote-endpoint = <&adv7511_out>;
++ };
++ };
++ };
++
++ dclkin_p0: clock-out0 {
++ compatible = "fixed-clock";
++ #clock-cells = <0>;
++ clock-frequency = <148500000>;
++ };
++
++ msiof_ref_clk: msiof-ref-clock {
++ compatible = "fixed-clock";
++ #clock-cells = <0>;
++ clock-frequency = <66666666>;
++ };
++};
++
++&du {
++ pinctrl-0 = <&du_pins>;
++ pinctrl-names = "default";
++ status = "okay";
++
++ ports {
++ port@0 {
++ endpoint {
++ remote-endpoint = <&adv7511_in>;
++ };
++ };
++ };
++};
++
++&extal_clk {
++ clock-frequency = <16666666>;
++};
++
++&extalr_clk {
++ clock-frequency = <32768>;
++};
++
++&pfc {
++ pinctrl-0 = <&scif_clk_pins>;
++ pinctrl-names = "default";
++
++ scif0_pins: scif0 {
++ groups = "scif0_data";
++ function = "scif0";
++ };
++
++ scif_clk_pins: scif_clk {
++ groups = "scif_clk_b";
++ function = "scif_clk";
++ };
++
++ i2c0_pins: i2c0 {
++ groups = "i2c0";
++ function = "i2c0";
++ };
++
++ i2c3_pins: i2c3 {
++ groups = "i2c3";
++ function = "i2c3";
++ };
++
++ avb_pins: avb {
++ groups = "avb0_mdc";
++ function = "avb0";
++ };
++
++ du_pins: du {
++ groups = "du_rgb666", "du_sync", "du_clk_out_0", "du_disp";
++ function = "du";
++ };
++};
++
++&scif0 {
++ pinctrl-0 = <&scif0_pins>;
++ pinctrl-names = "default";
++
++ status = "okay";
++};
++
++&scif_clk {
++ clock-frequency = <14745600>;
++ status = "okay";
++};
++
++&i2c0 {
++ pinctrl-0 = <&i2c0_pins>;
++ pinctrl-names = "default";
++
++ status = "okay";
++ clock-frequency = <400000>;
++
++ hdmi@39{
++ compatible = "adi,adv7511w";
++ #sound-dai-cells = <0>;
++ reg = <0x39>;
++ interrupt-parent = <&gpio1>;
++ interrupts = <20 IRQ_TYPE_LEVEL_LOW>;
++
++ adi,input-depth = <8>;
++ adi,input-colorspace = "rgb";
++ adi,input-clock = "1x";
++ adi,input-style = <1>;
++ adi,input-justification = "evenly";
++
++ ports {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ port@0 {
++ reg = <0>;
++ adv7511_in: endpoint {
++ remote-endpoint = <&lvds_enc_out>;
++ };
++ };
++ port@1 {
++ reg = <1>;
++ adv7511_out: endpoint {
++ remote-endpoint = <&hdmi_con>;
++ };
++ };
++ };
++ };
++
++ gpio_ext: pca9654@20 {
++ compatible = "onsemi,pca9654";
++ reg = <0x20>;
++ gpio-controller;
++ #gpio-cells = <2>;
++ };
++};
++
++&i2c3 {
++ pinctrl-0 = <&i2c3_pins>;
++ pinctrl-names = "default";
++
++ status = "okay";
++ clock-frequency = <400000>;
++
++ ov106xx@0 {
++ compatible = "ovti,ov106xx";
++ reg = <0x60>;
++
++ port@0 {
++ ov106xx_in0: endpoint {
++ clock-lanes = <0>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&vin0ep0>;
++ };
++ };
++ port@1 {
++ ov106xx_max9286_des0ep0: endpoint@0 {
++ remote-endpoint = <&max9286_des0ep0>;
++ };
++ };
++ };
++
++ ov106xx@1 {
++ compatible = "ovti,ov106xx";
++ reg = <0x61>;
++
++ port@0 {
++ ov106xx_in1: endpoint {
++ clock-lanes = <0>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&vin1ep0>;
++ };
++ };
++ port@1 {
++ ov106xx_max9286_des0ep1: endpoint@0 {
++ remote-endpoint = <&max9286_des0ep1>;
++ };
++ };
++ };
++
++ ov106xx@2 {
++ compatible = "ovti,ov106xx";
++ reg = <0x62>;
++
++ port@0 {
++ ov106xx_in2: endpoint {
++ clock-lanes = <0>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&vin2ep0>;
++ };
++ };
++ port@1 {
++ ov106xx_max9286_des0ep2: endpoint@0 {
++ remote-endpoint = <&max9286_des0ep2>;
++ };
++ };
++ };
++
++ ov106xx@3 {
++ compatible = "ovti,ov106xx";
++ reg = <0x63>;
++
++ port@0 {
++ ov106xx_in3: endpoint {
++ clock-lanes = <0>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&vin3ep0>;
++ };
++ };
++ port@1 {
++ ov106xx_des0ep3: endpoint {
++ remote-endpoint = <&max9286_des0ep3>;
++ };
++ };
++ };
++
++ max9286-max9271@0 {
++ compatible = "maxim,max9286-max9271";
++ reg = <0x48>;
++ gpios = <&gpio_ext 0 GPIO_ACTIVE_LOW>; /* CSI0 DE_PDn */
++ maxim,gpio0 = <0>;
++ maxim,sensor_delay = <100>;
++ maxim,links = <4>;
++ maxim,lanes = <4>;
++ maxim,resetb-gpio = <1>;
++ maxim,fsync-mode = "automatic";
++ maxim,timeout = <100>;
++
++ port@0 {
++ max9286_des0ep0: endpoint@0 {
++ max9271-addr = <0x50>;
++ dvp-order = <1>;
++ remote-endpoint = <&ov106xx_in0>;
++ };
++ max9286_des0ep1: endpoint@1 {
++ max9271-addr = <0x51>;
++ dvp-order = <1>;
++ remote-endpoint = <&ov106xx_in1>;
++ };
++ max9286_des0ep2: endpoint@2 {
++ max9271-addr = <0x52>;
++ dvp-order = <1>;
++ remote-endpoint = <&ov106xx_in2>;
++ };
++ max9286_des0ep3: endpoint@3 {
++ max9271-addr = <0x53>;
++ dvp-order = <1>;
++ remote-endpoint = <&ov106xx_in3>;
++ };
++ };
++ port@1 {
++ max9286_csi0ep0: endpoint {
++ csi-rate = <700>;
++ remote-endpoint = <&csi2_40_ep>;
++ };
++ };
++ };
++};
++
++&wdt0 {
++ status = "okay";
++};
++
++&avb {
++ pinctrl-0 = <&avb_pins>;
++ pinctrl-names = "default";
++ renesas,no-ether-link;
++ phy-handle = <&phy0>;
++ status = "okay";
++ phy-int-gpio = <&gpio1 17 GPIO_ACTIVE_LOW>;
++
++ phy0: ethernet-phy@0 {
++ rxc-skew-ps = <1500>;
++ rxdv-skew-ps = <420>; /* default */
++ rxd0-skew-ps = <420>; /* default */
++ rxd1-skew-ps = <420>; /* default */
++ rxd2-skew-ps = <420>; /* default */
++ rxd3-skew-ps = <420>; /* default */
++ txc-skew-ps = <900>; /* default */
++ txen-skew-ps = <420>; /* default */
++ txd0-skew-ps = <420>; /* default */
++ txd1-skew-ps = <420>; /* default */
++ txd2-skew-ps = <420>; /* default */
++ txd3-skew-ps = <420>; /* default */
++ reg = <0>;
++ interrupt-parent = <&gpio1>;
++ interrupts = <17 IRQ_TYPE_LEVEL_LOW>;
++ max-speed = <1000>;
++ };
++};
++
++&vin0 {
++ status = "okay";
++
++ ports {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ port@0 {
++ vin0ep0: endpoint {
++ csi,select = "csi40";
++ virtual,channel = <0>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&ov106xx_in0>;
++ };
++ };
++ port@1 {
++ csi0ep0: endpoint {
++ remote-endpoint = <&csi2_40_ep>;
++ };
++ };
++ port@2 {
++ vin0_max9286_des0ep0: endpoint@0 {
++ remote-endpoint = <&max9286_des0ep0>;
++ };
++ };
++ };
++};
++
++&vin1 {
++ status = "okay";
++
++ ports {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ port@0 {
++ vin1ep0: endpoint {
++ csi,select = "csi40";
++ virtual,channel = <1>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&ov106xx_in1>;
++ };
++ };
++ port@1 {
++ csi0ep1: endpoint {
++ remote-endpoint = <&csi2_40_ep>;
++ };
++ };
++ port@2 {
++ vin1_max9286_des0ep1: endpoint@0 {
++ remote-endpoint = <&max9286_des0ep1>;
++ };
++ };
++ };
++};
++
++&vin2 {
++ status = "okay";
++
++ ports {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ port@0 {
++ vin2ep0: endpoint {
++ csi,select = "csi40";
++ virtual,channel = <2>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&ov106xx_in2>;
++ };
++ };
++ port@1 {
++ csi0ep2: endpoint {
++ remote-endpoint = <&csi2_40_ep>;
++ };
++ };
++ port@2 {
++ vin2_max9286_des0ep2: endpoint@0 {
++ remote-endpoint = <&max9286_des0ep2>;
++ };
++ };
++ };
++};
++
++&vin3 {
++ status = "okay";
++
++ ports {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ port@0 {
++ vin3ep0: endpoint {
++ csi,select = "csi40";
++ virtual,channel = <3>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&ov106xx_in3>;
++ };
++ };
++ port@1 {
++ csi0ep3: endpoint {
++ remote-endpoint = <&csi2_40_ep>;
++ };
++ };
++ port@2 {
++ vin3_max9286_des0ep3: endpoint@0 {
++ remote-endpoint = <&max9286_des0ep3>;
++ };
++ };
++ };
++};
++
++&csi2_40 {
++ status = "okay";
++
++ virtual,channel {
++ csi2_vc0 {
++ data,type = "ycbcr422";
++ receive,vc = <0>;
++ };
++ csi2_vc1 {
++ data,type = "ycbcr422";
++ receive,vc = <1>;
++ };
++ csi2_vc2 {
++ data,type = "ycbcr422";
++ receive,vc = <2>;
++ };
++ csi2_vc3 {
++ data,type = "ycbcr422";
++ receive,vc = <3>;
++ };
++ };
++
++ port {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ csi2_40_ep: endpoint {
++ clock-lanes = <0>;
++ data-lanes = <1 2 3 4>;
++ csi-rate = <300>;
++ };
++ };
++};
++
+diff --git a/arch/arm64/boot/dts/renesas/r8a7797-v3msk-kf.dts b/arch/arm64/boot/dts/renesas/r8a7797-v3msk-kf.dts
+new file mode 100644
+index 0000000..9837e17
+--- /dev/null
++++ b/arch/arm64/boot/dts/renesas/r8a7797-v3msk-kf.dts
+@@ -0,0 +1,541 @@
++/*
++ * Device Tree Source for the V3MSK Kingfisher board on r8a7797
++ *
++ * Copyright (C) 2017 Renesas Electronics Corp.
++ * Copyright (C) 2017 Cogent Embedded, Inc.
++ *
++ * This file is licensed under the terms of the GNU General Public License
++ * version 2. This program is licensed "as is" without any warranty of any
++ * kind, whether express or implied.
++ */
++
++#include "r8a7797-v3msk.dts"
++
++/ {
++ model = "Renesas V3MSK Kingfisher board based on r8a7797";
++};
++
++&i2c0 {
++ /* i2c0 might conflict with pc9548 reset pin on Kingfisher (uncomment if h/w not patched) */
++// status = "disabled";
++};
++
++&i2c3 {
++ i2cswitch4: pca9548@71 {
++ compatible = "nxp,pca9548";
++ #address-cells = <1>;
++ #size-cells = <0>;
++ reg = <0x71>;
++// reset-gpios= <&gpio3 15 GPIO_ACTIVE_LOW>;
++
++ i2c@2 {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ reg = <2>;
++ /* Slot B (CN11) */
++
++ ov106xx@0 {
++ compatible = "ovti,ov106xx";
++ reg = <0x60>;
++
++ port@0 {
++ ov106xx_in0: endpoint {
++ clock-lanes = <0>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&vin0ep0>;
++ };
++ };
++ port@1 {
++ ov106xx_max9286_des0ep0: endpoint@0 {
++ remote-endpoint = <&max9286_des0ep0>;
++ };
++ ov106xx_ti964_des0ep0: endpoint@1 {
++ remote-endpoint = <&ti964_des0ep0>;
++ };
++ ov106xx_ti954_des0ep0: endpoint@2 {
++ remote-endpoint = <&ti954_des0ep0>;
++ };
++ };
++ };
++
++ ov106xx@1 {
++ compatible = "ovti,ov106xx";
++ reg = <0x61>;
++
++ port@0 {
++ ov106xx_in1: endpoint {
++ clock-lanes = <0>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&vin1ep0>;
++ };
++ };
++ port@1 {
++ ov106xx_max9286_des0ep1: endpoint@0 {
++ remote-endpoint = <&max9286_des0ep1>;
++ };
++ ov106xx_ti964_des0ep1: endpoint@1 {
++ remote-endpoint = <&ti964_des0ep1>;
++ };
++ ov106xx_ti954_des0ep1: endpoint@2 {
++ remote-endpoint = <&ti954_des0ep1>;
++ };
++ };
++ };
++
++ ov106xx@2 {
++ compatible = "ovti,ov106xx";
++ reg = <0x62>;
++
++ port@0 {
++ ov106xx_in2: endpoint {
++ clock-lanes = <0>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&vin2ep0>;
++ };
++ };
++ port@1 {
++ ov106xx_max9286_des0ep2: endpoint@0 {
++ remote-endpoint = <&max9286_des0ep2>;
++ };
++ ov106xx_ti964_des0ep2: endpoint@1 {
++ remote-endpoint = <&ti964_des0ep2>;
++ };
++ };
++ };
++
++ ov106xx@3 {
++ compatible = "ovti,ov106xx";
++ reg = <0x63>;
++
++ port@0 {
++ ov106xx_in3: endpoint {
++ clock-lanes = <0>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&vin3ep0>;
++ };
++ };
++ port@1 {
++ ov106xx_max9286_des0ep3: endpoint@0 {
++ remote-endpoint = <&max9286_des0ep3>;
++ };
++ ov106xx_ti964_des0ep3: endpoint@1 {
++ remote-endpoint = <&ti964_des0ep3>;
++ };
++ };
++ };
++
++ /* DS90UB964 @ 0x3a */
++ ti964-ti9x3@0 {
++ compatible = "ti,ti964-ti9x3";
++ reg = <0x3a>;
++ ti,sensor_delay = <350>;
++ ti,links = <4>;
++ ti,lanes = <4>;
++ ti,forwarding-mode = "round-robin";
++ ti,cable-mode = "coax";
++
++ port@0 {
++ ti964_des0ep0: endpoint@0 {
++ ti9x3-addr = <0x0c>;
++ dvp-order = <0>;
++ remote-endpoint = <&ov106xx_in0>;
++ };
++ ti964_des0ep1: endpoint@1 {
++ ti9x3-addr = <0x0d>;
++ dvp-order = <0>;
++ remote-endpoint = <&ov106xx_in1>;
++ };
++ ti964_des0ep2: endpoint@2 {
++ ti9x3-addr = <0x0e>;
++ dvp-order = <0>;
++ remote-endpoint = <&ov106xx_in2>;
++ };
++ ti964_des0ep3: endpoint@3 {
++ ti9x3-addr = <0x0f>;
++ dvp-order = <0>;
++ remote-endpoint = <&ov106xx_in3>;
++ };
++ };
++ port@1 {
++ ti964_csi0ep0: endpoint {
++ csi-rate = <800>;
++ remote-endpoint = <&csi2_40_ep>;
++ };
++ };
++ };
++
++ /* DS90UB954 @ 0x38 */
++ ti954-ti9x3@0 {
++ compatible = "ti,ti954-ti9x3";
++ reg = <0x38>;
++ /* gpios = <&video_a_ext1 10 GPIO_ACTIVE_HIGH>; */
++ ti,sensor_delay = <350>;
++ ti,links = <2>;
++ ti,lanes = <4>;
++ ti,forwarding-mode = "round-robin";
++ ti,cable-mode = "coax";
++
++ port@0 {
++ ti954_des0ep0: endpoint@0 {
++ ti9x3-addr = <0x0c>;
++ dvp-order = <0>;
++ remote-endpoint = <&ov106xx_in0>;
++ };
++ ti954_des0ep1: endpoint@1 {
++ ti9x3-addr = <0x0d>;
++ dvp-order = <0>;
++ remote-endpoint = <&ov106xx_in1>;
++ };
++ };
++ port@1 {
++ ti954_csi0ep0: endpoint {
++ csi-rate = <800>;
++ remote-endpoint = <&csi2_40_ep>;
++ };
++ };
++ };
++
++ /* MAX9286 @ 0x2c */
++ max9286-max9271@0 {
++ compatible = "maxim,max9286-max9271";
++ reg = <0x2c>;
++ maxim,sensor_delay = <350>;
++ maxim,links = <4>;
++ maxim,lanes = <4>;
++ maxim,resetb-gpio = <1>;
++ maxim,fsync-mode = "automatic";
++ maxim,timeout = <100>;
++
++ port@0 {
++ max9286_des0ep0: endpoint@0 {
++ max9271-addr = <0x50>;
++ dvp-order = <1>;
++ remote-endpoint = <&ov106xx_in0>;
++ };
++ max9286_des0ep1: endpoint@1 {
++ max9271-addr = <0x51>;
++ dvp-order = <1>;
++ remote-endpoint = <&ov106xx_in1>;
++ };
++ max9286_des0ep2: endpoint@2 {
++ max9271-addr = <0x52>;
++ dvp-order = <1>;
++ remote-endpoint = <&ov106xx_in2>;
++ };
++ max9286_des0ep3: endpoint@3 {
++ max9271-addr = <0x53>;
++ dvp-order = <1>;
++ remote-endpoint = <&ov106xx_in3>;
++ };
++ };
++ port@1 {
++ max9286_csi0ep0: endpoint {
++ csi-rate = <700>;
++ remote-endpoint = <&csi2_40_ep>;
++ };
++ };
++ };
++ };
++
++ i2c@6 {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ reg = <6>;
++ /* Slot B (CN11) */
++
++ video_a_ext0: pca9535@27 {
++ compatible = "nxp,pca9535";
++ reg = <0x27>;
++ gpio-controller;
++ #gpio-cells = <2>;
++
++ video_a_des_cfg1 {
++ gpio-hog;
++ gpios = <5 GPIO_ACTIVE_HIGH>;
++ input;
++ line-name = "Video-A cfg1";
++ };
++ video_a_des_cfg0 {
++ gpio-hog;
++ gpios = <6 GPIO_ACTIVE_HIGH>;
++ input;
++ line-name = "Video-A cfg0";
++ };
++ video_a_pwr_shdn {
++ gpio-hog;
++ gpios = <3 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "Video-A PWR_SHDN";
++ };
++ video_a_cam_pwr0 {
++ gpio-hog;
++ gpios = <12 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "Video-A PWR0";
++ };
++ video_a_cam_pwr1 {
++ gpio-hog;
++ gpios = <13 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "Video-A PWR1";
++ };
++ video_a_cam_pwr2 {
++ gpio-hog;
++ gpios = <14 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "Video-A PWR2";
++ };
++ video_a_cam_pwr3 {
++ gpio-hog;
++ gpios = <15 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "Video-A PWR3";
++ };
++ video_a_des_shdn {
++ gpio-hog;
++ gpios = <4 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "Video-A DES_SHDN";
++ };
++ video_a_des_led {
++ gpio-hog;
++ gpios = <7 GPIO_ACTIVE_HIGH>;
++ output-low;
++ line-name = "Video-A led";
++ };
++ };
++
++ video_a_ext1: max7325@5c {
++ compatible = "maxim,max7325";
++ reg = <0x5c>;
++ gpio-controller;
++ #gpio-cells = <2>;
++
++ video_a_des_cfg2 {
++ gpio-hog;
++ gpios = <4 GPIO_ACTIVE_HIGH>;
++ input;
++ line-name = "Video-A cfg2";
++ };
++ video_a_des_cfg1 {
++ gpio-hog;
++ gpios = <6 GPIO_ACTIVE_HIGH>;
++ input;
++ line-name = "Video-A cfg1";
++ };
++ video_a_des_cfg0 {
++ gpio-hog;
++ gpios = <7 GPIO_ACTIVE_HIGH>;
++ input;
++ line-name = "Video-A cfg0";
++ };
++ video_a_pwr_shdn {
++ gpio-hog;
++ gpios = <14 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "Video-A PWR_SHDN";
++ };
++ video_a_cam_pwr0 {
++ gpio-hog;
++ gpios = <8 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "Video-A PWR0";
++ };
++ video_a_cam_pwr1 {
++ gpio-hog;
++ gpios = <9 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "Video-A PWR1";
++ };
++ video_a_cam_pwr2 {
++ gpio-hog;
++ gpios = <10 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "Video-A PWR2";
++ };
++ video_a_cam_pwr3 {
++ gpio-hog;
++ gpios = <11 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "Video-A PWR3";
++ };
++ video_a_des_shdn {
++ gpio-hog;
++ gpios = <13 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "Video-A DES_SHDN";
++ };
++ video_a_led {
++ gpio-hog;
++ gpios = <12 GPIO_ACTIVE_HIGH>;
++ output-low;
++ line-name = "Video-A LED";
++ };
++ };
++ };
++ };
++};
++
++&vin0 {
++ status = "okay";
++
++ ports {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ port@0 {
++ vin0ep0: endpoint {
++ csi,select = "csi40";
++ virtual,channel = <0>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&ov106xx_in0>;
++ };
++ };
++ port@1 {
++ csi0ep0: endpoint {
++ remote-endpoint = <&csi2_40_ep>;
++ };
++ };
++ port@2 {
++ vin0_max9286_des0ep0: endpoint@0 {
++ remote-endpoint = <&max9286_des0ep0>;
++ };
++ vin0_ti964_des0ep0: endpoint@1 {
++ remote-endpoint = <&ti964_des0ep0>;
++ };
++ vin0_ti954_des0ep0: endpoint@2 {
++ remote-endpoint = <&ti954_des0ep0>;
++ };
++ };
++ };
++};
++
++&vin1 {
++ status = "okay";
++
++ ports {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ port@0 {
++ vin1ep0: endpoint {
++ csi,select = "csi40";
++ virtual,channel = <1>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&ov106xx_in1>;
++ };
++ };
++ port@1 {
++ csi0ep1: endpoint {
++ remote-endpoint = <&csi2_40_ep>;
++ };
++ };
++ port@2 {
++ vin1_max9286_des0ep1: endpoint@0 {
++ remote-endpoint = <&max9286_des0ep1>;
++ };
++ vin1_ti964_des0ep1: endpoint@1 {
++ remote-endpoint = <&ti964_des0ep1>;
++ };
++ vin1_ti954_des0ep1: endpoint@2 {
++ remote-endpoint = <&ti954_des0ep1>;
++ };
++ };
++ };
++};
++
++&vin2 {
++ status = "okay";
++
++ ports {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ port@0 {
++ vin2ep0: endpoint {
++ csi,select = "csi40";
++ virtual,channel = <2>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&ov106xx_in2>;
++ };
++ };
++ port@1 {
++ csi0ep2: endpoint {
++ remote-endpoint = <&csi2_40_ep>;
++ };
++ };
++ port@2 {
++ vin2_max9286_des0ep2: endpoint@0 {
++ remote-endpoint = <&max9286_des0ep2>;
++ };
++ vin2_ti964_des0ep2: endpoint@1 {
++ remote-endpoint = <&ti964_des0ep2>;
++ };
++ };
++ };
++};
++
++&vin3 {
++ status = "okay";
++
++ ports {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ port@0 {
++ vin3ep0: endpoint {
++ csi,select = "csi40";
++ virtual,channel = <3>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&ov106xx_in3>;
++ };
++ };
++ port@1 {
++ csi0ep3: endpoint {
++ remote-endpoint = <&csi2_40_ep>;
++ };
++ };
++ port@2 {
++ vin3_max9286_des0ep3: endpoint@0 {
++ remote-endpoint = <&max9286_des0ep3>;
++ };
++ vin3_ti964_des0ep3: endpoint@1 {
++ remote-endpoint = <&ti964_des0ep3>;
++ };
++ };
++ };
++};
++
++&csi2_40 {
++ status = "okay";
++
++ virtual,channel {
++ csi2_vc0 {
++ data,type = "ycbcr422";
++ receive,vc = <0>;
++ };
++ csi2_vc1 {
++ data,type = "ycbcr422";
++ receive,vc = <1>;
++ };
++ csi2_vc2 {
++ data,type = "ycbcr422";
++ receive,vc = <2>;
++ };
++ csi2_vc3 {
++ data,type = "ycbcr422";
++ receive,vc = <3>;
++ };
++ };
++
++ port {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ csi2_40_ep: endpoint {
++ clock-lanes = <0>;
++ data-lanes = <1 2 3 4>;
++ csi-rate = <300>;
++ };
++ };
++};
+diff --git a/arch/arm64/boot/dts/renesas/r8a7797-v3msk.dts b/arch/arm64/boot/dts/renesas/r8a7797-v3msk.dts
+new file mode 100644
+index 0000000..61f7e8b
+--- /dev/null
++++ b/arch/arm64/boot/dts/renesas/r8a7797-v3msk.dts
+@@ -0,0 +1,294 @@
++/*
++ * Device Tree Source for the V3M Starter Kit board on r8a7797
++ *
++ * Copyright (C) 2017 Renesas Electronics Corp.
++ * Copyright (C) 2017 Cogent Embedded, Inc.
++ *
++ * This file is licensed under the terms of the GNU General Public License
++ * version 2. This program is licensed "as is" without any warranty of any
++ * kind, whether express or implied.
++ */
++
++/dts-v1/;
++#include "r8a7797.dtsi"
++#include <dt-bindings/gpio/gpio.h>
++
++/ {
++ model = "Renesas V3M Starter Kit board based on r8a7797";
++ compatible = "renesas,v3msk", "renesas,r8a7797";
++
++ aliases {
++ serial0 = &scif0;
++ ethernet0 = &avb;
++ };
++
++ chosen {
++ bootargs = "ignore_loglevel rw root=/dev/nfs ip=dhcp";
++ stdout-path = "serial0:115200n8";
++ };
++
++ memory@48000000 {
++ device_type = "memory";
++ /* first 128MB is reserved for secure area. */
++ reg = <0x0 0x48000000 0x0 0x38000000>;
++ };
++
++ reserved-memory {
++ #address-cells = <2>;
++ #size-cells = <2>;
++ ranges;
++
++ /* device specific region for Lossy Decompression */
++ lossy_decompress: linux,lossy_decompress {
++ no-map;
++ reg = <0x00000000 0x64000000 0x0 0x03000000>;
++ };
++
++ /* global autoconfigured region for contiguous allocations */
++ linux,cma {
++ compatible = "shared-dma-pool";
++ reusable;
++ reg = <0x00000000 0x67000000 0x0 0x09000000>;
++ linux,cma-default;
++ };
++
++ /* device specific region for contiguous allocations */
++ linux,multimedia {
++ compatible = "shared-dma-pool";
++ reusable;
++ reg = <0x00000000 0x70000000 0x0 0x10000000>;
++ };
++ };
++
++ mmngr {
++ compatible = "renesas,mmngr";
++ memory-region = <&lossy_decompress>;
++ };
++
++ mmngrbuf {
++ compatible = "renesas,mmngrbuf";
++ };
++
++ vspm_if {
++ compatible = "renesas,vspm_if";
++ };
++
++ lvds-encoder {
++ compatible = "thine,thc63lvdm83d";
++
++ ports {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ port@0 {
++ reg = <0>;
++ lvds_enc_in: endpoint {
++ remote-endpoint = <&du_out_lvds0>;
++ };
++ };
++ port@1 {
++ reg = <1>;
++ lvds_enc_out: endpoint {
++ remote-endpoint = <&lvds_in>;
++ };
++ };
++ };
++ };
++
++ lvds {
++ compatible = "lvds-connector";
++
++ width-mm = <210>;
++ height-mm = <158>;
++
++ panel-timing {
++ clock-frequency = <133000000>;
++ hactive = <1024>;
++ vactive = <768>;
++ hsync-len = <136>;
++ hfront-porch = <20>;
++ hback-porch = <160>;
++ vfront-porch = <3>;
++ vback-porch = <29>;
++ vsync-len = <6>;
++ };
++
++ port {
++ lvds_in: endpoint {
++ remote-endpoint = <&lvds_enc_out>;
++ };
++ };
++ };
++
++ hdmi-out {
++ compatible = "hdmi-connector";
++ type = "a";
++
++ port {
++ hdmi_con: endpoint {
++ remote-endpoint = <&adv7511_out>;
++ };
++ };
++ };
++
++ dclkin_p0: clock-out0 {
++ compatible = "fixed-clock";
++ #clock-cells = <0>;
++ clock-frequency = <148500000>;
++ };
++
++ msiof_ref_clk: msiof-ref-clock {
++ compatible = "fixed-clock";
++ #clock-cells = <0>;
++ clock-frequency = <66666666>;
++ };
++};
++
++&du {
++ pinctrl-0 = <&du_pins>;
++ pinctrl-names = "default";
++ status = "okay";
++
++ ports {
++ port@0 {
++ endpoint {
++ remote-endpoint = <&adv7511_in>;
++ };
++ };
++ };
++};
++
++&extal_clk {
++ clock-frequency = <16666666>;
++};
++
++&extalr_clk {
++ clock-frequency = <32768>;
++};
++
++&pfc {
++ pinctrl-0 = <&scif_clk_pins>;
++ pinctrl-names = "default";
++
++ scif0_pins: scif0 {
++ groups = "scif0_data";
++ function = "scif0";
++ };
++
++ scif_clk_pins: scif_clk {
++ groups = "scif_clk_b";
++ function = "scif_clk";
++ };
++
++ i2c0_pins: i2c0 {
++ groups = "i2c0";
++ function = "i2c0";
++ };
++
++ i2c3_pins: i2c3 {
++ groups = "i2c3";
++ function = "i2c3";
++ };
++
++ avb_pins: avb {
++ groups = "avb0_mdc";
++ function = "avb0";
++ };
++
++ du_pins: du {
++ groups = "du_rgb666", "du_sync", "du_clk_out_0", "du_disp";
++ function = "du";
++ };
++};
++
++&scif0 {
++ pinctrl-0 = <&scif0_pins>;
++ pinctrl-names = "default";
++
++ status = "okay";
++};
++
++&scif_clk {
++ clock-frequency = <14745600>;
++ status = "okay";
++};
++
++&i2c0 {
++ pinctrl-0 = <&i2c0_pins>;
++ pinctrl-names = "default";
++
++ status = "okay";
++ clock-frequency = <400000>;
++
++ hdmi@39{
++ compatible = "adi,adv7511w";
++ #sound-dai-cells = <0>;
++ reg = <0x39>;
++ interrupt-parent = <&gpio1>;
++ interrupts = <20 IRQ_TYPE_LEVEL_LOW>;
++
++ adi,input-depth = <8>;
++ adi,input-colorspace = "rgb";
++ adi,input-clock = "1x";
++ adi,input-style = <1>;
++ adi,input-justification = "evenly";
++
++ ports {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ port@0 {
++ reg = <0>;
++ adv7511_in: endpoint {
++ remote-endpoint = <&lvds_enc_out>;
++ };
++ };
++ port@1 {
++ reg = <1>;
++ adv7511_out: endpoint {
++ remote-endpoint = <&hdmi_con>;
++ };
++ };
++ };
++ };
++};
++
++&i2c3 {
++ pinctrl-0 = <&i2c3_pins>;
++ pinctrl-names = "default";
++
++ status = "okay";
++ clock-frequency = <400000>;
++};
++
++&wdt0 {
++ status = "okay";
++};
++
++&avb {
++ pinctrl-0 = <&avb_pins>;
++ pinctrl-names = "default";
++ renesas,no-ether-link;
++ phy-handle = <&phy0>;
++ status = "okay";
++ phy-int-gpio = <&gpio1 17 GPIO_ACTIVE_LOW>;
++
++ phy0: ethernet-phy@0 {
++ rxc-skew-ps = <1500>;
++ rxdv-skew-ps = <420>; /* default */
++ rxd0-skew-ps = <420>; /* default */
++ rxd1-skew-ps = <420>; /* default */
++ rxd2-skew-ps = <420>; /* default */
++ rxd3-skew-ps = <420>; /* default */
++ txc-skew-ps = <900>; /* default */
++ txen-skew-ps = <420>; /* default */
++ txd0-skew-ps = <420>; /* default */
++ txd1-skew-ps = <420>; /* default */
++ txd2-skew-ps = <420>; /* default */
++ txd3-skew-ps = <420>; /* default */
++ reg = <0>;
++ interrupt-parent = <&gpio1>;
++ interrupts = <17 IRQ_TYPE_LEVEL_LOW>;
++ max-speed = <1000>;
++ };
++};
+diff --git a/arch/arm64/boot/dts/renesas/ulcb-kf-cn11.dtsi b/arch/arm64/boot/dts/renesas/ulcb-kf-cn11.dtsi
+new file mode 100644
+index 0000000..4ca502f
+--- /dev/null
++++ b/arch/arm64/boot/dts/renesas/ulcb-kf-cn11.dtsi
+@@ -0,0 +1,518 @@
++/*
++ * Device Tree Source for the H3ULCB Kingfisher board:
++ * this adding conflicting resource on VIN4/VIN5/VIN6/VIN7 for CN11
++ * use CN11 instead default CN29/CN48
++ *
++ * Copyright (C) 2017 Renesas Electronics Corp.
++ * Copyright (C) 2017 Cogent Embedded, Inc.
++ *
++ * This file is licensed under the terms of the GNU General Public License
++ * version 2. This program is licensed "as is" without any warranty of any
++ * kind, whether express or implied.
++ */
++
++&i2cswitch4 {
++ i2c@2 {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ reg = <2>;
++ /* Slot B (CN11) */
++
++ ov106xx@4 {
++ compatible = "ovti,ov106xx";
++ reg = <0x64>;
++
++ port@0 {
++ ov106xx_in4: endpoint {
++ clock-lanes = <0>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&vin4ep0>;
++ };
++ };
++ port@1 {
++ ov106xx_max9286_des1ep0: endpoint@0 {
++ remote-endpoint = <&max9286_des1ep0>;
++ };
++ ov106xx_ti964_des1ep0: endpoint@1 {
++ remote-endpoint = <&ti964_des1ep0>;
++ };
++ ov106xx_ti954_des1ep0: endpoint@2 {
++ remote-endpoint = <&ti954_des1ep0>;
++ };
++ };
++ };
++
++ ov106xx@5 {
++ compatible = "ovti,ov106xx";
++ reg = <0x65>;
++
++ port@0 {
++ ov106xx_in5: endpoint {
++ clock-lanes = <0>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&vin5ep0>;
++ };
++ };
++ port@1 {
++ ov106xx_max9286_des1ep1: endpoint@0 {
++ remote-endpoint = <&max9286_des1ep1>;
++ };
++ ov106xx_ti964_des1ep1: endpoint@1 {
++ remote-endpoint = <&ti964_des1ep1>;
++ };
++ ov106xx_ti954_des1ep1: endpoint@2 {
++ remote-endpoint = <&ti954_des1ep1>;
++ };
++ };
++ };
++
++ ov106xx@6 {
++ compatible = "ovti,ov106xx";
++ reg = <0x66>;
++ port@0 {
++ ov106xx_in6: endpoint {
++ clock-lanes = <0>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&vin6ep0>;
++ };
++ };
++ port@1 {
++ ov106xx_max9286_des1ep2: endpoint@0 {
++ remote-endpoint = <&max9286_des1ep2>;
++ };
++ ov106xx_ti964_des1ep2: endpoint@1 {
++ remote-endpoint = <&ti964_des1ep2>;
++ };
++ };
++ };
++
++ ov106xx@7 {
++ compatible = "ovti,ov106xx";
++ reg = <0x67>;
++ port@0 {
++ ov106xx_in7: endpoint {
++ clock-lanes = <0>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&vin7ep0>;
++ };
++ };
++ port@1 {
++ ov106xx_max9286_des1ep3: endpoint@0 {
++ remote-endpoint = <&max9286_des1ep3>;
++ };
++ ov106xx_ti964_des1ep3: endpoint@1 {
++ remote-endpoint = <&ti964_des1ep3>;
++ };
++ };
++ };
++
++ /* DS90UB964 @ 0x3a */
++ ti964-ti9x3@1 {
++ compatible = "ti,ti964-ti9x3";
++ reg = <0x3a>;
++ ti,sensor_delay = <350>;
++ ti,links = <4>;
++ ti,lanes = <4>;
++ ti,forwarding-mode = "round-robin";
++ ti,cable-mode = "coax";
++
++ port@0 {
++ ti964_des1ep0: endpoint@0 {
++ ti9x3-addr = <0x0c>;
++ dvp-order = <0>;
++ remote-endpoint = <&ov106xx_in4>;
++ };
++ ti964_des1ep1: endpoint@1 {
++ ti9x3-addr = <0x0d>;
++ dvp-order = <0>;
++ remote-endpoint = <&ov106xx_in5>;
++ };
++ ti964_des1ep2: endpoint@2 {
++ ti9x3-addr = <0x0e>;
++ dvp-order = <0>;
++ remote-endpoint = <&ov106xx_in6>;
++ };
++ ti964_des1ep3: endpoint@3 {
++ ti9x3-addr = <0x0f>;
++ dvp-order = <0>;
++ remote-endpoint = <&ov106xx_in7>;
++ };
++ };
++ port@1 {
++ ti964_csi2ep0: endpoint {
++ csi-rate = <1450>;
++ remote-endpoint = <&csi2_41_ep>;
++ };
++ };
++ };
++
++ /* DS90UB954 @ 0x38 */
++ ti954-ti9x3@1 {
++ compatible = "ti,ti954-ti9x3";
++ reg = <0x38>;
++ /* gpios = <&video_b_ext1 10 GPIO_ACTIVE_HIGH>; */
++ ti,sensor_delay = <350>;
++ ti,links = <2>;
++ ti,lanes = <4>;
++ ti,forwarding-mode = "round-robin";
++ ti,cable-mode = "coax";
++
++ port@0 {
++ ti954_des1ep0: endpoint@0 {
++ ti9x3-addr = <0x0c>;
++ dvp-order = <0>;
++ remote-endpoint = <&ov106xx_in4>;
++ };
++ ti954_des1ep1: endpoint@1 {
++ ti9x3-addr = <0x0d>;
++ dvp-order = <0>;
++ remote-endpoint = <&ov106xx_in5>;
++ };
++ };
++ port@1 {
++ ti954_csi2ep0: endpoint {
++ csi-rate = <1450>;
++ remote-endpoint = <&csi2_41_ep>;
++ };
++ };
++ };
++
++ /* MAX9286 @ 0x2c */
++ max9286-max9271@1 {
++ compatible = "maxim,max9286-max9271";
++ reg = <0x2c>;
++ maxim,sensor_delay = <350>;
++ maxim,links = <4>;
++ maxim,lanes = <4>;
++ maxim,resetb-gpio = <1>;
++ maxim,fsync-mode = "automatic";
++ maxim,timeout = <100>;
++
++ port@0 {
++ max9286_des1ep0: endpoint@0 {
++ max9271-addr = <0x50>;
++ dvp-order = <1>;
++ remote-endpoint = <&ov106xx_in4>;
++ };
++ max9286_des1ep1: endpoint@1 {
++ max9271-addr = <0x51>;
++ dvp-order = <1>;
++ remote-endpoint = <&ov106xx_in5>;
++ };
++ max9286_des1ep2: endpoint@2 {
++ max9271-addr = <0x52>;
++ dvp-order = <1>;
++ remote-endpoint = <&ov106xx_in6>;
++ };
++ max9286_des1ep3: endpoint@3 {
++ max9271-addr = <0x53>;
++ dvp-order = <1>;
++ remote-endpoint = <&ov106xx_in7>;
++ };
++ };
++ port@1 {
++ max9286_csi2ep0: endpoint {
++ csi-rate = <700>;
++ remote-endpoint = <&csi2_41_ep>;
++ };
++ };
++ };
++ };
++
++ i2c@6 {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ reg = <6>;
++ /* Slot B (CN11) */
++
++ video_b_ext0: pca9535@27 {
++ compatible = "nxp,pca9535";
++ reg = <0x27>;
++ gpio-controller;
++ #gpio-cells = <2>;
++
++ video_b_des_cfg1 {
++ gpio-hog;
++ gpios = <5 GPIO_ACTIVE_HIGH>;
++ input;
++ line-name = "Video-B cfg1";
++ };
++ video_b_des_cfg0 {
++ gpio-hog;
++ gpios = <6 GPIO_ACTIVE_HIGH>;
++ input;
++ line-name = "Video-B cfg0";
++ };
++ video_b_pwr_shdn {
++ gpio-hog;
++ gpios = <3 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "Video-B PWR_SHDN";
++ };
++ video_b_cam_pwr0 {
++ gpio-hog;
++ gpios = <12 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "Video-B PWR0";
++ };
++ video_b_cam_pwr1 {
++ gpio-hog;
++ gpios = <13 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "Video-B PWR1";
++ };
++ video_b_cam_pwr2 {
++ gpio-hog;
++ gpios = <14 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "Video-B PWR2";
++ };
++ video_b_cam_pwr3 {
++ gpio-hog;
++ gpios = <15 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "Video-B PWR3";
++ };
++ video_b_des_shdn {
++ gpio-hog;
++ gpios = <4 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "Video-B DES_SHDN";
++ };
++ video_b_des_led {
++ gpio-hog;
++ gpios = <7 GPIO_ACTIVE_HIGH>;
++ output-low;
++ line-name = "Video-B led";
++ };
++ };
++
++ video_b_ext1: max7325@5c {
++ compatible = "maxim,max7325";
++ reg = <0x5c>;
++ gpio-controller;
++ #gpio-cells = <2>;
++
++ video_b_des_cfg2 {
++ gpio-hog;
++ gpios = <4 GPIO_ACTIVE_HIGH>;
++ input;
++ line-name = "Video-B cfg2";
++ };
++ video_b_des_cfg1 {
++ gpio-hog;
++ gpios = <6 GPIO_ACTIVE_HIGH>;
++ input;
++ line-name = "Video-B cfg1";
++ };
++ video_b_des_cfg0 {
++ gpio-hog;
++ gpios = <7 GPIO_ACTIVE_HIGH>;
++ input;
++ line-name = "Video-B cfg0";
++ };
++ video_b_pwr_shdn {
++ gpio-hog;
++ gpios = <14 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "Video-B PWR_SHDN";
++ };
++ video_b_cam_pwr0 {
++ gpio-hog;
++ gpios = <8 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "Video-B PWR0";
++ };
++ video_b_cam_pwr1 {
++ gpio-hog;
++ gpios = <9 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "Video-B PWR1";
++ };
++ video_b_cam_pwr2 {
++ gpio-hog;
++ gpios = <10 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "Video-B PWR2";
++ };
++ video_b_cam_pwr3 {
++ gpio-hog;
++ gpios = <11 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "Video-B PWR3";
++ };
++ video_b_des_shdn {
++ gpio-hog;
++ gpios = <13 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "Video-B DES_SHDN";
++ };
++ video_b_led {
++ gpio-hog;
++ gpios = <12 GPIO_ACTIVE_HIGH>;
++ output-low;
++ line-name = "Video-B LED";
++ };
++ };
++ };
++};
++
++&vin4 {
++ ports {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ port@0 {
++ vin4ep0: endpoint {
++ csi,select = "csi41";
++ virtual,channel = <0>;
++ remote-endpoint = <&ov106xx_in4>;
++ data-lanes = <1 2 3 4>;
++ };
++ };
++ port@1 {
++ csi2ep0: endpoint {
++ remote-endpoint = <&csi2_41_ep>;
++ };
++ };
++ port@2 {
++ vin4_max9286_des1ep0: endpoint@0 {
++ remote-endpoint = <&max9286_des1ep0>;
++ };
++ vin4_ti964_des1ep0: endpoint@1 {
++ remote-endpoint = <&ti964_des1ep0>;
++ };
++ vin4_ti954_des1ep0: endpoint@2 {
++ remote-endpoint = <&ti954_des1ep0>;
++ };
++ };
++ };
++};
++
++&vin5 {
++ ports {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ port@0 {
++ vin5ep0: endpoint@0 {
++ csi,select = "csi41";
++ virtual,channel = <1>;
++ remote-endpoint = <&ov106xx_in5>;
++ data-lanes = <1 2 3 4>;
++ };
++ };
++ port@1 {
++ csi2ep1: endpoint {
++ remote-endpoint = <&csi2_41_ep>;
++ };
++ };
++ port@2 {
++ vin5_max9286_des1ep1: endpoint@0 {
++ remote-endpoint = <&max9286_des1ep1>;
++ };
++ vin5_ti964_des1ep1: endpoint@1 {
++ remote-endpoint = <&ti964_des1ep1>;
++ };
++ vin5_ti954_des1ep1: endpoint@2 {
++ remote-endpoint = <&ti954_des1ep1>;
++ };
++ };
++ };
++};
++
++&vin6 {
++ status = "okay";
++
++ ports {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ port@0 {
++ vin6ep0: endpoint@0 {
++ csi,select = "csi41";
++ virtual,channel = <2>;
++ remote-endpoint = <&ov106xx_in6>;
++ data-lanes = <1 2 3 4>;
++ };
++ };
++ port@1 {
++ csi2ep2: endpoint {
++ remote-endpoint = <&csi2_41_ep>;
++ };
++ };
++ port@2 {
++ vin6_max9286_des1ep2: endpoint@0 {
++ remote-endpoint = <&max9286_des1ep2>;
++ };
++ vin6_ti964_des1ep2: endpoint@1 {
++ remote-endpoint = <&ti964_des1ep2>;
++ };
++ };
++ };
++};
++
++&vin7 {
++ status = "okay";
++
++ ports {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ port@0 {
++ vin7ep0: endpoint@0 {
++ csi,select = "csi41";
++ virtual,channel = <3>;
++ remote-endpoint = <&ov106xx_in7>;
++ data-lanes = <1 2 3 4>;
++ };
++ };
++ port@1 {
++ csi2ep3: endpoint {
++ remote-endpoint = <&csi2_41_ep>;
++ };
++ };
++ port@2 {
++ vin7_max9286_des1ep3: endpoint@0 {
++ remote-endpoint = <&max9286_des1ep3>;
++ };
++ vin7_ti964_des1ep3: endpoint@1 {
++ remote-endpoint = <&ti964_des1ep3>;
++ };
++ };
++ };
++};
++
++&csi2_41 {
++ status = "okay";
++
++ virtual,channel {
++ csi2_vc0 {
++ data,type = "ycbcr422";
++ receive,vc = <0>;
++ };
++ csi2_vc1 {
++ data,type = "ycbcr422";
++ receive,vc = <1>;
++ };
++ csi2_vc2 {
++ data,type = "ycbcr422";
++ receive,vc = <2>;
++ };
++ csi2_vc3 {
++ data,type = "ycbcr422";
++ receive,vc = <3>;
++ };
++ };
++
++ port {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ csi2_41_ep: endpoint {
++ clock-lanes = <0>;
++ data-lanes = <1 2 3 4>;
++ csi-rate = <300>;
++ };
++ };
++};
+diff --git a/arch/arm64/boot/dts/renesas/ulcb-kf-most.dtsi b/arch/arm64/boot/dts/renesas/ulcb-kf-most.dtsi
+new file mode 100644
+index 0000000..4af5ca0
+--- /dev/null
++++ b/arch/arm64/boot/dts/renesas/ulcb-kf-most.dtsi
+@@ -0,0 +1,30 @@
++/*
++ * Device Tree Source for the H3/M3ULCB Kingfisher board:
++ * this overrides GPS in favour MOST on GP5_24/GP5_25 R-CAR pins
++ *
++ * Copyright (C) 2017 Renesas Electronics Corp.
++ * Copyright (C) 2017 Cogent Embedded, Inc.
++ *
++ * This file is licensed under the terms of the GNU General Public License
++ * version 2. This program is licensed "as is" without any warranty of any
++ * kind, whether express or implied.
++ */
++
++&pfc {
++ mlp_pins: mlp {
++ groups = "mlb_3pin";
++ function = "mlb_3pin";
++ };
++};
++
++&scif1 {
++ status = "disabled";
++};
++
++&mlp {
++ pinctrl-0 = <&mlp_pins>;
++ pinctrl-names = "default";
++ status = "okay";
++
++ clock-speed = "1024fs";
++};
+diff --git a/arch/arm64/boot/dts/renesas/ulcb-kf-sd3.dtsi b/arch/arm64/boot/dts/renesas/ulcb-kf-sd3.dtsi
+new file mode 100644
+index 0000000..b854216
+--- /dev/null
++++ b/arch/arm64/boot/dts/renesas/ulcb-kf-sd3.dtsi
+@@ -0,0 +1,46 @@
++/*
++ * Device Tree Source for the H3/M3ULCB Kingfisher board:
++ * this overrides WIFI in favour SD on SDHI3
++ *
++ * Copyright (C) 2017 Renesas Electronics Corp.
++ * Copyright (C) 2017 Cogent Embedded, Inc.
++ *
++ * This file is licensed under the terms of the GNU General Public License
++ * version 2. This program is licensed "as is" without any warranty of any
++ * kind, whether express or implied.
++ */
++
++&sdio_switch {
++ regulator-name = "sd_on";
++ enable-active-high;
++};
++
++&vccq_sdhi3 {
++ compatible = "regulator-gpio";
++
++ regulator-min-microvolt = <1800000>;
++
++ gpios = <&gpio3 14 GPIO_ACTIVE_HIGH>;
++ gpios-states = <1>;
++ states = <3300000 1
++ 1800000 0>;
++};
++
++&sdhi3 {
++ /delete-property/non-removable;
++ /delete-property/cap-power-off-card;
++ /delete-property/keep-power-in-suspend;
++ /delete-property/enable-sdio-wakeup;
++ /delete-property/max-frequency;
++ /delete-property/no-1-8-v;
++
++ vmmc-supply = <&vcc_sdhi3>;
++ cd-gpios = <&gpio4 15 GPIO_ACTIVE_LOW>;
++ wp-gpios = <&gpio4 16 GPIO_ACTIVE_HIGH>;
++// sd-uhs-sdr50;
++// sd-uhs-sdr104;
++};
++
++&wlcore {
++ status = "disabled";
++};
+diff --git a/arch/arm64/boot/dts/renesas/ulcb-kf.dtsi b/arch/arm64/boot/dts/renesas/ulcb-kf.dtsi
+new file mode 100644
+index 0000000..3990648
+--- /dev/null
++++ b/arch/arm64/boot/dts/renesas/ulcb-kf.dtsi
+@@ -0,0 +1,1529 @@
++/*
++ * Device Tree Source for the ULCB Kingfisher board
++ *
++ * Copyright (C) 2017 Renesas Electronics Corp.
++ * Copyright (C) 2017 Cogent Embedded, Inc.
++ *
++ * This file is licensed under the terms of the GNU General Public License
++ * version 2. This program is licensed "as is" without any warranty of any
++ * kind, whether express or implied.
++ */
++
++/ {
++ aliases {
++ serial1 = &hscif0;
++ serial2 = &hscif1;
++ serial3 = &scif1;
++ };
++
++ snd_clk: snd_clk {
++ compatible = "fixed-clock";
++ #clock-cells = <0>;
++ clock-frequency = <24576000>;
++ clock-output-names = "scki";
++ };
++
++ wlan_en: regulator@4 {
++ compatible = "regulator-fixed";
++ regulator-name = "wlan-en-regulator";
++
++ regulator-min-microvolt = <3300000>;
++ regulator-max-microvolt = <3300000>;
++
++ gpio = <&gpio_ext_74 4 GPIO_ACTIVE_HIGH>;
++ enable-active-high;
++ };
++
++ vcc_sdhi3: regulator@41 {
++ compatible = "regulator-fixed";
++
++ regulator-name = "SDHI3 Vcc";
++ regulator-min-microvolt = <3300000>;
++ regulator-max-microvolt = <3300000>;
++
++ gpio = <&gpio4 17 GPIO_ACTIVE_HIGH>;
++ enable-active-high;
++ };
++
++ vccq_sdhi3: regulator@5 {
++ compatible = "regulator-fixed";
++
++ regulator-name = "SDHI3 VccQ";
++ regulator-min-microvolt = <3300000>;
++ regulator-max-microvolt = <3300000>;
++ };
++
++ codec_en_reg: regulator@6 {
++ compatible = "regulator-fixed";
++ regulator-name = "codec-en-regulator";
++ regulator-min-microvolt = <3300000>;
++ regulator-max-microvolt = <3300000>;
++
++ gpio = <&gpio_ext_74 15 0>;
++
++ /* delay - CHECK */
++ startup-delay-us = <70000>;
++ enable-active-high;
++ };
++
++ amp_en_reg: regulator@7 {
++ compatible = "regulator-fixed";
++ regulator-name = "amp-en-regulator";
++ regulator-min-microvolt = <3300000>;
++ regulator-max-microvolt = <3300000>;
++
++ gpio = <&gpio_ext_74 0 0>;
++
++ startup-delay-us = <0>;
++ enable-active-high;
++ };
++
++ sdio_switch: regulator@9 {
++ compatible = "regulator-fixed";
++ regulator-name = "wifi_on";
++ regulator-min-microvolt = <3300000>;
++ regulator-max-microvolt = <3300000>;
++ gpio = <&gpio_ext_74 5 0>;
++ enable-active-low;
++ regulator-always-on;
++ };
++
++ radio_switch: regulator@11 {
++ compatible = "regulator-fixed";
++ regulator-name = "radio_on";
++ regulator-min-microvolt = <3300000>;
++ regulator-max-microvolt = <3300000>;
++ gpio = <&gpio_ext_74 13 GPIO_ACTIVE_HIGH>;
++ enable-active-high;
++ regulator-always-on;
++ };
++
++ mpcie_3v3: regulator@12 {
++ compatible = "regulator-fixed";
++ regulator-name = "mPCIe 3v3";
++ regulator-min-microvolt = <3300000>;
++ regulator-max-microvolt = <3300000>;
++ gpio = <&gpio_ext_77 14 GPIO_ACTIVE_HIGH>;
++ enable-active-high;
++ };
++
++ mpcie_1v8: regulator@13 {
++ compatible = "regulator-fixed";
++ regulator-name = "mPCIe 1v8";
++ regulator-min-microvolt = <1800000>;
++ regulator-max-microvolt = <1800000>;
++ gpio = <&gpio_ext_77 15 GPIO_ACTIVE_HIGH>;
++ startup-delay-us = <200000>;
++ enable-active-high;
++ };
++
++ kim {
++ compatible = "kim";
++ shutdown-gpios = <&gpio_ext_74 3 GPIO_ACTIVE_HIGH>;
++ /* serial1 */
++ dev_name = "/dev/ttySC1";
++ flow_cntrl = <1>;
++ /* int div 8 hscif@26.6666656MHz */
++ baud_rate = <3333332>;
++ };
++
++ btwilink {
++ compatible = "btwilink";
++ };
++
++ sound_ext: sound@0 {
++ pinctrl-0 = <&sound_0_pins>;
++ pinctrl-names = "default";
++ compatible = "simple-audio-card";
++
++ simple-audio-card,format = "left_j";
++ simple-audio-card,name = "pcm3168a";
++
++ simple-audio-card,bitclock-master = <&sound_ext_master>;
++ simple-audio-card,frame-master = <&sound_ext_master>;
++ sound_ext_master: simple-audio-card,cpu@0 {
++ sound-dai = <&rcar_sound 0>;
++ dai-tdm-slot-num = <8>;
++ dai-tdm-slot-width = <32>;
++ };
++
++ simple-audio-card,codec@0 {
++ sound-dai = <&pcm3168a>;
++ dai-tdm-slot-num = <8>;
++ dai-tdm-slot-width = <32>;
++ system-clock-frequency = <24576000>;
++ };
++ };
++
++ /delete-node/sound;
++
++ rsnd_ak4613: sound@1 {
++ pinctrl-0 = <&sound_pins>;
++ pinctrl-names = "default";
++ compatible = "simple-audio-card";
++
++ simple-audio-card,format = "left_j";
++ simple-audio-card,name = "ak4613";
++
++ simple-audio-card,bitclock-master = <&sndcpu>;
++ simple-audio-card,frame-master = <&sndcpu>;
++
++ sndcpu: simple-audio-card,cpu@1 {
++ sound-dai = <&rcar_sound 1>;
++ };
++
++ sndcodec: simple-audio-card,codec@1 {
++ sound-dai = <&ak4613>;
++ };
++ };
++
++ sound_radio: sound@2 {
++ pinctrl-0 = <&sound_2_pins>;
++ pinctrl-names = "default";
++ compatible = "simple-audio-card";
++
++ simple-audio-card,format = "i2s";
++ simple-audio-card,name = "radio";
++
++ simple-audio-card,bitclock-master = <&sound_radio_master>;
++ simple-audio-card,frame-master = <&sound_radio_master>;
++ simple-audio-card,cpu@2 {
++ sound-dai = <&rcar_sound 2>;
++ };
++
++ sound_radio_master: simple-audio-card,codec@2 {
++ sound-dai = <&radio>;
++ system-clock-frequency = <12288000>;
++ };
++ };
++
++ sound_wl18xx: sound@3 {
++ pinctrl-0 = <&sound_3_pins>;
++ pinctrl-names = "default";
++ compatible = "simple-audio-card";
++
++ simple-audio-card,format = "i2s";
++ simple-audio-card,name = "wl18xx";
++
++ simple-audio-card,bitclock-master = <&sound_wl18xx_master>;
++ simple-audio-card,frame-master = <&sound_wl18xx_master>;
++ sound_wl18xx_master: simple-audio-card,cpu@3 {
++ sound-dai = <&rcar_sound 3>;
++ };
++
++ simple-audio-card,codec@3 {
++ sound-dai = <&wl18xx_pcm>;
++ };
++ };
++
++ lvds-encoder {
++ compatible = "thine,thc63lvdm83d";
++
++ ports {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ port@0 {
++ reg = <0>;
++ lvds_enc_in: endpoint {
++ remote-endpoint = <&du_out_lvds0>;
++ };
++ };
++ port@1 {
++ reg = <1>;
++ lvds_enc_out: endpoint {
++ remote-endpoint = <&lvds_in>;
++ };
++ };
++ };
++ };
++
++ lvds {
++ compatible = "lvds-connector";
++
++ width-mm = <210>;
++ height-mm = <158>;
++
++ panel-timing {
++ /* 1280x800 @60Hz */
++ clock-frequency = <65000000>;
++ hactive = <1280>;
++ vactive = <800>;
++ hsync-len = <40>;
++ hfront-porch = <80>;
++ hback-porch = <40>;
++ vfront-porch = <14>;
++ vback-porch = <14>;
++ vsync-len = <4>;
++ };
++
++ port {
++ lvds_in: endpoint {
++ remote-endpoint = <&lvds_enc_out>;
++ };
++ };
++ };
++
++ hdmi-out {
++ compatible = "hdmi-connector";
++ type = "a";
++
++ port {
++ hdmi_con: endpoint {
++ remote-endpoint = <&adv7513_out>;
++ };
++ };
++ };
++
++ radio: si468x@0 {
++ compatible = "si,si468x-pcm";
++ status = "okay";
++
++ #sound-dai-cells = <0>;
++ };
++
++ wl18xx_pcm: wl18xx_pcm@0 {
++ compatible = "ti,wl18xx-pcm";
++ status = "okay";
++
++ #sound-dai-cells = <0>;
++ };
++
++ camera_clk: camera_clk {
++ compatible = "fixed-clock";
++ #clock-cells = <0>;
++ clock-frequency = <24000000>;
++ clock-output-names = "mclk";
++ };
++};
++
++&pfc {
++ scif1_pins: scif1 {
++ groups = "scif1_data_b";
++ function = "scif1";
++ };
++
++ hscif0_pins: hscif0 {
++ groups = "hscif0_data", "hscif0_ctrl";
++ function = "hscif0";
++ };
++
++ hscif1_pins: hscif1 {
++ groups = "hscif1_data_a", "hscif1_ctrl_a";
++ function = "hscif1";
++ };
++
++ du_pins: du {
++ groups = "du_rgb888", "du_sync", "du_clk_out_0", "du_disp";
++ function = "du";
++ };
++
++ sdhi3_pins_3v3: sd3_3v3 {
++ groups = "sdhi3_data4", "sdhi3_ctrl";
++ function = "sdhi3";
++ power-source = <3300>;
++ };
++
++ sdhi3_pins_1v8: sd3_1v8 {
++ groups = "sdhi3_data4", "sdhi3_ctrl";
++ function = "sdhi3";
++ power-source = <1800>;
++ };
++
++ sound_0_pins: sound0 {
++ groups = "ssi349_ctrl", "ssi3_data", "ssi4_data";
++ function = "ssi";
++ };
++
++ /* sound_pins defined in H3 or M3 ulsb file */
++
++ sound_2_pins: sound2 {
++ groups = "ssi6_ctrl", "ssi6_data";
++ function = "ssi";
++ };
++
++ sound_3_pins: sound3 {
++ groups = "ssi78_ctrl", "ssi7_data", "ssi8_data";
++ function = "ssi";
++ };
++
++ usb0_pins: usb0 {
++ groups = "usb0";
++ function = "usb0";
++ };
++
++ can0_pins: can0 {
++ groups = "can0_data_a";
++ function = "can0";
++ };
++
++ can1_pins: can1 {
++ groups = "can1_data";
++ function = "can1";
++ };
++
++ canfd0_pins: canfd0 {
++ groups = "canfd0_data_a";
++ function = "canfd0";
++ };
++
++ canfd1_pins: canfd1 {
++ groups = "canfd1_data";
++ function = "canfd1";
++ };
++
++ vin5_pins: vin5 {
++ groups = "vin5_data8", "vin5_sync", "vin5_clk";
++ function = "vin5";
++ };
++};
++
++&du {
++ pinctrl-0 = <&du_pins>;
++ pinctrl-names = "default";
++};
++
++&gpio2 {
++ bl_pwm {
++ gpio-hog;
++ gpios = <3 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "BL PWM 100%";
++ };
++};
++
++&gpio4 {
++ most_rst {
++ gpio-hog;
++ gpios = <14 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "MOST RST";
++ };
++};
++
++&gpio6 {
++ audio_sw {
++ gpio-hog;
++ gpios = <21 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "Onboard MCh Audio";
++ };
++};
++
++&scif1 {
++ pinctrl-0 = <&scif1_pins>;
++ pinctrl-names = "default";
++
++ status = "okay";
++};
++
++&hscif0 {
++ pinctrl-0 = <&hscif0_pins>;
++ pinctrl-names = "default";
++ uart-has-rtscts;
++
++ status = "okay";
++};
++
++&hscif1 {
++ pinctrl-0 = <&hscif1_pins>;
++ pinctrl-names = "default";
++
++ status = "okay";
++};
++
++&i2c2 {
++ clock-frequency = <400000>;
++
++ gpio_ext_74: pca9539@74 {
++ compatible = "nxp,pca9539";
++ reg = <0x74>;
++ gpio-controller;
++ #gpio-cells = <2>;
++ interrupt-controller;
++ interrupt-parent = <&gpio6>;
++ interrupts = <8 IRQ_TYPE_EDGE_FALLING>;
++
++ hub_pwen {
++ gpio-hog;
++ gpios = <6 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "HUB pwen";
++ };
++ hub_rst {
++ gpio-hog;
++ gpios = <7 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "HUB rst";
++ };
++ otg_offvbus {
++ gpio-hog;
++ gpios = <8 GPIO_ACTIVE_HIGH>;
++ output-low;
++ line-name = "OTG off VBUSn";
++ };
++ otg_extlpn {
++ gpio-hog;
++ gpios = <9 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "OTG EXTLPn";
++ };
++ otg_stat1 {
++ gpio-hog;
++ gpios = <10 GPIO_ACTIVE_HIGH>;
++ input;
++ line-name = "OTG Stat1";
++ };
++ otg_stat2 {
++ gpio-hog;
++ gpios = <11 GPIO_ACTIVE_HIGH>;
++ input;
++ line-name = "OTG Stat2";
++ };
++ };
++
++ gpio_ext_75: pca9539@75 {
++ compatible = "nxp,pca9539";
++ reg = <0x75>;
++ gpio-controller;
++ #gpio-cells = <2>;
++ interrupt-controller;
++ interrupt-parent = <&gpio6>;
++ interrupts = <4 IRQ_TYPE_EDGE_FALLING>;
++
++ gps_rst {
++ gpio-hog;
++ gpios = <6 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "GPS rst";
++ };
++ fpdl_shdn {
++ gpio-hog;
++ gpios = <9 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "FPDLink shdn";
++ };
++ };
++
++ i2cswitch2: pca9548@71 {
++ compatible = "nxp,pca9548";
++ #address-cells = <1>;
++ #size-cells = <0>;
++ reg = <0x71>;
++ reset-gpios = <&gpio5 3 GPIO_ACTIVE_LOW>;
++
++ i2c@0 {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ reg = <0>;
++ /* BCM node(s) */
++ };
++
++ i2c@1 {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ reg = <1>;
++ /* USB3.0 HUB node(s) */
++ };
++
++ i2c@2 {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ reg = <2>;
++ /* Power amp node(s) */
++ };
++
++ i2c@3 {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ reg = <3>;
++ /* Radio node(s) */
++ };
++
++ i2c@4 {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ reg = <4>;
++
++ hdmi@3d {
++ compatible = "adi,adv7511w";
++ reg = <0x3d>;
++// interrupt-parent = <&gpio2>;
++// interrupts = <0 IRQ_TYPE_EDGE_BOTH>;
++ pd-gpios = <&gpio_ext_75 5 GPIO_ACTIVE_LOW>;
++
++ adi,input-depth = <8>;
++ adi,input-colorspace = "rgb";
++ adi,input-clock = "1x";
++ adi,input-style = <1>;
++ adi,input-justification = "evenly";
++ adi,clock-delay = <1200>;
++ adi,clock-max-rate = <100000>;
++
++ ports {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ port@0 {
++ reg = <0>;
++ adv7513_in: endpoint {
++ remote-endpoint = <&du_out_rgb>;
++ };
++ };
++
++ port@1 {
++ reg = <1>;
++ adv7513_out: endpoint {
++ remote-endpoint = <&hdmi_con>;
++ };
++ };
++ };
++ };
++ };
++
++ i2c@5 {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ reg = <5>;
++ /* PCIe node(s) */
++ };
++
++ i2c@6 {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ reg = <6>;
++ /* LVDS display node(s) */
++
++ polytouch: edt-ft5x06@38 {
++ compatible = "edt,edt-ft5x06";
++ reg = <0x38>;
++ interrupt-parent = <&gpio5>;
++ interrupts = <6 IRQ_TYPE_EDGE_FALLING>;
++ };
++ };
++
++ i2c@7 {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ reg = <7>;
++ /* Audio, GPS and Gyro node(s) */
++
++ pcm3168a: audio-codec@44 {
++ #sound-dai-cells = <0>;
++ compatible = "ti,pcm3168a";
++ reg = <0x44>;
++ clocks = <&snd_clk>;
++ clock-names = "scki";
++ tdm;
++ VDD1-supply = <&codec_en_reg>;
++ VDD2-supply = <&codec_en_reg>;
++ VCCAD1-supply = <&codec_en_reg>;
++ VCCAD2-supply = <&codec_en_reg>;
++ VCCDA1-supply = <&amp_en_reg>;
++ VCCDA2-supply = <&amp_en_reg>;
++ };
++
++ lsm9ds0_acc_mag@1d {
++ compatible = "st,lsm9ds0_accel_magn";
++ reg = <0x1d>;
++ };
++
++ lsm9ds0_gyr@6b {
++ compatible = "st,lsm9ds0_gyro";
++ reg = <0x6b>;
++ };
++
++ /* GPS@ 0x42 */
++ };
++ };
++};
++
++&i2c4 {
++ gpio_ext_76: pca9539@76 {
++ compatible = "nxp,pca9539";
++ reg = <0x76>;
++ gpio-controller;
++ #gpio-cells = <2>;
++ interrupt-controller;
++ interrupt-parent = <&gpio7>;
++ interrupts = <3 IRQ_TYPE_EDGE_FALLING>;
++
++ port_b_a0 {
++ gpio-hog;
++ gpios = <0 GPIO_ACTIVE_HIGH>;
++ output-low;
++ line-name = "Video-B A0";
++ };
++ port_b_a1 {
++ gpio-hog;
++ gpios = <1 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "Video-B A1";
++ };
++ port_a_a0 {
++ gpio-hog;
++ gpios = <2 GPIO_ACTIVE_HIGH>;
++ output-low;
++ line-name = "Video-A A0";
++ };
++ port_a_a1 {
++ gpio-hog;
++ gpios = <3 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "Video-A A1";
++ };
++ cmos_pwdn {
++ gpio-hog;
++ gpios = <8 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "CMOS PWDN";
++ };
++ cmos_rst {
++ gpio-hog;
++ gpios = <9 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "CMOS RST";
++ };
++ /* pin 12 - CAM_CLK */
++ rpi_cam_io_1 {
++ gpio-hog;
++ gpios = <10 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "RaspB_IO1";
++ };
++ /* pin 11 - CAM_GPIO - assume pwdn */
++ rpi_cam_io_0 {
++ gpio-hog;
++ gpios = <11 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "RaspB_IO0";
++ };
++ sam_rst {
++ gpio-hog;
++ gpios = <4 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "SAM RST";
++ };
++ sam_pwr {
++ gpio-hog;
++ gpios = <5 GPIO_ACTIVE_HIGH>;
++ output-low;
++ line-name = "SAM PWR";
++ };
++ /* 0 - FPDLink output, 1 - LVDS output */
++ lvds_vs_fpdl {
++ gpio-hog;
++ gpios = <14 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "LVDS switch";
++ };
++ };
++
++ gpio_ext_77: pca9539@77 {
++ compatible = "nxp,pca9539";
++ reg = <0x77>;
++ gpio-controller;
++ #gpio-cells = <2>;
++ interrupt-controller;
++ interrupt-parent = <&gpio5>;
++ interrupts = <9 IRQ_TYPE_EDGE_FALLING>;
++
++ mpcie_wake {
++ gpio-hog;
++ gpios = <0 GPIO_ACTIVE_HIGH>;
++ output-low;
++ line-name = "mPCIe WAKE#";
++ };
++ mpcie_wdisable {
++ gpio-hog;
++ gpios = <1 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "mPCIe W_DISABLE";
++ };
++ mpcie_clreq {
++ gpio-hog;
++ gpios = <2 GPIO_ACTIVE_HIGH>;
++ input;
++ line-name = "mPCIe CLKREQ#";
++ };
++ mpcie_ovc {
++ gpio-hog;
++ gpios = <3 GPIO_ACTIVE_HIGH>;
++ input;
++ line-name = "mPCIe OVC";
++ };
++ };
++
++ i2cswitch4: pca9548@74 {
++ compatible = "nxp,pca9548";
++ #address-cells = <1>;
++ #size-cells = <0>;
++ reg = <0x71>;
++ reset-gpios= <&gpio3 15 GPIO_ACTIVE_LOW>;
++
++ i2c@0 {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ reg = <0>;
++ /* SAM node(s) */
++ };
++
++ i2c@1 {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ reg = <1>;
++ /* Slot A (CN10) */
++
++ ov106xx@0 {
++ compatible = "ovti,ov106xx";
++ reg = <0x60>;
++
++ port@0 {
++ ov106xx_in0: endpoint {
++ clock-lanes = <0>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&vin0ep0>;
++ };
++ };
++ port@1 {
++ ov106xx_max9286_des0ep0: endpoint@0 {
++ remote-endpoint = <&max9286_des0ep0>;
++ };
++ ov106xx_ti964_des0ep0: endpoint@1 {
++ remote-endpoint = <&ti964_des0ep0>;
++ };
++ ov106xx_ti954_des0ep0: endpoint@2 {
++ remote-endpoint = <&ti954_des0ep0>;
++ };
++ };
++ };
++
++ ov106xx@1 {
++ compatible = "ovti,ov106xx";
++ reg = <0x61>;
++
++ port@0 {
++ ov106xx_in1: endpoint {
++ clock-lanes = <0>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&vin1ep0>;
++ };
++ };
++ port@1 {
++ ov106xx_max9286_des0ep1: endpoint@0 {
++ remote-endpoint = <&max9286_des0ep1>;
++ };
++ ov106xx_ti964_des0ep1: endpoint@1 {
++ remote-endpoint = <&ti964_des0ep1>;
++ };
++ ov106xx_ti954_des0ep1: endpoint@2 {
++ remote-endpoint = <&ti954_des0ep1>;
++ };
++ };
++ };
++
++ ov106xx@2 {
++ compatible = "ovti,ov106xx";
++ reg = <0x62>;
++
++ port@0 {
++ ov106xx_in2: endpoint {
++ clock-lanes = <0>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&vin2ep0>;
++ };
++ };
++ port@1 {
++ ov106xx_max9286_des0ep2: endpoint@0 {
++ remote-endpoint = <&max9286_des0ep2>;
++ };
++ ov106xx_ti964_des0ep2: endpoint@1 {
++ remote-endpoint = <&ti964_des0ep2>;
++ };
++ };
++ };
++
++ ov106xx@3 {
++ compatible = "ovti,ov106xx";
++ reg = <0x63>;
++
++ port@0 {
++ ov106xx_in3: endpoint {
++ clock-lanes = <0>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&vin3ep0>;
++ };
++ };
++ port@1 {
++ ov106xx_max9286_des0ep3: endpoint@0 {
++ remote-endpoint = <&max9286_des0ep3>;
++ };
++ ov106xx_ti964_des0ep3: endpoint@1 {
++ remote-endpoint = <&ti964_des0ep3>;
++ };
++ };
++ };
++
++ /* DS90UB964 @ 0x3a */
++ ti964-ti9x3@0 {
++ compatible = "ti,ti964-ti9x3";
++ reg = <0x3a>;
++ ti,sensor_delay = <350>;
++ ti,links = <4>;
++ ti,lanes = <4>;
++ ti,forwarding-mode = "round-robin";
++ ti,cable-mode = "coax";
++
++ port@0 {
++ ti964_des0ep0: endpoint@0 {
++ ti9x3-addr = <0x0c>;
++ dvp-order = <0>;
++ remote-endpoint = <&ov106xx_in0>;
++ };
++ ti964_des0ep1: endpoint@1 {
++ ti9x3-addr = <0x0d>;
++ dvp-order = <0>;
++ remote-endpoint = <&ov106xx_in1>;
++ };
++ ti964_des0ep2: endpoint@2 {
++ ti9x3-addr = <0x0e>;
++ dvp-order = <0>;
++ remote-endpoint = <&ov106xx_in2>;
++ };
++ ti964_des0ep3: endpoint@3 {
++ ti9x3-addr = <0x0f>;
++ dvp-order = <0>;
++ remote-endpoint = <&ov106xx_in3>;
++ };
++ };
++ port@1 {
++ ti964_csi0ep0: endpoint {
++ csi-rate = <1450>;
++ remote-endpoint = <&csi2_40_ep>;
++ };
++ };
++ };
++
++ /* DS90UB954 @ 0x38 */
++ ti954-ti9x3@0 {
++ compatible = "ti,ti954-ti9x3";
++ reg = <0x38>;
++ /* gpios = <&video_a_ext1 10 GPIO_ACTIVE_HIGH>; */
++ ti,sensor_delay = <350>;
++ ti,links = <2>;
++ ti,lanes = <4>;
++ ti,forwarding-mode = "round-robin";
++ ti,cable-mode = "coax";
++
++ port@0 {
++ ti954_des0ep0: endpoint@0 {
++ ti9x3-addr = <0x0c>;
++ dvp-order = <0>;
++ remote-endpoint = <&ov106xx_in0>;
++ };
++ ti954_des0ep1: endpoint@1 {
++ ti9x3-addr = <0x0d>;
++ dvp-order = <0>;
++ remote-endpoint = <&ov106xx_in1>;
++ };
++ };
++ port@1 {
++ ti954_csi0ep0: endpoint {
++ csi-rate = <1450>;
++ remote-endpoint = <&csi2_40_ep>;
++ };
++ };
++ };
++
++ /* MAX9286 @ 0x2c */
++ max9286-max9271@0 {
++ compatible = "maxim,max9286-max9271";
++ reg = <0x2c>;
++ maxim,sensor_delay = <350>;
++ maxim,links = <4>;
++ maxim,lanes = <4>;
++ maxim,resetb-gpio = <1>;
++ maxim,fsync-mode = "automatic";
++ maxim,timeout = <100>;
++
++ port@0 {
++ max9286_des0ep0: endpoint@0 {
++ max9271-addr = <0x50>;
++ dvp-order = <1>;
++ remote-endpoint = <&ov106xx_in0>;
++ };
++ max9286_des0ep1: endpoint@1 {
++ max9271-addr = <0x51>;
++ dvp-order = <1>;
++ remote-endpoint = <&ov106xx_in1>;
++ };
++ max9286_des0ep2: endpoint@2 {
++ max9271-addr = <0x52>;
++ dvp-order = <1>;
++ remote-endpoint = <&ov106xx_in2>;
++ };
++ max9286_des0ep3: endpoint@3 {
++ max9271-addr = <0x53>;
++ dvp-order = <1>;
++ remote-endpoint = <&ov106xx_in3>;
++ };
++ };
++ port@1 {
++ max9286_csi0ep0: endpoint {
++ csi-rate = <700>;
++ remote-endpoint = <&csi2_40_ep>;
++ };
++ };
++ };
++ };
++
++ i2c@3 {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ reg = <3>;
++ /* MOST node(s) */
++ };
++
++ i2c@4 {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ reg = <4>;
++
++ rpi_camera: ov5647@36 {
++ compatible = "ovti,ov5647";
++ reg = <0x36>;
++
++ port@0 {
++ rpi_camera_in: endpoint {
++ clock-lanes = <0>;
++ data-lanes = <1 2>;
++ remote-endpoint = <&vin4ep0>;
++ };
++ };
++ };
++ };
++
++ i2c@5 {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ reg = <5>;
++
++ cmos_camera: ov5642@3c {
++ compatible = "ovti,ov5642";
++ reg = <0x3c>;
++ clocks = <&camera_clk>;
++ clock-names = "mclk";
++
++ port@0 {
++ cmos_camera_in: endpoint {
++ remote-endpoint = <&vin5ep0>;
++ };
++ };
++ };
++ };
++
++ i2c@7 {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ reg = <7>;
++ /* Slot A (CN10) */
++
++ video_a_ext0: pca9535@26 {
++ compatible = "nxp,pca9535";
++ reg = <0x26>;
++ gpio-controller;
++ #gpio-cells = <2>;
++
++ video_a_des_cfg1 {
++ gpio-hog;
++ gpios = <5 GPIO_ACTIVE_HIGH>;
++ input;
++ line-name = "Video-A cfg1";
++ };
++ video_a_des_cfg0 {
++ gpio-hog;
++ gpios = <6 GPIO_ACTIVE_HIGH>;
++ input;
++ line-name = "Video-A cfg0";
++ };
++ video_a_pwr_shdn {
++ gpio-hog;
++ gpios = <3 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "Video-A PWR_SHDN";
++ };
++ video_a_cam_pwr0 {
++ gpio-hog;
++ gpios = <12 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "Video-A PWR0";
++ };
++ video_a_cam_pwr1 {
++ gpio-hog;
++ gpios = <13 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "Video-A PWR1";
++ };
++ video_a_cam_pwr2 {
++ gpio-hog;
++ gpios = <14 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "Video-A PWR2";
++ };
++ video_a_cam_pwr3 {
++ gpio-hog;
++ gpios = <15 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "Video-A PWR3";
++ };
++ video_a_des_shdn {
++ gpio-hog;
++ gpios = <4 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "Video-A DES_SHDN";
++ };
++ video_a_des_led {
++ gpio-hog;
++ gpios = <7 GPIO_ACTIVE_HIGH>;
++ output-low;
++ line-name = "Video-A led";
++ };
++ };
++
++ video_a_ext1: max7325@5c {
++ compatible = "maxim,max7325";
++ reg = <0x5c>;
++ gpio-controller;
++ #gpio-cells = <2>;
++
++ video_a_des_cfg2 {
++ gpio-hog;
++ gpios = <4 GPIO_ACTIVE_HIGH>;
++ input;
++ line-name = "Video-A cfg2";
++ };
++ video_a_des_cfg1 {
++ gpio-hog;
++ gpios = <6 GPIO_ACTIVE_HIGH>;
++ input;
++ line-name = "Video-A cfg1";
++ };
++ video_a_des_cfg0 {
++ gpio-hog;
++ gpios = <7 GPIO_ACTIVE_HIGH>;
++ input;
++ line-name = "Video-A cfg0";
++ };
++ video_a_pwr_shdn {
++ gpio-hog;
++ gpios = <14 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "Video-A PWR_SHDN";
++ };
++ video_a_cam_pwr0 {
++ gpio-hog;
++ gpios = <8 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "Video-A PWR0";
++ };
++ video_a_cam_pwr1 {
++ gpio-hog;
++ gpios = <9 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "Video-A PWR1";
++ };
++ video_a_cam_pwr2 {
++ gpio-hog;
++ gpios = <10 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "Video-A PWR2";
++ };
++ video_a_cam_pwr3 {
++ gpio-hog;
++ gpios = <11 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "Video-A PWR3";
++ };
++ video_a_des_shdn {
++ gpio-hog;
++ gpios = <13 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "Video-A DES_SHDN";
++ };
++ video_a_led {
++ gpio-hog;
++ gpios = <12 GPIO_ACTIVE_HIGH>;
++ output-low;
++ line-name = "Video-A LED";
++ };
++ };
++ };
++ };
++};
++
++&pcie_bus_clk {
++ clock-frequency = <100000000>;
++ status = "okay";
++};
++
++&pciec0 {
++ status = "okay";
++};
++
++&pciec1 {
++ status = "okay";
++};
++
++&vin0 {
++ status = "okay";
++
++ ports {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ port@0 {
++ vin0ep0: endpoint {
++ csi,select = "csi40";
++ virtual,channel = <0>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&ov106xx_in0>;
++ };
++ };
++ port@1 {
++ csi0ep0: endpoint {
++ remote-endpoint = <&csi2_40_ep>;
++ };
++ };
++ port@2 {
++ vin0_max9286_des0ep0: endpoint@0 {
++ remote-endpoint = <&max9286_des0ep0>;
++ };
++ vin0_ti964_des0ep0: endpoint@1 {
++ remote-endpoint = <&ti964_des0ep0>;
++ };
++ vin0_ti954_des0ep0: endpoint@2 {
++ remote-endpoint = <&ti954_des0ep0>;
++ };
++ };
++ };
++};
++
++&vin1 {
++ status = "okay";
++
++ ports {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ port@0 {
++ vin1ep0: endpoint {
++ csi,select = "csi40";
++ virtual,channel = <1>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&ov106xx_in1>;
++ };
++ };
++ port@1 {
++ csi0ep1: endpoint {
++ remote-endpoint = <&csi2_40_ep>;
++ };
++ };
++ port@2 {
++ vin1_max9286_des0ep1: endpoint@0 {
++ remote-endpoint = <&max9286_des0ep1>;
++ };
++ vin1_ti964_des0ep1: endpoint@1 {
++ remote-endpoint = <&ti964_des0ep1>;
++ };
++ vin1_ti954_des0ep1: endpoint@2 {
++ remote-endpoint = <&ti954_des0ep1>;
++ };
++ };
++ };
++};
++
++&vin2 {
++ status = "okay";
++
++ ports {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ port@0 {
++ vin2ep0: endpoint {
++ csi,select = "csi40";
++ virtual,channel = <2>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&ov106xx_in2>;
++ };
++ };
++ port@1 {
++ csi0ep2: endpoint {
++ remote-endpoint = <&csi2_40_ep>;
++ };
++ };
++ port@2 {
++ vin2_max9286_des0ep2: endpoint@0 {
++ remote-endpoint = <&max9286_des0ep2>;
++ };
++ vin2_ti964_des0ep2: endpoint@1 {
++ remote-endpoint = <&ti964_des0ep2>;
++ };
++ };
++ };
++};
++
++&vin3 {
++ status = "okay";
++
++ ports {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ port@0 {
++ vin3ep0: endpoint {
++ csi,select = "csi40";
++ virtual,channel = <3>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&ov106xx_in3>;
++ };
++ };
++ port@1 {
++ csi0ep3: endpoint {
++ remote-endpoint = <&csi2_40_ep>;
++ };
++ };
++ port@2 {
++ vin3_max9286_des0ep3: endpoint@0 {
++ remote-endpoint = <&max9286_des0ep3>;
++ };
++ vin3_ti964_des0ep3: endpoint@1 {
++ remote-endpoint = <&ti964_des0ep3>;
++ };
++ };
++ };
++};
++
++&vin4 {
++ status = "okay";
++
++ ports {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ port@0 {
++ vin4ep0: endpoint {
++ csi,select = "csi20";
++ virtual,channel = <0>;
++ remote-endpoint = <&rpi_camera_in>;
++ data-lanes = <1 2>;
++ };
++ };
++ port@1 {
++ csi2ep0: endpoint {
++ remote-endpoint = <&csi2_20_ep>;
++ };
++ };
++ };
++};
++
++&vin5 {
++ pinctrl-0 = <&vin5_pins>;
++ pinctrl-names = "default";
++ status = "okay";
++
++ ports {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ port@0 {
++ vin5ep0: endpoint@0 {
++ bus-width = <8>;
++ /* #HSYNC, #VSYNC */
++ vsync-active = <1>;
++ hsync-active = <0>;
++ remote-endpoint = <&cmos_camera_in>;
++ };
++ };
++ };
++};
++
++&csi2_40 {
++ status = "okay";
++
++ virtual,channel {
++ csi2_vc0 {
++ data,type = "ycbcr422";
++ receive,vc = <0>;
++ };
++ csi2_vc1 {
++ data,type = "ycbcr422";
++ receive,vc = <1>;
++ };
++ csi2_vc2 {
++ data,type = "ycbcr422";
++ receive,vc = <2>;
++ };
++ csi2_vc3 {
++ data,type = "ycbcr422";
++ receive,vc = <3>;
++ };
++ };
++
++ port {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ csi2_40_ep: endpoint {
++ clock-lanes = <0>;
++ data-lanes = <1 2 3 4>;
++ csi-rate = <300>;
++ };
++ };
++};
++
++&csi2_20 {
++ status = "okay";
++
++ virtual,channel {
++ csi2_vc0 {
++ data,type = "raw8";
++ receive,vc = <0>;
++ };
++ };
++
++ port {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ csi2_20_ep: endpoint {
++ clock-lanes = <0>;
++ data-lanes = <1 2>;
++ csi-rate = <280>;
++ };
++ };
++};
++
++
++&rcar_sound {
++ pinctrl-0 = <&sound_clk_pins>;
++ pinctrl-names = "default";
++
++ /* Multi DAI */
++ #sound-dai-cells = <1>;
++
++ rcar_sound,dai {
++ dai0 {
++ playback = <&ssi3>;
++ capture = <&ssi4>;
++ };
++
++ dai1 {
++ playback = <&ssi0 &src0 &dvc0>;
++ capture = <&ssi1 &src1 &dvc1>;
++ };
++
++ dai2 {
++ capture = <&ssi6>;
++ };
++
++ dai3 {
++ playback = <&ssi7>;
++ capture = <&ssi8>;
++ };
++ };
++};
++
++&sdhi3 {
++ pinctrl-0 = <&sdhi3_pins_3v3>;
++ pinctrl-1 = <&sdhi3_pins_1v8>;
++ pinctrl-names = "default", "state_uhs";
++
++ vmmc-supply = <&wlan_en>;
++ vqmmc-supply = <&vccq_sdhi3>;
++ keep-power-in-suspend;
++ enable-sdio-wakeup;
++ bus-width = <4>;
++ no-1-8-v;
++ non-removable;
++ cap-power-off-card;
++ max-frequency = <26000000>;
++ status = "okay";
++
++ #address-cells = <1>;
++ #size-cells = <0>;
++ wlcore: wlcore@2 {
++ compatible = "ti,wl1837";
++ reg = <2>;
++ interrupt-parent = <&gpio1>;
++ interrupts = <25 IRQ_TYPE_EDGE_FALLING>;
++ };
++};
++
++&usb2_phy0 {
++ pinctrl-0 = <&usb0_pins>;
++ pinctrl-names = "default";
++
++ status = "okay";
++};
++
++&ehci0 {
++ status = "okay";
++};
++
++&ohci0 {
++ status = "okay";
++};
++
++&xhci0 {
++ status = "okay";
++};
++
++&msiof1 {
++ status = "disabled";
++};
++
++&can0 {
++ pinctrl-0 = <&can0_pins>;
++ pinctrl-names = "default";
++ status = "okay";
++
++ renesas,can-clock-select = <0x0>;
++};
++
++&can1 {
++ pinctrl-0 = <&can1_pins>;
++ pinctrl-names = "default";
++ status = "okay";
++
++ renesas,can-clock-select = <0x0>;
++};
++
++&canfd {
++ pinctrl-0 = <&canfd0_pins &canfd1_pins>;
++ pinctrl-names = "default";
++ status = "disabled";
++
++ channel0 {
++ status = "okay";
++ };
++
++ channel1 {
++ status = "okay";
++ };
++};
++
++&ssi4 {
++ shared-pin;
++};
++
++&ssi8 {
++ shared-pin;
++};
++
++&pciec1 {
++ pcie3v3-supply = <&mpcie_3v3>;
++ pcie1v8-supply = <&mpcie_1v8>;
++};
++
++
++
+diff --git a/arch/arm64/boot/dts/renesas/ulcb-vb-cn12.dtsi b/arch/arm64/boot/dts/renesas/ulcb-vb-cn12.dtsi
+new file mode 100644
+index 0000000..92ed4a4
+--- /dev/null
++++ b/arch/arm64/boot/dts/renesas/ulcb-vb-cn12.dtsi
+@@ -0,0 +1,515 @@
++/*
++ * Device Tree Source for the H3ULCB Videobox board:
++ * this adding conflicting resource on VIN4/VIN5/VIN6/VIN7 for CN12
++ *
++ * Copyright (C) 2017 Renesas Electronics Corp.
++ * Copyright (C) 2017 Cogent Embedded, Inc.
++ *
++ * This file is licensed under the terms of the GNU General Public License
++ * version 2. This program is licensed "as is" without any warranty of any
++ * kind, whether express or implied.
++ */
++
++&i2cswitch2 {
++ i2c@3 {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ reg = <3>;
++ /* Slot C (CN12) */
++
++ ov106xx@8 {
++ compatible = "ovti,ov106xx";
++ reg = <0x68>;
++
++ port@0 {
++ ov106xx_in8: endpoint {
++ clock-lanes = <0>;
++ data-lanes = <1 2>;
++ remote-endpoint = <&vin4ep0>;
++ };
++ };
++ port@1 {
++ ov106xx_max9286_des2ep0: endpoint@0 {
++ remote-endpoint = <&max9286_des2ep0>;
++ };
++ ov106xx_ti964_des2ep0: endpoint@1 {
++ remote-endpoint = <&ti964_des2ep0>;
++ };
++ ov106xx_ti954_des2ep0: endpoint@2 {
++ remote-endpoint = <&ti954_des2ep0>;
++ };
++ };
++ };
++
++ ov106xx@9 {
++ compatible = "ovti,ov106xx";
++ reg = <0x69>;
++
++ port@0 {
++ ov106xx_in9: endpoint {
++ clock-lanes = <0>;
++ data-lanes = <1 2>;
++ remote-endpoint = <&vin5ep0>;
++ };
++ };
++ port@1 {
++ ov106xx_max9286_des2ep1: endpoint@0 {
++ remote-endpoint = <&max9286_des2ep1>;
++ };
++ ov106xx_ti964_des2ep1: endpoint@1 {
++ remote-endpoint = <&ti964_des2ep1>;
++ };
++ ov106xx_ti954_des2ep1: endpoint@2 {
++ remote-endpoint = <&ti954_des2ep1>;
++ };
++ };
++ };
++
++ ov106xx@10 {
++ compatible = "ovti,ov106xx";
++ reg = <0x6a>;
++
++ port@0 {
++ ov106xx_in10: endpoint {
++ clock-lanes = <0>;
++ data-lanes = <1 2>;
++ remote-endpoint = <&vin6ep0>;
++ };
++ };
++ port@1 {
++ ov106xx_max9286_des2ep2: endpoint@0 {
++ remote-endpoint = <&max9286_des2ep2>;
++ };
++ ov106xx_ti964_des2ep2: endpoint@1 {
++ remote-endpoint = <&ti964_des2ep2>;
++ };
++ };
++ };
++
++ ov106xx@11 {
++ compatible = "ovti,ov106xx";
++ reg = <0x6b>;
++
++ port@0 {
++ ov106xx_in11: endpoint {
++ clock-lanes = <0>;
++ data-lanes = <1 2>;
++ remote-endpoint = <&vin7ep0>;
++ };
++ };
++ port@1 {
++ ov106xx_max9286_des2ep3: endpoint@0 {
++ remote-endpoint = <&max9286_des2ep3>;
++ };
++ ov106xx_ti964_des2ep3: endpoint@1 {
++ remote-endpoint = <&ti964_des2ep3>;
++ };
++ };
++ };
++
++ /* DS90UB964 @ 0x3a */
++ ti964-ti9x3@2 {
++ compatible = "ti,ti964-ti9x3";
++ reg = <0x3a>;
++ ti,sensor_delay = <350>;
++ ti,links = <4>;
++ ti,lanes = <2>;
++ ti,forwarding-mode = "round-robin";
++ ti,cable-mode = "coax";
++
++ port@0 {
++ ti964_des2ep0: endpoint@0 {
++ ti9x3-addr = <0x0c>;
++ dvp-order = <0>;
++ remote-endpoint = <&ov106xx_in8>;
++ };
++ ti964_des2ep1: endpoint@1 {
++ ti9x3-addr = <0x0d>;
++ dvp-order = <0>;
++ remote-endpoint = <&ov106xx_in9>;
++ };
++ ti964_des2ep2: endpoint@2 {
++ ti9x3-addr = <0x0e>;
++ dvp-order = <0>;
++ remote-endpoint = <&ov106xx_in10>;
++ };
++ ti964_des2ep3: endpoint@3 {
++ ti9x3-addr = <0x0f>;
++ dvp-order = <0>;
++ remote-endpoint = <&ov106xx_in11>;
++ };
++ };
++ port@1 {
++ ti964_csi1ep0: endpoint {
++ csi-rate = <1450>;
++ remote-endpoint = <&csi2_20_ep>;
++ };
++ };
++ };
++
++ /* DS90UB954 @ 0x38 */
++ ti954-ti9x3@2 {
++ compatible = "ti,ti954-ti9x3";
++ reg = <0x38>;
++ /* gpios = <&video_c_ext1 10 GPIO_ACTIVE_HIGH>; */
++ ti,sensor_delay = <350>;
++ ti,links = <2>;
++ ti,lanes = <2>;
++ ti,forwarding-mode = "round-robin";
++ ti,cable-mode = "coax";
++
++ port@0 {
++ ti954_des2ep0: endpoint@0 {
++ ti9x3-addr = <0x0c>;
++ dvp-order = <0>;
++ remote-endpoint = <&ov106xx_in8>;
++ };
++ ti954_des2ep1: endpoint@1 {
++ ti9x3-addr = <0x0d>;
++ dvp-order = <0>;
++ remote-endpoint = <&ov106xx_in9>;
++ };
++ };
++ port@1 {
++ ti954_csi1ep0: endpoint {
++ csi-rate = <1450>;
++ remote-endpoint = <&csi2_20_ep>;
++ };
++ };
++ };
++
++ /* MAX9286 @ 0x2c */
++ max9286-max9271@2 {
++ compatible = "maxim,max9286-max9271";
++ reg = <0x2c>;
++ maxim,sensor_delay = <350>;
++ maxim,links = <4>;
++ maxim,lanes = <2>;
++ maxim,resetb-gpio = <1>;
++ maxim,fsync-mode = "automatic";
++ maxim,timeout = <100>;
++
++ port@0 {
++ max9286_des2ep0: endpoint@0 {
++ max9271-addr = <0x50>;
++ dvp-order = <1>;
++ remote-endpoint = <&ov106xx_in8>;
++ };
++ max9286_des2ep1: endpoint@1 {
++ max9271-addr = <0x51>;
++ dvp-order = <1>;
++ remote-endpoint = <&ov106xx_in9>;
++ };
++ max9286_des2ep2: endpoint@2 {
++ max9271-addr = <0x52>;
++ dvp-order = <1>;
++ remote-endpoint = <&ov106xx_in10>;
++ };
++ max9286_des2ep3: endpoint@3 {
++ max9271-addr = <0x53>;
++ dvp-order = <1>;
++ remote-endpoint = <&ov106xx_in11>;
++ };
++ };
++ port@1 {
++ max9286_csi1ep0: endpoint {
++ csi-rate = <700>;
++ remote-endpoint = <&csi2_20_ep>;
++ };
++ };
++ };
++ };
++
++ i2c@4 {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ reg = <4>;
++ /* Slot C (CN12) */
++
++ video_c_ext0: pca9535@26 {
++ compatible = "nxp,pca9535";
++ reg = <0x26>;
++ gpio-controller;
++ #gpio-cells = <2>;
++
++ video_c_des_cfg1 {
++ gpio-hog;
++ gpios = <5 GPIO_ACTIVE_HIGH>;
++ input;
++ line-name = "Video-C cfg1";
++ };
++ video_c_des_cfg0 {
++ gpio-hog;
++ gpios = <6 GPIO_ACTIVE_HIGH>;
++ input;
++ line-name = "Video-C cfg0";
++ };
++ video_c_pwr_shdn {
++ gpio-hog;
++ gpios = <3 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "Video-C PWR_SHDN";
++ };
++ video_c_cam_pwr0 {
++ gpio-hog;
++ gpios = <12 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "Video-C PWR0";
++ };
++ video_c_cam_pwr1 {
++ gpio-hog;
++ gpios = <13 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "Video-C PWR1";
++ };
++ video_c_cam_pwr2 {
++ gpio-hog;
++ gpios = <14 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "Video-C PWR2";
++ };
++ video_c_cam_pwr3 {
++ gpio-hog;
++ gpios = <15 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "Video-C PWR3";
++ };
++ video_c_des_shdn {
++ gpio-hog;
++ gpios = <4 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "Video-C DES_SHDN";
++ };
++ video_c_des_led {
++ gpio-hog;
++ gpios = <7 GPIO_ACTIVE_HIGH>;
++ output-low;
++ line-name = "Video-C led";
++ };
++ };
++
++ video_c_ext1: max7325@5c {
++ compatible = "maxim,max7325";
++ reg = <0x5c>;
++ gpio-controller;
++ #gpio-cells = <2>;
++
++ video_c_des_cfg2 {
++ gpio-hog;
++ gpios = <4 GPIO_ACTIVE_HIGH>;
++ input;
++ line-name = "Video-C cfg2";
++ };
++ video_c_des_cfg1 {
++ gpio-hog;
++ gpios = <6 GPIO_ACTIVE_HIGH>;
++ input;
++ line-name = "Video-C cfg1";
++ };
++ video_c_des_cfg0 {
++ gpio-hog;
++ gpios = <7 GPIO_ACTIVE_HIGH>;
++ input;
++ line-name = "Video-C cfg0";
++ };
++ video_c_pwr_shdn {
++ gpio-hog;
++ gpios = <14 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "Video-C PWR_SHDN";
++ };
++ video_c_cam_pwr0 {
++ gpio-hog;
++ gpios = <8 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "Video-C PWR0";
++ };
++ video_c_cam_pwr1 {
++ gpio-hog;
++ gpios = <9 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "Video-C PWR1";
++ };
++ video_c_cam_pwr2 {
++ gpio-hog;
++ gpios = <10 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "Video-C PWR2";
++ };
++ video_c_cam_pwr3 {
++ gpio-hog;
++ gpios = <11 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "Video-C PWR3";
++ };
++ video_c_des_shdn {
++ gpio-hog;
++ gpios = <13 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "Video-C DES_SHDN";
++ };
++ video_c_led {
++ gpio-hog;
++ gpios = <12 GPIO_ACTIVE_HIGH>;
++ output-low;
++ line-name = "Video-C LED";
++ };
++ };
++ };
++};
++
++&vin4 {
++ ports {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ port@0 {
++ vin4ep0: endpoint {
++ csi,select = "csi20";
++ virtual,channel = <0>;
++ remote-endpoint = <&ov106xx_in8>;
++ data-lanes = <1 2>;
++ };
++ };
++ port@1 {
++ csi2ep0: endpoint {
++ remote-endpoint = <&csi2_20_ep>;
++ };
++ };
++ port@2 {
++ vin4_max9286_des2ep0: endpoint@0 {
++ remote-endpoint = <&max9286_des2ep0>;
++ };
++ vin4_ti964_des2ep0: endpoint@1 {
++ remote-endpoint = <&ti964_des2ep0>;
++ };
++ vin4_ti954_des2ep0: endpoint@2 {
++ remote-endpoint = <&ti954_des2ep0>;
++ };
++ };
++ };
++};
++
++&vin5 {
++ ports {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ port@0 {
++ vin5ep0: endpoint@0 {
++ csi,select = "csi20";
++ virtual,channel = <1>;
++ remote-endpoint = <&ov106xx_in9>;
++ data-lanes = <1 2>;
++ };
++ };
++ port@1 {
++ csi2ep1: endpoint {
++ remote-endpoint = <&csi2_20_ep>;
++ };
++ };
++ port@2 {
++ vin5_max9286_des2ep1: endpoint@0 {
++ remote-endpoint = <&max9286_des2ep1>;
++ };
++ vin5_ti964_des2ep1: endpoint@1 {
++ remote-endpoint = <&ti964_des2ep1>;
++ };
++ vin5_ti954_des2ep1: endpoint@2 {
++ remote-endpoint = <&ti954_des2ep1>;
++ };
++ };
++ };
++};
++
++&vin6 {
++ ports {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ port@0 {
++ vin6ep0: endpoint@0 {
++ csi,select = "csi20";
++ virtual,channel = <2>;
++ remote-endpoint = <&ov106xx_in10>;
++ data-lanes = <1 2>;
++ };
++ };
++ port@1 {
++ csi2ep2: endpoint {
++ remote-endpoint = <&csi2_20_ep>;
++ };
++ };
++ port@2 {
++ vin6_max9286_des2ep2: endpoint@0 {
++ remote-endpoint = <&max9286_des2ep2>;
++ };
++ vin6_ti964_des2ep2: endpoint@1 {
++ remote-endpoint = <&ti964_des2ep2>;
++ };
++ };
++ };
++};
++
++&vin7 {
++ ports {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ port@0 {
++ vin7ep0: endpoint@0 {
++ csi,select = "csi20";
++ virtual,channel = <3>;
++ remote-endpoint = <&ov106xx_in11>;
++ data-lanes = <1 2>;
++ };
++ };
++ port@1 {
++ csi2ep3: endpoint {
++ remote-endpoint = <&csi2_20_ep>;
++ };
++ };
++ port@2 {
++ vin7_max9286_des2ep3: endpoint@0 {
++ remote-endpoint = <&max9286_des2ep3>;
++ };
++ vin7_ti964_des2ep3: endpoint@1 {
++ remote-endpoint = <&ti964_des2ep3>;
++ };
++ };
++ };
++};
++
++&csi2_20 {
++ status = "okay";
++
++ virtual,channel {
++ csi2_vc0 {
++ data,type = "ycbcr422";
++ receive,vc = <0>;
++ };
++ csi2_vc1 {
++ data,type = "ycbcr422";
++ receive,vc = <1>;
++ };
++ csi2_vc2 {
++ data,type = "ycbcr422";
++ receive,vc = <2>;
++ };
++ csi2_vc3 {
++ data,type = "ycbcr422";
++ receive,vc = <3>;
++ };
++ };
++
++ port {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ csi2_20_ep: endpoint {
++ clock-lanes = <0>;
++ data-lanes = <1 2>;
++ csi-rate = <300>;
++ };
++ };
++};
+--
+1.9.1
+
diff --git a/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0041-arm64-dts-renesas-ulcb-enlarge-cma-region.patch b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0041-arm64-dts-renesas-ulcb-enlarge-cma-region.patch
new file mode 100644
index 0000000..755317b
--- /dev/null
+++ b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0041-arm64-dts-renesas-ulcb-enlarge-cma-region.patch
@@ -0,0 +1,56 @@
+From 0636358bc75e9d5187515ee99d7c8d490c56bd52 Mon Sep 17 00:00:00 2001
+From: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+Date: Sat, 15 Jul 2017 00:41:49 +0300
+Subject: [PATCH] arm64: dts: renesas: ulcb: enlarge cma region
+
+Enlarge cma region since ADSP is not used on ulcb
+
+Signed-off-by: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+---
+ arch/arm64/boot/dts/renesas/r8a7795-es1-h3ulcb.dts | 2 +-
+ arch/arm64/boot/dts/renesas/r8a7795-h3ulcb.dts | 2 +-
+ arch/arm64/boot/dts/renesas/r8a7796-m3ulcb.dts | 2 +-
+ 3 files changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/arch/arm64/boot/dts/renesas/r8a7795-es1-h3ulcb.dts b/arch/arm64/boot/dts/renesas/r8a7795-es1-h3ulcb.dts
+index 1ba7a22..9d83c6c 100644
+--- a/arch/arm64/boot/dts/renesas/r8a7795-es1-h3ulcb.dts
++++ b/arch/arm64/boot/dts/renesas/r8a7795-es1-h3ulcb.dts
+@@ -63,7 +63,7 @@
+ linux,cma {
+ compatible = "shared-dma-pool";
+ reusable;
+- reg = <0x00000000 0x58000000 0x0 0x18000000>;
++ reg = <0x00000000 0x57000000 0x0 0x19000000>;
+ linux,cma-default;
+ };
+
+diff --git a/arch/arm64/boot/dts/renesas/r8a7795-h3ulcb.dts b/arch/arm64/boot/dts/renesas/r8a7795-h3ulcb.dts
+index c237888..7406534 100644
+--- a/arch/arm64/boot/dts/renesas/r8a7795-h3ulcb.dts
++++ b/arch/arm64/boot/dts/renesas/r8a7795-h3ulcb.dts
+@@ -63,7 +63,7 @@
+ linux,cma {
+ compatible = "shared-dma-pool";
+ reusable;
+- reg = <0x00000000 0x58000000 0x0 0x18000000>;
++ reg = <0x00000000 0x57000000 0x0 0x19000000>;
+ linux,cma-default;
+ };
+
+diff --git a/arch/arm64/boot/dts/renesas/r8a7796-m3ulcb.dts b/arch/arm64/boot/dts/renesas/r8a7796-m3ulcb.dts
+index b3ecbd3..9aa4292 100644
+--- a/arch/arm64/boot/dts/renesas/r8a7796-m3ulcb.dts
++++ b/arch/arm64/boot/dts/renesas/r8a7796-m3ulcb.dts
+@@ -53,7 +53,7 @@
+ linux,cma {
+ compatible = "shared-dma-pool";
+ reusable;
+- reg = <0x00000000 0x58000000 0x0 0x18000000>;
++ reg = <0x00000000 0x57000000 0x0 0x19000000>;
+ linux,cma-default;
+ };
+
+--
+1.9.1
+
diff --git a/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0042-arm64-dts-renesas-r8a7795-es1-h3ulcb-disable-eMMC.patch b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0042-arm64-dts-renesas-r8a7795-es1-h3ulcb-disable-eMMC.patch
new file mode 100644
index 0000000..1146a09
--- /dev/null
+++ b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0042-arm64-dts-renesas-r8a7795-es1-h3ulcb-disable-eMMC.patch
@@ -0,0 +1,28 @@
+From 7440eb1bd8d9fdd197664086d67c540495832620 Mon Sep 17 00:00:00 2001
+From: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+Date: Sat, 15 Jul 2017 00:44:12 +0300
+Subject: [PATCH] arm64: dts: renesas: r8a7795-es1-h3ulcb: disable eMMC
+
+Disable eMMC due to ES1.x silicon bug
+
+Signed-off-by: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+---
+ arch/arm64/boot/dts/renesas/r8a7795-es1-h3ulcb.dts | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/arm64/boot/dts/renesas/r8a7795-es1-h3ulcb.dts b/arch/arm64/boot/dts/renesas/r8a7795-es1-h3ulcb.dts
+index 9d83c6c..677bf88 100644
+--- a/arch/arm64/boot/dts/renesas/r8a7795-es1-h3ulcb.dts
++++ b/arch/arm64/boot/dts/renesas/r8a7795-es1-h3ulcb.dts
+@@ -458,7 +458,7 @@
+ mmc-hs200-1_8v;
+ bus-width = <8>;
+ non-removable;
+- status = "okay";
++ status = "disabled";
+ };
+
+ &ssi1 {
+--
+1.9.1
+
diff --git a/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0043-arm64-dts-renesas-ulcb-use-versaclock-for-du-rgb-and-lvds.patch b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0043-arm64-dts-renesas-ulcb-use-versaclock-for-du-rgb-and-lvds.patch
new file mode 100644
index 0000000..1298ba8
--- /dev/null
+++ b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0043-arm64-dts-renesas-ulcb-use-versaclock-for-du-rgb-and-lvds.patch
@@ -0,0 +1,143 @@
+From 29bcecbb93b009e650dfdf9e6a1ff6efadc871bc Mon Sep 17 00:00:00 2001
+From: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+Date: Thu, 10 Aug 2017 08:41:53 +0300
+Subject: [PATCH] arm64: dts: renesas: ulcb: use versaclock for DU RGB and LVDS
+
+This allows to chgange preprogrammed clock in Versa5 clock
+generator.
+DU has PLL that is not too accurate, hence use prescaled value by VC5.
+
+[200~Signed-off-by: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+---
+ arch/arm64/boot/dts/renesas/r8a7795-es1-h3ulcb.dts | 24 ++++++++++++++++++++++
+ arch/arm64/boot/dts/renesas/r8a7795-h3ulcb.dts | 24 ++++++++++++++++++++++
+ arch/arm64/boot/dts/renesas/r8a7796-m3ulcb.dts | 22 ++++++++++++++++++++
+ 3 files changed, 70 insertions(+)
+
+diff --git a/arch/arm64/boot/dts/renesas/r8a7795-es1-h3ulcb.dts b/arch/arm64/boot/dts/renesas/r8a7795-es1-h3ulcb.dts
+index 677bf88..6fe4416 100644
+--- a/arch/arm64/boot/dts/renesas/r8a7795-es1-h3ulcb.dts
++++ b/arch/arm64/boot/dts/renesas/r8a7795-es1-h3ulcb.dts
+@@ -229,6 +229,15 @@
+ &du {
+ status = "okay";
+
++ /* update <du_dotclkin0/3> to <programable_clk0/1> */
++ clocks = <&cpg CPG_MOD 724>,
++ <&cpg CPG_MOD 723>,
++ <&cpg CPG_MOD 722>,
++ <&cpg CPG_MOD 721>,
++ <&cpg CPG_MOD 727>,
++ <&programmable_clk0>, <&du_dotclkin1>, <&du_dotclkin2>,
++ <&programmable_clk1>;
++
+ ports {
+ port@1 {
+ endpoint {
+@@ -390,6 +399,21 @@
+ status = "okay";
+
+ clock-frequency = <400000>;
++
++ clk_5p49v5925: programmable_clk@6a {
++ compatible = "idt,5p49v5925";
++ reg = <0x6a>;
++
++ programmable_clk0: 5p49x_clk1@6a {
++ #clock-cells = <0>;
++ clocks = <&du_dotclkin0>;
++ };
++
++ programmable_clk1: 5p49x_clk2@6a {
++ #clock-cells = <0>;
++ clocks = <&du_dotclkin3>;
++ };
++ };
+ };
+
+ &rcar_sound {
+diff --git a/arch/arm64/boot/dts/renesas/r8a7795-h3ulcb.dts b/arch/arm64/boot/dts/renesas/r8a7795-h3ulcb.dts
+index 7406534..e018f21 100644
+--- a/arch/arm64/boot/dts/renesas/r8a7795-h3ulcb.dts
++++ b/arch/arm64/boot/dts/renesas/r8a7795-h3ulcb.dts
+@@ -229,6 +229,15 @@
+ &du {
+ status = "okay";
+
++ /* update <du_dotclkin0/3> to <programable_clk0/1> */
++ clocks = <&cpg CPG_MOD 724>,
++ <&cpg CPG_MOD 723>,
++ <&cpg CPG_MOD 722>,
++ <&cpg CPG_MOD 721>,
++ <&cpg CPG_MOD 727>,
++ <&programmable_clk0>, <&du_dotclkin1>, <&du_dotclkin2>,
++ <&programmable_clk1>;
++
+ ports {
+ port@1 {
+ endpoint {
+@@ -390,6 +399,21 @@
+ status = "okay";
+
+ clock-frequency = <400000>;
++
++ clk_5p49v5925: programmable_clk@6a {
++ compatible = "idt,5p49v5925";
++ reg = <0x6a>;
++
++ programmable_clk0: 5p49x_clk1@6a {
++ #clock-cells = <0>;
++ clocks = <&du_dotclkin0>;
++ };
++
++ programmable_clk1: 5p49x_clk2@6a {
++ #clock-cells = <0>;
++ clocks = <&du_dotclkin3>;
++ };
++ };
+ };
+
+ &rcar_sound {
+diff --git a/arch/arm64/boot/dts/renesas/r8a7796-m3ulcb.dts b/arch/arm64/boot/dts/renesas/r8a7796-m3ulcb.dts
+index 9aa4292..130c068 100644
+--- a/arch/arm64/boot/dts/renesas/r8a7796-m3ulcb.dts
++++ b/arch/arm64/boot/dts/renesas/r8a7796-m3ulcb.dts
+@@ -312,6 +312,13 @@
+ &du {
+ status = "okay";
+
++ /* update <du_dotclkin0/2> to <programable_clk0/1> */
++ clocks = <&cpg CPG_MOD 724>,
++ <&cpg CPG_MOD 723>,
++ <&cpg CPG_MOD 722>,
++ <&cpg CPG_MOD 727>,
++ <&programmable_clk0>, <&du_dotclkin1>, <&programmable_clk1>;
++
+ ports {
+ port@1 {
+ endpoint {
+@@ -422,6 +429,21 @@
+ &i2c4 {
+ status = "okay";
+ clock-frequency = <400000>;
++
++ clk_5p49v5925: programmable_clk@6a {
++ compatible = "idt,5p49v5925";
++ reg = <0x6a>;
++
++ programmable_clk0: 5p49x_clk1@6a {
++ #clock-cells = <0>;
++ clocks = <&du_dotclkin0>;
++ };
++
++ programmable_clk1: 5p49x_clk2@6a {
++ #clock-cells = <0>;
++ clocks = <&du_dotclkin2>;
++ };
++ };
+ };
+
+ &rcar_sound {
+--
+1.9.1
+
diff --git a/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0044-pinctrl-r8a779x-add-mlb-pinmux.patch b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0044-pinctrl-r8a779x-add-mlb-pinmux.patch
new file mode 100644
index 0000000..8541e19
--- /dev/null
+++ b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0044-pinctrl-r8a779x-add-mlb-pinmux.patch
@@ -0,0 +1,154 @@
+From 7f797fef45307ed6c5960cc116ce8de65d192269 Mon Sep 17 00:00:00 2001
+From: Andrey Gusakov <andrey.gusakov@cogentembedded.com>
+Date: Fri, 7 Jul 2017 16:22:40 +0300
+Subject: [PATCH] pinctrl: r8a779x: add mlb pinmux
+
+Signed-off-by: Andrey Gusakov <andrey.gusakov@cogentembedded.com>
+Signed-off-by: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+---
+ drivers/pinctrl/sh-pfc/pfc-r8a7795-es1.c | 14 ++++++++++++++
+ drivers/pinctrl/sh-pfc/pfc-r8a7795.c | 14 ++++++++++++++
+ drivers/pinctrl/sh-pfc/pfc-r8a7796.c | 14 ++++++++++++++
+ 3 files changed, 42 insertions(+)
+
+diff --git a/drivers/pinctrl/sh-pfc/pfc-r8a7795-es1.c b/drivers/pinctrl/sh-pfc/pfc-r8a7795-es1.c
+index 378065d..f544546 100644
+--- a/drivers/pinctrl/sh-pfc/pfc-r8a7795-es1.c
++++ b/drivers/pinctrl/sh-pfc/pfc-r8a7795-es1.c
+@@ -2403,6 +2403,14 @@ enum {
+ IRQ5_MARK,
+ };
+
++/* - MLB+ ------------------------------------------------------------------- */
++static const unsigned int mlb_3pin_pins[] = {
++ RCAR_GP_PIN(5, 23), RCAR_GP_PIN(5, 24), RCAR_GP_PIN(5, 25),
++};
++static const unsigned int mlb_3pin_mux[] = {
++ MLB_CLK_MARK, MLB_SIG_MARK, MLB_DAT_MARK,
++};
++
+ /* - MSIOF0 ----------------------------------------------------------------- */
+ static const unsigned int msiof0_clk_pins[] = {
+ /* SCK */
+@@ -4266,6 +4274,7 @@ enum {
+ SH_PFC_PIN_GROUP(intc_ex_irq3),
+ SH_PFC_PIN_GROUP(intc_ex_irq4),
+ SH_PFC_PIN_GROUP(intc_ex_irq5),
++ SH_PFC_PIN_GROUP(mlb_3pin),
+ SH_PFC_PIN_GROUP(msiof0_clk),
+ SH_PFC_PIN_GROUP(msiof0_sync),
+ SH_PFC_PIN_GROUP(msiof0_ss1),
+@@ -4682,6 +4691,10 @@ enum {
+ "intc_ex_irq5",
+ };
+
++static const char * const mlb_3pin_groups[] = {
++ "mlb_3pin",
++};
++
+ static const char * const msiof0_groups[] = {
+ "msiof0_clk",
+ "msiof0_sync",
+@@ -5032,6 +5045,7 @@ enum {
+ SH_PFC_FUNCTION(i2c5),
+ SH_PFC_FUNCTION(i2c6),
+ SH_PFC_FUNCTION(intc_ex),
++ SH_PFC_FUNCTION(mlb_3pin),
+ SH_PFC_FUNCTION(msiof0),
+ SH_PFC_FUNCTION(msiof1),
+ SH_PFC_FUNCTION(msiof2),
+diff --git a/drivers/pinctrl/sh-pfc/pfc-r8a7795.c b/drivers/pinctrl/sh-pfc/pfc-r8a7795.c
+index 1198998..928bbbc 100644
+--- a/drivers/pinctrl/sh-pfc/pfc-r8a7795.c
++++ b/drivers/pinctrl/sh-pfc/pfc-r8a7795.c
+@@ -2466,6 +2466,14 @@ enum {
+ IRQ5_MARK,
+ };
+
++/* - MLB+ ------------------------------------------------------------------- */
++static const unsigned int mlb_3pin_pins[] = {
++ RCAR_GP_PIN(5, 23), RCAR_GP_PIN(5, 24), RCAR_GP_PIN(5, 25),
++};
++static const unsigned int mlb_3pin_mux[] = {
++ MLB_CLK_MARK, MLB_SIG_MARK, MLB_DAT_MARK,
++};
++
+ /* - MSIOF0 ----------------------------------------------------------------- */
+ static const unsigned int msiof0_clk_pins[] = {
+ /* SCK */
+@@ -4387,6 +4395,7 @@ enum {
+ SH_PFC_PIN_GROUP(intc_ex_irq3),
+ SH_PFC_PIN_GROUP(intc_ex_irq4),
+ SH_PFC_PIN_GROUP(intc_ex_irq5),
++ SH_PFC_PIN_GROUP(mlb_3pin),
+ SH_PFC_PIN_GROUP(msiof0_clk),
+ SH_PFC_PIN_GROUP(msiof0_sync),
+ SH_PFC_PIN_GROUP(msiof0_ss1),
+@@ -4811,6 +4820,10 @@ enum {
+ "intc_ex_irq5",
+ };
+
++static const char * const mlb_3pin_groups[] = {
++ "mlb_3pin",
++};
++
+ static const char * const msiof0_groups[] = {
+ "msiof0_clk",
+ "msiof0_sync",
+@@ -5169,6 +5182,7 @@ enum {
+ SH_PFC_FUNCTION(i2c5),
+ SH_PFC_FUNCTION(i2c6),
+ SH_PFC_FUNCTION(intc_ex),
++ SH_PFC_FUNCTION(mlb_3pin),
+ SH_PFC_FUNCTION(msiof0),
+ SH_PFC_FUNCTION(msiof1),
+ SH_PFC_FUNCTION(msiof2),
+diff --git a/drivers/pinctrl/sh-pfc/pfc-r8a7796.c b/drivers/pinctrl/sh-pfc/pfc-r8a7796.c
+index 1cef61b..26a69dc 100644
+--- a/drivers/pinctrl/sh-pfc/pfc-r8a7796.c
++++ b/drivers/pinctrl/sh-pfc/pfc-r8a7796.c
+@@ -2468,6 +2468,14 @@ enum {
+ IRQ5_MARK,
+ };
+
++/* - MLB+ ------------------------------------------------------------------- */
++static const unsigned int mlb_3pin_pins[] = {
++ RCAR_GP_PIN(5, 23), RCAR_GP_PIN(5, 24), RCAR_GP_PIN(5, 25),
++};
++static const unsigned int mlb_3pin_mux[] = {
++ MLB_CLK_MARK, MLB_SIG_MARK, MLB_DAT_MARK,
++};
++
+ /* - MSIOF0 ----------------------------------------------------------------- */
+ static const unsigned int msiof0_clk_pins[] = {
+ /* SCK */
+@@ -4310,6 +4318,7 @@ enum {
+ SH_PFC_PIN_GROUP(intc_ex_irq3),
+ SH_PFC_PIN_GROUP(intc_ex_irq4),
+ SH_PFC_PIN_GROUP(intc_ex_irq5),
++ SH_PFC_PIN_GROUP(mlb_3pin),
+ SH_PFC_PIN_GROUP(msiof0_clk),
+ SH_PFC_PIN_GROUP(msiof0_sync),
+ SH_PFC_PIN_GROUP(msiof0_ss1),
+@@ -4722,6 +4731,10 @@ enum {
+ "intc_ex_irq5",
+ };
+
++static const char * const mlb_3pin_groups[] = {
++ "mlb_3pin",
++};
++
+ static const char * const msiof0_groups[] = {
+ "msiof0_clk",
+ "msiof0_sync",
+@@ -5054,6 +5067,7 @@ enum {
+ SH_PFC_FUNCTION(i2c5),
+ SH_PFC_FUNCTION(i2c6),
+ SH_PFC_FUNCTION(intc_ex),
++ SH_PFC_FUNCTION(mlb_3pin),
+ SH_PFC_FUNCTION(msiof0),
+ SH_PFC_FUNCTION(msiof1),
+ SH_PFC_FUNCTION(msiof2),
+--
+1.9.1
+
diff --git a/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0045-clk-r8a779x-add-mlp-clock.patch b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0045-clk-r8a779x-add-mlp-clock.patch
new file mode 100644
index 0000000..ca473a1
--- /dev/null
+++ b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0045-clk-r8a779x-add-mlp-clock.patch
@@ -0,0 +1,38 @@
+From 741e7fcf44527632a06538419f000843b24d9293 Mon Sep 17 00:00:00 2001
+From: Andrey Gusakov <andrey.gusakov@cogentembedded.com>
+Date: Fri, 7 Jul 2017 16:23:44 +0300
+Subject: [PATCH] clk: r8a779x: add mlp clock
+
+Signed-off-by: Andrey Gusakov <andrey.gusakov@cogentembedded.com>
+---
+ drivers/clk/renesas/r8a7795-cpg-mssr.c | 1 +
+ drivers/clk/renesas/r8a7796-cpg-mssr.c | 1 +
+ 2 files changed, 2 insertions(+)
+
+diff --git a/drivers/clk/renesas/r8a7795-cpg-mssr.c b/drivers/clk/renesas/r8a7795-cpg-mssr.c
+index f833031..38d1f41 100644
+--- a/drivers/clk/renesas/r8a7795-cpg-mssr.c
++++ b/drivers/clk/renesas/r8a7795-cpg-mssr.c
+@@ -219,6 +219,7 @@ enum clk_ids {
+ DEF_MOD("lvds", 727, R8A7795_CLK_S0D4),
+ DEF_MOD("hdmi1", 728, R8A7795_CLK_HDMI),
+ DEF_MOD("hdmi0", 729, R8A7795_CLK_HDMI),
++ DEF_MOD("mlp", 802, R8A7795_CLK_S2D1),
+ DEF_MOD("vin7", 804, R8A7795_CLK_S0D2),
+ DEF_MOD("vin6", 805, R8A7795_CLK_S0D2),
+ DEF_MOD("vin5", 806, R8A7795_CLK_S0D2),
+diff --git a/drivers/clk/renesas/r8a7796-cpg-mssr.c b/drivers/clk/renesas/r8a7796-cpg-mssr.c
+index b938750..6a5936e 100644
+--- a/drivers/clk/renesas/r8a7796-cpg-mssr.c
++++ b/drivers/clk/renesas/r8a7796-cpg-mssr.c
+@@ -194,6 +194,7 @@ enum clk_ids {
+ DEF_MOD("du0", 724, R8A7796_CLK_S2D1),
+ DEF_MOD("lvds", 727, R8A7796_CLK_S2D1),
+ DEF_MOD("hdmi0", 729, R8A7796_CLK_HDMI),
++ DEF_MOD("mlp", 802, R8A7796_CLK_S2D1),
+ DEF_MOD("vin7", 804, R8A7796_CLK_S0D2),
+ DEF_MOD("vin6", 805, R8A7796_CLK_S0D2),
+ DEF_MOD("vin5", 806, R8A7796_CLK_S0D2),
+--
+1.9.1
+
diff --git a/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0046-arm64-dts-renesas-r8a779x-add-mlp-nodes.patch b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0046-arm64-dts-renesas-r8a779x-add-mlp-nodes.patch
new file mode 100644
index 0000000..1f17f0e
--- /dev/null
+++ b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0046-arm64-dts-renesas-r8a779x-add-mlp-nodes.patch
@@ -0,0 +1,87 @@
+From 8d5de721b2e037ce77f886a4307ea5668df9417f Mon Sep 17 00:00:00 2001
+From: Andrey Gusakov <andrey.gusakov@cogentembedded.com>
+Date: Fri, 7 Jul 2017 16:25:06 +0300
+Subject: [PATCH] arm64: dts: renesas: r8a779x: add mlp nodes
+
+Signed-off-by: Andrey Gusakov <andrey.gusakov@cogentembedded.com>
+---
+ arch/arm64/boot/dts/renesas/r8a7795-es1.dtsi | 13 +++++++++++++
+ arch/arm64/boot/dts/renesas/r8a7795.dtsi | 13 +++++++++++++
+ arch/arm64/boot/dts/renesas/r8a7796.dtsi | 13 +++++++++++++
+ 3 files changed, 39 insertions(+)
+
+diff --git a/arch/arm64/boot/dts/renesas/r8a7795-es1.dtsi b/arch/arm64/boot/dts/renesas/r8a7795-es1.dtsi
+index 89c70bb7738b..44a290b32899 100644
+--- a/arch/arm64/boot/dts/renesas/r8a7795-es1.dtsi
++++ b/arch/arm64/boot/dts/renesas/r8a7795-es1.dtsi
+@@ -2072,6 +2072,19 @@
+ status = "disabled";
+ };
+
++ mlp: mlp@ec520000 {
++ compatible = "rcar,medialb-dim2";
++ reg = <0 0xec520000 0 0x800>;
++ interrupts = <GIC_SPI 385 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 386 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 384 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 387 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 388 IRQ_TYPE_LEVEL_HIGH>;
++ clocks = <&cpg CPG_MOD 802>;
++ power-domains = <&sysc R8A7795_PD_ALWAYS_ON>;
++ status = "disabled";
++ };
++
+ msiof0: spi@e6e90000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+diff --git a/arch/arm64/boot/dts/renesas/r8a7795.dtsi b/arch/arm64/boot/dts/renesas/r8a7795.dtsi
+index 89c70bb7738b..44a290b32899 100644
+--- a/arch/arm64/boot/dts/renesas/r8a7795.dtsi
++++ b/arch/arm64/boot/dts/renesas/r8a7795.dtsi
+@@ -2072,6 +2072,19 @@
+ status = "disabled";
+ };
+
++ mlp: mlp@ec520000 {
++ compatible = "rcar,medialb-dim2";
++ reg = <0 0xec520000 0 0x800>;
++ interrupts = <GIC_SPI 385 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 386 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 384 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 387 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 388 IRQ_TYPE_LEVEL_HIGH>;
++ clocks = <&cpg CPG_MOD 802>;
++ power-domains = <&sysc R8A7795_PD_ALWAYS_ON>;
++ status = "disabled";
++ };
++
+ msiof0: spi@e6e90000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+diff --git a/arch/arm64/boot/dts/renesas/r8a7796.dtsi b/arch/arm64/boot/dts/renesas/r8a7796.dtsi
+index f430df9df961..565d6e7de4cc 100644
+--- a/arch/arm64/boot/dts/renesas/r8a7796.dtsi
++++ b/arch/arm64/boot/dts/renesas/r8a7796.dtsi
+@@ -1955,6 +1955,19 @@
+ status = "disabled";
+ };
+
++ mlp: mlp@ec520000 {
++ compatible = "rcar,medialb-dim2";
++ reg = <0 0xec520000 0 0x800>;
++ interrupts = <GIC_SPI 385 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 386 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 384 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 387 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 388 IRQ_TYPE_LEVEL_HIGH>;
++ clocks = <&cpg CPG_MOD 802>;
++ power-domains = <&sysc R8A7796_PD_ALWAYS_ON>;
++ status = "disabled";
++ };
++
+ msiof1: spi@e6ea0000 {
+ compatible = "renesas,msiof-r8a7796";
+ reg = <0 0xe6ea0000 0 0x0064>;
+--
+2.13.0
+
diff --git a/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0047-arm64-dts-renesas-ulcb-kf-enable-sd3.patch b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0047-arm64-dts-renesas-ulcb-kf-enable-sd3.patch
new file mode 100644
index 0000000..81b3dc9
--- /dev/null
+++ b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0047-arm64-dts-renesas-ulcb-kf-enable-sd3.patch
@@ -0,0 +1,28 @@
+From a5eed343caa82837c72a2c0e3d53f4db0c5944e4 Mon Sep 17 00:00:00 2001
+From: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+Date: Fri, 27 Oct 2017 20:54:47 +0300
+Subject: [PATCH] arm64: dts: renesas: ulcb-kf: enable sd3
+
+This enables SD3 on CN47 instead wifi
+
+Signed-off-by: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+---
+ arch/arm64/boot/dts/renesas/ulcb-kf.dtsi | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+diff --git a/arch/arm64/boot/dts/renesas/ulcb-kf.dtsi b/arch/arm64/boot/dts/renesas/ulcb-kf.dtsi
+index 8ffafb2..ea6cb1b 100644
+--- a/arch/arm64/boot/dts/renesas/ulcb-kf.dtsi
++++ b/arch/arm64/boot/dts/renesas/ulcb-kf.dtsi
+@@ -1527,3 +1527,8 @@
+
+
+
++/* enable CN47: SD on SDHI3 */
++#include "ulcb-kf-sd3.dtsi"
++
++
++
+--
+1.9.1
+
diff --git a/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0048-arm64-dts-renesas-ulcb-kf-enable-most.patch b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0048-arm64-dts-renesas-ulcb-kf-enable-most.patch
new file mode 100644
index 0000000..37ad738
--- /dev/null
+++ b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0048-arm64-dts-renesas-ulcb-kf-enable-most.patch
@@ -0,0 +1,28 @@
+From ab803d3c36d8444948c7eec238c19926fd036fcc Mon Sep 17 00:00:00 2001
+From: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+Date: Fri, 27 Oct 2017 20:58:21 +0300
+Subject: [PATCH] arm64: dts: renesas: ulcb-kf: enable most
+
+This enables MOST on CN22 instead GPS
+
+Signed-off-by: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+---
+ arch/arm64/boot/dts/renesas/ulcb-kf.dtsi | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+diff --git a/arch/arm64/boot/dts/renesas/ulcb-kf.dtsi b/arch/arm64/boot/dts/renesas/ulcb-kf.dtsi
+index ea6cb1b..ddd5450 100644
+--- a/arch/arm64/boot/dts/renesas/ulcb-kf.dtsi
++++ b/arch/arm64/boot/dts/renesas/ulcb-kf.dtsi
+@@ -1532,3 +1532,8 @@
+
+
+
++/* enable CN22: enable MOST and disable GPS (move R661->R660, R663->R662) */
++#include "ulcb-kf-most.dtsi"
++
++
++
+--
+1.9.1
+
diff --git a/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0050-arm64-dts-Gen3-view-boards-TYPE1-first-4-cameras.patch b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0050-arm64-dts-Gen3-view-boards-TYPE1-first-4-cameras.patch
new file mode 100644
index 0000000..d368b6a
--- /dev/null
+++ b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0050-arm64-dts-Gen3-view-boards-TYPE1-first-4-cameras.patch
@@ -0,0 +1,302 @@
+From 67d29f4fe320f555366ea45f5439ac52641472ec Mon Sep 17 00:00:00 2001
+From: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+Date: Mon, 15 May 2017 19:16:23 +0300
+Subject: [PATCH] arm64: dts: Gen3 view boards: TYPE1 first 4 cameras
+
+This set 4 cameras to TYPE1 in DT
+
+Signed-off-by: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+---
+ arch/arm64/boot/dts/renesas/r8a7795-es1-h3ulcb-kf.dts | 8 ++++----
+ arch/arm64/boot/dts/renesas/r8a7795-es1-h3ulcb-view.dts | 8 ++++----
+ arch/arm64/boot/dts/renesas/r8a7795-es1-salvator-x-view.dts | 8 ++++----
+ arch/arm64/boot/dts/renesas/r8a7795-h3ulcb-kf.dts | 8 ++++----
+ arch/arm64/boot/dts/renesas/r8a7795-h3ulcb-view.dts | 8 ++++----
+ arch/arm64/boot/dts/renesas/r8a7795-salvator-x-view.dts | 8 ++++----
+ arch/arm64/boot/dts/renesas/r8a7796-m3ulcb-kf.dts | 8 ++++----
+ arch/arm64/boot/dts/renesas/r8a7796-m3ulcb-view.dts | 8 ++++----
+ arch/arm64/boot/dts/renesas/r8a7796-salvator-x-view.dts | 8 ++++----
+ 9 files changed, 36 insertions(+), 36 deletions(-)
+
+diff --git a/arch/arm64/boot/dts/renesas/r8a7795-es1-h3ulcb-kf.dts b/arch/arm64/boot/dts/renesas/r8a7795-es1-h3ulcb-kf.dts
+index 50a37e0..8da87dd 100644
+--- a/arch/arm64/boot/dts/renesas/r8a7795-es1-h3ulcb-kf.dts
++++ b/arch/arm64/boot/dts/renesas/r8a7795-es1-h3ulcb-kf.dts
+@@ -780,22 +780,22 @@
+ port@0 {
+ max9286_des0ep0: endpoint@0 {
+ max9271-addr = <0x50>;
+- dvp-order = <1>;
++ dvp-order = <2>;
+ remote-endpoint = <&ov106xx_in0>;
+ };
+ max9286_des0ep1: endpoint@1 {
+ max9271-addr = <0x51>;
+- dvp-order = <1>;
++ dvp-order = <2>;
+ remote-endpoint = <&ov106xx_in1>;
+ };
+ max9286_des0ep2: endpoint@2 {
+ max9271-addr = <0x52>;
+- dvp-order = <1>;
++ dvp-order = <2>;
+ remote-endpoint = <&ov106xx_in2>;
+ };
+ max9286_des0ep3: endpoint@3 {
+ max9271-addr = <0x53>;
+- dvp-order = <1>;
++ dvp-order = <2>;
+ remote-endpoint = <&ov106xx_in3>;
+ };
+ };
+diff --git a/arch/arm64/boot/dts/renesas/r8a7795-es1-h3ulcb-view.dts b/arch/arm64/boot/dts/renesas/r8a7795-es1-h3ulcb-view.dts
+index de56fa4..b36b9d8 100644
+--- a/arch/arm64/boot/dts/renesas/r8a7795-es1-h3ulcb-view.dts
++++ b/arch/arm64/boot/dts/renesas/r8a7795-es1-h3ulcb-view.dts
+@@ -175,22 +175,22 @@
+ port@0 {
+ max9286_des0ep0: endpoint@0 {
+ max9271-addr = <0x50>;
+- dvp-order = <1>;
++ dvp-order = <2>;
+ remote-endpoint = <&ov106xx_in0>;
+ };
+ max9286_des0ep1: endpoint@1 {
+ max9271-addr = <0x51>;
+- dvp-order = <1>;
++ dvp-order = <2>;
+ remote-endpoint = <&ov106xx_in1>;
+ };
+ max9286_des0ep2: endpoint@2 {
+ max9271-addr = <0x52>;
+- dvp-order = <1>;
++ dvp-order = <2>;
+ remote-endpoint = <&ov106xx_in2>;
+ };
+ max9286_des0ep3: endpoint@3 {
+ max9271-addr = <0x53>;
+- dvp-order = <1>;
++ dvp-order = <2>;
+ remote-endpoint = <&ov106xx_in3>;
+ };
+ };
+diff --git a/arch/arm64/boot/dts/renesas/r8a7795-es1-salvator-x-view.dts b/arch/arm64/boot/dts/renesas/r8a7795-es1-salvator-x-view.dts
+index 3f3d66a..c063899 100644
+--- a/arch/arm64/boot/dts/renesas/r8a7795-es1-salvator-x-view.dts
++++ b/arch/arm64/boot/dts/renesas/r8a7795-es1-salvator-x-view.dts
+@@ -190,22 +190,22 @@
+ port@0 {
+ max9286_des0ep0: endpoint@0 {
+ max9271-addr = <0x50>;
+- dvp-order = <1>;
++ dvp-order = <2>;
+ remote-endpoint = <&ov106xx_in0>;
+ };
+ max9286_des0ep1: endpoint@1 {
+ max9271-addr = <0x51>;
+- dvp-order = <1>;
++ dvp-order = <2>;
+ remote-endpoint = <&ov106xx_in1>;
+ };
+ max9286_des0ep2: endpoint@2 {
+ max9271-addr = <0x52>;
+- dvp-order = <1>;
++ dvp-order = <2>;
+ remote-endpoint = <&ov106xx_in2>;
+ };
+ max9286_des0ep3: endpoint@3 {
+ max9271-addr = <0x53>;
+- dvp-order = <1>;
++ dvp-order = <2>;
+ remote-endpoint = <&ov106xx_in3>;
+ };
+ };
+diff --git a/arch/arm64/boot/dts/renesas/r8a7795-h3ulcb-kf.dts b/arch/arm64/boot/dts/renesas/r8a7795-h3ulcb-kf.dts
+index 94c86f6..b26d8e2 100644
+--- a/arch/arm64/boot/dts/renesas/r8a7795-h3ulcb-kf.dts
++++ b/arch/arm64/boot/dts/renesas/r8a7795-h3ulcb-kf.dts
+@@ -780,22 +780,22 @@
+ port@0 {
+ max9286_des0ep0: endpoint@0 {
+ max9271-addr = <0x50>;
+- dvp-order = <1>;
++ dvp-order = <2>;
+ remote-endpoint = <&ov106xx_in0>;
+ };
+ max9286_des0ep1: endpoint@1 {
+ max9271-addr = <0x51>;
+- dvp-order = <1>;
++ dvp-order = <2>;
+ remote-endpoint = <&ov106xx_in1>;
+ };
+ max9286_des0ep2: endpoint@2 {
+ max9271-addr = <0x52>;
+- dvp-order = <1>;
++ dvp-order = <2>;
+ remote-endpoint = <&ov106xx_in2>;
+ };
+ max9286_des0ep3: endpoint@3 {
+ max9271-addr = <0x53>;
+- dvp-order = <1>;
++ dvp-order = <2>;
+ remote-endpoint = <&ov106xx_in3>;
+ };
+ };
+diff --git a/arch/arm64/boot/dts/renesas/r8a7795-h3ulcb-view.dts b/arch/arm64/boot/dts/renesas/r8a7795-h3ulcb-view.dts
+index 2c24b85..a8b9eea 100644
+--- a/arch/arm64/boot/dts/renesas/r8a7795-h3ulcb-view.dts
++++ b/arch/arm64/boot/dts/renesas/r8a7795-h3ulcb-view.dts
+@@ -175,22 +175,22 @@
+ port@0 {
+ max9286_des0ep0: endpoint@0 {
+ max9271-addr = <0x50>;
+- dvp-order = <1>;
++ dvp-order = <2>;
+ remote-endpoint = <&ov106xx_in0>;
+ };
+ max9286_des0ep1: endpoint@1 {
+ max9271-addr = <0x51>;
+- dvp-order = <1>;
++ dvp-order = <2>;
+ remote-endpoint = <&ov106xx_in1>;
+ };
+ max9286_des0ep2: endpoint@2 {
+ max9271-addr = <0x52>;
+- dvp-order = <1>;
++ dvp-order = <2>;
+ remote-endpoint = <&ov106xx_in2>;
+ };
+ max9286_des0ep3: endpoint@3 {
+ max9271-addr = <0x53>;
+- dvp-order = <1>;
++ dvp-order = <2>;
+ remote-endpoint = <&ov106xx_in3>;
+ };
+ };
+diff --git a/arch/arm64/boot/dts/renesas/r8a7795-salvator-x-view.dts b/arch/arm64/boot/dts/renesas/r8a7795-salvator-x-view.dts
+index fb12a39f3..eb09ef0 100644
+--- a/arch/arm64/boot/dts/renesas/r8a7795-salvator-x-view.dts
++++ b/arch/arm64/boot/dts/renesas/r8a7795-salvator-x-view.dts
+@@ -190,22 +190,22 @@
+ port@0 {
+ max9286_des0ep0: endpoint@0 {
+ max9271-addr = <0x50>;
+- dvp-order = <1>;
++ dvp-order = <2>;
+ remote-endpoint = <&ov106xx_in0>;
+ };
+ max9286_des0ep1: endpoint@1 {
+ max9271-addr = <0x51>;
+- dvp-order = <1>;
++ dvp-order = <2>;
+ remote-endpoint = <&ov106xx_in1>;
+ };
+ max9286_des0ep2: endpoint@2 {
+ max9271-addr = <0x52>;
+- dvp-order = <1>;
++ dvp-order = <2>;
+ remote-endpoint = <&ov106xx_in2>;
+ };
+ max9286_des0ep3: endpoint@3 {
+ max9271-addr = <0x53>;
+- dvp-order = <1>;
++ dvp-order = <2>;
+ remote-endpoint = <&ov106xx_in3>;
+ };
+ };
+diff --git a/arch/arm64/boot/dts/renesas/r8a7796-m3ulcb-kf.dts b/arch/arm64/boot/dts/renesas/r8a7796-m3ulcb-kf.dts
+index ffaef74..83c6355 100644
+--- a/arch/arm64/boot/dts/renesas/r8a7796-m3ulcb-kf.dts
++++ b/arch/arm64/boot/dts/renesas/r8a7796-m3ulcb-kf.dts
+@@ -780,22 +780,22 @@
+ port@0 {
+ max9286_des0ep0: endpoint@0 {
+ max9271-addr = <0x50>;
+- dvp-order = <1>;
++ dvp-order = <2>;
+ remote-endpoint = <&ov106xx_in0>;
+ };
+ max9286_des0ep1: endpoint@1 {
+ max9271-addr = <0x51>;
+- dvp-order = <1>;
++ dvp-order = <2>;
+ remote-endpoint = <&ov106xx_in1>;
+ };
+ max9286_des0ep2: endpoint@2 {
+ max9271-addr = <0x52>;
+- dvp-order = <1>;
++ dvp-order = <2>;
+ remote-endpoint = <&ov106xx_in2>;
+ };
+ max9286_des0ep3: endpoint@3 {
+ max9271-addr = <0x53>;
+- dvp-order = <1>;
++ dvp-order = <2>;
+ remote-endpoint = <&ov106xx_in3>;
+ };
+ };
+diff --git a/arch/arm64/boot/dts/renesas/r8a7796-m3ulcb-view.dts b/arch/arm64/boot/dts/renesas/r8a7796-m3ulcb-view.dts
+index 1ac0041..096fb5f 100644
+--- a/arch/arm64/boot/dts/renesas/r8a7796-m3ulcb-view.dts
++++ b/arch/arm64/boot/dts/renesas/r8a7796-m3ulcb-view.dts
+@@ -103,22 +103,22 @@
+ port@0 {
+ max9286_des0ep0: endpoint@0 {
+ max9271-addr = <0x50>;
+- dvp-order = <1>;
++ dvp-order = <2>;
+ remote-endpoint = <&ov106xx_in0>;
+ };
+ max9286_des0ep1: endpoint@1 {
+ max9271-addr = <0x51>;
+- dvp-order = <1>;
++ dvp-order = <2>;
+ remote-endpoint = <&ov106xx_in1>;
+ };
+ max9286_des0ep2: endpoint@2 {
+ max9271-addr = <0x52>;
+- dvp-order = <1>;
++ dvp-order = <2>;
+ remote-endpoint = <&ov106xx_in2>;
+ };
+ max9286_des0ep3: endpoint@3 {
+ max9271-addr = <0x53>;
+- dvp-order = <1>;
++ dvp-order = <2>;
+ remote-endpoint = <&ov106xx_in3>;
+ };
+ };
+diff --git a/arch/arm64/boot/dts/renesas/r8a7796-salvator-x-view.dts b/arch/arm64/boot/dts/renesas/r8a7796-salvator-x-view.dts
+index cc6866c..7a592d1 100644
+--- a/arch/arm64/boot/dts/renesas/r8a7796-salvator-x-view.dts
++++ b/arch/arm64/boot/dts/renesas/r8a7796-salvator-x-view.dts
+@@ -118,22 +118,22 @@
+ port@0 {
+ max9286_des0ep0: endpoint@0 {
+ max9271-addr = <0x50>;
+- dvp-order = <1>;
++ dvp-order = <2>;
+ remote-endpoint = <&ov106xx_in0>;
+ };
+ max9286_des0ep1: endpoint@1 {
+ max9271-addr = <0x51>;
+- dvp-order = <1>;
++ dvp-order = <2>;
+ remote-endpoint = <&ov106xx_in1>;
+ };
+ max9286_des0ep2: endpoint@2 {
+ max9271-addr = <0x52>;
+- dvp-order = <1>;
++ dvp-order = <2>;
+ remote-endpoint = <&ov106xx_in2>;
+ };
+ max9286_des0ep3: endpoint@3 {
+ max9271-addr = <0x53>;
+- dvp-order = <1>;
++ dvp-order = <2>;
+ remote-endpoint = <&ov106xx_in3>;
+ };
+ };
+--
+1.9.1
+
diff --git a/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0051-arm64-dts-Gen3-view-boards-TYPE1-second-4-cameras.patch b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0051-arm64-dts-Gen3-view-boards-TYPE1-second-4-cameras.patch
new file mode 100644
index 0000000..a09c485
--- /dev/null
+++ b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0051-arm64-dts-Gen3-view-boards-TYPE1-second-4-cameras.patch
@@ -0,0 +1,206 @@
+From d9ec2149ffc47fd2ea4ab5e9a503a3be7c6f09f5 Mon Sep 17 00:00:00 2001
+From: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+Date: Mon, 15 May 2017 19:18:06 +0300
+Subject: [PATCH] arm64: dts: Gen3 view boards: TYPE1 second 4 cameras
+
+This set 4 cameras to TYPE1 in DT
+
+Signed-off-by: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+---
+ arch/arm64/boot/dts/renesas/r8a7795-es1-h3ulcb-kf.dts | 8 ++++----
+ arch/arm64/boot/dts/renesas/r8a7795-es1-h3ulcb-view.dts | 8 ++++----
+ arch/arm64/boot/dts/renesas/r8a7795-es1-salvator-x-view.dts | 8 ++++----
+ arch/arm64/boot/dts/renesas/r8a7795-h3ulcb-kf.dts | 8 ++++----
+ arch/arm64/boot/dts/renesas/r8a7795-h3ulcb-view.dts | 8 ++++----
+ arch/arm64/boot/dts/renesas/r8a7795-salvator-x-view.dts | 8 ++++----
+ 6 files changed, 24 insertions(+), 24 deletions(-)
+
+diff --git a/arch/arm64/boot/dts/renesas/r8a7795-es1-h3ulcb-kf.dts b/arch/arm64/boot/dts/renesas/r8a7795-es1-h3ulcb-kf.dts
+index 8da87dd..d2e6f66 100644
+--- a/arch/arm64/boot/dts/renesas/r8a7795-es1-h3ulcb-kf.dts
++++ b/arch/arm64/boot/dts/renesas/r8a7795-es1-h3ulcb-kf.dts
+@@ -989,22 +989,22 @@
+ port@0 {
+ max9286_des1ep0: endpoint@0 {
+ max9271-addr = <0x50>;
+- dvp-order = <1>;
++ dvp-order = <2>;
+ remote-endpoint = <&ov106xx_in4>;
+ };
+ max9286_des1ep1: endpoint@1 {
+ max9271-addr = <0x51>;
+- dvp-order = <1>;
++ dvp-order = <2>;
+ remote-endpoint = <&ov106xx_in5>;
+ };
+ max9286_des1ep2: endpoint@2 {
+ max9271-addr = <0x52>;
+- dvp-order = <1>;
++ dvp-order = <2>;
+ remote-endpoint = <&ov106xx_in6>;
+ };
+ max9286_des1ep3: endpoint@3 {
+ max9271-addr = <0x53>;
+- dvp-order = <1>;
++ dvp-order = <2>;
+ remote-endpoint = <&ov106xx_in7>;
+ };
+ };
+diff --git a/arch/arm64/boot/dts/renesas/r8a7795-es1-h3ulcb-view.dts b/arch/arm64/boot/dts/renesas/r8a7795-es1-h3ulcb-view.dts
+index b36b9d8..e3a9414 100644
+--- a/arch/arm64/boot/dts/renesas/r8a7795-es1-h3ulcb-view.dts
++++ b/arch/arm64/boot/dts/renesas/r8a7795-es1-h3ulcb-view.dts
+@@ -216,22 +216,22 @@
+ port@0 {
+ max9286_des1ep0: endpoint@0 {
+ max9271-addr = <0x54>;
+- dvp-order = <1>;
++ dvp-order = <2>;
+ remote-endpoint = <&ov106xx_in4>;
+ };
+ max9286_des1ep1: endpoint@1 {
+ max9271-addr = <0x55>;
+- dvp-order = <1>;
++ dvp-order = <2>;
+ remote-endpoint = <&ov106xx_in5>;
+ };
+ max9286_des1ep2: endpoint@2 {
+ max9271-addr = <0x56>;
+- dvp-order = <1>;
++ dvp-order = <2>;
+ remote-endpoint = <&ov106xx_in6>;
+ };
+ max9286_des1ep3: endpoint@3 {
+ max9271-addr = <0x57>;
+- dvp-order = <1>;
++ dvp-order = <2>;
+ remote-endpoint = <&ov106xx_in7>;
+ };
+ };
+diff --git a/arch/arm64/boot/dts/renesas/r8a7795-es1-salvator-x-view.dts b/arch/arm64/boot/dts/renesas/r8a7795-es1-salvator-x-view.dts
+index c063899..2785fd7 100644
+--- a/arch/arm64/boot/dts/renesas/r8a7795-es1-salvator-x-view.dts
++++ b/arch/arm64/boot/dts/renesas/r8a7795-es1-salvator-x-view.dts
+@@ -230,22 +230,22 @@
+ port@0 {
+ max9286_des1ep0: endpoint@0 {
+ max9271-addr = <0x54>;
+- dvp-order = <1>;
++ dvp-order = <2>;
+ remote-endpoint = <&ov106xx_in4>;
+ };
+ max9286_des1ep1: endpoint@1 {
+ max9271-addr = <0x55>;
+- dvp-order = <1>;
++ dvp-order = <2>;
+ remote-endpoint = <&ov106xx_in5>;
+ };
+ max9286_des1ep2: endpoint@2 {
+ max9271-addr = <0x56>;
+- dvp-order = <1>;
++ dvp-order = <2>;
+ remote-endpoint = <&ov106xx_in6>;
+ };
+ max9286_des1ep3: endpoint@3 {
+ max9271-addr = <0x57>;
+- dvp-order = <1>;
++ dvp-order = <2>;
+ remote-endpoint = <&ov106xx_in7>;
+ };
+ };
+diff --git a/arch/arm64/boot/dts/renesas/r8a7795-h3ulcb-kf.dts b/arch/arm64/boot/dts/renesas/r8a7795-h3ulcb-kf.dts
+index b26d8e2..b8f8819 100644
+--- a/arch/arm64/boot/dts/renesas/r8a7795-h3ulcb-kf.dts
++++ b/arch/arm64/boot/dts/renesas/r8a7795-h3ulcb-kf.dts
+@@ -989,22 +989,22 @@
+ port@0 {
+ max9286_des1ep0: endpoint@0 {
+ max9271-addr = <0x50>;
+- dvp-order = <1>;
++ dvp-order = <2>;
+ remote-endpoint = <&ov106xx_in4>;
+ };
+ max9286_des1ep1: endpoint@1 {
+ max9271-addr = <0x51>;
+- dvp-order = <1>;
++ dvp-order = <2>;
+ remote-endpoint = <&ov106xx_in5>;
+ };
+ max9286_des1ep2: endpoint@2 {
+ max9271-addr = <0x52>;
+- dvp-order = <1>;
++ dvp-order = <2>;
+ remote-endpoint = <&ov106xx_in6>;
+ };
+ max9286_des1ep3: endpoint@3 {
+ max9271-addr = <0x53>;
+- dvp-order = <1>;
++ dvp-order = <2>;
+ remote-endpoint = <&ov106xx_in7>;
+ };
+ };
+diff --git a/arch/arm64/boot/dts/renesas/r8a7795-h3ulcb-view.dts b/arch/arm64/boot/dts/renesas/r8a7795-h3ulcb-view.dts
+index a8b9eea..86ed4a8 100644
+--- a/arch/arm64/boot/dts/renesas/r8a7795-h3ulcb-view.dts
++++ b/arch/arm64/boot/dts/renesas/r8a7795-h3ulcb-view.dts
+@@ -216,22 +216,22 @@
+ port@0 {
+ max9286_des1ep0: endpoint@0 {
+ max9271-addr = <0x54>;
+- dvp-order = <1>;
++ dvp-order = <2>;
+ remote-endpoint = <&ov106xx_in4>;
+ };
+ max9286_des1ep1: endpoint@1 {
+ max9271-addr = <0x55>;
+- dvp-order = <1>;
++ dvp-order = <2>;
+ remote-endpoint = <&ov106xx_in5>;
+ };
+ max9286_des1ep2: endpoint@2 {
+ max9271-addr = <0x56>;
+- dvp-order = <1>;
++ dvp-order = <2>;
+ remote-endpoint = <&ov106xx_in6>;
+ };
+ max9286_des1ep3: endpoint@3 {
+ max9271-addr = <0x57>;
+- dvp-order = <1>;
++ dvp-order = <2>;
+ remote-endpoint = <&ov106xx_in7>;
+ };
+ };
+diff --git a/arch/arm64/boot/dts/renesas/r8a7795-salvator-x-view.dts b/arch/arm64/boot/dts/renesas/r8a7795-salvator-x-view.dts
+index eb09ef0..37eabc0 100644
+--- a/arch/arm64/boot/dts/renesas/r8a7795-salvator-x-view.dts
++++ b/arch/arm64/boot/dts/renesas/r8a7795-salvator-x-view.dts
+@@ -230,22 +230,22 @@
+ port@0 {
+ max9286_des1ep0: endpoint@0 {
+ max9271-addr = <0x54>;
+- dvp-order = <1>;
++ dvp-order = <2>;
+ remote-endpoint = <&ov106xx_in4>;
+ };
+ max9286_des1ep1: endpoint@1 {
+ max9271-addr = <0x55>;
+- dvp-order = <1>;
++ dvp-order = <2>;
+ remote-endpoint = <&ov106xx_in5>;
+ };
+ max9286_des1ep2: endpoint@2 {
+ max9271-addr = <0x56>;
+- dvp-order = <1>;
++ dvp-order = <2>;
+ remote-endpoint = <&ov106xx_in6>;
+ };
+ max9286_des1ep3: endpoint@3 {
+ max9271-addr = <0x57>;
+- dvp-order = <1>;
++ dvp-order = <2>;
+ remote-endpoint = <&ov106xx_in7>;
+ };
+ };
+--
+1.9.1
+
diff --git a/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0052-arm64-dts-Gen3-view-boards-TYPE2-first-4-cameras.patch b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0052-arm64-dts-Gen3-view-boards-TYPE2-first-4-cameras.patch
new file mode 100644
index 0000000..2c4d9f3
--- /dev/null
+++ b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0052-arm64-dts-Gen3-view-boards-TYPE2-first-4-cameras.patch
@@ -0,0 +1,527 @@
+From fa7c75c71d40c8ce44b0fbaea79031daaede2ba7 Mon Sep 17 00:00:00 2001
+From: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+Date: Mon, 15 May 2017 19:24:29 +0300
+Subject: [PATCH] arm64: dts: Gen3 view boards: TYPE2 first 4 cameras
+
+This set 4 cameras to TYPE2 in DT
+
+Signed-off-by: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+---
+ arch/arm64/boot/dts/renesas/r8a7795-es1-h3ulcb-kf.dts | 17 +++++++++++++++--
+ arch/arm64/boot/dts/renesas/r8a7795-es1-h3ulcb-view.dts | 17 +++++++++++++++--
+ .../boot/dts/renesas/r8a7795-es1-salvator-x-view.dts | 17 +++++++++++++++--
+ arch/arm64/boot/dts/renesas/r8a7795-h3ulcb-kf.dts | 17 +++++++++++++++--
+ arch/arm64/boot/dts/renesas/r8a7795-h3ulcb-view.dts | 17 +++++++++++++++--
+ arch/arm64/boot/dts/renesas/r8a7795-salvator-x-view.dts | 17 +++++++++++++++--
+ arch/arm64/boot/dts/renesas/r8a7796-m3ulcb-kf.dts | 17 +++++++++++++++--
+ arch/arm64/boot/dts/renesas/r8a7796-m3ulcb-view.dts | 17 +++++++++++++++--
+ arch/arm64/boot/dts/renesas/r8a7796-salvator-x-view.dts | 17 +++++++++++++++--
+ 9 files changed, 135 insertions(+), 18 deletions(-)
+
+diff --git a/arch/arm64/boot/dts/renesas/r8a7795-es1-h3ulcb-kf.dts b/arch/arm64/boot/dts/renesas/r8a7795-es1-h3ulcb-kf.dts
+index 50a37e0..8808e80 100644
+--- a/arch/arm64/boot/dts/renesas/r8a7795-es1-h3ulcb-kf.dts
++++ b/arch/arm64/boot/dts/renesas/r8a7795-es1-h3ulcb-kf.dts
+@@ -609,6 +609,9 @@
+ compatible = "ovti,ov106xx";
+ reg = <0x60>;
+
++ maxim,fixed-sensor = "ov490";
++ maxim,width = <1280>;
++ maxim,height = <966>;
+ port@0 {
+ ov106xx_in0: endpoint {
+ clock-lanes = <0>;
+@@ -633,6 +636,9 @@
+ compatible = "ovti,ov106xx";
+ reg = <0x61>;
+
++ maxim,fixed-sensor = "ov490";
++ maxim,width = <1280>;
++ maxim,height = <966>;
+ port@0 {
+ ov106xx_in1: endpoint {
+ clock-lanes = <0>;
+@@ -657,6 +663,9 @@
+ compatible = "ovti,ov106xx";
+ reg = <0x62>;
+
++ maxim,fixed-sensor = "ov490";
++ maxim,width = <1280>;
++ maxim,height = <966>;
+ port@0 {
+ ov106xx_in2: endpoint {
+ clock-lanes = <0>;
+@@ -678,6 +687,9 @@
+ compatible = "ovti,ov106xx";
+ reg = <0x63>;
+
++ maxim,fixed-sensor = "ov490";
++ maxim,width = <1280>;
++ maxim,height = <966>;
+ port@0 {
+ ov106xx_in3: endpoint {
+ clock-lanes = <0>;
+@@ -773,8 +785,9 @@
+ maxim,sensor_delay = <350>;
+ maxim,links = <4>;
+ maxim,lanes = <4>;
+- maxim,resetb-gpio = <1>;
+- maxim,fsync-mode = "automatic";
++ maxim,resetb-gpio = <4>;
++ maxim,resetb-active-high;
++ maxim,fsync-mode = "manual";
+ maxim,timeout = <100>;
+
+ port@0 {
+diff --git a/arch/arm64/boot/dts/renesas/r8a7795-es1-h3ulcb-view.dts b/arch/arm64/boot/dts/renesas/r8a7795-es1-h3ulcb-view.dts
+index de56fa4..007aa7a 100644
+--- a/arch/arm64/boot/dts/renesas/r8a7795-es1-h3ulcb-view.dts
++++ b/arch/arm64/boot/dts/renesas/r8a7795-es1-h3ulcb-view.dts
+@@ -20,6 +20,9 @@
+ compatible = "ovti,ov106xx";
+ reg = <0x60>;
+
++ maxim,fixed-sensor = "ov490";
++ maxim,width = <1280>;
++ maxim,height = <966>;
+ port@0 {
+ ov106xx_in0: endpoint {
+ clock-lanes = <0>;
+@@ -38,6 +41,9 @@
+ compatible = "ovti,ov106xx";
+ reg = <0x61>;
+
++ maxim,fixed-sensor = "ov490";
++ maxim,width = <1280>;
++ maxim,height = <966>;
+ port@0 {
+ ov106xx_in1: endpoint {
+ clock-lanes = <0>;
+@@ -56,6 +62,9 @@
+ compatible = "ovti,ov106xx";
+ reg = <0x62>;
+
++ maxim,fixed-sensor = "ov490";
++ maxim,width = <1280>;
++ maxim,height = <966>;
+ port@0 {
+ ov106xx_in2: endpoint {
+ clock-lanes = <0>;
+@@ -74,6 +83,9 @@
+ compatible = "ovti,ov106xx";
+ reg = <0x63>;
+
++ maxim,fixed-sensor = "ov490";
++ maxim,width = <1280>;
++ maxim,height = <966>;
+ port@0 {
+ ov106xx_in3: endpoint {
+ clock-lanes = <0>;
+@@ -167,8 +179,9 @@
+ maxim,sensor_delay = <0>;
+ maxim,links = <4>;
+ maxim,lanes = <4>;
+- maxim,resetb-gpio = <1>;
+- maxim,fsync-mode = "automatic";
++ maxim,resetb-gpio = <4>;
++ maxim,resetb-active-high;
++ maxim,fsync-mode = "manual";
+ maxim,timeout = <100>;
+ maxim,i2c-quirk = <0x6c>;
+
+diff --git a/arch/arm64/boot/dts/renesas/r8a7795-es1-salvator-x-view.dts b/arch/arm64/boot/dts/renesas/r8a7795-es1-salvator-x-view.dts
+index 3f3d66a..4b3513a 100644
+--- a/arch/arm64/boot/dts/renesas/r8a7795-es1-salvator-x-view.dts
++++ b/arch/arm64/boot/dts/renesas/r8a7795-es1-salvator-x-view.dts
+@@ -35,6 +35,9 @@
+ compatible = "ovti,ov106xx";
+ reg = <0x60>;
+
++ maxim,fixed-sensor = "ov490";
++ maxim,width = <1280>;
++ maxim,height = <966>;
+ port@0 {
+ ov106xx_in0: endpoint {
+ clock-lanes = <0>;
+@@ -53,6 +56,9 @@
+ compatible = "ovti,ov106xx";
+ reg = <0x61>;
+
++ maxim,fixed-sensor = "ov490";
++ maxim,width = <1280>;
++ maxim,height = <966>;
+ port@0 {
+ ov106xx_in1: endpoint {
+ clock-lanes = <0>;
+@@ -71,6 +77,9 @@
+ compatible = "ovti,ov106xx";
+ reg = <0x62>;
+
++ maxim,fixed-sensor = "ov490";
++ maxim,width = <1280>;
++ maxim,height = <966>;
+ port@0 {
+ ov106xx_in2: endpoint {
+ clock-lanes = <0>;
+@@ -89,6 +98,9 @@
+ compatible = "ovti,ov106xx";
+ reg = <0x63>;
+
++ maxim,fixed-sensor = "ov490";
++ maxim,width = <1280>;
++ maxim,height = <966>;
+ port@0 {
+ ov106xx_in3: endpoint {
+ clock-lanes = <0>;
+@@ -182,8 +194,9 @@
+ maxim,sensor_delay = <0>;
+ maxim,links = <4>;
+ maxim,lanes = <4>;
+- maxim,resetb-gpio = <1>;
+- maxim,fsync-mode = "automatic";
++ maxim,resetb-gpio = <4>;
++ maxim,resetb-active-high;
++ maxim,fsync-mode = "manual";
+ maxim,timeout = <100>;
+ maxim,i2c-quirk = <0x6c>;
+
+diff --git a/arch/arm64/boot/dts/renesas/r8a7795-h3ulcb-kf.dts b/arch/arm64/boot/dts/renesas/r8a7795-h3ulcb-kf.dts
+index 94c86f6..e650c5b 100644
+--- a/arch/arm64/boot/dts/renesas/r8a7795-h3ulcb-kf.dts
++++ b/arch/arm64/boot/dts/renesas/r8a7795-h3ulcb-kf.dts
+@@ -609,6 +609,9 @@
+ compatible = "ovti,ov106xx";
+ reg = <0x60>;
+
++ maxim,fixed-sensor = "ov490";
++ maxim,width = <1280>;
++ maxim,height = <966>;
+ port@0 {
+ ov106xx_in0: endpoint {
+ clock-lanes = <0>;
+@@ -633,6 +636,9 @@
+ compatible = "ovti,ov106xx";
+ reg = <0x61>;
+
++ maxim,fixed-sensor = "ov490";
++ maxim,width = <1280>;
++ maxim,height = <966>;
+ port@0 {
+ ov106xx_in1: endpoint {
+ clock-lanes = <0>;
+@@ -657,6 +663,9 @@
+ compatible = "ovti,ov106xx";
+ reg = <0x62>;
+
++ maxim,fixed-sensor = "ov490";
++ maxim,width = <1280>;
++ maxim,height = <966>;
+ port@0 {
+ ov106xx_in2: endpoint {
+ clock-lanes = <0>;
+@@ -678,6 +687,9 @@
+ compatible = "ovti,ov106xx";
+ reg = <0x63>;
+
++ maxim,fixed-sensor = "ov490";
++ maxim,width = <1280>;
++ maxim,height = <966>;
+ port@0 {
+ ov106xx_in3: endpoint {
+ clock-lanes = <0>;
+@@ -773,8 +785,9 @@
+ maxim,sensor_delay = <350>;
+ maxim,links = <4>;
+ maxim,lanes = <4>;
+- maxim,resetb-gpio = <1>;
+- maxim,fsync-mode = "automatic";
++ maxim,resetb-gpio = <4>;
++ maxim,resetb-active-high;
++ maxim,fsync-mode = "manual";
+ maxim,timeout = <100>;
+
+ port@0 {
+diff --git a/arch/arm64/boot/dts/renesas/r8a7795-h3ulcb-view.dts b/arch/arm64/boot/dts/renesas/r8a7795-h3ulcb-view.dts
+index 2c24b85..ac0723d 100644
+--- a/arch/arm64/boot/dts/renesas/r8a7795-h3ulcb-view.dts
++++ b/arch/arm64/boot/dts/renesas/r8a7795-h3ulcb-view.dts
+@@ -20,6 +20,9 @@
+ compatible = "ovti,ov106xx";
+ reg = <0x60>;
+
++ maxim,fixed-sensor = "ov490";
++ maxim,width = <1280>;
++ maxim,height = <966>;
+ port@0 {
+ ov106xx_in0: endpoint {
+ clock-lanes = <0>;
+@@ -38,6 +41,9 @@
+ compatible = "ovti,ov106xx";
+ reg = <0x61>;
+
++ maxim,fixed-sensor = "ov490";
++ maxim,width = <1280>;
++ maxim,height = <966>;
+ port@0 {
+ ov106xx_in1: endpoint {
+ clock-lanes = <0>;
+@@ -56,6 +62,9 @@
+ compatible = "ovti,ov106xx";
+ reg = <0x62>;
+
++ maxim,fixed-sensor = "ov490";
++ maxim,width = <1280>;
++ maxim,height = <966>;
+ port@0 {
+ ov106xx_in2: endpoint {
+ clock-lanes = <0>;
+@@ -74,6 +83,9 @@
+ compatible = "ovti,ov106xx";
+ reg = <0x63>;
+
++ maxim,fixed-sensor = "ov490";
++ maxim,width = <1280>;
++ maxim,height = <966>;
+ port@0 {
+ ov106xx_in3: endpoint {
+ clock-lanes = <0>;
+@@ -167,8 +179,9 @@
+ maxim,sensor_delay = <0>;
+ maxim,links = <4>;
+ maxim,lanes = <4>;
+- maxim,resetb-gpio = <1>;
+- maxim,fsync-mode = "automatic";
++ maxim,resetb-gpio = <4>;
++ maxim,resetb-active-high;
++ maxim,fsync-mode = "manual";
+ maxim,timeout = <100>;
+ maxim,i2c-quirk = <0x6c>;
+
+diff --git a/arch/arm64/boot/dts/renesas/r8a7795-salvator-x-view.dts b/arch/arm64/boot/dts/renesas/r8a7795-salvator-x-view.dts
+index fb12a39f3..ef0895e 100644
+--- a/arch/arm64/boot/dts/renesas/r8a7795-salvator-x-view.dts
++++ b/arch/arm64/boot/dts/renesas/r8a7795-salvator-x-view.dts
+@@ -35,6 +35,9 @@
+ compatible = "ovti,ov106xx";
+ reg = <0x60>;
+
++ maxim,fixed-sensor = "ov490";
++ maxim,width = <1280>;
++ maxim,height = <966>;
+ port@0 {
+ ov106xx_in0: endpoint {
+ clock-lanes = <0>;
+@@ -53,6 +56,9 @@
+ compatible = "ovti,ov106xx";
+ reg = <0x61>;
+
++ maxim,fixed-sensor = "ov490";
++ maxim,width = <1280>;
++ maxim,height = <966>;
+ port@0 {
+ ov106xx_in1: endpoint {
+ clock-lanes = <0>;
+@@ -71,6 +77,9 @@
+ compatible = "ovti,ov106xx";
+ reg = <0x62>;
+
++ maxim,fixed-sensor = "ov490";
++ maxim,width = <1280>;
++ maxim,height = <966>;
+ port@0 {
+ ov106xx_in2: endpoint {
+ clock-lanes = <0>;
+@@ -89,6 +98,9 @@
+ compatible = "ovti,ov106xx";
+ reg = <0x63>;
+
++ maxim,fixed-sensor = "ov490";
++ maxim,width = <1280>;
++ maxim,height = <966>;
+ port@0 {
+ ov106xx_in3: endpoint {
+ clock-lanes = <0>;
+@@ -182,8 +194,9 @@
+ maxim,sensor_delay = <0>;
+ maxim,links = <4>;
+ maxim,lanes = <4>;
+- maxim,resetb-gpio = <1>;
+- maxim,fsync-mode = "automatic";
++ maxim,resetb-gpio = <4>;
++ maxim,resetb-active-high;
++ maxim,fsync-mode = "manual";
+ maxim,timeout = <100>;
+ maxim,i2c-quirk = <0x6c>;
+
+diff --git a/arch/arm64/boot/dts/renesas/r8a7796-m3ulcb-kf.dts b/arch/arm64/boot/dts/renesas/r8a7796-m3ulcb-kf.dts
+index ffaef74..5670f3a 100644
+--- a/arch/arm64/boot/dts/renesas/r8a7796-m3ulcb-kf.dts
++++ b/arch/arm64/boot/dts/renesas/r8a7796-m3ulcb-kf.dts
+@@ -609,6 +609,9 @@
+ compatible = "ovti,ov106xx";
+ reg = <0x60>;
+
++ maxim,fixed-sensor = "ov490";
++ maxim,width = <1280>;
++ maxim,height = <966>;
+ port@0 {
+ ov106xx_in0: endpoint {
+ clock-lanes = <0>;
+@@ -633,6 +636,9 @@
+ compatible = "ovti,ov106xx";
+ reg = <0x61>;
+
++ maxim,fixed-sensor = "ov490";
++ maxim,width = <1280>;
++ maxim,height = <966>;
+ port@0 {
+ ov106xx_in1: endpoint {
+ clock-lanes = <0>;
+@@ -657,6 +663,9 @@
+ compatible = "ovti,ov106xx";
+ reg = <0x62>;
+
++ maxim,fixed-sensor = "ov490";
++ maxim,width = <1280>;
++ maxim,height = <966>;
+ port@0 {
+ ov106xx_in2: endpoint {
+ clock-lanes = <0>;
+@@ -678,6 +687,9 @@
+ compatible = "ovti,ov106xx";
+ reg = <0x63>;
+
++ maxim,fixed-sensor = "ov490";
++ maxim,width = <1280>;
++ maxim,height = <966>;
+ port@0 {
+ ov106xx_in3: endpoint {
+ clock-lanes = <0>;
+@@ -773,8 +785,9 @@
+ maxim,sensor_delay = <350>;
+ maxim,links = <4>;
+ maxim,lanes = <4>;
+- maxim,resetb-gpio = <1>;
+- maxim,fsync-mode = "automatic";
++ maxim,resetb-gpio = <4>;
++ maxim,resetb-active-high;
++ maxim,fsync-mode = "manual";
+ maxim,timeout = <100>;
+
+ port@0 {
+diff --git a/arch/arm64/boot/dts/renesas/r8a7796-m3ulcb-view.dts b/arch/arm64/boot/dts/renesas/r8a7796-m3ulcb-view.dts
+index 1ac0041..8a67c5f 100644
+--- a/arch/arm64/boot/dts/renesas/r8a7796-m3ulcb-view.dts
++++ b/arch/arm64/boot/dts/renesas/r8a7796-m3ulcb-view.dts
+@@ -20,6 +20,9 @@
+ compatible = "ovti,ov106xx";
+ reg = <0x60>;
+
++ maxim,fixed-sensor = "ov490";
++ maxim,width = <1280>;
++ maxim,height = <966>;
+ port@0 {
+ ov106xx_in0: endpoint {
+ clock-lanes = <0>;
+@@ -38,6 +41,9 @@
+ compatible = "ovti,ov106xx";
+ reg = <0x61>;
+
++ maxim,fixed-sensor = "ov490";
++ maxim,width = <1280>;
++ maxim,height = <966>;
+ port@0 {
+ ov106xx_in1: endpoint {
+ clock-lanes = <0>;
+@@ -56,6 +62,9 @@
+ compatible = "ovti,ov106xx";
+ reg = <0x62>;
+
++ maxim,fixed-sensor = "ov490";
++ maxim,width = <1280>;
++ maxim,height = <966>;
+ port@0 {
+ ov106xx_in2: endpoint {
+ clock-lanes = <0>;
+@@ -74,6 +83,9 @@
+ compatible = "ovti,ov106xx";
+ reg = <0x63>;
+
++ maxim,fixed-sensor = "ov490";
++ maxim,width = <1280>;
++ maxim,height = <966>;
+ port@0 {
+ ov106xx_in3: endpoint {
+ clock-lanes = <0>;
+@@ -95,8 +107,9 @@
+ maxim,sensor_delay = <0>;
+ maxim,links = <4>;
+ maxim,lanes = <4>;
+- maxim,resetb-gpio = <1>;
+- maxim,fsync-mode = "automatic";
++ maxim,resetb-gpio = <4>;
++ maxim,resetb-active-high;
++ maxim,fsync-mode = "manual";
+ maxim,timeout = <100>;
+ maxim,i2c-quirk = <0x6c>;
+
+diff --git a/arch/arm64/boot/dts/renesas/r8a7796-salvator-x-view.dts b/arch/arm64/boot/dts/renesas/r8a7796-salvator-x-view.dts
+index cc6866c..ab6e28a 100644
+--- a/arch/arm64/boot/dts/renesas/r8a7796-salvator-x-view.dts
++++ b/arch/arm64/boot/dts/renesas/r8a7796-salvator-x-view.dts
+@@ -35,6 +35,9 @@
+ compatible = "ovti,ov106xx";
+ reg = <0x60>;
+
++ maxim,fixed-sensor = "ov490";
++ maxim,width = <1280>;
++ maxim,height = <966>;
+ port@0 {
+ ov106xx_in0: endpoint {
+ clock-lanes = <0>;
+@@ -53,6 +56,9 @@
+ compatible = "ovti,ov106xx";
+ reg = <0x61>;
+
++ maxim,fixed-sensor = "ov490";
++ maxim,width = <1280>;
++ maxim,height = <966>;
+ port@0 {
+ ov106xx_in1: endpoint {
+ clock-lanes = <0>;
+@@ -71,6 +77,9 @@
+ compatible = "ovti,ov106xx";
+ reg = <0x62>;
+
++ maxim,fixed-sensor = "ov490";
++ maxim,width = <1280>;
++ maxim,height = <966>;
+ port@0 {
+ ov106xx_in2: endpoint {
+ clock-lanes = <0>;
+@@ -89,6 +98,9 @@
+ compatible = "ovti,ov106xx";
+ reg = <0x63>;
+
++ maxim,fixed-sensor = "ov490";
++ maxim,width = <1280>;
++ maxim,height = <966>;
+ port@0 {
+ ov106xx_in3: endpoint {
+ clock-lanes = <0>;
+@@ -110,8 +122,9 @@
+ maxim,sensor_delay = <0>;
+ maxim,links = <4>;
+ maxim,lanes = <4>;
+- maxim,resetb-gpio = <1>;
+- maxim,fsync-mode = "automatic";
++ maxim,resetb-gpio = <4>;
++ maxim,resetb-active-high;
++ maxim,fsync-mode = "manual";
+ maxim,timeout = <100>;
+ maxim,i2c-quirk = <0x6c>;
+
+--
+1.9.1
+
diff --git a/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0062-IIO-lsm9ds0-add-IMU-driver.patch b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0062-IIO-lsm9ds0-add-IMU-driver.patch
new file mode 100644
index 0000000..d3a329f
--- /dev/null
+++ b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0062-IIO-lsm9ds0-add-IMU-driver.patch
@@ -0,0 +1,972 @@
+From 4631208dd9557e0183acba14dec79318f9cabdc3 Mon Sep 17 00:00:00 2001
+From: Andrey Gusakov <andrey.gusakov@cogentembedded.com>
+Date: Wed, 7 Jun 2017 13:35:52 +0300
+Subject: [PATCH] IIO: lsm9ds0: add IMU driver
+
+Taken from:
+https://github.com/mpod/kernel-playground
+
+Signed-off-by: Andrey Gusakov <andrey.gusakov@cogentembedded.com>
+---
+ drivers/iio/imu/Kconfig | 11 +
+ drivers/iio/imu/Makefile | 2 +
+ drivers/iio/imu/lsm9ds0.c | 912 ++++++++++++++++++++++++++++++++++++++++++++++
+ 3 files changed, 925 insertions(+)
+ create mode 100644 drivers/iio/imu/lsm9ds0.c
+
+diff --git a/drivers/iio/imu/Kconfig b/drivers/iio/imu/Kconfig
+index 1f1ad41ef881..063c09b8fc53 100644
+--- a/drivers/iio/imu/Kconfig
++++ b/drivers/iio/imu/Kconfig
+@@ -38,6 +38,17 @@ config KMX61
+ To compile this driver as module, choose M here: the module will
+ be called kmx61.
+
++config LSM9DS0
++ tristate "ST LSM9DS0 9-axis IMU"
++ depends on I2C
++ select IIO_BUFFER
++ select IIO_TRIGGERED_BUFFER
++ help
++ Say Y here if you want to build a driver for ST LSM9DS0
++ system-in-package featuring a 3D digital linear acceleration
++ sensor, a 3D digital angular rate sensor, and a 3D digital magnetic
++ sensor.
++
+ source "drivers/iio/imu/inv_mpu6050/Kconfig"
+
+ endmenu
+diff --git a/drivers/iio/imu/Makefile b/drivers/iio/imu/Makefile
+index c71bcd30dc38..4de076d0766e 100644
+--- a/drivers/iio/imu/Makefile
++++ b/drivers/iio/imu/Makefile
+@@ -13,6 +13,8 @@ adis_lib-$(CONFIG_IIO_ADIS_LIB_BUFFER) += adis_trigger.o
+ adis_lib-$(CONFIG_IIO_ADIS_LIB_BUFFER) += adis_buffer.o
+ obj-$(CONFIG_IIO_ADIS_LIB) += adis_lib.o
+
++obj-$(CONFIG_LSM9DS0) += lsm9ds0.o
++
+ obj-y += bmi160/
+ obj-y += inv_mpu6050/
+
+diff --git a/drivers/iio/imu/lsm9ds0.c b/drivers/iio/imu/lsm9ds0.c
+new file mode 100644
+index 000000000000..15e2671daef9
+--- /dev/null
++++ b/drivers/iio/imu/lsm9ds0.c
+@@ -0,0 +1,912 @@
++/*
++ * lsm9ds0_gyro.c
++ *
++ * Copyright (C) 2016 Matija Podravec <matija_podravec@fastmail.fm>
++ *
++ * This program is free software: you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation, either version 3 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++
++ * You should have received a copy of the GNU General Public License
++ * along with this program. If not, see <http://www.gnu.org/licenses/>.
++ *
++ *
++ * Driver for ST LSM9DS0 gyroscope, accelerometer, and magnetometer sensor.
++ *
++ */
++
++#include <linux/kernel.h>
++#include <linux/module.h>
++#include <linux/slab.h>
++#include <linux/i2c.h>
++#include <linux/bitops.h>
++#include <linux/iio/iio.h>
++#include <linux/iio/sysfs.h>
++#include <linux/iio/trigger_consumer.h>
++#include <linux/iio/kfifo_buf.h>
++
++#define LSM9DS0_WHO_AM_I_REG (0x0F)
++#define LSM9DS0_CTRL_REG1_G_REG (0x20)
++#define LSM9DS0_CTRL_REG2_G_REG (0x21)
++#define LSM9DS0_CTRL_REG3_G_REG (0x22)
++#define LSM9DS0_CTRL_REG4_G_REG (0x23)
++#define LSM9DS0_CTRL_REG5_G_REG (0x24)
++#define LSM9DS0_REFERENCE_G_REG (0x25)
++#define LSM9DS0_STATUS_REG_G_REG (0x27)
++#define LSM9DS0_OUT_X_L_G_REG (0x28)
++#define LSM9DS0_OUT_X_H_G_REG (0x29)
++#define LSM9DS0_OUT_Y_L_G_REG (0x2A)
++#define LSM9DS0_OUT_Y_H_G_REG (0x2B)
++#define LSM9DS0_OUT_Z_L_G_REG (0x2C)
++#define LSM9DS0_OUT_Z_H_G_REG (0x2D)
++#define LSM9DS0_FIFO_CTRL_REG_G_REG (0x2E)
++#define LSM9DS0_FIFO_SRC_REG_G_REG (0x2F)
++#define LSM9DS0_INT1_CFG_G_REG (0x30)
++#define LSM9DS0_INT1_SRC_G_REG (0x31)
++#define LSM9DS0_INT1_TSH_XH_G_REG (0x32)
++#define LSM9DS0_INT1_TSH_XL_G_REG (0x33)
++#define LSM9DS0_INT1_TSH_YH_G_REG (0x34)
++#define LSM9DS0_INT1_TSH_YL_G_REG (0x35)
++#define LSM9DS0_INT1_TSH_ZH_G_REG (0x36)
++#define LSM9DS0_INT1_TSH_ZL_G_REG (0x37)
++#define LSM9DS0_INT1_DURATION_G_REG (0x38)
++#define LSM9DS0_OUT_TEMP_L_XM_REG (0x05)
++#define LSM9DS0_OUT_TEMP_H_XM_REG (0x06)
++#define LSM9DS0_STATUS_REG_M_REG (0x07)
++#define LSM9DS0_OUT_X_L_M_REG (0x08)
++#define LSM9DS0_OUT_X_H_M_REG (0x09)
++#define LSM9DS0_OUT_Y_L_M_REG (0x0A)
++#define LSM9DS0_OUT_Y_H_M_REG (0x0B)
++#define LSM9DS0_OUT_Z_L_M_REG (0x0C)
++#define LSM9DS0_OUT_Z_H_M_REG (0x0D)
++#define LSM9DS0_INT_CTRL_REG_M_REG (0x12)
++#define LSM9DS0_INT_SRC_REG_M_REG (0x13)
++#define LSM9DS0_INT_THS_L_M_REG (0x14)
++#define LSM9DS0_INT_THS_H_M_REG (0x15)
++#define LSM9DS0_OFFSET_X_L_M_REG (0x16)
++#define LSM9DS0_OFFSET_X_H_M_REG (0x17)
++#define LSM9DS0_OFFSET_Y_L_M_REG (0x18)
++#define LSM9DS0_OFFSET_Y_H_M_REG (0x19)
++#define LSM9DS0_OFFSET_Z_L_M_REG (0x1A)
++#define LSM9DS0_OFFSET_Z_H_M_REG (0x1B)
++#define LSM9DS0_REFERENCE_X_REG (0x1C)
++#define LSM9DS0_REFERENCE_Y_REG (0x1D)
++#define LSM9DS0_REFERENCE_Z_REG (0x1E)
++#define LSM9DS0_CTRL_REG0_XM_REG (0x1F)
++#define LSM9DS0_CTRL_REG1_XM_REG (0x20)
++#define LSM9DS0_CTRL_REG2_XM_REG (0x21)
++#define LSM9DS0_CTRL_REG3_XM_REG (0x22)
++#define LSM9DS0_CTRL_REG4_XM_REG (0x23)
++#define LSM9DS0_CTRL_REG5_XM_REG (0x24)
++#define LSM9DS0_CTRL_REG6_XM_REG (0x25)
++#define LSM9DS0_CTRL_REG7_XM_REG (0x26)
++#define LSM9DS0_STATUS_REG_A_REG (0x27)
++#define LSM9DS0_OUT_X_L_A_REG (0x28)
++#define LSM9DS0_OUT_X_H_A_REG (0x29)
++#define LSM9DS0_OUT_Y_L_A_REG (0x2A)
++#define LSM9DS0_OUT_Y_H_A_REG (0x2B)
++#define LSM9DS0_OUT_Z_L_A_REG (0x2C)
++#define LSM9DS0_OUT_Z_H_A_REG (0x2D)
++#define LSM9DS0_FIFO_CTRL_REG_REG (0x2E)
++#define LSM9DS0_FIFO_SRC_REG_REG (0x2F)
++#define LSM9DS0_INT_GEN_1_REG_REG (0x30)
++#define LSM9DS0_INT_GEN_1_SRC_REG (0x31)
++#define LSM9DS0_INT_GEN_1_THS_REG (0x32)
++#define LSM9DS0_INT_GEN_1_DURATION_REG (0x33)
++#define LSM9DS0_INT_GEN_2_REG_REG (0x34)
++#define LSM9DS0_INT_GEN_2_SRC_REG (0x35)
++#define LSM9DS0_INT_GEN_2_THS_REG (0x36)
++#define LSM9DS0_INT_GEN_2_DURATION_REG (0x37)
++#define LSM9DS0_CLICK_CFG_REG (0x38)
++#define LSM9DS0_CLICK_SRC_REG (0x39)
++#define LSM9DS0_CLICK_THS_REG (0x3A)
++#define LSM9DS0_TIME_LIMIT_REG (0x3B)
++#define LSM9DS0_TIME_LATENCY_REG (0x3C)
++#define LSM9DS0_TIME_WINDOW_REG (0x3D)
++#define LSM9DS0_ACT_THS_REG (0x3E)
++#define LSM9DS0_ACT_DUR_REG (0x3F)
++
++#define LSM9DS0_GYRO_ODR_95HZ_VAL (0x00 << 6)
++#define LSM9DS0_GYRO_ODR_190HZ_VAL (0x01 << 6)
++#define LSM9DS0_GYRO_ODR_380HZ_VAL (0x02 << 6)
++#define LSM9DS0_GYRO_ODR_760HZ_VAL (0x03 << 6)
++
++#define LSM9DS0_ACCEL_POWER_DOWN (0x00 << 4)
++#define LSM9DS0_ACCEL_ODR_3_125HZ_VAL (0x01 << 4)
++#define LSM9DS0_ACCEL_ODR_6_25HZ_VAL (0x02 << 4)
++#define LSM9DS0_ACCEL_ODR_12_5HZ_VAL (0x03 << 4)
++#define LSM9DS0_ACCEL_ODR_25HZ_VAL (0x04 << 4)
++#define LSM9DS0_ACCEL_ODR_50HZ_VAL (0x05 << 4)
++#define LSM9DS0_ACCEL_ODR_100HZ_VAL (0x06 << 4)
++#define LSM9DS0_ACCEL_ODR_200HZ_VAL (0x07 << 4)
++#define LSM9DS0_ACCEL_ODR_400HZ_VAL (0x08 << 4)
++#define LSM9DS0_ACCEL_ODR_800HZ_VAL (0x09 << 4)
++#define LSM9DS0_ACCEL_ODR_1600HZ_VAL (0x0A << 4)
++
++#define LSM9DS0_ACCEL_FS_MASK (0x03 << 3)
++#define LSM9DS0_ACCEL_FS_2G_VAL (0x00 << 3)
++#define LSM9DS0_ACCEL_FS_4G_VAL (0x01 << 3)
++#define LSM9DS0_ACCEL_FS_6G_VAL (0x02 << 3)
++#define LSM9DS0_ACCEL_FS_8G_VAL (0x03 << 3)
++#define LSM9DS0_ACCEL_FS_16G_VAL (0x04 << 3)
++#define LSM9DS0_ACCEL_FS_2G_GAIN 61 /* ug/LSB */
++#define LSM9DS0_ACCEL_FS_4G_GAIN 122 /* ug/LSB */
++#define LSM9DS0_ACCEL_FS_6G_GAIN 183 /* ug/LSB */
++#define LSM9DS0_ACCEL_FS_8G_GAIN 244 /* ug/LSB */
++#define LSM9DS0_ACCEL_FS_16G_GAIN 732 /* ug/LSB */
++
++#define LSM9DS0_MAGN_ODR_3_125HZ_VAL (0x00 << 2)
++#define LSM9DS0_MAGN_ODR_6_25HZ_VAL (0x01 << 2)
++#define LSM9DS0_MAGN_ODR_12_5HZ_VAL (0x02 << 2)
++#define LSM9DS0_MAGN_ODR_25HZ_VAL (0x03 << 2)
++#define LSM9DS0_MAGN_ODR_50HZ_VAL (0x04 << 2)
++#define LSM9DS0_MAGN_ODR_100HZ_VAL (0x05 << 2)
++
++#define LSM9DS0_MAGN_FS_MASK (0x03 << 5)
++#define LSM9DS0_MAGN_FS_2GAUSS_VAL (0x00 << 5)
++#define LSM9DS0_MAGN_FS_4GAUSS_VAL (0x01 << 5)
++#define LSM9DS0_MAGN_FS_8GAUSS_VAL (0x02 << 5)
++#define LSM9DS0_MAGN_FS_12GAUSS_VAL (0x03 << 5)
++#define LSM9DS0_MAGN_FS_2GAUSS_GAIN 80 /* ugauss/LSB */
++#define LSM9DS0_MAGN_FS_4GAUSS_GAIN 160 /* ugauss/LSB */
++#define LSM9DS0_MAGN_FS_8GAUSS_GAIN 320 /* ugauss/LSB */
++#define LSM9DS0_MAGN_FS_12GAUSS_GAIN 480 /* ugauss/LSB */
++
++#define LSM9DS0_GYRO_FS_MASK (0x03 << 4)
++#define LSM9DS0_GYRO_FS_245DPS_VAL (0x00 << 4)
++#define LSM9DS0_GYRO_FS_500DPS_VAL (0x01 << 4)
++#define LSM9DS0_GYRO_FS_2000DPS_VAL (0x02 << 4)
++#define LSM9DS0_GYRO_FS_245DPS_GAIN 8750 /* udps/LSB */
++#define LSM9DS0_GYRO_FS_500DPS_GAIN 17500 /* udps/LSB */
++#define LSM9DS0_GYRO_FS_2000DPS_GAIN 70000 /* udps/LSB */
++
++#define LSM9DS0_GYRO_X_EN BIT(1)
++#define LSM9DS0_GYRO_Y_EN BIT(0)
++#define LSM9DS0_GYRO_Z_EN BIT(2)
++#define LSM9DS0_GYRO_POWER_DOWN (0x00 << 3)
++#define LSM9DS0_GYRO_NORMAL_MODE BIT(3)
++#define LSM9DS0_ACCEL_X_EN BIT(0)
++#define LSM9DS0_ACCEL_Y_EN BIT(1)
++#define LSM9DS0_ACCEL_Z_EN BIT(2)
++#define LSM9DS0_TEMP_EN BIT(7)
++#define LSM9DS0_MAGN_LOW_RES_VAL (0x00 << 5)
++#define LSM9DS0_MAGN_HIGH_RES_VAL (0x03 << 5)
++#define LSM9DS0_MAGN_POWER_DOWN (0x02)
++#define LSM9DS0_MAGN_CONT_CONV_MODE (0x00)
++#define LSM9DS0_MAGN_SINGLE_CONV_MODE (0x01)
++
++#define LSM9DS0_GYRO_ID 0xD4
++#define LSM9DS0_ACCEL_MAGN_ID 0x49
++
++enum { SCAN_INDEX_X, SCAN_INDEX_Y, SCAN_INDEX_Z };
++enum {
++ SCAN_INDEX_ACCEL_X, SCAN_INDEX_ACCEL_Y, SCAN_INDEX_ACCEL_Z,
++ SCAN_INDEX_MAGN_X, SCAN_INDEX_MAGN_Y, SCAN_INDEX_MAGN_Z
++};
++enum { GYRO, ACCEL_MAGN };
++
++struct lsm9ds0_data {
++ struct i2c_client *client;
++ struct mutex lock;
++ int sensor_type;
++ int gyro_scale;
++ int accel_scale;
++ int magn_scale;
++};
++
++struct sensor_fs_avl {
++ unsigned int num;
++ u8 value;
++ unsigned int gain;
++};
++
++static const struct sensor_fs_avl lsm9ds0_gyro_fs_avl[3] = {
++ {245, LSM9DS0_GYRO_FS_245DPS_VAL, LSM9DS0_GYRO_FS_245DPS_GAIN},
++ {500, LSM9DS0_GYRO_FS_500DPS_VAL, LSM9DS0_GYRO_FS_500DPS_GAIN},
++ {2000, LSM9DS0_GYRO_FS_2000DPS_VAL, LSM9DS0_GYRO_FS_2000DPS_GAIN},
++};
++
++static const struct sensor_fs_avl lsm9ds0_accel_fs_avl[5] = {
++ {2, LSM9DS0_ACCEL_FS_2G_VAL, LSM9DS0_ACCEL_FS_2G_GAIN},
++ {4, LSM9DS0_ACCEL_FS_4G_VAL, LSM9DS0_ACCEL_FS_4G_GAIN},
++ {6, LSM9DS0_ACCEL_FS_6G_VAL, LSM9DS0_ACCEL_FS_6G_GAIN},
++ {8, LSM9DS0_ACCEL_FS_8G_VAL, LSM9DS0_ACCEL_FS_8G_GAIN},
++ {16, LSM9DS0_ACCEL_FS_16G_VAL, LSM9DS0_ACCEL_FS_16G_GAIN},
++};
++
++static const struct sensor_fs_avl lsm9ds0_magn_fs_avl[4] = {
++ {2, LSM9DS0_MAGN_FS_2GAUSS_VAL, LSM9DS0_MAGN_FS_2GAUSS_GAIN},
++ {4, LSM9DS0_MAGN_FS_4GAUSS_VAL, LSM9DS0_MAGN_FS_4GAUSS_GAIN},
++ {8, LSM9DS0_MAGN_FS_8GAUSS_VAL, LSM9DS0_MAGN_FS_8GAUSS_GAIN},
++ {12, LSM9DS0_MAGN_FS_12GAUSS_VAL, LSM9DS0_MAGN_FS_12GAUSS_GAIN},
++};
++
++static ssize_t lsm9ds0_show_scale_avail(struct device *dev,
++ struct device_attribute *attr, char *buf)
++{
++ //struct iio_dev *indio_dev = dev_to_iio_dev(dev);
++ //struct lsm9ds0_data *data = iio_priv(indio_dev);
++ size_t len = 0;
++ int n;
++ const struct sensor_fs_avl (*avl)[];
++
++ if (strcmp(attr->attr.name, "in_gyro_scale_available") == 0) {
++ avl = &lsm9ds0_gyro_fs_avl;
++ n = ARRAY_SIZE(lsm9ds0_gyro_fs_avl);
++ } else if (strcmp(attr->attr.name, "in_accel_scale_available") == 0) {
++ avl = &lsm9ds0_accel_fs_avl;
++ n = ARRAY_SIZE(lsm9ds0_accel_fs_avl);
++ } else if (strcmp(attr->attr.name, "in_magn_scale_available") == 0) {
++ avl = &lsm9ds0_magn_fs_avl;
++ n = ARRAY_SIZE(lsm9ds0_magn_fs_avl);
++ } else {
++ return -EINVAL;
++ }
++
++ while (n-- > 0)
++ len += scnprintf(buf + len, PAGE_SIZE - len,
++ "0.%06u ", (*avl)[n].gain);
++ buf[len - 1] = '\n';
++
++ return len;
++}
++
++static IIO_DEVICE_ATTR(in_accel_scale_available, S_IRUGO,
++ lsm9ds0_show_scale_avail, NULL, 0);
++static IIO_DEVICE_ATTR(in_magn_scale_available, S_IRUGO,
++ lsm9ds0_show_scale_avail, NULL, 0);
++static IIO_DEVICE_ATTR(in_gyro_scale_available, S_IRUGO,
++ lsm9ds0_show_scale_avail, NULL, 0);
++
++static struct attribute *lsm9ds0_gyro_attributes[] = {
++ &iio_dev_attr_in_gyro_scale_available.dev_attr.attr,
++ NULL
++};
++
++static struct attribute *lsm9ds0_accel_magn_attributes[] = {
++ &iio_dev_attr_in_accel_scale_available.dev_attr.attr,
++ &iio_dev_attr_in_magn_scale_available.dev_attr.attr,
++ NULL
++};
++
++static const struct attribute_group lsm9ds0_gyro_group = {
++ .attrs = lsm9ds0_gyro_attributes,
++};
++
++static const struct attribute_group lsm9ds0_accel_magn_group = {
++ .attrs = lsm9ds0_accel_magn_attributes,
++};
++
++static const struct iio_buffer_setup_ops lsm9ds0_buffer_setup_ops = {
++ .postenable = &iio_triggered_buffer_postenable,
++ .predisable = &iio_triggered_buffer_predisable,
++};
++
++static const struct iio_chan_spec lsm9ds0_gyro_channels[] = {
++ {
++ .type = IIO_ANGL_VEL,
++ .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
++ .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE),
++ .modified = 1,
++ .channel2 = IIO_MOD_X,
++ .scan_index = SCAN_INDEX_X,
++ .scan_type = {
++ .sign = 's',
++ .realbits = 16,
++ .storagebits = 16,
++ .shift = 0,
++ .endianness = IIO_LE,
++ },
++ }, {
++ .type = IIO_ANGL_VEL,
++ .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
++ .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE),
++ .modified = 1,
++ .channel2 = IIO_MOD_Y,
++ .scan_index = SCAN_INDEX_Y,
++ .scan_type = {
++ .sign = 's',
++ .realbits = 16,
++ .storagebits = 16,
++ .shift = 0,
++ .endianness = IIO_LE,
++ },
++ }, {
++ .type = IIO_ANGL_VEL,
++ .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
++ .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE),
++ .modified = 1,
++ .channel2 = IIO_MOD_Z,
++ .scan_index = SCAN_INDEX_Z,
++ .scan_type = {
++ .sign = 's',
++ .realbits = 16,
++ .storagebits = 16,
++ .shift = 0,
++ .endianness = IIO_LE,
++ },
++ },
++ IIO_CHAN_SOFT_TIMESTAMP(3),
++};
++
++static const struct iio_chan_spec lsm9ds0_accel_magn_channels[] = {
++ {
++ .type = IIO_ACCEL,
++ .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
++ .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE),
++ .modified = 1,
++ .channel2 = IIO_MOD_X,
++ .scan_index = SCAN_INDEX_ACCEL_X,
++ .scan_type = {
++ .sign = 's',
++ .realbits = 16,
++ .storagebits = 16,
++ .shift = 0,
++ .endianness = IIO_LE,
++ },
++ }, {
++ .type = IIO_ACCEL,
++ .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
++ .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE),
++ .modified = 1,
++ .channel2 = IIO_MOD_Y,
++ .scan_index = SCAN_INDEX_ACCEL_Y,
++ .scan_type = {
++ .sign = 's',
++ .realbits = 16,
++ .storagebits = 16,
++ .shift = 0,
++ .endianness = IIO_LE,
++ },
++ }, {
++ .type = IIO_ACCEL,
++ .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
++ .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE),
++ .modified = 1,
++ .channel2 = IIO_MOD_Z,
++ .scan_index = SCAN_INDEX_ACCEL_Z,
++ .scan_type = {
++ .sign = 's',
++ .realbits = 16,
++ .storagebits = 16,
++ .shift = 0,
++ .endianness = IIO_LE,
++ },
++ }, {
++ .type = IIO_MAGN,
++ .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
++ .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE),
++ .modified = 1,
++ .channel2 = IIO_MOD_X,
++ .scan_index = SCAN_INDEX_MAGN_X,
++ .scan_type = {
++ .sign = 's',
++ .realbits = 16,
++ .storagebits = 16,
++ .shift = 0,
++ .endianness = IIO_LE,
++ },
++ }, {
++ .type = IIO_MAGN,
++ .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
++ .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE),
++ .modified = 1,
++ .channel2 = IIO_MOD_Y,
++ .scan_index = SCAN_INDEX_MAGN_Y,
++ .scan_type = {
++ .sign = 's',
++ .realbits = 16,
++ .storagebits = 16,
++ .shift = 0,
++ .endianness = IIO_LE,
++ },
++ }, {
++ .type = IIO_MAGN,
++ .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
++ .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE),
++ .modified = 1,
++ .channel2 = IIO_MOD_Z,
++ .scan_index = SCAN_INDEX_MAGN_Z,
++ .scan_type = {
++ .sign = 's',
++ .realbits = 16,
++ .storagebits = 16,
++ .shift = 0,
++ .endianness = IIO_LE,
++ },
++ },
++ IIO_CHAN_SOFT_TIMESTAMP(6),
++};
++
++static int lsm9ds0_read_measurements(struct i2c_client *client,
++ u8 reg_address, s16 *x, s16 *y, s16 *z)
++{
++ int ret;
++ u8 buf[6] = {0};
++
++ buf[0] = 0x80 | reg_address;
++ ret = i2c_master_send(client, buf, 1);
++ if (ret < 0)
++ return ret;
++
++ ret = i2c_master_recv(client, buf, 6);
++ if (ret < 0)
++ return ret;
++
++ *x = (buf[1] << 8) | buf[0];
++ *y = (buf[3] << 8) | buf[2];
++ *z = (buf[5] << 8) | buf[4];
++ return ret;
++}
++
++static int lsm9ds0_read_raw(struct iio_dev *iio_dev,
++ struct iio_chan_spec const *channel,
++ int *val, int *val2, long mask)
++{
++ struct lsm9ds0_data *data = iio_priv(iio_dev);
++ int err = 0;
++ s16 x = 0, y = 0, z = 0;
++ int scale = 0;
++
++ switch (mask) {
++ case IIO_CHAN_INFO_RAW:
++ mutex_lock(&data->lock);
++ switch (channel->type) {
++ case IIO_ANGL_VEL:
++ err = lsm9ds0_read_measurements(data->client,
++ LSM9DS0_OUT_X_L_G_REG, &x, &y, &z);
++ scale = data->gyro_scale;
++ break;
++ case IIO_ACCEL:
++ err = lsm9ds0_read_measurements(data->client,
++ LSM9DS0_OUT_X_L_A_REG, &x, &y, &z);
++ scale = data->accel_scale;
++ break;
++ case IIO_MAGN:
++ err = lsm9ds0_read_measurements(data->client,
++ LSM9DS0_OUT_X_L_M_REG, &x, &y, &z);
++ scale = data->magn_scale;
++ break;
++ default:
++ return -EINVAL;
++ }
++ mutex_unlock(&data->lock);
++ if (err < 0)
++ goto read_error;
++
++ switch (channel->channel2) {
++ case IIO_MOD_X:
++ *val = x;
++ break;
++ case IIO_MOD_Y:
++ *val = y;
++ break;
++ case IIO_MOD_Z:
++ *val = z;
++ break;
++ }
++ return IIO_VAL_INT;
++ case IIO_CHAN_INFO_SCALE:
++ *val = 0;
++ switch (channel->type) {
++ case IIO_ANGL_VEL:
++ *val2 = data->gyro_scale;
++ break;
++ case IIO_ACCEL:
++ *val2 = data->accel_scale;
++ break;
++ case IIO_MAGN:
++ *val2 = data->magn_scale;
++ break;
++ default:
++ return -EINVAL;
++ }
++ return IIO_VAL_INT_PLUS_MICRO;
++ default:
++ return -EINVAL;
++ }
++
++read_error:
++ return err;
++}
++
++static int lsm9ds0_write_config(struct i2c_client *client,
++ u8 reg_address, u8 mask, u8 value)
++{
++ u8 reg;
++ s32 ret;
++ ret = i2c_smbus_read_byte_data(client, reg_address);
++ if (ret < 0)
++ return -EINVAL;
++
++ reg = (u8)ret;
++ reg &= ~mask;
++ reg |= value;
++
++ ret = i2c_smbus_write_byte_data(client, reg_address, reg);
++
++ return ret;
++}
++
++static int lsm9ds0_write_raw(struct iio_dev *indio_dev,
++ struct iio_chan_spec const *channel,
++ int val, int val2, long mask)
++{
++ struct lsm9ds0_data *data = iio_priv(indio_dev);
++ struct i2c_client *client = data->client;
++ const struct sensor_fs_avl (*avl)[];
++ int n, i, ret;
++ u8 reg_address, reg_mask, new_value;
++ int *scale_in_data;
++
++ mutex_lock(&data->lock);
++ switch (mask) {
++ case IIO_CHAN_INFO_SCALE:
++ dev_info(&client->dev, "Vals %d %d\n", val, val2);
++ switch (channel->type) {
++ case IIO_ANGL_VEL:
++ avl = &lsm9ds0_gyro_fs_avl;
++ n = ARRAY_SIZE(lsm9ds0_gyro_fs_avl);
++ reg_address = LSM9DS0_CTRL_REG4_G_REG;
++ reg_mask = LSM9DS0_GYRO_FS_MASK;
++ scale_in_data = &(data->gyro_scale);
++ break;
++ case IIO_ACCEL:
++ avl = &lsm9ds0_accel_fs_avl;
++ n = ARRAY_SIZE(lsm9ds0_accel_fs_avl);
++ reg_address = LSM9DS0_CTRL_REG2_XM_REG;
++ reg_mask = LSM9DS0_ACCEL_FS_MASK;
++ scale_in_data = &(data->accel_scale);
++ break;
++ case IIO_MAGN:
++ avl = &lsm9ds0_magn_fs_avl;
++ n = ARRAY_SIZE(lsm9ds0_magn_fs_avl);
++ reg_address = LSM9DS0_CTRL_REG6_XM_REG;
++ reg_mask = LSM9DS0_MAGN_FS_MASK;
++ scale_in_data = &(data->magn_scale);
++ break;
++ default:
++ ret = -EINVAL;
++ goto done;
++ }
++ ret = -EINVAL;
++ for (i = 0; i < n; i++) {
++ if ((*avl)[i].gain == val2) {
++ ret = 0;
++ new_value = (*avl)[i].value;
++ break;
++ }
++ }
++ if (ret < 0)
++ goto done;
++
++ ret = lsm9ds0_write_config(client, reg_address, reg_mask, new_value);
++ if (ret < 0)
++ goto done;
++
++ *scale_in_data = (*avl)[i].gain;
++ break;
++ default:
++ ret = -EINVAL;
++ }
++
++done:
++ mutex_unlock(&data->lock);
++ return ret;
++}
++
++static irqreturn_t lsm9ds0_trigger_h(int irq, void *p)
++{
++ struct iio_poll_func *pf = p;
++ struct iio_dev *indio_dev = pf->indio_dev;
++ struct lsm9ds0_data *data = iio_priv(indio_dev);
++ u32 *buf_data;
++ int i, j;
++ s16 x1, y1, z1, x2, y2, z2;
++ int err;
++
++ buf_data = kmalloc(indio_dev->scan_bytes, GFP_KERNEL);
++ if (!buf_data)
++ goto done;
++
++ mutex_lock(&data->lock);
++ if (!bitmap_empty(indio_dev->active_scan_mask, indio_dev->masklength)) {
++
++ if (data->sensor_type == GYRO) {
++ err = lsm9ds0_read_measurements(data->client,
++ LSM9DS0_OUT_X_L_G_REG, &x1, &y1, &z1);
++ if (err < 0)
++ goto free_buf;
++ } else if (data->sensor_type == ACCEL_MAGN) {
++ err = lsm9ds0_read_measurements(data->client,
++ LSM9DS0_OUT_X_L_A_REG, &x1, &y1, &z1);
++ if (err < 0)
++ goto free_buf;
++ err = lsm9ds0_read_measurements(data->client,
++ LSM9DS0_OUT_X_L_M_REG, &x2, &y2, &z2);
++ if (err < 0)
++ goto free_buf;
++ } else
++ goto free_buf;
++
++ for (i = 0, j = 0;
++ i < bitmap_weight(indio_dev->active_scan_mask, indio_dev->masklength);
++ i++, j++) {
++ j = find_next_bit(indio_dev->active_scan_mask, indio_dev->masklength, j);
++
++ if (data->sensor_type == GYRO) {
++ switch (j) {
++ case SCAN_INDEX_X:
++ buf_data[i] = x1;
++ break;
++ case SCAN_INDEX_Y:
++ buf_data[i] = y1;
++ break;
++ case SCAN_INDEX_Z:
++ buf_data[i] = z1;
++ break;
++ default:
++ break;
++ }
++ } else {
++ switch (j) {
++ case SCAN_INDEX_ACCEL_X:
++ buf_data[i] = x1;
++ break;
++ case SCAN_INDEX_ACCEL_Y:
++ buf_data[i] = y1;
++ break;
++ case SCAN_INDEX_ACCEL_Z:
++ buf_data[i] = z1;
++ break;
++ case SCAN_INDEX_MAGN_X:
++ buf_data[i] = x2;
++ break;
++ case SCAN_INDEX_MAGN_Y:
++ buf_data[i] = y2;
++ break;
++ case SCAN_INDEX_MAGN_Z:
++ buf_data[i] = z2;
++ break;
++ default:
++ break;
++ }
++ }
++ }
++ }
++
++ iio_push_to_buffers_with_timestamp(indio_dev, buf_data, iio_get_time_ns(indio_dev));
++
++free_buf:
++ kfree(buf_data);
++ mutex_unlock(&data->lock);
++
++done:
++ iio_trigger_notify_done(indio_dev->trig);
++
++ return IRQ_HANDLED;
++}
++
++static const struct iio_info lsm9ds0_gyro_info = {
++ .attrs = &lsm9ds0_gyro_group,
++ .read_raw = lsm9ds0_read_raw,
++ .write_raw = lsm9ds0_write_raw,
++ .driver_module = THIS_MODULE,
++};
++
++static const struct iio_info lsm9ds0_accel_magn_info = {
++ .attrs = &lsm9ds0_accel_magn_group,
++ .read_raw = lsm9ds0_read_raw,
++ .write_raw = lsm9ds0_write_raw,
++ .driver_module = THIS_MODULE,
++};
++
++static int lsm9ds0_gyro_init(struct i2c_client *client)
++{
++ int ret;
++ struct iio_dev *indio_dev;
++ struct lsm9ds0_data *data;
++
++ ret = i2c_smbus_write_byte_data(client, LSM9DS0_CTRL_REG1_G_REG,
++ LSM9DS0_GYRO_NORMAL_MODE | LSM9DS0_GYRO_X_EN |
++ LSM9DS0_GYRO_Y_EN | LSM9DS0_GYRO_Z_EN);
++ if (ret < 0) {
++ dev_err(&client->dev, "Failed to write control register 5.\n");
++ return ret;
++ }
++ ret = i2c_smbus_write_byte_data(client, LSM9DS0_CTRL_REG4_G_REG,
++ LSM9DS0_GYRO_FS_245DPS_VAL);
++ if (ret < 0) {
++ dev_err(&client->dev, "Failed to write control register 4.\n");
++ return ret;
++ }
++
++ indio_dev = i2c_get_clientdata(client);
++ data = iio_priv(indio_dev);
++
++ data->gyro_scale = LSM9DS0_GYRO_FS_245DPS_GAIN;
++
++ return 0;
++}
++
++static int lsm9ds0_accel_magn_init(struct i2c_client *client)
++{
++ int ret;
++ struct iio_dev *indio_dev;
++ struct lsm9ds0_data *data;
++
++ ret = i2c_smbus_write_byte_data(client, LSM9DS0_CTRL_REG1_XM_REG,
++ LSM9DS0_ACCEL_ODR_100HZ_VAL | LSM9DS0_ACCEL_X_EN |
++ LSM9DS0_ACCEL_Y_EN | LSM9DS0_ACCEL_Z_EN);
++ if (ret < 0) {
++ dev_err(&client->dev, "Failed to write control register 1.\n");
++ return ret;
++ }
++ ret = i2c_smbus_write_byte_data(client, LSM9DS0_CTRL_REG5_XM_REG,
++ LSM9DS0_TEMP_EN | LSM9DS0_MAGN_HIGH_RES_VAL | LSM9DS0_MAGN_ODR_50HZ_VAL);
++ if (ret < 0) {
++ dev_err(&client->dev, "Failed to write control register 5.\n");
++ return ret;
++ }
++ ret = i2c_smbus_write_byte_data(client, LSM9DS0_CTRL_REG7_XM_REG,
++ LSM9DS0_MAGN_CONT_CONV_MODE);
++ if (ret < 0) {
++ dev_err(&client->dev, "Failed to write control register 7.\n");
++ return ret;
++ }
++ ret = i2c_smbus_write_byte_data(client, LSM9DS0_CTRL_REG2_XM_REG,
++ LSM9DS0_ACCEL_FS_2G_VAL);
++ if (ret < 0) {
++ dev_err(&client->dev, "Failed to write control register 2.\n");
++ return ret;
++ }
++ ret = i2c_smbus_write_byte_data(client, LSM9DS0_CTRL_REG6_XM_REG,
++ LSM9DS0_MAGN_FS_2GAUSS_VAL);
++ if (ret < 0) {
++ dev_err(&client->dev, "Failed to write control register 6.\n");
++ return ret;
++ }
++
++ indio_dev = i2c_get_clientdata(client);
++ data = iio_priv(indio_dev);
++
++ data->accel_scale = LSM9DS0_ACCEL_FS_2G_GAIN;
++ data->magn_scale = LSM9DS0_MAGN_FS_2GAUSS_GAIN;
++
++ return 0;
++}
++
++static int lsm9ds0_probe(struct i2c_client *client,
++ const struct i2c_device_id *id)
++{
++ struct iio_dev *indio_dev;
++ struct lsm9ds0_data *data;
++ struct iio_buffer *buffer;
++ int sensor_type;
++ int ret;
++
++
++ if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_WORD_DATA)) {
++ ret = -ENODEV;
++ goto error_ret;
++ }
++
++ ret = i2c_smbus_read_byte_data(client, LSM9DS0_WHO_AM_I_REG);
++ if (ret < 0) {
++ ret = -EINVAL;
++ goto error_ret;
++ }
++ if (ret == LSM9DS0_GYRO_ID) {
++ dev_info(&client->dev, "Gyroscope found.\n");
++ sensor_type = GYRO;
++ } else if (ret == LSM9DS0_ACCEL_MAGN_ID) {
++ dev_info(&client->dev, "Accelerometer and magnetometer found.\n");
++ sensor_type = ACCEL_MAGN;
++ } else {
++ dev_err(&client->dev, "No LSM9DS0 sensor found.\n");
++ ret = -ENODEV;
++ goto error_ret;
++ }
++
++ indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data));
++ if (!indio_dev) {
++ ret = -ENOMEM;
++ goto error_ret;
++ }
++
++ data = iio_priv(indio_dev);
++ mutex_init(&data->lock);
++ i2c_set_clientdata(client, indio_dev);
++ data->client = client;
++ data->sensor_type = sensor_type;
++
++ indio_dev->dev.parent = &client->dev;
++ indio_dev->name = dev_name(&client->dev);
++ indio_dev->modes = INDIO_DIRECT_MODE | INDIO_BUFFER_TRIGGERED;
++
++
++ if (sensor_type == GYRO) {
++ ret = lsm9ds0_gyro_init(client);
++ indio_dev->info = &lsm9ds0_gyro_info;
++ indio_dev->channels = lsm9ds0_gyro_channels;
++ indio_dev->num_channels = ARRAY_SIZE(lsm9ds0_gyro_channels);
++ } else {
++ ret = lsm9ds0_accel_magn_init(client);
++ indio_dev->info = &lsm9ds0_accel_magn_info;
++ indio_dev->channels = lsm9ds0_accel_magn_channels;
++ indio_dev->num_channels = ARRAY_SIZE(lsm9ds0_accel_magn_channels);
++ }
++ if (ret < 0)
++ goto error_free_device;
++
++ buffer = iio_kfifo_allocate();
++ if (!buffer) {
++ ret = -ENOMEM;
++ goto error_free_device;
++ }
++ iio_device_attach_buffer(indio_dev, buffer);
++ buffer->scan_timestamp = true;
++ indio_dev->setup_ops = &lsm9ds0_buffer_setup_ops;
++ indio_dev->pollfunc = iio_alloc_pollfunc(NULL,
++ &lsm9ds0_trigger_h,
++ IRQF_ONESHOT,
++ indio_dev,
++ "lsm9ds0_consumer%d",
++ indio_dev->id);
++ if (!indio_dev->pollfunc) {
++ ret = -ENOMEM;
++ goto error_free_buffer;
++ }
++
++ ret = iio_device_register(indio_dev);
++ if (ret < 0)
++ goto error_unconfigure_buffer;
++
++ return 0;
++
++error_unconfigure_buffer:
++ iio_dealloc_pollfunc(indio_dev->pollfunc);
++error_free_buffer:
++ iio_kfifo_free(indio_dev->buffer);
++error_free_device:
++ iio_device_free(indio_dev);
++error_ret:
++ return ret;
++}
++
++static int lsm9ds0_remove(struct i2c_client *client)
++{
++ struct iio_dev *indio_dev = i2c_get_clientdata(client);
++ iio_device_unregister(indio_dev);
++ iio_device_free(indio_dev);
++ dev_info(&client->dev, "Driver removed.");
++ return 0;
++}
++
++static const struct i2c_device_id lsm9ds0_id[] = {
++ { "lsm9ds0_gyro", 0 },
++ { "lsm9ds0_accel_magn", 0 },
++ { }
++};
++MODULE_DEVICE_TABLE(i2c, lsm9ds0_id);
++
++static struct i2c_driver lsm9ds0_driver = {
++ .driver = {
++ .name = "lsm9ds0",
++ .owner = THIS_MODULE,
++ },
++ .probe = lsm9ds0_probe,
++ .remove = lsm9ds0_remove,
++ .id_table = lsm9ds0_id,
++};
++module_i2c_driver(lsm9ds0_driver);
++
++MODULE_AUTHOR("Matija Podravec <matija_podravec@fastmail.fm>");
++MODULE_DESCRIPTION("LSM9DS0 gyroscope, accelerometer, and magnetometer sensor");
++MODULE_LICENSE("GPL");
+--
+2.13.0
+
diff --git a/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0063-ASoC-PCM3168A-add-TDM-modes-merge-ADC-and-DAC.patch b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0063-ASoC-PCM3168A-add-TDM-modes-merge-ADC-and-DAC.patch
new file mode 100644
index 0000000..46d5d84
--- /dev/null
+++ b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0063-ASoC-PCM3168A-add-TDM-modes-merge-ADC-and-DAC.patch
@@ -0,0 +1,479 @@
+From 963d9e84748bc43a8dbcd28019bd8ff0942b5934 Mon Sep 17 00:00:00 2001
+From: Andrey Gusakov <andrey.gusakov@cogentembedded.com>
+Date: Wed, 13 Apr 2016 15:32:38 +0300
+Subject: [PATCH] ASoC: PCM3168A: add TDM modes, merge ADC and DAC
+
+Also disable 16 bit format and enable at start
+
+Signed-off-by: Andrey Gusakov <andrey.gusakov@cogentembedded.com>
+---
+ sound/soc/codecs/pcm3168a.c | 320 ++++++++++++++++++++++++++++----------------
+ sound/soc/codecs/pcm3168a.h | 2 +-
+ 2 files changed, 205 insertions(+), 117 deletions(-)
+
+diff --git a/sound/soc/codecs/pcm3168a.c b/sound/soc/codecs/pcm3168a.c
+index 992a77edcd5d..8b9e4ff6b354 100644
+--- a/sound/soc/codecs/pcm3168a.c
++++ b/sound/soc/codecs/pcm3168a.c
+@@ -22,7 +22,7 @@
+
+ #include "pcm3168a.h"
+
+-#define PCM3168A_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | \
++#define PCM3168A_FORMATS (/*SNDRV_PCM_FMTBIT_S16_LE | */\
+ SNDRV_PCM_FMTBIT_S24_3LE | \
+ SNDRV_PCM_FMTBIT_S24_LE | \
+ SNDRV_PCM_FMTBIT_S32_LE)
+@@ -33,7 +33,11 @@
+ #define PCM3168A_FMT_RIGHT_J_16 0x3
+ #define PCM3168A_FMT_DSP_A 0x4
+ #define PCM3168A_FMT_DSP_B 0x5
+-#define PCM3168A_FMT_DSP_MASK 0x4
++#define PCM3168A_FMT_I2S_TDM 0x6
++#define PCM3168A_FMT_LEFT_J_TDM 0x7
++/* High speed */
++#define PCM3168A_FMT_I2S_TDMHS 0x8
++#define PCM3168A_FMT_LEFT_J_TDMHS 0x9
+
+ #define PCM3168A_NUM_SUPPLIES 6
+ static const char *const pcm3168a_supply_names[PCM3168A_NUM_SUPPLIES] = {
+@@ -45,12 +49,18 @@ static const char *const pcm3168a_supply_names[PCM3168A_NUM_SUPPLIES] = {
+ "VCCDA2"
+ };
+
++#define TDM_MODE_NONE 0
++#define TDM_MODE_NORM 1
++#define TDM_MODE_HS 2
++
+ struct pcm3168a_priv {
+ struct regulator_bulk_data supplies[PCM3168A_NUM_SUPPLIES];
+ struct regmap *regmap;
+ struct clk *scki;
+- bool adc_master_mode;
+- bool dac_master_mode;
++ bool master_mode;
++ unsigned int tdm;
++ unsigned int slots;
++ unsigned int slot_width;
+ unsigned long sysclk;
+ unsigned int adc_fmt;
+ unsigned int dac_fmt;
+@@ -313,32 +323,43 @@ static int pcm3168a_set_dai_sysclk(struct snd_soc_dai *dai,
+ return 0;
+ }
+
+-static int pcm3168a_set_dai_fmt(struct snd_soc_dai *dai,
++int format_table[3][6] = {
++ [TDM_MODE_NONE] = {
++ [0] = -1,
++ [SND_SOC_DAIFMT_I2S] = PCM3168A_FMT_I2S,
++ [SND_SOC_DAIFMT_LEFT_J] = PCM3168A_FMT_LEFT_J,
++ [SND_SOC_DAIFMT_RIGHT_J] = PCM3168A_FMT_RIGHT_J,
++ [SND_SOC_DAIFMT_DSP_A] = PCM3168A_FMT_DSP_A,
++ [SND_SOC_DAIFMT_DSP_B] = PCM3168A_FMT_DSP_B},
++ [TDM_MODE_NORM] = {
++ [0] = -1,
++ [SND_SOC_DAIFMT_I2S] = PCM3168A_FMT_I2S_TDM,
++ [SND_SOC_DAIFMT_LEFT_J] = PCM3168A_FMT_LEFT_J_TDM,
++ [SND_SOC_DAIFMT_RIGHT_J] = -1,
++ [SND_SOC_DAIFMT_DSP_A] = -1,
++ [SND_SOC_DAIFMT_DSP_B] = -1},
++ [TDM_MODE_HS] = {
++ [0] = -1,
++ [SND_SOC_DAIFMT_I2S] = PCM3168A_FMT_I2S_TDMHS,
++ [SND_SOC_DAIFMT_LEFT_J] = PCM3168A_FMT_LEFT_J_TDMHS,
++ [SND_SOC_DAIFMT_RIGHT_J] = -1,
++ [SND_SOC_DAIFMT_DSP_A] = -1,
++ [SND_SOC_DAIFMT_DSP_B] = -1},
++};
++
++static int __pcm3168a_set_dai_fmt(struct snd_soc_dai *dai,
+ unsigned int format, bool dac)
+ {
+ struct snd_soc_codec *codec = dai->codec;
+ struct pcm3168a_priv *pcm3168a = snd_soc_codec_get_drvdata(codec);
+- u32 fmt, reg, mask, shift;
++ u32 reg, mask, shift;
++ int fmt;
+ bool master_mode;
+
+- switch (format & SND_SOC_DAIFMT_FORMAT_MASK) {
+- case SND_SOC_DAIFMT_LEFT_J:
+- fmt = PCM3168A_FMT_LEFT_J;
+- break;
+- case SND_SOC_DAIFMT_I2S:
+- fmt = PCM3168A_FMT_I2S;
+- break;
+- case SND_SOC_DAIFMT_RIGHT_J:
+- fmt = PCM3168A_FMT_RIGHT_J;
+- break;
+- case SND_SOC_DAIFMT_DSP_A:
+- fmt = PCM3168A_FMT_DSP_A;
+- break;
+- case SND_SOC_DAIFMT_DSP_B:
+- fmt = PCM3168A_FMT_DSP_B;
+- break;
+- default:
+- dev_err(codec->dev, "unsupported dai format\n");
++ fmt = format_table[pcm3168a->tdm][format & SND_SOC_DAIFMT_FORMAT_MASK];
++
++ if (fmt < 0) {
++ dev_err(codec->dev, "unsupported dai format of TDM mode\n");
+ return -EINVAL;
+ }
+
+@@ -354,6 +375,16 @@ static int pcm3168a_set_dai_fmt(struct snd_soc_dai *dai,
+ return -EINVAL;
+ }
+
++ if ((pcm3168a->tdm == TDM_MODE_HS) && (master_mode)) {
++ dev_err(codec->dev, "TDM high speed supported only in slave mode\n");
++ return -EINVAL;
++ }
++
++ if ((pcm3168a->tdm == TDM_MODE_HS) && (!dac)) {
++ dev_err(codec->dev, "TDM high speed not supported for ADC\n");
++ return -EINVAL;
++ }
++
+ switch (format & SND_SOC_DAIFMT_INV_MASK) {
+ case SND_SOC_DAIFMT_NB_NF:
+ break;
+@@ -365,31 +396,32 @@ static int pcm3168a_set_dai_fmt(struct snd_soc_dai *dai,
+ reg = PCM3168A_DAC_PWR_MST_FMT;
+ mask = PCM3168A_DAC_FMT_MASK;
+ shift = PCM3168A_DAC_FMT_SHIFT;
+- pcm3168a->dac_master_mode = master_mode;
+ pcm3168a->dac_fmt = fmt;
+ } else {
+ reg = PCM3168A_ADC_MST_FMT;
+ mask = PCM3168A_ADC_FMTAD_MASK;
+ shift = PCM3168A_ADC_FMTAD_SHIFT;
+- pcm3168a->adc_master_mode = master_mode;
+ pcm3168a->adc_fmt = fmt;
+ }
+
++ pcm3168a->master_mode = master_mode;
++
+ regmap_update_bits(pcm3168a->regmap, reg, mask, fmt << shift);
+
+ return 0;
+ }
+
+-static int pcm3168a_set_dai_fmt_dac(struct snd_soc_dai *dai,
++static int pcm3168a_set_dai_fmt(struct snd_soc_dai *dai,
+ unsigned int format)
+ {
+- return pcm3168a_set_dai_fmt(dai, format, true);
+-}
++ int ret;
+
+-static int pcm3168a_set_dai_fmt_adc(struct snd_soc_dai *dai,
+- unsigned int format)
+-{
+- return pcm3168a_set_dai_fmt(dai, format, false);
++ /* dac */
++ ret = __pcm3168a_set_dai_fmt(dai, format, false);
++ if (ret)
++ return ret;
++ /* adc */
++ return __pcm3168a_set_dai_fmt(dai, format, true);
+ }
+
+ static int pcm3168a_hw_params(struct snd_pcm_substream *substream,
+@@ -398,127 +430,170 @@ static int pcm3168a_hw_params(struct snd_pcm_substream *substream,
+ {
+ struct snd_soc_codec *codec = dai->codec;
+ struct pcm3168a_priv *pcm3168a = snd_soc_codec_get_drvdata(codec);
+- bool tx, master_mode;
++ int bits;
++ bool tx;
+ u32 val, mask, shift, reg;
+- unsigned int rate, fmt, ratio, max_ratio;
++ u32 sample_rate = 0; /* auto */
++ unsigned int rate, channels, fmt, ratio, max_ratio;
+ int i, min_frame_size;
+ snd_pcm_format_t format;
+
+ rate = params_rate(params);
+ format = params_format(params);
+-
+- ratio = pcm3168a->sysclk / rate;
++ channels = params_channels(params);
++ bits = params->msbits;
+
+ tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
++
+ if (tx) {
+ max_ratio = PCM3168A_NUM_SCKI_RATIOS_DAC;
+- reg = PCM3168A_DAC_PWR_MST_FMT;
+- mask = PCM3168A_DAC_MSDA_MASK;
+- shift = PCM3168A_DAC_MSDA_SHIFT;
+- master_mode = pcm3168a->dac_master_mode;
+ fmt = pcm3168a->dac_fmt;
+ } else {
+ max_ratio = PCM3168A_NUM_SCKI_RATIOS_ADC;
+- reg = PCM3168A_ADC_MST_FMT;
+- mask = PCM3168A_ADC_MSAD_MASK;
+- shift = PCM3168A_ADC_MSAD_SHIFT;
+- master_mode = pcm3168a->adc_master_mode;
+ fmt = pcm3168a->adc_fmt;
+ }
+
+- for (i = 0; i < max_ratio; i++) {
+- if (pcm3168a_scki_ratios[i] == ratio)
+- break;
+- }
+-
+- if (i == max_ratio) {
+- dev_err(codec->dev, "unsupported sysclk ratio\n");
+- return -EINVAL;
+- }
++ if (pcm3168a->master_mode) {
++ ratio = pcm3168a->sysclk / rate;
++ for (i = 0; i < max_ratio; i++)
++ if (pcm3168a_scki_ratios[i] == ratio)
++ break;
+
+- min_frame_size = params_width(params) * 2;
+- switch (min_frame_size) {
+- case 32:
+- if (master_mode || (fmt != PCM3168A_FMT_RIGHT_J)) {
+- dev_err(codec->dev, "32-bit frames are supported only for slave mode using right justified\n");
++ if (i == max_ratio) {
++ dev_err(codec->dev, "unsupported sysclk ratio: %d\n", ratio);
+ return -EINVAL;
+ }
+- fmt = PCM3168A_FMT_RIGHT_J_16;
+- break;
+- case 48:
+- if (master_mode || (fmt & PCM3168A_FMT_DSP_MASK)) {
+- dev_err(codec->dev, "48-bit frames not supported in master mode, or slave mode using DSP\n");
+- return -EINVAL;
+- }
+- break;
+- case 64:
+- break;
+- default:
+- dev_err(codec->dev, "unsupported frame size: %d\n", min_frame_size);
+- return -EINVAL;
++ val = i + 1;
++ } else {
++ /* slave mode */
++ val = 0;
+ }
+
+- if (master_mode)
+- val = ((i + 1) << shift);
+- else
++ if (pcm3168a->tdm == TDM_MODE_NONE) {
++ /* one stereo frame size */
++ min_frame_size = bits * 2;
++ switch (min_frame_size) {
++ case 32:
++ if (pcm3168a->master_mode ||
++ (fmt != PCM3168A_FMT_RIGHT_J)) {
++ dev_err(codec->dev, "32-bit frames are supported only for slave mode using right justified\n");
++ return -EINVAL;
++ }
++ fmt = PCM3168A_FMT_RIGHT_J_16;
++ break;
++ case 48:
++ if (pcm3168a->master_mode ||
++ (fmt == PCM3168A_FMT_DSP_A) ||
++ (fmt == PCM3168A_FMT_DSP_B)) {
++ dev_err(codec->dev, "48-bit frames not supported in master mode, or slave mode using DSP\n");
++ return -EINVAL;
++ }
++ break;
++ case 64:
++ break;
++ default:
++ dev_err(codec->dev, "unsupported frame size: %d\n", min_frame_size);
++ return -EINVAL;
++ }
++ }
++ if ((pcm3168a->tdm == TDM_MODE_NORM) ||
++ (pcm3168a->tdm == TDM_MODE_HS)) {
++ /* all channels over one or two line */
++ min_frame_size = bits * channels;
++
++ /* single rate */
++ sample_rate = 1;
++
++ /*
++ * 256fs for single line DIN0/DOUT0
++ * 128fs for two lines DIN01/DOU01
++ */
++ if ((min_frame_size != 256) &&
++ (min_frame_size != 128)) {
++ dev_err(codec->dev, "256/128-bit frames only supported in TDM formats\n");
++ return -EINVAL;
++ }
++ }
++
++ /* Setup ADC in master mode, couse it drives ADC */
++ if ((pcm3168a->master_mode) || (tx)) {
++ fmt = pcm3168a->dac_fmt;
++ reg = PCM3168A_DAC_PWR_MST_FMT;
++ mask = PCM3168A_DAC_MSDA_MASK | PCM3168A_DAC_FMT_MASK;
++ shift = PCM3168A_DAC_MSDA_SHIFT;
++ /* start DAC */
++ regmap_update_bits(pcm3168a->regmap, reg, mask, (val << shift) | fmt);
++ }
++ /* Do we need also ADC? */
++ if (!tx) {
++ fmt = pcm3168a->adc_fmt;
++ reg = PCM3168A_ADC_MST_FMT;
++ mask = PCM3168A_ADC_MSAD_MASK | PCM3168A_ADC_FMTAD_MASK;
++ shift = PCM3168A_ADC_MSAD_SHIFT;
++ /* ADC slave mode only, driven by DAC or CPU DAI */
+ val = 0;
++ regmap_update_bits(pcm3168a->regmap, reg, mask, (val << shift) | fmt);
++ }
+
+- regmap_update_bits(pcm3168a->regmap, reg, mask, val);
++ regmap_update_bits(pcm3168a->regmap, PCM3168A_RST_SMODE,
++ PCM3168A_DAC_SRDA_MASK,
++ sample_rate << PCM3168A_DAC_SRDA_SHIFT);
+
+- if (tx) {
+- mask = PCM3168A_DAC_FMT_MASK;
+- shift = PCM3168A_DAC_FMT_SHIFT;
+- } else {
+- mask = PCM3168A_ADC_FMTAD_MASK;
+- shift = PCM3168A_ADC_FMTAD_SHIFT;
+- }
++ return 0;
++}
+
+- regmap_update_bits(pcm3168a->regmap, reg, mask, fmt << shift);
++static int pcm3168a_set_tdm_slot(struct snd_soc_dai *dai,
++ unsigned int tx_mask,
++ unsigned int rx_mask,
++ int slots,
++ int slot_width)
++{
++ struct snd_soc_codec *codec = dai->codec;
++ struct pcm3168a_priv *pcm3168a = snd_soc_codec_get_drvdata(codec);
++
++ if ((slots != 8) && (slots != 4))
++ return -EINVAL;
++
++ if ((slot_width != 32) && (slot_width != 24))
++ return -EINVAL;
++
++ pcm3168a->slots = slots;
++ pcm3168a->slot_width = slot_width;
+
+ return 0;
+ }
+
+-static const struct snd_soc_dai_ops pcm3168a_dac_dai_ops = {
+- .set_fmt = pcm3168a_set_dai_fmt_dac,
++static const struct snd_soc_dai_ops pcm3168a_dai_ops = {
++ .set_fmt = pcm3168a_set_dai_fmt,
+ .set_sysclk = pcm3168a_set_dai_sysclk,
++ .set_tdm_slot = pcm3168a_set_tdm_slot,
+ .hw_params = pcm3168a_hw_params,
+ .digital_mute = pcm3168a_digital_mute
+ };
+
+-static const struct snd_soc_dai_ops pcm3168a_adc_dai_ops = {
+- .set_fmt = pcm3168a_set_dai_fmt_adc,
+- .set_sysclk = pcm3168a_set_dai_sysclk,
+- .hw_params = pcm3168a_hw_params
+-};
+-
+-static struct snd_soc_dai_driver pcm3168a_dais[] = {
+- {
+- .name = "pcm3168a-dac",
+- .playback = {
+- .stream_name = "Playback",
+- .channels_min = 1,
+- .channels_max = 8,
+- .rates = SNDRV_PCM_RATE_8000_192000,
+- .formats = PCM3168A_FORMATS
+- },
+- .ops = &pcm3168a_dac_dai_ops
++static struct snd_soc_dai_driver pcm3168a_dai = {
++ .name = "pcm3168a",
++ .playback = {
++ .stream_name = "Playback",
++ .channels_min = 1,
++ .channels_max = 8,
++ .rates = SNDRV_PCM_RATE_8000_192000,
++ .formats = PCM3168A_FORMATS
+ },
+- {
+- .name = "pcm3168a-adc",
+- .capture = {
+- .stream_name = "Capture",
+- .channels_min = 1,
+- .channels_max = 6,
+- .rates = SNDRV_PCM_RATE_8000_96000,
+- .formats = PCM3168A_FORMATS
+- },
+- .ops = &pcm3168a_adc_dai_ops
++ .capture = {
++ .stream_name = "Capture",
++ .channels_min = 1,
++ .channels_max = 8,
++ .rates = SNDRV_PCM_RATE_8000_96000,
++ .formats = PCM3168A_FORMATS
+ },
++ .ops = &pcm3168a_dai_ops,
++ .symmetric_rates = 1,
+ };
+
+ static const struct reg_default pcm3168a_reg_default[] = {
+ { PCM3168A_RST_SMODE, PCM3168A_MRST_MASK | PCM3168A_SRST_MASK },
+- { PCM3168A_DAC_PWR_MST_FMT, 0x00 },
++ { PCM3168A_DAC_PWR_MST_FMT, 0x80 },
+ { PCM3168A_DAC_OP_FLT, 0x00 },
+ { PCM3168A_DAC_INV, 0x00 },
+ { PCM3168A_DAC_MUTE, 0x00 },
+@@ -665,12 +740,25 @@ int pcm3168a_probe(struct device *dev, struct regmap *regmap)
+ goto err_regulator;
+ }
+
++ /* get TDM mode */
++ if (dev->of_node) {
++ if (of_get_property(dev->of_node, "tdm", NULL))
++ pcm3168a->tdm = TDM_MODE_NORM;
++ else if (of_get_property(dev->of_node, "tdmhs", NULL))
++ pcm3168a->tdm = TDM_MODE_HS;
++ }
++
+ pm_runtime_set_active(dev);
+ pm_runtime_enable(dev);
+ pm_runtime_idle(dev);
+
+- ret = snd_soc_register_codec(dev, &pcm3168a_driver, pcm3168a_dais,
+- ARRAY_SIZE(pcm3168a_dais));
++ if (pcm3168a->tdm != TDM_MODE_NONE) {
++ pcm3168a_dai.playback.channels_min = 8;
++ pcm3168a_dai.capture.channels_min = 8;
++ }
++
++ ret = snd_soc_register_codec(dev, &pcm3168a_driver,
++ &pcm3168a_dai, 1);
+ if (ret) {
+ dev_err(dev, "failed to register codec: %d\n", ret);
+ goto err_regulator;
+diff --git a/sound/soc/codecs/pcm3168a.h b/sound/soc/codecs/pcm3168a.h
+index 56c8332d82fb..658507f86c97 100644
+--- a/sound/soc/codecs/pcm3168a.h
++++ b/sound/soc/codecs/pcm3168a.h
+@@ -69,7 +69,7 @@ extern void pcm3168a_remove(struct device *dev);
+ #define PCM3168A_ADC_MSAD_SHIFT 4
+ #define PCM3168A_ADC_MSAD_MASK 0x70
+ #define PCM3168A_ADC_FMTAD_SHIFT 0
+-#define PCM3168A_ADC_FMTAD_MASK 0x7
++#define PCM3168A_ADC_FMTAD_MASK 0xf
+
+ #define PCM3168A_ADC_PWR_HPFB 0x52
+ #define PCM3168A_ADC_PSVAD_SHIFT 4
+--
+2.13.0
+
diff --git a/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0064-ADV7511-limit-maximum-pixelclock.patch b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0064-ADV7511-limit-maximum-pixelclock.patch
new file mode 100644
index 0000000..3ca9284
--- /dev/null
+++ b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0064-ADV7511-limit-maximum-pixelclock.patch
@@ -0,0 +1,76 @@
+From 1df040dabaec1697f81b71f15739b499f3e4266e Mon Sep 17 00:00:00 2001
+From: Andrey Gusakov <andrey.gusakov@cogentembedded.com>
+Date: Fri, 9 Jun 2017 20:12:26 +0300
+Subject: [PATCH] ADV7511: limit maximum pixelclock
+
+DU0 (RGB) supports clock freq up to 100MHz only.
+Add ability to set max clock via dts.
+
+Signed-off-by: Andrey Gusakov <andrey.gusakov@cogentembedded.com>
+---
+ drivers/gpu/drm/bridge/adv7511/adv7511.h | 3 +++
+ drivers/gpu/drm/bridge/adv7511/adv7511_drv.c | 6 +++++-
+ 2 files changed, 8 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/gpu/drm/bridge/adv7511/adv7511.h b/drivers/gpu/drm/bridge/adv7511/adv7511.h
+index 161c923..12ee238 100644
+--- a/drivers/gpu/drm/bridge/adv7511/adv7511.h
++++ b/drivers/gpu/drm/bridge/adv7511/adv7511.h
+@@ -242,6 +242,7 @@ enum adv7511_sync_polarity {
+ * @input_style: The input component arrangement variant
+ * @input_justification: Video input format bit justification
+ * @clock_delay: Clock delay for the input clock (in ps)
++ * @clock_max_rate: Clock maximum rate (in Hz)
+ * @embedded_sync: Video input uses BT.656-style embedded sync
+ * @sync_pulse: Select the sync pulse
+ * @vsync_polarity: vsync input signal configuration
+@@ -255,6 +256,7 @@ struct adv7511_link_config {
+ enum adv7511_input_justification input_justification;
+
+ int clock_delay;
++ int clock_max_rate;
+
+ bool embedded_sync;
+ enum adv7511_input_sync_pulse sync_pulse;
+@@ -307,6 +309,7 @@ struct adv7511 {
+ bool powered;
+
+ struct drm_display_mode curr_mode;
++ int clock_max_rate;
+
+ unsigned int f_tmds;
+
+diff --git a/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c b/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c
+index 41b45de..5dfa619 100644
+--- a/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c
++++ b/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c
+@@ -323,6 +323,7 @@ static void adv7511_set_link_config(struct adv7511 *adv7511,
+ adv7511->hsync_polarity = config->hsync_polarity;
+ adv7511->vsync_polarity = config->vsync_polarity;
+ adv7511->rgb = config->input_colorspace == HDMI_COLORSPACE_RGB;
++ adv7511->clock_max_rate = config->clock_max_rate;
+ }
+
+ static void adv7511_power_on(struct adv7511 *adv7511)
+@@ -621,7 +622,7 @@ static int adv7511_get_modes(struct adv7511 *adv7511,
+ static int adv7511_mode_valid(struct adv7511 *adv7511,
+ struct drm_display_mode *mode)
+ {
+- if (mode->clock > 165000)
++ if (mode->clock > adv7511->clock_max_rate)
+ return MODE_CLOCK_HIGH;
+
+ return MODE_OK;
+@@ -917,6 +918,9 @@ static int adv7511_parse_dt(struct device_node *np,
+ if (config->clock_delay < -1200 || config->clock_delay > 1600)
+ return -EINVAL;
+
++ if (of_property_read_u32(np, "adi,clock-max-rate", &config->clock_max_rate))
++ config->clock_max_rate = 166000;
++
+ config->embedded_sync = of_property_read_bool(np, "adi,embedded-sync");
+
+ /* Hardcode the sync pulse configurations for now. */
+--
+1.9.1
+
diff --git a/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0066-pci-pcie-rcar-add-regulators-support.patch b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0066-pci-pcie-rcar-add-regulators-support.patch
new file mode 100644
index 0000000..2a9a2a0
--- /dev/null
+++ b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0066-pci-pcie-rcar-add-regulators-support.patch
@@ -0,0 +1,107 @@
+From d5a3dee65f4ee9d320128bbf79df80d51aec7687 Mon Sep 17 00:00:00 2001
+From: Andrey Gusakov <andrey.gusakov@cogentembedded.com>
+Date: Mon, 24 Jul 2017 20:22:03 +0300
+Subject: [PATCH] pci: pcie-rcar: add regulators support
+
+Add PCIE regulators
+
+Signed-off-by: Andrey Gusakov <andrey.gusakov@cogentembedded.com>
+---
+ drivers/pci/host/pcie-rcar.c | 54 ++++++++++++++++++++++++++++++++++++++++++++
+ 1 file changed, 54 insertions(+)
+
+diff --git a/drivers/pci/host/pcie-rcar.c b/drivers/pci/host/pcie-rcar.c
+index 8e24d5f88415..6994ea2ac936 100644
+--- a/drivers/pci/host/pcie-rcar.c
++++ b/drivers/pci/host/pcie-rcar.c
+@@ -16,6 +16,7 @@
+
+ #include <linux/clk.h>
+ #include <linux/delay.h>
++#include <linux/regulator/consumer.h>
+ #include <linux/interrupt.h>
+ #include <linux/irq.h>
+ #include <linux/irqdomain.h>
+@@ -155,6 +156,8 @@ struct rcar_pcie {
+ int root_bus_nr;
+ struct clk *clk;
+ struct clk *bus_clk;
++ struct regulator *pcie3v3; /* 3.3V power supply */
++ struct regulator *pcie1v8; /* 1.8V power supply */
+ struct rcar_msi msi;
+ };
+
+@@ -1193,6 +1196,36 @@ static int rcar_pcie_parse_request_of_pci_ranges(struct rcar_pcie *pci)
+ return err;
+ }
+
++static int rcar_pcie_set_vpcie(struct rcar_pcie *pcie)
++{
++ struct device *dev = pcie->dev;
++ int err;
++
++ if (!IS_ERR(pcie->pcie3v3)) {
++ err = regulator_enable(pcie->pcie3v3);
++ if (err) {
++ dev_err(dev, "fail to enable vpcie3v3 regulator\n");
++ goto err_out;
++ }
++ }
++
++ if (!IS_ERR(pcie->pcie1v8)) {
++ err = regulator_enable(pcie->pcie1v8);
++ if (err) {
++ dev_err(dev, "fail to enable vpcie1v8 regulator\n");
++ goto err_disable_3v3;
++ }
++ }
++
++ return 0;
++
++err_disable_3v3:
++ if (!IS_ERR(pcie->pcie3v3))
++ regulator_disable(pcie->pcie3v3);
++err_out:
++ return err;
++}
++
+ static int rcar_pcie_probe(struct platform_device *pdev)
+ {
+ struct device *dev = &pdev->dev;
+@@ -1209,6 +1242,26 @@ static int rcar_pcie_probe(struct platform_device *pdev)
+ pcie->dev = dev;
+ platform_set_drvdata(pdev, pcie);
+
++ pcie->pcie3v3 = devm_regulator_get_optional(dev, "pcie3v3");
++ if (IS_ERR(pcie->pcie3v3)) {
++ if (PTR_ERR(pcie->pcie3v3) == -EPROBE_DEFER)
++ return -EPROBE_DEFER;
++ dev_info(dev, "no pcie3v3 regulator found\n");
++ }
++
++ pcie->pcie1v8 = devm_regulator_get_optional(dev, "pcie1v8");
++ if (IS_ERR(pcie->pcie1v8)) {
++ if (PTR_ERR(pcie->pcie1v8) == -EPROBE_DEFER)
++ return -EPROBE_DEFER;
++ dev_info(dev, "no pcie1v8 regulator found\n");
++ }
++
++ err = rcar_pcie_set_vpcie(pcie);
++ if (err) {
++ dev_err(dev, "failed to set pcie regulators\n");
++ goto err_set_pcie;
++ }
++
+ INIT_LIST_HEAD(&pcie->resources);
+
+ rcar_pcie_parse_request_of_pci_ranges(pcie);
+@@ -1267,6 +1320,7 @@ static int rcar_pcie_probe(struct platform_device *pdev)
+
+ err_pm_disable:
+ pm_runtime_disable(dev);
++err_set_pcie:
+ return err;
+ }
+
+--
+2.13.0
diff --git a/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0067-ti-st-use-proper-way-to-get-shutdown-gpio.patch b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0067-ti-st-use-proper-way-to-get-shutdown-gpio.patch
new file mode 100644
index 0000000..4d99054
--- /dev/null
+++ b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0067-ti-st-use-proper-way-to-get-shutdown-gpio.patch
@@ -0,0 +1,61 @@
+From 36a9b5317c58a1cdcb8a6fa05416efd524480fbe Mon Sep 17 00:00:00 2001
+From: Andrey Gusakov <andrey.gusakov@cogentembedded.com>
+Date: Wed, 2 Aug 2017 17:39:56 +0300
+Subject: [PATCH] ti-st: use proper way to get shutdown gpio
+
+Signed-off-by: Andrey Gusakov <andrey.gusakov@cogentembedded.com>
+---
+ drivers/misc/ti-st/st_kim.c | 23 ++++++++++++++++++-----
+ 1 file changed, 18 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/misc/ti-st/st_kim.c b/drivers/misc/ti-st/st_kim.c
+index cb2734568471..03b21d314b0b 100644
+--- a/drivers/misc/ti-st/st_kim.c
++++ b/drivers/misc/ti-st/st_kim.c
+@@ -32,6 +32,8 @@
+ #include <linux/sched.h>
+ #include <linux/sysfs.h>
+ #include <linux/tty.h>
++#include <linux/of_device.h>
++#include <linux/of_gpio.h>
+
+ #include <linux/skbuff.h>
+ #include <linux/ti_wilink_st.h>
+@@ -749,18 +751,29 @@ static struct ti_st_plat_data *get_platform_data(struct device *dev)
+
+ dt_pdata = kzalloc(sizeof(*dt_pdata), GFP_KERNEL);
+
+- if (!dt_pdata)
++ if (!dt_pdata) {
+ pr_err("Can't allocate device_tree platform data\n");
++ return NULL;
++ }
+
+ dt_property = of_get_property(np, "dev_name", &len);
+- if (dt_property)
+- memcpy(&dt_pdata->dev_name, dt_property, len);
+- of_property_read_u32(np, "nshutdown_gpio",
+- (u32 *)&dt_pdata->nshutdown_gpio);
++ if (!dt_property) {
++ dev_err(dev, "failed to get tty name\n");
++ goto err;
++ }
++ memcpy(&dt_pdata->dev_name, dt_property, len);
++ dt_pdata->nshutdown_gpio = of_get_named_gpio(np, "shutdown-gpios", 0);
++ if (!gpio_is_valid(dt_pdata->nshutdown_gpio)) {
++ dev_err(dev, "failed to get shutdown gpio\n");
++ goto err;
++ }
+ of_property_read_u32(np, "flow_cntrl", (u32 *)&dt_pdata->flow_cntrl);
+ of_property_read_u32(np, "baud_rate", (u32 *)&dt_pdata->baud_rate);
+
+ return dt_pdata;
++err:
++ kfree(dt_pdata);
++ return NULL;
+ }
+
+ static struct dentry *kim_debugfs_dir;
+--
+2.13.0
+
diff --git a/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0068-drm-adv7511-use-smbus-to-retrieve-edid.patch b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0068-drm-adv7511-use-smbus-to-retrieve-edid.patch
new file mode 100644
index 0000000..1b4dbd8
--- /dev/null
+++ b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0068-drm-adv7511-use-smbus-to-retrieve-edid.patch
@@ -0,0 +1,53 @@
+From 2e2b673a2a47e8358ef92ec4019be87552949304 Mon Sep 17 00:00:00 2001
+From: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+Date: Wed, 9 Aug 2017 11:52:22 +0300
+Subject: [PATCH] drm: adv7511: use smbus to retrieve edid
+
+Get EDID using smbus protocol instead block i2c transfer
+This fixes often checksum errors while retriving EDID at 400kHz bus speed
+
+Signed-off-by: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+---
+ drivers/gpu/drm/bridge/adv7511/adv7511_drv.c | 9 +++++----
+ 1 file changed, 5 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c b/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c
+index d3ece87..b2e1b58 100644
+--- a/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c
++++ b/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c
+@@ -500,18 +500,19 @@ static int adv7511_get_edid_block(void *data, u8 *buf, unsigned int block,
+ * support 64 byte transfers than 256 byte transfers
+ */
+
++#define CHUNK_SIZE 1
+ xfer[0].addr = adv7511->i2c_edid->addr;
+ xfer[0].flags = 0;
+ xfer[0].len = 1;
+ xfer[0].buf = &offset;
+ xfer[1].addr = adv7511->i2c_edid->addr;
+ xfer[1].flags = I2C_M_RD;
+- xfer[1].len = 64;
++ xfer[1].len = CHUNK_SIZE;
+ xfer[1].buf = adv7511->edid_buf;
+
+ offset = 0;
+
+- for (i = 0; i < 4; ++i) {
++ for (i = 0; i < 256/CHUNK_SIZE; ++i) {
+ ret = i2c_transfer(adv7511->i2c_edid->adapter, xfer,
+ ARRAY_SIZE(xfer));
+ if (ret < 0)
+@@ -519,8 +520,8 @@ static int adv7511_get_edid_block(void *data, u8 *buf, unsigned int block,
+ else if (ret != 2)
+ return -EIO;
+
+- xfer[1].buf += 64;
+- offset += 64;
++ xfer[1].buf += CHUNK_SIZE;
++ offset += CHUNK_SIZE;
+ }
+
+ adv7511->current_edid_segment = block / 2;
+--
+1.9.1
+
diff --git a/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0070-clk-clk-5p49x-add-5P49V5925-chip.patch b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0070-clk-clk-5p49x-add-5P49V5925-chip.patch
new file mode 100644
index 0000000..0608eca
--- /dev/null
+++ b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0070-clk-clk-5p49x-add-5P49V5925-chip.patch
@@ -0,0 +1,49 @@
+From d9e198a198e8892ac7e1e2636f55207757ee505a Mon Sep 17 00:00:00 2001
+From: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+Date: Thu, 10 Aug 2017 08:46:54 +0300
+Subject: [PATCH] clk: clk-5p49x: add 5P49V5925 chip
+
+Add 5P49V5925 chip
+
+Signed-off-by: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+---
+ drivers/clk/clk-5p49x.c | 9 +++++++++
+ 1 file changed, 9 insertions(+)
+
+diff --git a/drivers/clk/clk-5p49x.c b/drivers/clk/clk-5p49x.c
+index 928bacb..8070154 100644
+--- a/drivers/clk/clk-5p49x.c
++++ b/drivers/clk/clk-5p49x.c
+@@ -60,6 +60,10 @@ struct clk_5p49_priv {
+ .xtal_fre = 25000000,
+ };
+
++static const struct clk_5p49_info clk_5p49v5925 = {
++ .xtal_fre = 25000000,
++};
++
+ static const struct clk_5p49_info clk_5p49v6901a = {
+ .xtal_fre = 50000000,
+ };
+@@ -70,6 +74,10 @@ struct clk_5p49_priv {
+ .data = &clk_5p49v5923a,
+ },
+ {
++ .compatible = "idt,5p49v5925",
++ .data = &clk_5p49v5925,
++ },
++ {
+ .compatible = "idt,5p49v6901a",
+ .data = &clk_5p49v6901a,
+ },
+@@ -79,6 +87,7 @@ struct clk_5p49_priv {
+
+ static const struct i2c_device_id clk_5p49_id[] = {
+ { "5p49v5923a",},
++ { "5p49v5925",},
+ { "5p49v6901a",},
+ {}
+ };
+--
+1.9.1
+
diff --git a/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0071-ASoC-add-dummy-device-for-WL18xx-PCM-audio.patch b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0071-ASoC-add-dummy-device-for-WL18xx-PCM-audio.patch
new file mode 100644
index 0000000..9ebca61
--- /dev/null
+++ b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0071-ASoC-add-dummy-device-for-WL18xx-PCM-audio.patch
@@ -0,0 +1,128 @@
+From 81ddd8a5dbf200938ef70efaa9254742f49d3034 Mon Sep 17 00:00:00 2001
+From: Andrey Gusakov <andrey.gusakov@cogentembedded.com>
+Date: Thu, 10 Aug 2017 16:29:01 +0300
+Subject: [PATCH] ASoC: add dummy device for WL18xx PCM audio
+
+Signed-off-by: Andrey Gusakov <andrey.gusakov@cogentembedded.com>
+---
+ sound/soc/codecs/Kconfig | 3 ++
+ sound/soc/codecs/Makefile | 2 ++
+ sound/soc/codecs/wl18xx.c | 72 +++++++++++++++++++++++++++++++++++++++++++++++
+ 3 files changed, 77 insertions(+)
+ create mode 100644 sound/soc/codecs/wl18xx.c
+
+diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig
+index 140f1597966a..6658d05f1648 100644
+--- a/sound/soc/codecs/Kconfig
++++ b/sound/soc/codecs/Kconfig
+@@ -625,6 +625,9 @@ config SND_SOC_PCM3168A_SPI
+ config SND_SOC_SI468X
+ tristate "Dummy sound driver for Si468x radio"
+
++config SND_SOC_WL18XX
++ tristate "Dummy sound driver for WL18xx BT"
++
+ config SND_SOC_PCM5102A
+ tristate
+
+diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile
+index 8e02341428d8..17fd313489de 100644
+--- a/sound/soc/codecs/Makefile
++++ b/sound/soc/codecs/Makefile
+@@ -126,6 +126,7 @@ snd-soc-sigmadsp-i2c-objs := sigmadsp-i2c.o
+ snd-soc-sigmadsp-regmap-objs := sigmadsp-regmap.o
+ snd-soc-si476x-objs := si476x.o
+ snd-soc-si468x-objs := si468x.o
++snd-soc-wl18xx-objs := wl18xx.o
+ snd-soc-sirf-audio-codec-objs := sirf-audio-codec.o
+ snd-soc-sn95031-objs := sn95031.o
+ snd-soc-spdif-tx-objs := spdif_transmitter.o
+@@ -349,6 +350,7 @@ obj-$(CONFIG_SND_SOC_SIGMADSP_I2C) += snd-soc-sigmadsp-i2c.o
+ obj-$(CONFIG_SND_SOC_SIGMADSP_REGMAP) += snd-soc-sigmadsp-regmap.o
+ obj-$(CONFIG_SND_SOC_SI476X) += snd-soc-si476x.o
+ obj-$(CONFIG_SND_SOC_SI468X) += snd-soc-si468x.o
++obj-$(CONFIG_SND_SOC_WL18XX) += snd-soc-wl18xx.o
+ obj-$(CONFIG_SND_SOC_SN95031) +=snd-soc-sn95031.o
+ obj-$(CONFIG_SND_SOC_SPDIF) += snd-soc-spdif-rx.o snd-soc-spdif-tx.o
+ obj-$(CONFIG_SND_SOC_SSM2518) += snd-soc-ssm2518.o
+diff --git a/sound/soc/codecs/wl18xx.c b/sound/soc/codecs/wl18xx.c
+new file mode 100644
+index 000000000000..50ebbd4c0013
+--- /dev/null
++++ b/sound/soc/codecs/wl18xx.c
+@@ -0,0 +1,72 @@
++/*
++ * Dummy sound driver for wl18xx BT modules
++ * Copyright 2016 Andrey Gusakov <andrey.gusakov@cogentembedded.com>
++ *
++ * Based on: Driver for the DFBM-CS320 bluetooth module
++ * Copyright 2011 Lars-Peter Clausen <lars@metafoo.de>
++ *
++ * This program is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License as published by the
++ * Free Software Foundation; either version 2 of the License, or (at your
++ * option) any later version.
++ *
++ */
++
++#include <linux/init.h>
++#include <linux/module.h>
++#include <linux/platform_device.h>
++
++#include <sound/soc.h>
++
++static struct snd_soc_dai_driver wl18xx_dai = {
++ .name = "wl18xx-pcm",
++ .capture = {
++ .channels_min = 2,
++ .channels_max = 2,
++ .rates = SNDRV_PCM_RATE_8000,
++ .formats = SNDRV_PCM_FMTBIT_S16_LE,
++ },
++ .playback = {
++ .channels_min = 2,
++ .channels_max = 2,
++ .rates = SNDRV_PCM_RATE_8000,
++ .formats = SNDRV_PCM_FMTBIT_S16_LE,
++ },
++};
++
++static struct snd_soc_codec_driver soc_codec_dev_wl18xx;
++
++static int wl18xx_probe(struct platform_device *pdev)
++{
++ return snd_soc_register_codec(&pdev->dev, &soc_codec_dev_wl18xx,
++ &wl18xx_dai, 1);
++}
++
++static int wl18xx_remove(struct platform_device *pdev)
++{
++ snd_soc_unregister_codec(&pdev->dev);
++
++ return 0;
++}
++
++static const struct of_device_id wl18xx_of_match[] = {
++ { .compatible = "ti,wl18xx-pcm", },
++ { }
++};
++MODULE_DEVICE_TABLE(of, wl18xx_of_match);
++
++static struct platform_driver wl18xx_driver = {
++ .driver = {
++ .name = "wl18xx-codec",
++ .of_match_table = wl18xx_of_match,
++ .owner = THIS_MODULE,
++ },
++ .probe = wl18xx_probe,
++ .remove = wl18xx_remove,
++};
++
++module_platform_driver(wl18xx_driver);
++
++MODULE_AUTHOR("Andrey Gusakov <andrey.gusakov@cogentembedded.com>");
++MODULE_DESCRIPTION("ASoC wl18xx driver");
++MODULE_LICENSE("GPL");
+--
+2.13.0
+
diff --git a/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0072-usb-hub-disable-autosuspend-for-SMSC-hubs.patch b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0072-usb-hub-disable-autosuspend-for-SMSC-hubs.patch
new file mode 100644
index 0000000..4989e05
--- /dev/null
+++ b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0072-usb-hub-disable-autosuspend-for-SMSC-hubs.patch
@@ -0,0 +1,51 @@
+From 8276db72581e4d1e3f89ccce84555c9fea145e16 Mon Sep 17 00:00:00 2001
+From: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+Date: Fri, 11 Aug 2017 17:30:40 +0300
+Subject: [PATCH] usb: hub: disable autosuspend for SMSC hubs
+
+Disable autosuspend for SMSC hubs (USB5534B/USB2134B devices)
+This is a workaround for RCar Gen3 XHCI
+
+Signed-off-by: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+---
+ drivers/usb/core/hub.c | 9 +++++++++
+ 1 file changed, 9 insertions(+)
+
+diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
+index cbb1467..2c4c006 100644
+--- a/drivers/usb/core/hub.c
++++ b/drivers/usb/core/hub.c
+@@ -34,7 +34,9 @@
+ #include "otg_whitelist.h"
+
+ #define USB_VENDOR_GENESYS_LOGIC 0x05e3
++#define USB_VENDOR_SMSC 0x0424
+ #define HUB_QUIRK_CHECK_PORT_AUTOSUSPEND 0x01
++#define HUB_QUIRK_DISABLE_AUTOSUSPEND 0x02
+
+ /* Protect struct usb_device->state and ->children members
+ * Note: Both are also protected by ->dev.sem, except that ->state can
+@@ -1845,6 +1847,9 @@ static int hub_probe(struct usb_interface *intf, const struct usb_device_id *id)
+ if (id->driver_info & HUB_QUIRK_CHECK_PORT_AUTOSUSPEND)
+ hub->quirk_check_port_auto_suspend = 1;
+
++ if (id->driver_info & HUB_QUIRK_DISABLE_AUTOSUSPEND)
++ pm_runtime_set_autosuspend_delay(&hdev->dev, -1);
++
+ if (hub_configure(hub, endpoint) >= 0)
+ return 0;
+
+@@ -5226,6 +5231,10 @@ static void hub_event(struct work_struct *work)
+ }
+
+ static const struct usb_device_id hub_id_table[] = {
++ { .match_flags = USB_DEVICE_ID_MATCH_VENDOR | USB_DEVICE_ID_MATCH_INT_CLASS,
++ .idVendor = USB_VENDOR_SMSC,
++ .bInterfaceClass = USB_CLASS_HUB,
++ .driver_info = HUB_QUIRK_DISABLE_AUTOSUSPEND},
+ { .match_flags = USB_DEVICE_ID_MATCH_VENDOR
+ | USB_DEVICE_ID_MATCH_INT_CLASS,
+ .idVendor = USB_VENDOR_GENESYS_LOGIC,
+--
+1.9.1
+
diff --git a/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0073-MOST-dim2-add-device-tree-support.patch b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0073-MOST-dim2-add-device-tree-support.patch
new file mode 100644
index 0000000..b3e2e0b
--- /dev/null
+++ b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0073-MOST-dim2-add-device-tree-support.patch
@@ -0,0 +1,169 @@
+From cc64770782e6bb01b2d8b76c1731a28d5d06d135 Mon Sep 17 00:00:00 2001
+From: Andrey Gusakov <andrey.gusakov@cogentembedded.com>
+Date: Fri, 7 Jul 2017 20:42:36 +0300
+Subject: [PATCH] MOST: dim2: add device tree support
+
+Signed-off-by: Andrey Gusakov <andrey.gusakov@cogentembedded.com>
+---
+ drivers/staging/most/hdm-dim2/dim2_hdm.c | 72 ++++++++++++++++++++++----------
+ 1 file changed, 50 insertions(+), 22 deletions(-)
+
+diff --git a/drivers/staging/most/hdm-dim2/dim2_hdm.c b/drivers/staging/most/hdm-dim2/dim2_hdm.c
+index a36449551513..f28f169180fe 100644
+--- a/drivers/staging/most/hdm-dim2/dim2_hdm.c
++++ b/drivers/staging/most/hdm-dim2/dim2_hdm.c
+@@ -14,6 +14,7 @@
+ #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+ #include <linux/module.h>
++#include <linux/of_platform.h>
+ #include <linux/printk.h>
+ #include <linux/kernel.h>
+ #include <linux/init.h>
+@@ -21,6 +22,7 @@
+ #include <linux/interrupt.h>
+ #include <linux/slab.h>
+ #include <linux/io.h>
++#include <linux/clk.h>
+ #include <linux/dma-mapping.h>
+ #include <linux/sched.h>
+ #include <linux/kthread.h>
+@@ -101,6 +103,7 @@ struct dim2_hdm {
+ struct most_interface most_iface;
+ char name[16 + sizeof "dim2-"];
+ void __iomem *io_base;
++ struct clk *clk;
+ int clk_speed;
+ struct task_struct *netinfo_task;
+ wait_queue_head_t netinfo_waitq;
+@@ -165,6 +168,27 @@ void dimcb_on_error(u8 error_id, const char *error_message)
+ error_message);
+ }
+
++static int dim_parce_speed(const char *clock_speed)
++{
++ if (!strcmp(clock_speed, "256fs"))
++ return CLK_256FS;
++ else if (!strcmp(clock_speed, "512fs"))
++ return CLK_512FS;
++ else if (!strcmp(clock_speed, "1024fs"))
++ return CLK_1024FS;
++ else if (!strcmp(clock_speed, "2048fs"))
++ return CLK_2048FS;
++ else if (!strcmp(clock_speed, "3072fs"))
++ return CLK_3072FS;
++ else if (!strcmp(clock_speed, "4096fs"))
++ return CLK_4096FS;
++ else if (!strcmp(clock_speed, "6144fs"))
++ return CLK_6144FS;
++ else if (!strcmp(clock_speed, "8192fs"))
++ return CLK_8192FS;
++ return -1;
++}
++
+ /**
+ * startup_dim - initialize the dim2 interface
+ * @pdev: platform device
+@@ -178,32 +202,12 @@ static int startup_dim(struct platform_device *pdev)
+ struct dim2_platform_data *pdata = pdev->dev.platform_data;
+ u8 hal_ret;
+
+- dev->clk_speed = -1;
+-
+- if (clock_speed) {
+- if (!strcmp(clock_speed, "256fs"))
+- dev->clk_speed = CLK_256FS;
+- else if (!strcmp(clock_speed, "512fs"))
+- dev->clk_speed = CLK_512FS;
+- else if (!strcmp(clock_speed, "1024fs"))
+- dev->clk_speed = CLK_1024FS;
+- else if (!strcmp(clock_speed, "2048fs"))
+- dev->clk_speed = CLK_2048FS;
+- else if (!strcmp(clock_speed, "3072fs"))
+- dev->clk_speed = CLK_3072FS;
+- else if (!strcmp(clock_speed, "4096fs"))
+- dev->clk_speed = CLK_4096FS;
+- else if (!strcmp(clock_speed, "6144fs"))
+- dev->clk_speed = CLK_6144FS;
+- else if (!strcmp(clock_speed, "8192fs"))
+- dev->clk_speed = CLK_8192FS;
+- }
++ if (clock_speed)
++ dev->clk_speed = dim_parce_speed(clock_speed);
+
+ if (dev->clk_speed == -1) {
+ pr_info("Bad or missing clock speed parameter, using default value: 3072fs\n");
+ dev->clk_speed = CLK_3072FS;
+- } else {
+- pr_info("Selected clock speed: %s\n", clock_speed);
+ }
+ if (pdata && pdata->init) {
+ int ret = pdata->init(pdata, dev->io_base, dev->clk_speed);
+@@ -735,6 +739,7 @@ static int dim2_probe(struct platform_device *pdev)
+ int ret, i;
+ struct kobject *kobj;
+ int irq;
++ struct device_node *np = pdev->dev.of_node;
+
+ dev = devm_kzalloc(&pdev->dev, sizeof(*dev), GFP_KERNEL);
+ if (!dev)
+@@ -765,6 +770,14 @@ static int dim2_probe(struct platform_device *pdev)
+ dev_err(&pdev->dev, "failed to request mlb_int irq %d\n", irq);
+ return ret;
+ }
++
++ dev->clk = devm_clk_get(&pdev->dev, NULL);
++ if (IS_ERR(dev->clk)) {
++ dev_err(&pdev->dev, "cannot get clock\n");
++ ret = PTR_ERR(dev->clk);
++ return ret;
++ }
++ clk_prepare_enable(dev->clk);
+
+ init_waitqueue_head(&dev->netinfo_waitq);
+ dev->deliver_netinfo = 0;
+@@ -814,6 +827,12 @@ static int dim2_probe(struct platform_device *pdev)
+ dev->most_iface.poison_channel = poison_channel;
+ dev->most_iface.request_netinfo = request_netinfo;
+
++ if (np) {
++ const char *tmp;
++ if (!of_property_read_string(np, "clock-speed", &tmp))
++ dev->clk_speed = dim_parce_speed(tmp);
++ }
++
+ kobj = most_register_interface(&dev->most_iface);
+ if (IS_ERR(kobj)) {
+ ret = PTR_ERR(kobj);
+@@ -866,6 +885,8 @@ static int dim2_remove(struct platform_device *pdev)
+ most_deregister_interface(&dev->most_iface);
+ kthread_stop(dev->netinfo_task);
+
++ clk_disable_unprepare(dev->clk);
++
+ /*
+ * break link to local platform_device_id struct
+ * to prevent crash by unload platform device module
+@@ -882,12 +903,19 @@ static struct platform_device_id dim2_id[] = {
+
+ MODULE_DEVICE_TABLE(platform, dim2_id);
+
++static const struct of_device_id dim2_of_match[] = {
++ { .compatible = "rcar,medialb-dim2", },
++ {},
++};
++MODULE_DEVICE_TABLE(of, dim2_of_match);
++
+ static struct platform_driver dim2_driver = {
+ .probe = dim2_probe,
+ .remove = dim2_remove,
+ .id_table = dim2_id,
+ .driver = {
+ .name = "hdm_dim2",
++ .of_match_table = dim2_of_match,
+ },
+ };
+
+--
+2.13.0
+
diff --git a/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0074-MOST-dim2-add-R-Car3-related-initialization.patch b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0074-MOST-dim2-add-R-Car3-related-initialization.patch
new file mode 100644
index 0000000..572da2a
--- /dev/null
+++ b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0074-MOST-dim2-add-R-Car3-related-initialization.patch
@@ -0,0 +1,63 @@
+From 41d15fa6003b65080f05d271bf495104013754f9 Mon Sep 17 00:00:00 2001
+From: Andrey Gusakov <andrey.gusakov@cogentembedded.com>
+Date: Fri, 7 Jul 2017 20:43:33 +0300
+Subject: [PATCH 112/114] MOST: dim2: add R-Car3 related initialization
+
+Signed-off-by: Andrey Gusakov <andrey.gusakov@cogentembedded.com>
+---
+ drivers/staging/most/hdm-dim2/dim2_hdm.c | 28 +++++++++++++++++++++++++++-
+ 1 file changed, 27 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/staging/most/hdm-dim2/dim2_hdm.c b/drivers/staging/most/hdm-dim2/dim2_hdm.c
+index f28f169180fe..c1beabc28fa8 100644
+--- a/drivers/staging/most/hdm-dim2/dim2_hdm.c
++++ b/drivers/staging/most/hdm-dim2/dim2_hdm.c
+@@ -26,6 +26,7 @@
+ #include <linux/dma-mapping.h>
+ #include <linux/sched.h>
+ #include <linux/kthread.h>
++#include <linux/delay.h>
+
+ #include <mostcore.h>
+ #include <networking.h>
+@@ -189,6 +191,26 @@ static int dim_parce_speed(const char *clock_speed)
+ return -1;
+ }
+
++static int dim_rcar_init(struct dim2_hdm *dev)
++{
++ /* PLL */
++ __raw_writel(0x04, dev->io_base + 0x600);
++
++ /* 512FS Enable Register */
++ if (dev->clk_speed == CLK_512FS)
++ __raw_writel(0x01, dev->io_base + 0x604);
++ else
++ __raw_writel(0x00, dev->io_base + 0x604);
++
++ udelay(200);
++
++ /* BBCR = 0b11 */
++ __raw_writel(0x03, dev->io_base + 0x500);
++ __raw_writel(0x0002FF02, dev->io_base + 0x508);
++
++ return 0;
++}
++
+ /**
+ * startup_dim - initialize the dim2 interface
+ * @pdev: platform device
+@@ -216,6 +238,10 @@ static int startup_dim(struct platform_device *pdev)
+ return ret;
+ }
+
++ if (1 /* renesas */) {
++ dim_rcar_init(dev);
++ }
++
+ pr_info("sync: num of frames per sub-buffer: %u\n", fcnt);
+ hal_ret = dim_startup(dev->io_base, dev->clk_speed, fcnt);
+ if (hal_ret != DIM_NO_ERROR) {
+--
+2.13.0
+
diff --git a/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0075-MOST-core-fix-memory-allocation-at-arm64.patch b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0075-MOST-core-fix-memory-allocation-at-arm64.patch
new file mode 100644
index 0000000..33a7c3a
--- /dev/null
+++ b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0075-MOST-core-fix-memory-allocation-at-arm64.patch
@@ -0,0 +1,54 @@
+From 90bfbf16c895aa53e1d017d4ce7f4f8121e0da3c Mon Sep 17 00:00:00 2001
+From: Andrey Gusakov <andrey.gusakov@cogentembedded.com>
+Date: Fri, 7 Jul 2017 20:45:01 +0300
+Subject: [PATCH 113/114] MOST: core: fix memory allocation at arm64
+
+Provide valid dev pointer to dma_alloc_coherent
+
+Signed-off-by: Andrey Gusakov <andrey.gusakov@cogentembedded.com>
+---
+ drivers/staging/most/hdm-dim2/dim2_hdm.c | 1 +
+ drivers/staging/most/mostcore/core.c | 2 +-
+ drivers/staging/most/mostcore/mostcore.h | 1 +
+ 3 files changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/staging/most/hdm-dim2/dim2_hdm.c b/drivers/staging/most/hdm-dim2/dim2_hdm.c
+index c1beabc28fa8..81edf4f4beb3 100644
+--- a/drivers/staging/most/hdm-dim2/dim2_hdm.c
++++ b/drivers/staging/most/hdm-dim2/dim2_hdm.c
+@@ -852,6 +852,7 @@ static int dim2_probe(struct platform_device *pdev)
+ dev->most_iface.enqueue = enqueue;
+ dev->most_iface.poison_channel = poison_channel;
+ dev->most_iface.request_netinfo = request_netinfo;
++ dev->most_iface.dev = &pdev->dev;
+
+ if (np) {
+ const char *tmp;
+diff --git a/drivers/staging/most/mostcore/core.c b/drivers/staging/most/mostcore/core.c
+index 7c619feb12d3..ce56d5ca582c 100644
+--- a/drivers/staging/most/mostcore/core.c
++++ b/drivers/staging/most/mostcore/core.c
+@@ -1265,7 +1265,7 @@ static int arm_mbo_chain(struct most_c_obj *c, int dir,
+ mbo->context = c;
+ mbo->ifp = c->iface;
+ mbo->hdm_channel_id = c->channel_id;
+- mbo->virt_address = dma_alloc_coherent(NULL,
++ mbo->virt_address = dma_alloc_coherent(c->iface->dev,
+ coherent_buf_size,
+ &mbo->bus_address,
+ GFP_KERNEL);
+diff --git a/drivers/staging/most/mostcore/mostcore.h b/drivers/staging/most/mostcore/mostcore.h
+index 60e018e499ef..334908639067 100644
+--- a/drivers/staging/most/mostcore/mostcore.h
++++ b/drivers/staging/most/mostcore/mostcore.h
+@@ -247,6 +247,7 @@ struct most_interface {
+ struct mbo *mbo);
+ int (*poison_channel)(struct most_interface *iface, int channel_idx);
+ void (*request_netinfo)(struct most_interface *iface, int channel_idx);
++ struct device *dev;
+ void *priv;
+ };
+
+--
+2.13.0
+
diff --git a/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0076-MOST-dim2-Renesas-R-Car3-variant.patch b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0076-MOST-dim2-Renesas-R-Car3-variant.patch
new file mode 100644
index 0000000..5ab496b
--- /dev/null
+++ b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0076-MOST-dim2-Renesas-R-Car3-variant.patch
@@ -0,0 +1,120 @@
+From d595053486568b5be30fda582becf9240d171c66 Mon Sep 17 00:00:00 2001
+From: Andrey Gusakov <andrey.gusakov@cogentembedded.com>
+Date: Mon, 25 Sep 2017 7:16:25 +0300
+Subject: [PATCH] MOST: dim2: Renesas R-Car3 variant
+
+- R-Car H3 has 8 FPSB
+- remove not existing registers access
+
+Signed-off-by: Andrey Gusakov <andrey.gusakov@cogentembedded.com>
+Signed-off-by: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+---
+ drivers/staging/most/hdm-dim2/dim2_hal.c | 8 ++++----
+ drivers/staging/most/hdm-dim2/dim2_hdm.c | 2 +-
+ drivers/staging/most/hdm-dim2/dim2_reg.h | 18 +++++++++---------
+ 3 files changed, 14 insertions(+), 14 deletions(-)
+
+diff --git a/drivers/staging/most/hdm-dim2/dim2_hal.c b/drivers/staging/most/hdm-dim2/dim2_hal.c
+index 0b9816c..231138c 100644
+--- a/drivers/staging/most/hdm-dim2/dim2_hal.c
++++ b/drivers/staging/most/hdm-dim2/dim2_hal.c
+@@ -528,11 +528,11 @@ static void dim2_cleanup(void)
+
+ /* clear status for all dma channels */
+ dimcb_io_write(&g.dim2->ACSR0, 0xFFFFFFFF);
+- dimcb_io_write(&g.dim2->ACSR1, 0xFFFFFFFF);
++// dimcb_io_write(&g.dim2->ACSR1, 0xFFFFFFFF);
+
+ /* mask interrupts for all channels */
+ dimcb_io_write(&g.dim2->ACMR0, 0);
+- dimcb_io_write(&g.dim2->ACMR1, 0);
++// dimcb_io_write(&g.dim2->ACMR1, 0);
+ }
+
+ static void dim2_initialize(bool enable_6pin, u8 mlb_clock)
+@@ -548,7 +548,7 @@ static void dim2_initialize(bool enable_6pin, u8 mlb_clock)
+
+ /* activate all HBI channels */
+ dimcb_io_write(&g.dim2->HCMR0, 0xFFFFFFFF);
+- dimcb_io_write(&g.dim2->HCMR1, 0xFFFFFFFF);
++// dimcb_io_write(&g.dim2->HCMR1, 0xFFFFFFFF);
+
+ /* enable HBI */
+ dimcb_io_write(&g.dim2->HCTL, bit_mask(HCTL_EN_BIT));
+@@ -778,7 +778,7 @@ static u8 init_ctrl_async(struct dim_channel *ch, u8 type, u8 is_tx,
+ void dim_service_mlb_int_irq(void)
+ {
+ dimcb_io_write(&g.dim2->MS0, 0);
+- dimcb_io_write(&g.dim2->MS1, 0);
++// dimcb_io_write(&g.dim2->MS1, 0);
+ }
+
+ u16 dim_norm_ctrl_async_buffer_size(u16 buf_size)
+diff --git a/drivers/staging/most/hdm-dim2/dim2_hdm.c b/drivers/staging/most/hdm-dim2/dim2_hdm.c
+index 195efff..84f56c9 100644
+--- a/drivers/staging/most/hdm-dim2/dim2_hdm.c
++++ b/drivers/staging/most/hdm-dim2/dim2_hdm.c
+@@ -54,7 +54,7 @@
+ * The values 0, 1, 2, 3, 4, 5, 6 represent corresponding number of frames per
+ * sub-buffer 1, 2, 4, 8, 16, 32, 64.
+ */
+-static u8 fcnt = 4; /* (1 << fcnt) frames per subbuffer */
++static u8 fcnt = 3; /* (1 << fcnt) frames per subbuffer */
+ module_param(fcnt, byte, 0);
+ MODULE_PARM_DESC(fcnt, "Num of frames per sub-buffer for sync channels as a power of 2");
+
+diff --git a/drivers/staging/most/hdm-dim2/dim2_reg.h b/drivers/staging/most/hdm-dim2/dim2_reg.h
+index 01fe499..54e9b6e 100644
+--- a/drivers/staging/most/hdm-dim2/dim2_reg.h
++++ b/drivers/staging/most/hdm-dim2/dim2_reg.h
+@@ -20,28 +20,28 @@
+ struct dim2_regs {
+ /* 0x00 */ u32 MLBC0;
+ /* 0x01 */ u32 rsvd0[1];
+- /* 0x02 */ u32 MLBPC0;
++ /* 0x02 */ u32 MLBPC0; /* no at R-Car3 */
+ /* 0x03 */ u32 MS0;
+ /* 0x04 */ u32 rsvd1[1];
+- /* 0x05 */ u32 MS1;
++ /* 0x05 */ u32 MS1; /* no at R-Car3 */
+ /* 0x06 */ u32 rsvd2[2];
+ /* 0x08 */ u32 MSS;
+ /* 0x09 */ u32 MSD;
+ /* 0x0A */ u32 rsvd3[1];
+ /* 0x0B */ u32 MIEN;
+ /* 0x0C */ u32 rsvd4[1];
+- /* 0x0D */ u32 MLBPC2;
+- /* 0x0E */ u32 MLBPC1;
++ /* 0x0D */ u32 MLBPC2; /* no at R-Car3 */
++ /* 0x0E */ u32 MLBPC1; /* no at R-Car3 */
+ /* 0x0F */ u32 MLBC1;
+ /* 0x10 */ u32 rsvd5[0x10];
+ /* 0x20 */ u32 HCTL;
+ /* 0x21 */ u32 rsvd6[1];
+ /* 0x22 */ u32 HCMR0;
+- /* 0x23 */ u32 HCMR1;
++ /* 0x23 */ u32 HCMR1; /* no at R-Car3 */
+ /* 0x24 */ u32 HCER0;
+- /* 0x25 */ u32 HCER1;
++ /* 0x25 */ u32 HCER1; /* no at R-Car3 */
+ /* 0x26 */ u32 HCBR0;
+- /* 0x27 */ u32 HCBR1;
++ /* 0x27 */ u32 HCBR1; /* no at R-Car3 */
+ /* 0x28 */ u32 rsvd7[8];
+ /* 0x30 */ u32 MDAT0;
+ /* 0x31 */ u32 MDAT1;
+@@ -57,9 +57,9 @@ struct dim2_regs {
+ /* 0xF0 */ u32 ACTL;
+ /* 0xF1 */ u32 rsvd9[3];
+ /* 0xF4 */ u32 ACSR0;
+- /* 0xF5 */ u32 ACSR1;
++ /* 0xF5 */ u32 ACSR1; /* no at R-Car3 */
+ /* 0xF6 */ u32 ACMR0;
+- /* 0xF7 */ u32 ACMR1;
++ /* 0xF7 */ u32 ACMR1; /* no at R-Car3 */
+ };
+
+ #define DIM2_MASK(n) (~((~(u32)0) << (n)))
+--
+1.9.1
+
diff --git a/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0077-MOST-dim2-add-timeouts.patch b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0077-MOST-dim2-add-timeouts.patch
new file mode 100644
index 0000000..d47c5c6
--- /dev/null
+++ b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0077-MOST-dim2-add-timeouts.patch
@@ -0,0 +1,46 @@
+From f02aa2831e169a9f17eebb2784db4c95944ba927 Mon Sep 17 00:00:00 2001
+From: Andrey Gusakov <andrey.gusakov@cogentembedded.com>
+Date: Mon, 25 Sep 2017 07:13:29 +0300
+Subject: [PATCH] MOST: dim2: add timeouts
+
+Get rid from loop hang if device not functional
+
+Signed-off-by: Andrey Gusakov <andrey.gusakov@cogentembedded.com>
+Signed-off-by: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+---
+ drivers/staging/most/hdm-dim2/dim2_hal.c | 8 +++++++-
+ 1 file changed, 7 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/staging/most/hdm-dim2/dim2_hal.c b/drivers/staging/most/hdm-dim2/dim2_hal.c
+index 231138c..ee0e307 100644
+--- a/drivers/staging/most/hdm-dim2/dim2_hal.c
++++ b/drivers/staging/most/hdm-dim2/dim2_hal.c
+@@ -18,6 +18,7 @@
+ #include "dim2_errors.h"
+ #include "dim2_reg.h"
+ #include <linux/stddef.h>
++#include <linux/delay.h>
+
+ /*
+ * Size factor for isochronous DBR buffer.
+@@ -148,11 +149,16 @@ static void free_dbr(int offs, int size)
+
+ static void dim2_transfer_madr(u32 val)
+ {
++ int timeout = 1000;
+ dimcb_io_write(&g.dim2->MADR, val);
+
+ /* wait for transfer completion */
+- while ((dimcb_io_read(&g.dim2->MCTL) & 1) != 1)
++ while ((dimcb_io_read(&g.dim2->MCTL) & 1) != 1) {
++ if (--timeout == 0)
++ break;
++ udelay(1);
+ continue;
++ }
+
+ dimcb_io_write(&g.dim2->MCTL, 0); /* clear transfer complete */
+ }
+--
+1.9.1
+
diff --git a/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0078-MOST-aim-fix-null-pointer-crash.patch b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0078-MOST-aim-fix-null-pointer-crash.patch
new file mode 100644
index 0000000..fd66258
--- /dev/null
+++ b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0078-MOST-aim-fix-null-pointer-crash.patch
@@ -0,0 +1,29 @@
+From f3c2f6f40c2b3e43a447c89b523de40ce2211e91 Mon Sep 17 00:00:00 2001
+From: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+Date: Fri, 27 Oct 2017 17:34:05 +0300
+Subject: [PATCH] MOST: aim: fix null pointer crash
+
+The snd_card_new now crashes if first argument NULL
+
+Signed-off-by: Andrey Gusakov <andrey.gusakov@cogentembedded.com>
+Signed-off-by: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+---
+ drivers/staging/most/aim-sound/sound.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/staging/most/aim-sound/sound.c b/drivers/staging/most/aim-sound/sound.c
+index e4198e5..a2ccc79 100644
+--- a/drivers/staging/most/aim-sound/sound.c
++++ b/drivers/staging/most/aim-sound/sound.c
+@@ -595,7 +595,7 @@ static int audio_probe_channel(struct most_interface *iface, int channel_id,
+ return ret;
+ }
+
+- ret = snd_card_new(NULL, -1, card_name, THIS_MODULE,
++ ret = snd_card_new(iface->dev, -1, card_name, THIS_MODULE,
+ sizeof(*channel), &card);
+ if (ret < 0)
+ return ret;
+--
+1.9.1
+
diff --git a/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0100-LVDS-ar0132-use-raw12.patch b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0100-LVDS-ar0132-use-raw12.patch
new file mode 100644
index 0000000..abf2624
--- /dev/null
+++ b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0100-LVDS-ar0132-use-raw12.patch
@@ -0,0 +1,152 @@
+From 2869ff3002560ee637f905ed684aaccfac53372e Mon Sep 17 00:00:00 2001
+From: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+Date: Mon, 28 Aug 2017 03:16:21 +0300
+Subject: [PATCH] LVDS: ar0132: use raw12
+
+Set CSI2 type raw8 in RCAR CSI2 and set raw12 in ti960
+
+Signed-off-by: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+---
+ arch/arm64/boot/dts/renesas/legacy/r8a7795-es1-h3ulcb-kf-v0.dts | 8 ++++----
+ arch/arm64/boot/dts/renesas/legacy/r8a7795-h3ulcb-kf-v0.dts | 8 ++++----
+ arch/arm64/boot/dts/renesas/r8a7797-v3msk-kf.dts | 8 ++++----
+ arch/arm64/boot/dts/renesas/ulcb-kf.dtsi | 8 ++++----
+ drivers/media/i2c/soc_camera/ti964_ti9x3.c | 5 +++--
+ 5 files changed, 19 insertions(+), 18 deletions(-)
+
+diff --git a/arch/arm64/boot/dts/renesas/legacy/r8a7795-es1-h3ulcb-kf-v0.dts b/arch/arm64/boot/dts/renesas/legacy/r8a7795-es1-h3ulcb-kf-v0.dts
+index cd23797..5dc5144 100644
+--- a/arch/arm64/boot/dts/renesas/legacy/r8a7795-es1-h3ulcb-kf-v0.dts
++++ b/arch/arm64/boot/dts/renesas/legacy/r8a7795-es1-h3ulcb-kf-v0.dts
+@@ -1571,19 +1571,19 @@
+
+ virtual,channel {
+ csi2_vc0 {
+- data,type = "ycbcr422";
++ data,type = "raw8";
+ receive,vc = <0>;
+ };
+ csi2_vc1 {
+- data,type = "ycbcr422";
++ data,type = "raw8";
+ receive,vc = <1>;
+ };
+ csi2_vc2 {
+- data,type = "ycbcr422";
++ data,type = "raw8";
+ receive,vc = <2>;
+ };
+ csi2_vc3 {
+- data,type = "ycbcr422";
++ data,type = "raw8";
+ receive,vc = <3>;
+ };
+ };
+diff --git a/arch/arm64/boot/dts/renesas/legacy/r8a7795-h3ulcb-kf-v0.dts b/arch/arm64/boot/dts/renesas/legacy/r8a7795-h3ulcb-kf-v0.dts
+index f640350..b26ca3a 100644
+--- a/arch/arm64/boot/dts/renesas/legacy/r8a7795-h3ulcb-kf-v0.dts
++++ b/arch/arm64/boot/dts/renesas/legacy/r8a7795-h3ulcb-kf-v0.dts
+@@ -1578,19 +1578,19 @@
+
+ virtual,channel {
+ csi2_vc0 {
+- data,type = "ycbcr422";
++ data,type = "raw8";
+ receive,vc = <0>;
+ };
+ csi2_vc1 {
+- data,type = "ycbcr422";
++ data,type = "raw8";
+ receive,vc = <1>;
+ };
+ csi2_vc2 {
+- data,type = "ycbcr422";
++ data,type = "raw8";
+ receive,vc = <2>;
+ };
+ csi2_vc3 {
+- data,type = "ycbcr422";
++ data,type = "raw8";
+ receive,vc = <3>;
+ };
+ };
+diff --git a/arch/arm64/boot/dts/renesas/r8a7797-v3msk-kf.dts b/arch/arm64/boot/dts/renesas/r8a7797-v3msk-kf.dts
+index 9837e17..402e894 100644
+--- a/arch/arm64/boot/dts/renesas/r8a7797-v3msk-kf.dts
++++ b/arch/arm64/boot/dts/renesas/r8a7797-v3msk-kf.dts
+@@ -511,19 +511,19 @@
+
+ virtual,channel {
+ csi2_vc0 {
+- data,type = "ycbcr422";
++ data,type = "raw8";
+ receive,vc = <0>;
+ };
+ csi2_vc1 {
+- data,type = "ycbcr422";
++ data,type = "raw8";
+ receive,vc = <1>;
+ };
+ csi2_vc2 {
+- data,type = "ycbcr422";
++ data,type = "raw8";
+ receive,vc = <2>;
+ };
+ csi2_vc3 {
+- data,type = "ycbcr422";
++ data,type = "raw8";
+ receive,vc = <3>;
+ };
+ };
+diff --git a/arch/arm64/boot/dts/renesas/ulcb-kf.dtsi b/arch/arm64/boot/dts/renesas/ulcb-kf.dtsi
+index 4ead97a..6dbcf7f 100644
+--- a/arch/arm64/boot/dts/renesas/ulcb-kf.dtsi
++++ b/arch/arm64/boot/dts/renesas/ulcb-kf.dtsi
+@@ -1346,19 +1346,19 @@
+
+ virtual,channel {
+ csi2_vc0 {
+- data,type = "ycbcr422";
++ data,type = "raw8";
+ receive,vc = <0>;
+ };
+ csi2_vc1 {
+- data,type = "ycbcr422";
++ data,type = "raw8";
+ receive,vc = <1>;
+ };
+ csi2_vc2 {
+- data,type = "ycbcr422";
++ data,type = "raw8";
+ receive,vc = <2>;
+ };
+ csi2_vc3 {
+- data,type = "ycbcr422";
++ data,type = "raw8";
+ receive,vc = <3>;
+ };
+ };
+diff --git a/drivers/media/i2c/soc_camera/ti964_ti9x3.c b/drivers/media/i2c/soc_camera/ti964_ti9x3.c
+index 8dd0f99..caa3f74 100644
+--- a/drivers/media/i2c/soc_camera/ti964_ti9x3.c
++++ b/drivers/media/i2c/soc_camera/ti964_ti9x3.c
+@@ -122,12 +122,14 @@ static void ti964_ti9x3_fpdlink3_setup(struct i2c_client *client, int idx)
+ // reg8_write(client, 0x5d, SENSOR_ID << 1); /* SENSOR I2C native - must be set by sensor driver */
+ // reg8_write(client, 0x65, (0x60 + idx) << 1); /* SENSOR I2C translated - must be set by sensor driver */
+ if (strcmp(priv->cable_mode, "coax") == 0) {
+- reg8_write(client, 0x6d, 0x7f); /* Coax, RAW10 */
++ reg8_write(client, 0x6d, 0x7e); /* Coax, RAW12 */
+ } else if (strcmp(priv->cable_mode, "stp") == 0) {
+ reg8_write(client, 0x6d, 0x78); /* STP, CSI */
+ }
+ reg8_write(client, 0x70, (idx << 6) | 0x1e); /* CSI data type: yuv422 8-bit, assign VC */
+- reg8_write(client, 0x7c, 0x81); /* BIT(7) - magic to Use RAW10 as 8-bit mode */
++ reg8_write(client, 0x71, (idx << 6) | 0x2a); /* CSI data type: RAW12, assign VC */
++ reg8_write(client, 0x7c, 0x00); /* RAW12 mode */
++ reg8_write(client, 0xbc, 0x00); /* Setup minimal time between FV and LV to 3 PCLKs */
+ reg8_write(client, 0x6e, 0x88); /* Sensor reset: backchannel GPIO0/GPIO1 set low */
+ }
+
+--
+1.9.1
+
diff --git a/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0101-LVDS-ar0132-use-context-swwitch.patch b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0101-LVDS-ar0132-use-context-swwitch.patch
new file mode 100644
index 0000000..00b62e8
--- /dev/null
+++ b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0101-LVDS-ar0132-use-context-swwitch.patch
@@ -0,0 +1,119 @@
+From d9b811e183d9cae753929cb55e627a29c6a971a8 Mon Sep 17 00:00:00 2001
+From: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+Date: Wed, 30 Aug 2017 14:44:29 +0300
+Subject: [PATCH] LVDS: ar0132 use context swwitch
+
+This enabled context-A-B switch on every frame
+
+Signed-off-by: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+---
+ drivers/media/i2c/soc_camera/ar0132.c | 19 +++++++++++++++++++
+ drivers/media/platform/soc_camera/rcar_vin.c | 23 ++++++++++++++++++-----
+ 2 files changed, 37 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/media/i2c/soc_camera/ar0132.c b/drivers/media/i2c/soc_camera/ar0132.c
+index 284c522..2c21fa9 100644
+--- a/drivers/media/i2c/soc_camera/ar0132.c
++++ b/drivers/media/i2c/soc_camera/ar0132.c
+@@ -238,11 +238,30 @@ static int ar0132_s_register(struct v4l2_subdev *sd,
+ }
+ #endif
+
++static int ar0132_isr(struct v4l2_subdev *sd, u32 status, bool *handled)
++{
++ struct i2c_client *client = v4l2_get_subdevdata(sd);
++#if 1
++ u16 frame_count = 0;
++ /* read frame counter from sensor */
++ reg16_read16(client, 0x303a, &frame_count);
++#else
++ static int frame_count = 0;
++ /* get cached frame counter */
++ frame_count++;
++#endif
++ /* odd frame -> Mode A, even frame -> Mode B */
++ reg16_write16(client, 0x30b0, frame_count & 1 ? 0x2 : 0x2002);
++
++ return 0;
++};
++
+ static struct v4l2_subdev_core_ops ar0132_core_ops = {
+ #ifdef CONFIG_VIDEO_ADV_DEBUG
+ .g_register = ar0132_g_register,
+ .s_register = ar0132_s_register,
+ #endif
++ .interrupt_service_routine = ar0132_isr,
+ };
+
+ static int ar0132_s_ctrl(struct v4l2_ctrl *ctrl)
+diff --git a/drivers/media/platform/soc_camera/rcar_vin.c b/drivers/media/platform/soc_camera/rcar_vin.c
+index c39fe63..9ab6f00 100644
+--- a/drivers/media/platform/soc_camera/rcar_vin.c
++++ b/drivers/media/platform/soc_camera/rcar_vin.c
+@@ -1292,13 +1292,24 @@ static void rcar_vin_stop_streaming(struct vb2_queue *vq)
+ .wait_finish = vb2_ops_wait_finish,
+ };
+
++static irqreturn_t rcar_vin_threaded_irq(int irq, void *data)
++{
++ struct rcar_vin_priv *priv = data;
++ struct soc_camera_device *icd = priv->ici.icd;
++ struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
++
++ v4l2_subdev_call(sd, core, interrupt_service_routine, 0, NULL);
++
++ return IRQ_HANDLED;
++};
++
+ static irqreturn_t rcar_vin_irq(int irq, void *data)
+ {
+ struct rcar_vin_priv *priv = data;
+ u32 int_status;
+ bool can_run = false, hw_stopped;
+ int slot;
+- unsigned int handled = 0;
++ unsigned int handled = IRQ_NONE;
+ int vin_ovr_cnt = 0;
+
+ spin_lock(&priv->lock);
+@@ -1309,7 +1320,7 @@ static irqreturn_t rcar_vin_irq(int irq, void *data)
+
+ /* ack interrupts */
+ iowrite32(int_status, priv->base + VNINTS_REG);
+- handled = 1;
++ handled = IRQ_HANDLED;
+
+ /* overflow occurs */
+ if (vin_debug && (int_status & VNINTS_FOS)) {
+@@ -1342,6 +1353,8 @@ static irqreturn_t rcar_vin_irq(int irq, void *data)
+ priv->queue_buf[slot] = NULL;
+
+ can_run = rcar_vin_fill_hw_slot(priv);
++
++ handled = IRQ_WAKE_THREAD;
+ }
+
+ if (is_continuous_transfer(priv)) {
+@@ -1370,7 +1383,7 @@ static irqreturn_t rcar_vin_irq(int irq, void *data)
+ done:
+ spin_unlock(&priv->lock);
+
+- return IRQ_RETVAL(handled);
++ return handled;
+ }
+
+ static struct v4l2_subdev *find_csi2(struct rcar_vin_priv *pcdev)
+@@ -2930,8 +2943,8 @@ static int rcar_vin_probe(struct platform_device *pdev)
+ if (IS_ERR(priv->base))
+ return PTR_ERR(priv->base);
+
+- ret = devm_request_irq(&pdev->dev, irq, rcar_vin_irq, IRQF_SHARED,
+- dev_name(&pdev->dev), priv);
++ ret = devm_request_threaded_irq(&pdev->dev, irq, rcar_vin_irq, rcar_vin_threaded_irq,
++ IRQF_SHARED, dev_name(&pdev->dev), priv);
+ if (ret)
+ return ret;
+
+--
+1.9.1
+
diff --git a/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/eagle.cfg b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/eagle.cfg
new file mode 100644
index 0000000..333b917
--- /dev/null
+++ b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/eagle.cfg
@@ -0,0 +1,28 @@
+CONFIG_ARCH_R8A7797=y
+CONFIG_CAN=y
+CONFIG_CAN_PEAK_USB=y
+CONFIG_CAN_BCM=y
+CONFIG_CAN_RAW=y
+CONFIG_CAN_DEV=y
+CONFIG_CAN_CALC_BITTIMING=y
+CONFIG_CAN_RCAR=y
+CONFIG_CANFD_RCAR=y
+CONFIG_DUMMY=y
+CONFIG_DRM_I2C_ADV7511=y
+CONFIG_GPIO_PCA953X=y
+CONFIG_GPIO_PCA953X_IRQ=y
+CONFIG_VIDEO_ADV_DEBUG=y
+CONFIG_VIDEO_RCAR_VIN_LEGACY=y
+CONFIG_VIDEO_RCAR_CSI2_LEGACY=y
+# CONFIG_VIDEO_RCAR_VIN is not set
+# CONFIG_VIDEO_RCAR_CSI2 is not set
+CONFIG_SOC_CAMERA=y
+CONFIG_SOC_CAMERA_SCALE_CROP=y
+CONFIG_SOC_CAMERA_PLATFORM=y
+CONFIG_SOC_CAMERA_MAX9286_MAX9271=y
+CONFIG_SOC_CAMERA_OV106XX=y
+CONFIG_VIDEO_RENESAS_IMR=y
+CONFIG_INPUT_TOUCHSCREEN=y
+CONFIG_TOUCHSCREEN_PROPERTIES=y
+CONFIG_HID_MULTITOUCH=y
+CONFIG_SERIAL_SH_SCI_DMA=y
diff --git a/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/hyperflash.cfg b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/hyperflash.cfg
new file mode 100644
index 0000000..df45d5e
--- /dev/null
+++ b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/hyperflash.cfg
@@ -0,0 +1,2 @@
+CONFIG_MTD=y
+CONFIG_MTD_RPC_HYPERFLASH=y
diff --git a/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/salvator-x.cfg b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/salvator-x.cfg
new file mode 100644
index 0000000..29425e5
--- /dev/null
+++ b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/salvator-x.cfg
@@ -0,0 +1,31 @@
+CONFIG_CAN=y
+CONFIG_CAN_PEAK_USB=y
+CONFIG_CAN_BCM=y
+CONFIG_CAN_RAW=y
+CONFIG_CAN_DEV=y
+CONFIG_CAN_CALC_BITTIMING=y
+CONFIG_CAN_RCAR=y
+CONFIG_CAN_RCAR_CANFD=y
+CONFIG_DUMMY=y
+CONFIG_EXTRA_FIRMWARE="r8a779x_usb3_v2.dlmem"
+CONFIG_EXTRA_FIRMWARE_DIR="firmware"
+CONFIG_VIDEO_ADV_DEBUG=y
+CONFIG_VIDEO_RCAR_VIN_LEGACY=y
+CONFIG_VIDEO_RCAR_CSI2_LEGACY=y
+# CONFIG_VIDEO_RCAR_VIN is not set
+# CONFIG_VIDEO_RCAR_CSI2 is not set
+CONFIG_SOC_CAMERA=y
+CONFIG_SOC_CAMERA_SCALE_CROP=y
+CONFIG_SOC_CAMERA_PLATFORM=y
+CONFIG_SOC_CAMERA_MAX9286_MAX9271=y
+CONFIG_SOC_CAMERA_OV106XX=y
+CONFIG_USB_XHCI_HCD=y
+CONFIG_USB_XHCI_PLATFORM=y
+CONFIG_USB_XHCI_RCAR=y
+CONFIG_MMC_SDHI_PRE_REQ=y
+CONFIG_MMC_SDHI_SEQ=y
+CONFIG_VIDEO_RENESAS_IMR=y
+CONFIG_INPUT_TOUCHSCREEN=y
+CONFIG_TOUCHSCREEN_PROPERTIES=y
+CONFIG_HID_MULTITOUCH=y
+CONFIG_SERIAL_SH_SCI_DMA=y
diff --git a/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/sdhi_seq.cfg b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/sdhi_seq.cfg
new file mode 100644
index 0000000..9c43599
--- /dev/null
+++ b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/sdhi_seq.cfg
@@ -0,0 +1,2 @@
+CONFIG_MMC_SDHI_PRE_REQ=y
+CONFIG_MMC_SDHI_SEQ=y
diff --git a/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/ulcb.cfg b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/ulcb.cfg
new file mode 100644
index 0000000..b52636a
--- /dev/null
+++ b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/ulcb.cfg
@@ -0,0 +1,80 @@
+CONFIG_CAN=y
+CONFIG_CAN_PEAK_USB=y
+CONFIG_CAN_BCM=y
+CONFIG_CAN_RAW=y
+CONFIG_CAN_DEV=y
+CONFIG_CAN_CALC_BITTIMING=y
+CONFIG_CAN_RCAR=y
+CONFIG_CAN_RCAR_CANFD=y
+CONFIG_DUMMY=y
+CONFIG_EXTRA_FIRMWARE="r8a779x_usb3_v2.dlmem r8a779x_usb3_v3.dlmem"
+CONFIG_EXTRA_FIRMWARE_DIR="firmware"
+CONFIG_BLK_DEV_NVME=m
+CONFIG_SATA_ACARD_AHCI=y
+CONFIG_FIXED_PHY=y
+CONFIG_SPI_BITBANG=y
+CONFIG_SPI_GPIO=y
+CONFIG_GPIO_MAX732X=y
+CONFIG_GPIO_MAX732X_IRQ=y
+CONFIG_GPIO_PCA953X=y
+CONFIG_GPIO_PCA953X_IRQ=y
+CONFIG_VIDEO_ADV_DEBUG=y
+CONFIG_VIDEO_RCAR_VIN_LEGACY=y
+CONFIG_VIDEO_RCAR_CSI2_LEGACY=y
+# CONFIG_VIDEO_RCAR_VIN is not set
+# CONFIG_VIDEO_RCAR_CSI2 is not set
+CONFIG_SOC_CAMERA=y
+CONFIG_SOC_CAMERA_SCALE_CROP=y
+CONFIG_SOC_CAMERA_PLATFORM=y
+CONFIG_SOC_CAMERA_MAX9286_MAX9271=y
+CONFIG_SOC_CAMERA_TI964_TI9X3=y
+CONFIG_SOC_CAMERA_TI954_TI9X3=y
+CONFIG_SOC_CAMERA_OV106XX=y
+CONFIG_SOC_CAMERA_OV5647=y
+CONFIG_SOC_CAMERA_OV5642=y
+CONFIG_USB_XHCI_HCD=y
+CONFIG_USB_XHCI_PLATFORM=y
+CONFIG_USB_XHCI_RCAR=y
+CONFIG_USB_ACM=y
+CONFIG_VIDEO_RENESAS_IMR=y
+CONFIG_VIRTIO_RCAR_PCIE=y
+CONFIG_BT=y
+CONFIG_BT_BNEP=m
+CONFIG_BT_RFCOMM=m
+CONFIG_BT_HIDP=m
+CONFIG_TI_ST=m
+CONFIG_BT_WILINK=m
+CONFIG_WEXT_CORE=y
+CONFIG_WEXT_PROC=y
+CONFIG_CFG80211_WEXT=y
+CONFIG_MAC80211=y
+CONFIG_WLAN=y
+CONFIG_WL18XX=m
+CONFIG_WLCORE=m
+CONFIG_WLCORE_SDIO=m
+CONFIG_SND_SOC_SI468X=y
+CONFIG_SND_SOC_PCM3168A=y
+CONFIG_SND_SOC_PCM3168A_I2C=y
+CONFIG_SND_SOC_WL18XX=y
+CONFIG_INPUT_TOUCHSCREEN=y
+CONFIG_TOUCHSCREEN_PROPERTIES=y
+CONFIG_HID_MULTITOUCH=y
+CONFIG_IIO=y
+CONFIG_IIO_BUFFER=y
+CONFIG_IIO_BUFFER_CB=y
+CONFIG_IIO_KFIFO_BUF=y
+CONFIG_IIO_TRIGGERED_BUFFER=y
+CONFIG_IIO_TRIGGER=y
+CONFIG_IIO_CONSUMERS_PER_TRIGGER=2
+CONFIG_LSM9DS0=y
+CONFIG_DRM_I2C_ADV7511=y
+CONFIG_TOUCHSCREEN_EDT_FT5X06=y
+CONFIG_SERIAL_SH_SCI_DMA=y
+CONFIG_STAGING=y
+CONFIG_MOST=y
+CONFIG_MOSTCORE=y
+CONFIG_AIM_CDEV=y
+CONFIG_AIM_NETWORK=y
+CONFIG_AIM_SOUND=y
+CONFIG_AIM_V4L2=y
+CONFIG_HDM_DIM2=y
diff --git a/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/v3msk.cfg b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/v3msk.cfg
new file mode 100644
index 0000000..ffc54dc
--- /dev/null
+++ b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/v3msk.cfg
@@ -0,0 +1,32 @@
+CONFIG_ARCH_R8A7797=y
+CONFIG_CAN=y
+CONFIG_CAN_PEAK_USB=y
+CONFIG_CAN_BCM=y
+CONFIG_CAN_RAW=y
+CONFIG_CAN_DEV=y
+CONFIG_CAN_CALC_BITTIMING=y
+CONFIG_CAN_RCAR=y
+CONFIG_CANFD_RCAR=y
+CONFIG_DUMMY=y
+CONFIG_DRM_I2C_ADV7511=y
+CONFIG_GPIO_MAX732X=y
+CONFIG_GPIO_MAX732X_IRQ=y
+CONFIG_GPIO_PCA953X=y
+CONFIG_GPIO_PCA953X_IRQ=y
+CONFIG_VIDEO_ADV_DEBUG=y
+CONFIG_VIDEO_RCAR_VIN_LEGACY=y
+CONFIG_VIDEO_RCAR_CSI2_LEGACY=y
+# CONFIG_VIDEO_RCAR_VIN is not set
+# CONFIG_VIDEO_RCAR_CSI2 is not set
+CONFIG_SOC_CAMERA=y
+CONFIG_SOC_CAMERA_SCALE_CROP=y
+CONFIG_SOC_CAMERA_PLATFORM=y
+CONFIG_SOC_CAMERA_MAX9286_MAX9271=y
+CONFIG_SOC_CAMERA_TI964_TI9X3=y
+CONFIG_SOC_CAMERA_TI954_TI9X3=y
+CONFIG_SOC_CAMERA_OV106XX=y
+CONFIG_VIDEO_RENESAS_IMR=y
+CONFIG_INPUT_TOUCHSCREEN=y
+CONFIG_TOUCHSCREEN_PROPERTIES=y
+CONFIG_HID_MULTITOUCH=y
+CONFIG_SERIAL_SH_SCI_DMA=y