diff --git a/README_JP5.md b/README_JP5.md index 4d1cb4a2..05939a45 100644 --- a/README_JP5.md +++ b/README_JP5.md @@ -95,6 +95,19 @@ The developers can set up the source code with NVIDIA's Jetson git repositories ./build_all.sh 5.1.2 ``` +For Fangzhu FG12-16CH support (Currently only supported on 5.0.2): +``` +./setup_workspace.sh 5.0.2 + +- Single camera connected to cam0: +./apply_patches.sh --fg12-16ch 5.0.2 + +- Dual camera connected to cam0 and cam4: +./apply_patches.sh --fg12-16ch-dual 5.0.2 + +./build_all.sh 5.1.2 +``` + Note: dev_dbg() log support will not be enabled by default. If needed, run the `./build_all.sh` script with `--dev-dbg` option like below. ``` ./build_all.sh --dev-dbg 5.1.2 @@ -111,6 +124,7 @@ The necessary files are: - kernel image `images/5.1.2/arch/arm64/boot/Image` - dtb `images/5.1.2/arch/arm64/boot/dts/nvidia/tegra194-p2888-0001-p2822-0000.dtb` - D457 driver `images/5.1.2/drivers/media/i2c/d4xx.ko` +- MAX96712 driver `images/5.1.2/drivers/media/i2c/max96712.ko` - UVC Video driver `images/5.1.2/drivers/media/usb/uvc/uvcvideo.ko` - V4L2 Core Video driver `images/5.1.2/drivers/media/v4l2-core/videobuf-core.ko` - V4L2 VMalloc Video driver `images/5.1.2/drivers/media/v4l2-core/videobuf-vmalloc.ko` @@ -120,6 +134,7 @@ Copy build results from Host to Jetson target `10.0.0.116` user `nvidia` scp ./images/5.1.2/arch/arm64/boot/Image nvidia@10.0.0.116:~/ scp ./images/5.1.2/arch/arm64/boot/dts/nvidia/tegra194-p2888-0001-p2822-0000.dtb nvidia@10.0.0.116:~/ scp ./images/5.1.2/drivers/media/i2c/d4xx.ko nvidia@10.0.0.116:~/ +scp ./images/5.1.2/drivers/media/i2c/max96712.ko nvidia@10.0.0.116:~/ scp ./images/5.1.2/drivers/media/usb/uvc/uvcvideo.ko nvidia@10.0.0.116:~/ scp ./images/5.1.2/drivers/media/v4l2-core/videobuf-core.ko nvidia@10.0.0.116:~/ scp ./images/5.1.2/drivers/media/v4l2-core/videobuf-vmalloc.ko nvidia@10.0.0.116:~/ @@ -132,6 +147,7 @@ sudo mkdir /lib/modules/$(uname -r)/updates sudo cp Image /boot/d457/ sudo cp tegra194-p2888-0001-p2822-0000.dtb /boot/d457/ sudo cp d4xx.ko /lib/modules/$(uname -r)/updates/ +sudo cp max96712.ko /lib/modules/$(uname -r)/updates/ sudo cp uvcvideo.ko /lib/modules/$(uname -r)/updates/ sudo cp videobuf-core.ko /lib/modules/$(uname -r)/updates/ sudo cp videobuf-vmalloc.ko /lib/modules/$(uname -r)/updates/ diff --git a/README_JP6.2.md b/README_JP6.2.md index c0207027..a88d6d24 100644 --- a/README_JP6.2.md +++ b/README_JP6.2.md @@ -104,6 +104,8 @@ Assuming 6.2 (or 6.1) build the kernel version is 5.15.148-tegra. For 6.0 the ke - dtb: `images/6.2/rootfs/boot/dtb/tegra234-p3737-0000+p3701-0000-nv.dtb` - dtb overlay: `images/6.2/rootfs/boot/tegra234-camera-d4xx-overlay.dtbo` - dtb dual camera overlay: `images/6.2/rootfs/boot/tegra234-camera-d4xx-overlay-dual.dtbo` +- dtb fg12-16ch camera overlay: `images/6.0/rootfs/boot/tegra234-camera-d4xx-overlay-fg12-16ch.dtbo` +- dtb fg12-16ch dual camera overlay: `images/6.0/rootfs/boot/tegra234-camera-d4xx-overlay-fg12-16ch-dual.dtbo` - kernel modules: `images/6.2/rootfs/lib/modules/5.15.148-tegra` ## Backup JetPack 6.2 boot configuration and drivers (optional) @@ -176,6 +178,9 @@ LABEL dev ``` sudo reboot ``` + +For fg12-16ch/dual/quad, use `tegra234-camera-d4xx-overlay-fg12-16ch.dtbo` + On Jetson target (user home folder) assuming backup step was followed: ### Verify driver loaded - on Jetson: diff --git a/apply_patches.sh b/apply_patches.sh index 1d732a6d..df25c19b 100755 --- a/apply_patches.sh +++ b/apply_patches.sh @@ -18,6 +18,15 @@ if [[ "$1" == "--one-cam" ]]; then elif [[ "$1" == "--dual-cam" ]]; then JP5_D4XX_DTSI="tegra194-camera-d4xx-dual.dtsi" shift +elif [[ "$1" == "--max96712-EVB" ]]; then + JP5_D4XX_DTSI="tegra194-camera-d4xx-max96712-EVB.dtsi" + shift +elif [[ "$1" == "--fg12-16ch" ]]; then + JP5_D4XX_DTSI="tegra194-camera-d4xx-fg12-16ch.dtsi" + shift +elif [[ "$1" == "--fg12-16ch-dual" ]]; then + JP5_D4XX_DTSI="tegra194-camera-d4xx-fg12-16ch-dual.dtsi" + shift fi . scripts/setup-common "$1" @@ -109,8 +118,13 @@ if [[ "$ACTION" = "apply" ]]; then if [[ "$JETPACK_VERSION" == "6.x" ]]; then # jp6 overlay cp hardware/realsense/tegra234-camera-d4xx-overlay*.dts "sources_$SOURCES_VERSION/hardware/nvidia/t23x/nv-public/overlay/" + # max96712 header + cp nvidia-oot/max96712.h "sources_$SOURCES_VERSION/nvidia-oot/include/media/" else + # device tree cp "hardware/realsense/${JP5_D4XX_DTSI}" "sources_$SOURCES_VERSION/hardware/nvidia/platform/t19x/galen/kernel-dts/common/tegra194-camera-d4xx.dtsi" + # max96712 header + cp kernel/nvidia/max96712.h "sources_$SOURCES_VERSION/kernel/nvidia/include/media/" fi # Stage all modified files after patching diff --git a/hardware/nvidia/t23x/nv-public/6.x/0001-overlay-enable-d4xx-camera-for-Orin-jp6.patch b/hardware/nvidia/t23x/nv-public/6.x/0001-overlay-enable-d4xx-camera-for-Orin-jp6.patch index 69452b87..6ced79e6 100644 --- a/hardware/nvidia/t23x/nv-public/6.x/0001-overlay-enable-d4xx-camera-for-Orin-jp6.patch +++ b/hardware/nvidia/t23x/nv-public/6.x/0001-overlay-enable-d4xx-camera-for-Orin-jp6.patch @@ -1,26 +1,31 @@ -From 00f96bc253e0e35235b221af28bddf25d185d84d Mon Sep 17 00:00:00 2001 -From: Dmitry Perchanov -Date: Mon, 20 May 2024 18:16:07 +0300 +From d28ebc27d32166b754b7483f76252f8ca14b2fb0 Mon Sep 17 00:00:00 2001 +From: ejgoldik +Date: Wed, 21 Jan 2026 15:55:54 +0200 Subject: [PATCH] overlay: enable d4xx camera for Orin jp6 -Signed-off-by: Dmitry Perchanov +Signed-off-by: ejgoldik --- - overlay/Makefile | 2 ++ - 1 file changed, 2 insertion(+) + overlay/Makefile | 7 +++++++ + 1 file changed, 7 insertions(+) diff --git a/overlay/Makefile b/overlay/Makefile -index c88bbe2..3f6354e 100644 +index c88bbe2..28e505a 100644 --- a/overlay/Makefile +++ b/overlay/Makefile -@@ -60,6 +60,8 @@ dtbo-y += tegra234-p3767-camera-p3768-imx219-A.dtbo +@@ -60,6 +60,13 @@ dtbo-y += tegra234-p3767-camera-p3768-imx219-A.dtbo dtbo-y += tegra234-p3767-camera-p3768-imx219-imx477.dtbo dtbo-y += tegra234-p3767-camera-p3768-imx477-C.dtbo dtbo-y += tegra234-p3767-camera-p3768-imx477-A.dtbo +dtbo-y += tegra234-camera-d4xx-overlay.dtbo +dtbo-y += tegra234-camera-d4xx-overlay-dual.dtbo ++dtbo-y += tegra234-camera-d4xx-overlay-max96712-EVB.dtbo ++dtbo-y += tegra234-camera-d4xx-overlay-fg12-16ch.dtbo ++dtbo-y += tegra234-camera-d4xx-overlay-fg12-16ch-dual.dtbo ++dtbo-y += tegra234-camera-d4xx-overlay-fg12-16ch-quad.dtbo ++ ifneq ($(dtb-y),) dtb-y := $(addprefix $(makefile-path)/,$(dtb-y)) -- -2.34.1 +2.43.0 diff --git a/hardware/realsense/tegra194-camera-d4xx-fg12-16ch-dual.dtsi b/hardware/realsense/tegra194-camera-d4xx-fg12-16ch-dual.dtsi new file mode 100644 index 00000000..c2c1aab4 --- /dev/null +++ b/hardware/realsense/tegra194-camera-d4xx-fg12-16ch-dual.dtsi @@ -0,0 +1,800 @@ +#include "dt-bindings/clock/tegra194-clock.h" + +#define CAMERA_I2C_MUX_BUS(x) (0x1E + x) + +#define CAM0_PWDN TEGRA194_MAIN_GPIO(H, 6) +#define CAM1_PWDN TEGRA194_MAIN_GPIO(H, 3) +#define CAM2_PWDN TEGRA194_MAIN_GPIO(T, 5) +#define CAM3_PWDN TEGRA194_MAIN_GPIO(T, 6) + +/ { + tegra-capture-vi { + num-channels = <8>; + + ports { + #address-cells = <0x1>; + #size-cells = <0x0>; + + port@0 { + reg = <0>; + status = "ok"; + + vi_in0: endpoint { + status = "ok"; + port-index = <0>; + bus-width = <2>; + vc-id = <0>; + remote-endpoint = <&csi_out0>; + }; + }; + port@1 { + reg = <1>; + status = "ok"; + + vi_in1: endpoint { + status = "ok"; + vc-id = <1>; + port-index = <0>; + bus-width = <2>; + remote-endpoint = <&csi_out1>; + }; + }; + port@2 { + reg = <2>; + status = "ok"; + + vi_in2: endpoint { + status = "ok"; + port-index = <0>; + bus-width = <2>; + vc-id = <2>; + remote-endpoint = <&csi_out2>; + }; + }; + port@3 { + reg = <3>; + status = "ok"; + + vi_in3: endpoint { + status = "ok"; + port-index = <0>; + bus-width = <2>; + vc-id = <3>; + remote-endpoint = <&csi_out3>; + }; + }; + port@4 { + reg = <4>; + status = "ok"; + + vi_in4: endpoint { + status = "ok"; + port-index = <2>; + bus-width = <2>; + vc-id = <0>; + remote-endpoint = <&csi_out4>; + }; + }; + port@5 { + reg = <5>; + status = "ok"; + + vi_in5: endpoint { + status = "ok"; + vc-id = <1>; + port-index = <2>; + bus-width = <2>; + remote-endpoint = <&csi_out5>; + }; + }; + port@6 { + reg = <6>; + status = "ok"; + + vi_in6: endpoint { + status = "ok"; + port-index = <2>; + bus-width = <2>; + vc-id = <2>; + remote-endpoint = <&csi_out6>; + }; + }; + port@7 { + reg = <7>; + status = "ok"; + + vi_in7: endpoint { + status = "ok"; + port-index = <2>; + bus-width = <2>; + vc-id = <3>; + remote-endpoint = <&csi_out7>; + }; + }; + }; + }; + + i2c@3180000 { + status = "ok"; + clock-frequency = <100000>; + tca9546@70 { + status = "ok"; + reg = <0x70>; + compatible = "nxp,pca9546"; + #address-cells = <1>; + #size-cells = <0>; + skip_mux_detect = "yes"; + vcc-supply = <&p2822_vdd_sys_en>; + /*vcc-pullup-supply = <&battery_reg>;*/ + force_bus_start = ; + vcc_lp = "vcc"; + i2c@0 { + reg = <0x0>; + #address-cells = <0x1>; + i2c-mux,deselect-on-exit; + #size-cells = <0x0>; + + dser_a: max96712@29 { + status = "ok"; + reg = <0x29>; + compatible = "maxim,max96712"; + csi-mode = "2x4"; + max-src = <1>; + channel = "a"; + pwdn-gpios = <&tegra_main_gpio CAM0_PWDN GPIO_ACTIVE_HIGH>; + }; + + ser_a: max9295_a@40 { + compatible = "maxim,max9295"; + reg = <0x40>; + vcc-poc-supply = <&p2822_vdd_sys_en>; + maxim,gmsl-dser-device = <&dser_a>; + }; + + ds5_0: ds5@1a { + status = "ok"; + def-addr = <0x10>; + reg = <0x1a>; + compatible = "intel,d4xx"; + vcc-supply = <&p2822_vdd_sys_en>; + cam-type = "Depth"; + maxim,gmsl-ser-device = <&ser_a>; + maxim,gmsl-dser-device = <&dser_a>; + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + ds5_0_out: endpoint { + port-index = <0>; + bus-width = <2>; + remote-endpoint = <&csi_in0>; + vc-id = <0>; + }; + }; + }; + mode0 { + pixel_t = "grey_y16"; + num_lanes = "2"; + csi_pixel_bit_depth = "16"; + active_w = "128"; + active_h = "0"; + tegra_sinterface = "serial_a"; + mclk_khz = "24000"; + pix_clk_hz = "74250000"; + line_length = "1280"; /* 2200 */ + embedded_metadata_height = "1"; + }; + gmsl-link { + src-csi-port = "b"; + dst-csi-port = "a"; + serdes-csi-link = "a"; + csi-mode = "1x4"; + st-vc = <0>; + vc-id = <0>; + num-lanes = <2>; + }; + }; + + ds5_1: ds5@1b { + status = "ok"; + def-addr = <0x10>; + reg = <0x1b>; + override_reg = <0x1a>; + compatible = "intel,d4xx"; + vcc-supply = <&p2822_vdd_sys_en>; + cam-type = "RGB"; + maxim,gmsl-ser-device = <&ser_a>; + maxim,gmsl-dser-device = <&dser_a>; + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + ds5_1_out: endpoint { + port-index = <1>; + bus-width = <2>; + remote-endpoint = <&csi_in1>; + vc-id = <1>; + }; + }; + }; + mode0 { + pixel_t = "grey_y16"; + num_lanes = "2"; + csi_pixel_bit_depth = "16"; + active_w = "128"; + active_h = "0"; + tegra_sinterface = "serial_e"; + mclk_khz = "24000"; + pix_clk_hz = "74250000"; + line_length = "1280"; /* 2200 */ + embedded_metadata_height = "1"; + }; + gmsl-link { + src-csi-port = "b"; + dst-csi-port = "a"; + serdes-csi-link = "a"; + csi-mode = "1x4"; + st-vc = <0>; + vc-id = <1>; + num-lanes = <2>; + }; + }; + + ds5_2: ds5@1c { + status = "ok"; + def-addr = <0x10>; + reg = <0x1c>; + override_reg = <0x1a>; + compatible = "intel,d4xx"; + vcc-supply = <&p2822_vdd_sys_en>; + cam-type = "Y8"; + maxim,gmsl-ser-device = <&ser_a>; + maxim,gmsl-dser-device = <&dser_a>; + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + ds5_2_out: endpoint { + port-index = <2>; + bus-width = <2>; + remote-endpoint = <&csi_in2>; + vc-id = <2>; + }; + }; + }; + /* mode0: Y8, mode1: depth D16 */ + mode0 { + pixel_t = "grey_y16"; + num_lanes = "2"; + csi_pixel_bit_depth = "16"; + active_w = "128"; + active_h = "0"; + tegra_sinterface = "serial_b"; + mclk_khz = "24000"; + pix_clk_hz = "74250000"; + line_length = "1280"; /* 2200 */ + embedded_metadata_height = "1"; + }; + gmsl-link { + src-csi-port = "b"; + dst-csi-port = "a"; + serdes-csi-link = "a"; + csi-mode = "1x4"; + st-vc = <0>; + vc-id = <2>; + num-lanes = <2>; + }; + }; + + ds5_3: ds5@1d { + status = "ok"; + def-addr = <0x10>; + reg = <0x1d>; + override_reg = <0x1a>; + compatible = "intel,d4xx"; + vcc-supply = <&p2822_vdd_sys_en>; + cam-type = "IMU"; + maxim,gmsl-ser-device = <&ser_a>; + maxim,gmsl-dser-device = <&dser_a>; + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + ds5_3_out: endpoint { + port-index = <3>; + bus-width = <2>; + remote-endpoint = <&csi_in3>; + vc-id = <3>; + }; + }; + }; + mode0 { + pixel_t = "grey_y16"; + num_lanes = "2"; + csi_pixel_bit_depth = "16"; + active_w = "128"; + active_h = "0"; + tegra_sinterface = "serial_b"; + mclk_khz = "24000"; + pix_clk_hz = "74250000"; + line_length = "1280"; /* 2200 */ + embedded_metadata_height = "0"; + }; + gmsl-link { + src-csi-port = "b"; + dst-csi-port = "a"; + serdes-csi-link = "a"; + csi-mode = "1x4"; + st-vc = <0>; + vc-id = <3>; + num-lanes = <2>; + }; + }; + }; + i2c@1 { + reg = <0x1>; + #address-cells = <0x1>; + i2c-mux,deselect-on-exit; + #size-cells = <0x0>; + + dser_b: max96712@29 { + status = "ok"; + reg = <0x29>; + compatible = "maxim,max96712"; + csi-mode = "2x4"; + max-src = <1>; + channel = "b"; + pwdn-gpios = <&tegra_main_gpio CAM1_PWDN GPIO_ACTIVE_HIGH>; + }; + + ser_b: max9295_a@40 { + compatible = "maxim,max9295"; + reg = <0x40>; + maxim,gmsl-dser-device = <&dser_b>; + }; + + ds5_4: ds5@1a { + status = "ok"; + def-addr = <0x10>; + reg = <0x1a>; + compatible = "intel,d4xx"; + vcc-supply = <&p2822_vdd_sys_en>; + cam-type = "Depth"; + maxim,gmsl-ser-device = <&ser_b>; + maxim,gmsl-dser-device = <&dser_b>; + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + ds5_4_out: endpoint { + port-index = <4>; + bus-width = <2>; + remote-endpoint = <&csi_in4>; + vc-id = <0>; + }; + }; + }; + mode0 { + pixel_t = "grey_y16"; + num_lanes = "2"; + csi_pixel_bit_depth = "16"; + active_w = "128"; + active_h = "0"; + tegra_sinterface = "serial_c"; + mclk_khz = "24000"; + pix_clk_hz = "74250000"; + line_length = "1280"; /* 2200 */ + embedded_metadata_height = "1"; + }; + gmsl-link { + src-csi-port = "b"; + dst-csi-port = "c"; + serdes-csi-link = "a"; + csi-mode = "1x4"; + st-vc = <0>; + vc-id = <0>; + num-lanes = <2>; + }; + }; + + ds5_5: ds5@1b { + status = "ok"; + def-addr = <0x10>; + reg = <0x1b>; + override_reg = <0x1a>; + compatible = "intel,d4xx"; + vcc-supply = <&p2822_vdd_sys_en>; + cam-type = "RGB"; + maxim,gmsl-ser-device = <&ser_b>; + maxim,gmsl-dser-device = <&dser_b>; + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + ds5_5_out: endpoint { + port-index = <5>; + bus-width = <2>; + remote-endpoint = <&csi_in5>; + vc-id = <1>; + }; + }; + }; + mode0 { + pixel_t = "grey_y16"; + num_lanes = "2"; + csi_pixel_bit_depth = "16"; + active_w = "128"; + active_h = "0"; + tegra_sinterface = "serial_c"; + mclk_khz = "24000"; + pix_clk_hz = "74250000"; + line_length = "1280"; /* 2200 */ + embedded_metadata_height = "1"; + }; + gmsl-link { + src-csi-port = "b"; + dst-csi-port = "c"; + serdes-csi-link = "a"; + csi-mode = "1x4"; + st-vc = <0>; + vc-id = <1>; + num-lanes = <2>; + }; + }; + + ds5_6: ds5@1c { + status = "ok"; + def-addr = <0x10>; + reg = <0x1c>; + override_reg = <0x1a>; + compatible = "intel,d4xx"; + vcc-supply = <&p2822_vdd_sys_en>; + cam-type = "Y8"; + maxim,gmsl-ser-device = <&ser_b>; + maxim,gmsl-dser-device = <&dser_b>; + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + ds5_6_out: endpoint { + port-index = <6>; + bus-width = <2>; + remote-endpoint = <&csi_in6>; + vc-id = <2>; + }; + }; + }; + /* mode0: Y8, mode1: depth D16 */ + mode0 { + pixel_t = "grey_y16"; + num_lanes = "2"; + csi_pixel_bit_depth = "16"; + active_w = "128"; + active_h = "0"; + tegra_sinterface = "serial_c"; + mclk_khz = "24000"; + pix_clk_hz = "74250000"; + line_length = "1280"; /* 2200 */ + embedded_metadata_height = "1"; + }; + gmsl-link { + src-csi-port = "b"; + dst-csi-port = "c"; + serdes-csi-link = "a"; + csi-mode = "1x4"; + st-vc = <0>; + vc-id = <2>; + num-lanes = <2>; + }; + }; + + ds5_7: ds5@1d { + status = "ok"; + def-addr = <0x10>; + reg = <0x1d>; + override_reg = <0x1a>; + compatible = "intel,d4xx"; + vcc-supply = <&p2822_vdd_sys_en>; + cam-type = "IMU"; + maxim,gmsl-ser-device = <&ser_b>; + maxim,gmsl-dser-device = <&dser_b>; + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + ds5_7_out: endpoint { + port-index = <7>; + bus-width = <2>; + remote-endpoint = <&csi_in7>; + vc-id = <3>; + }; + }; + }; + mode0 { + pixel_t = "grey_y16"; + num_lanes = "2"; + csi_pixel_bit_depth = "16"; + active_w = "128"; + active_h = "0"; + tegra_sinterface = "serial_c"; + mclk_khz = "24000"; + pix_clk_hz = "74250000"; + line_length = "1280"; /* 2200 */ + embedded_metadata_height = "0"; + }; + gmsl-link { + src-csi-port = "b"; + dst-csi-port = "c"; + serdes-csi-link = "a"; + csi-mode = "1x4"; + st-vc = <0>; + vc-id = <3>; + num-lanes = <2>; + }; + }; + }; + }; + }; + + host1x@13e00000 { + nvcsi@15a00000 { + #address-cells = <0x1>; + #size-cells = <0x0>; + + num-channels = <8>; + + channel@0 { + reg = <0x0>; + status = "ok"; + + ports { + #address-cells = <0x1>; + #size-cells = <0x0>; + + port@0 { + reg = <0>; + status = "ok"; + + csi_in0: endpoint@0 { + status = "ok"; + port-index = <0>; + bus-width = <2>; + remote-endpoint = <&ds5_0_out>; + }; + }; + port@1 { + reg = <1>; + status = "ok"; + csi_out0: endpoint@1 { + status = "ok"; + remote-endpoint = <&vi_in0>; + }; + }; + + }; + }; + channel@1 { + reg = <0x1>; + status = "ok"; + + ports { + #address-cells = <0x1>; + #size-cells = <0x0>; + + port@0 { + reg = <0>; + status = "ok"; + + csi_in1: endpoint@2 { + status = "ok"; + port-index = <0>; + bus-width = <2>; + remote-endpoint = <&ds5_1_out>; + }; + }; + port@1 { + reg = <1>; + status = "ok"; + csi_out1: endpoint@3 { + status = "ok"; + remote-endpoint = <&vi_in1>; + }; + }; + + }; + }; + channel@2 { + reg = <0x2>; + status = "ok"; + + ports { + #address-cells = <0x1>; + #size-cells = <0x0>; + + port@0 { + reg = <0>; + status = "ok"; + + csi_in2: endpoint@4 { + status = "ok"; + port-index = <0>; + bus-width = <2>; + remote-endpoint = <&ds5_2_out>; + }; + }; + port@1 { + reg = <1>; + status = "ok"; + csi_out2: endpoint@5 { + status = "ok"; + remote-endpoint = <&vi_in2>; + }; + }; + }; + }; + channel@3 { + reg = <0x3>; + status = "ok"; + + ports { + #address-cells = <0x1>; + #size-cells = <0x0>; + + port@0 { + reg = <0>; + status = "ok"; + + csi_in3: endpoint@6 { + status = "ok"; + port-index = <0>; + bus-width = <2>; + remote-endpoint = <&ds5_3_out>; + }; + }; + port@1 { + reg = <1>; + status = "ok"; + csi_out3: endpoint@7 { + status = "ok"; + remote-endpoint = <&vi_in3>; + }; + }; + }; + }; + channel@4 { + reg = <0x4>; + status = "ok"; + + ports { + #address-cells = <0x1>; + #size-cells = <0x0>; + + port@0 { + reg = <0>; + status = "ok"; + + csi_in4: endpoint@8 { + status = "ok"; + port-index = <2>; + bus-width = <2>; + remote-endpoint = <&ds5_4_out>; + }; + }; + port@1 { + reg = <1>; + status = "ok"; + csi_out4: endpoint@9 { + status = "ok"; + remote-endpoint = <&vi_in4>; + }; + }; + + }; + }; + channel@5 { + reg = <0x5>; + status = "ok"; + + ports { + #address-cells = <0x1>; + #size-cells = <0x0>; + + port@0 { + reg = <0>; + status = "ok"; + + csi_in5: endpoint@10 { + status = "ok"; + port-index = <2>; + bus-width = <2>; + remote-endpoint = <&ds5_5_out>; + }; + }; + port@1 { + reg = <1>; + status = "ok"; + csi_out5: endpoint@11 { + status = "ok"; + remote-endpoint = <&vi_in5>; + }; + }; + + }; + }; + channel@6 { + reg = <0x6>; + status = "ok"; + + ports { + #address-cells = <0x1>; + #size-cells = <0x0>; + + port@0 { + reg = <0>; + status = "ok"; + + csi_in6: endpoint@12 { + status = "ok"; + port-index = <2>; + bus-width = <2>; + remote-endpoint = <&ds5_6_out>; + }; + }; + port@1 { + reg = <1>; + status = "ok"; + csi_out6: endpoint@13 { + status = "ok"; + remote-endpoint = <&vi_in6>; + }; + }; + }; + }; + channel@7 { + reg = <0x7>; + status = "ok"; + + ports { + #address-cells = <0x1>; + #size-cells = <0x0>; + + port@0 { + reg = <0>; + status = "ok"; + + csi_in7: endpoint@14 { + status = "ok"; + port-index = <2>; + bus-width = <2>; + remote-endpoint = <&ds5_7_out>; + }; + }; + port@1 { + reg = <1>; + status = "ok"; + csi_out7: endpoint@15 { + status = "ok"; + remote-endpoint = <&vi_in7>; + }; + }; + }; + }; + }; + }; +}; diff --git a/hardware/realsense/tegra194-camera-d4xx-fg12-16ch.dtsi b/hardware/realsense/tegra194-camera-d4xx-fg12-16ch.dtsi new file mode 100644 index 00000000..3b9a0ff6 --- /dev/null +++ b/hardware/realsense/tegra194-camera-d4xx-fg12-16ch.dtsi @@ -0,0 +1,424 @@ +#include "dt-bindings/clock/tegra194-clock.h" + +#define CAMERA_I2C_MUX_BUS(x) (0x1E + x) + +#define CAM0_PWDN TEGRA194_MAIN_GPIO(H, 6) +#define CAM1_PWDN TEGRA194_MAIN_GPIO(H, 3) +#define CAM2_PWDN TEGRA194_MAIN_GPIO(T, 5) +#define CAM3_PWDN TEGRA194_MAIN_GPIO(T, 6) + +/ { + tegra-capture-vi { + num-channels = <4>; + + ports { + #address-cells = <0x1>; + #size-cells = <0x0>; + + port@0 { + reg = <0>; + status = "ok"; + + vi_in0: endpoint { + status = "ok"; + port-index = <0>; + bus-width = <2>; + vc-id = <0>; + remote-endpoint = <&csi_out0>; + }; + }; + port@1 { + reg = <1>; + status = "ok"; + + vi_in1: endpoint { + status = "ok"; + vc-id = <1>; + port-index = <0>; + bus-width = <2>; + remote-endpoint = <&csi_out1>; + }; + }; + port@2 { + reg = <2>; + status = "ok"; + + vi_in2: endpoint { + status = "ok"; + port-index = <0>; + bus-width = <2>; + vc-id = <2>; + remote-endpoint = <&csi_out2>; + }; + }; + port@3 { + reg = <3>; + status = "ok"; + + vi_in3: endpoint { + status = "ok"; + port-index = <0>; + bus-width = <2>; + vc-id = <3>; + remote-endpoint = <&csi_out3>; + }; + }; + }; + }; + + i2c@3180000 { + status = "ok"; + clock-frequency = <100000>; + tca9546@70 { + status = "ok"; + reg = <0x70>; + compatible = "nxp,pca9546"; + #address-cells = <1>; + #size-cells = <0>; + skip_mux_detect = "yes"; + vcc-supply = <&p2822_vdd_sys_en>; + /*vcc-pullup-supply = <&battery_reg>;*/ + force_bus_start = ; + vcc_lp = "vcc"; + i2c@0 { + reg = <0x0>; + #address-cells = <0x1>; + i2c-mux,deselect-on-exit; + #size-cells = <0x0>; + + dser: max96712@29 { + status = "ok"; + reg = <0x29>; + compatible = "maxim,max96712"; + csi-mode = "2x4"; + max-src = <1>; + channel = "a"; + pwdn-gpios = <&tegra_main_gpio CAM0_PWDN GPIO_ACTIVE_HIGH>; + }; + + ser_a: max9295_a@40 { + compatible = "maxim,max9295"; + reg = <0x40>; + vcc-poc-supply = <&p2822_vdd_sys_en>; + maxim,gmsl-dser-device = <&dser>; + }; + + ds5_0: ds5@1a { + status = "ok"; + def-addr = <0x10>; + reg = <0x1a>; + compatible = "intel,d4xx"; + vcc-supply = <&p2822_vdd_sys_en>; + cam-type = "Depth"; + maxim,gmsl-ser-device = <&ser_a>; + maxim,gmsl-dser-device = <&dser>; + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + ds5_0_out: endpoint { + port-index = <0>; + bus-width = <2>; + remote-endpoint = <&csi_in0>; + vc-id = <0>; + }; + }; + }; + mode0 { + pixel_t = "grey_y16"; + num_lanes = "2"; + csi_pixel_bit_depth = "16"; + active_w = "128"; + active_h = "0"; + tegra_sinterface = "serial_a"; + mclk_khz = "24000"; + pix_clk_hz = "74250000"; + line_length = "1280"; /* 2200 */ + embedded_metadata_height = "1"; + }; + gmsl-link { + src-csi-port = "b"; + dst-csi-port = "a"; + serdes-csi-link = "a"; + csi-mode = "1x4"; + st-vc = <0>; + vc-id = <0>; + num-lanes = <2>; + }; + }; + + ds5_1: ds5@1b { + status = "ok"; + def-addr = <0x10>; + reg = <0x1b>; + override_reg = <0x1a>; + compatible = "intel,d4xx"; + vcc-supply = <&p2822_vdd_sys_en>; + cam-type = "RGB"; + maxim,gmsl-ser-device = <&ser_a>; + maxim,gmsl-dser-device = <&dser>; + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + ds5_1_out: endpoint { + port-index = <1>; + bus-width = <2>; + remote-endpoint = <&csi_in1>; + vc-id = <1>; + }; + }; + }; + mode0 { + pixel_t = "grey_y16"; + num_lanes = "2"; + csi_pixel_bit_depth = "16"; + active_w = "128"; + active_h = "0"; + tegra_sinterface = "serial_e"; + mclk_khz = "24000"; + pix_clk_hz = "74250000"; + line_length = "1280"; /* 2200 */ + embedded_metadata_height = "1"; + }; + gmsl-link { + src-csi-port = "b"; + dst-csi-port = "a"; + serdes-csi-link = "a"; + csi-mode = "1x4"; + st-vc = <0>; + vc-id = <1>; + num-lanes = <2>; + }; + }; + + ds5_2: ds5@1c { + status = "ok"; + def-addr = <0x10>; + reg = <0x1c>; + override_reg = <0x1a>; + compatible = "intel,d4xx"; + vcc-supply = <&p2822_vdd_sys_en>; + cam-type = "Y8"; + maxim,gmsl-ser-device = <&ser_a>; + maxim,gmsl-dser-device = <&dser>; + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + ds5_2_out: endpoint { + port-index = <2>; + bus-width = <2>; + remote-endpoint = <&csi_in2>; + vc-id = <2>; + }; + }; + }; + /* mode0: Y8, mode1: depth D16 */ + mode0 { + pixel_t = "grey_y16"; + num_lanes = "2"; + csi_pixel_bit_depth = "16"; + active_w = "128"; + active_h = "0"; + tegra_sinterface = "serial_b"; + mclk_khz = "24000"; + pix_clk_hz = "74250000"; + line_length = "1280"; /* 2200 */ + embedded_metadata_height = "1"; + }; + gmsl-link { + src-csi-port = "b"; + dst-csi-port = "a"; + serdes-csi-link = "a"; + csi-mode = "1x4"; + st-vc = <0>; + vc-id = <2>; + num-lanes = <2>; + }; + }; + + ds5_3: ds5@1d { + status = "ok"; + def-addr = <0x10>; + reg = <0x1d>; + override_reg = <0x1a>; + compatible = "intel,d4xx"; + vcc-supply = <&p2822_vdd_sys_en>; + cam-type = "IMU"; + maxim,gmsl-ser-device = <&ser_a>; + maxim,gmsl-dser-device = <&dser>; + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + ds5_3_out: endpoint { + port-index = <3>; + bus-width = <2>; + remote-endpoint = <&csi_in3>; + vc-id = <3>; + }; + }; + }; + mode0 { + pixel_t = "grey_y16"; + num_lanes = "2"; + csi_pixel_bit_depth = "16"; + active_w = "128"; + active_h = "0"; + tegra_sinterface = "serial_b"; + mclk_khz = "24000"; + pix_clk_hz = "74250000"; + line_length = "1280"; /* 2200 */ + embedded_metadata_height = "0"; + }; + gmsl-link { + src-csi-port = "b"; + dst-csi-port = "a"; + serdes-csi-link = "a"; + csi-mode = "1x4"; + st-vc = <0>; + vc-id = <3>; + num-lanes = <2>; + }; + }; + }; + }; + }; + + host1x@13e00000 { + nvcsi@15a00000 { + #address-cells = <0x1>; + #size-cells = <0x0>; + + num-channels = <4>; + + channel@0 { + reg = <0x0>; + status = "ok"; + + ports { + #address-cells = <0x1>; + #size-cells = <0x0>; + + port@0 { + reg = <0>; + status = "ok"; + + csi_in0: endpoint@0 { + status = "ok"; + port-index = <0>; + bus-width = <2>; + remote-endpoint = <&ds5_0_out>; + }; + }; + port@1 { + reg = <1>; + status = "ok"; + csi_out0: endpoint@1 { + status = "ok"; + remote-endpoint = <&vi_in0>; + }; + }; + + }; + }; + channel@1 { + reg = <0x1>; + status = "ok"; + + ports { + #address-cells = <0x1>; + #size-cells = <0x0>; + + port@0 { + reg = <0>; + status = "ok"; + + csi_in1: endpoint@2 { + status = "ok"; + port-index = <0>; + bus-width = <2>; + remote-endpoint = <&ds5_1_out>; + }; + }; + port@1 { + reg = <1>; + status = "ok"; + csi_out1: endpoint@3 { + status = "ok"; + remote-endpoint = <&vi_in1>; + }; + }; + + }; + }; + channel@2 { + reg = <0x2>; + status = "ok"; + + ports { + #address-cells = <0x1>; + #size-cells = <0x0>; + + port@0 { + reg = <0>; + status = "ok"; + + csi_in2: endpoint@4 { + status = "ok"; + port-index = <0>; + bus-width = <2>; + remote-endpoint = <&ds5_2_out>; + }; + }; + port@1 { + reg = <1>; + status = "ok"; + csi_out2: endpoint@5 { + status = "ok"; + remote-endpoint = <&vi_in2>; + }; + }; + }; + }; + channel@3 { + reg = <0x3>; + status = "ok"; + + ports { + #address-cells = <0x1>; + #size-cells = <0x0>; + + port@0 { + reg = <0>; + status = "ok"; + + csi_in3: endpoint@6 { + status = "ok"; + port-index = <0>; + bus-width = <2>; + remote-endpoint = <&ds5_3_out>; + }; + }; + port@1 { + reg = <1>; + status = "ok"; + csi_out3: endpoint@7 { + status = "ok"; + remote-endpoint = <&vi_in3>; + }; + }; + }; + }; + }; + }; +}; diff --git a/hardware/realsense/tegra194-camera-d4xx-max96712-EVB.dtsi b/hardware/realsense/tegra194-camera-d4xx-max96712-EVB.dtsi new file mode 100644 index 00000000..9c0a0997 --- /dev/null +++ b/hardware/realsense/tegra194-camera-d4xx-max96712-EVB.dtsi @@ -0,0 +1,418 @@ +#include "dt-bindings/clock/tegra194-clock.h" + +#define CAMERA_I2C_MUX_BUS(x) (0x1E + x) + +/ { + tegra-capture-vi { + num-channels = <4>; + + ports { + #address-cells = <0x1>; + #size-cells = <0x0>; + + port@0 { + reg = <0>; + status = "ok"; + + vi_in0: endpoint { + status = "ok"; + port-index = <0>; + bus-width = <2>; + vc-id = <0>; + remote-endpoint = <&csi_out0>; + }; + }; + port@1 { + reg = <1>; + status = "ok"; + + vi_in1: endpoint { + status = "ok"; + vc-id = <1>; + port-index = <0>; + bus-width = <2>; + remote-endpoint = <&csi_out1>; + }; + }; + port@2 { + reg = <2>; + status = "ok"; + + vi_in2: endpoint { + status = "ok"; + port-index = <0>; + bus-width = <2>; + vc-id = <2>; + remote-endpoint = <&csi_out2>; + }; + }; + port@3 { + reg = <3>; + status = "ok"; + + vi_in3: endpoint { + status = "ok"; + port-index = <0>; + bus-width = <2>; + vc-id = <3>; + remote-endpoint = <&csi_out3>; + }; + }; + }; + }; + + i2c@3180000 { + status = "ok"; + clock-frequency = <100000>; + tca9548@72 { + status = "ok"; + reg = <0x72>; + compatible = "nxp,pca9548"; + #address-cells = <1>; + #size-cells = <0>; + skip_mux_detect = "yes"; + //vcc-supply = <&p2822_vdd_sys_en>; + /*vcc-pullup-supply = <&battery_reg>;*/ + force_bus_start = ; + vcc_lp = "vcc"; + i2c@0 { + reg = <0x0>; + #address-cells = <0x1>; + i2c-mux,deselect-on-exit; + #size-cells = <0x0>; + + dser: max96712@29 { + status = "ok"; + reg = <0x29>; + compatible = "maxim,max96712"; + csi-mode = "2x4"; + max-src = <1>; + channel = "a"; + }; + + ser_a: max9295_a@40 { + compatible = "maxim,max9295"; + reg = <0x40>; + vcc-poc-supply = <&p2822_vdd_sys_en>; + maxim,gmsl-dser-device = <&dser>; + }; + + ds5_0: ds5@1a { + status = "ok"; + def-addr = <0x10>; + reg = <0x1a>; + compatible = "intel,d4xx"; + //vcc-supply = <&p2822_vdd_sys_en>; + cam-type = "Depth"; + maxim,gmsl-ser-device = <&ser_a>; + maxim,gmsl-dser-device = <&dser>; + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + ds5_0_out: endpoint { + port-index = <0>; + bus-width = <2>; + remote-endpoint = <&csi_in0>; + vc-id = <0>; + }; + }; + }; + mode0 { + pixel_t = "grey_y16"; + num_lanes = "2"; + csi_pixel_bit_depth = "16"; + active_w = "128"; + active_h = "0"; + tegra_sinterface = "serial_a"; + mclk_khz = "24000"; + pix_clk_hz = "74250000"; + line_length = "1280"; /* 2200 */ + embedded_metadata_height = "1"; + }; + gmsl-link { + src-csi-port = "b"; + dst-csi-port = "a"; + serdes-csi-link = "a"; + csi-mode = "1x4"; + st-vc = <0>; + vc-id = <0>; + num-lanes = <2>; + }; + }; + + ds5_1: ds5@1b { + status = "ok"; + def-addr = <0x10>; + reg = <0x1b>; + override_reg = <0x1a>; + compatible = "intel,d4xx"; + //vcc-supply = <&p2822_vdd_sys_en>; + cam-type = "RGB"; + maxim,gmsl-ser-device = <&ser_a>; + maxim,gmsl-dser-device = <&dser>; + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + ds5_1_out: endpoint { + port-index = <1>; + bus-width = <2>; + remote-endpoint = <&csi_in1>; + vc-id = <1>; + }; + }; + }; + mode0 { + pixel_t = "grey_y16"; + num_lanes = "2"; + csi_pixel_bit_depth = "16"; + active_w = "128"; + active_h = "0"; + tegra_sinterface = "serial_e"; + mclk_khz = "24000"; + pix_clk_hz = "74250000"; + line_length = "1280"; /* 2200 */ + embedded_metadata_height = "1"; + }; + gmsl-link { + src-csi-port = "b"; + dst-csi-port = "a"; + serdes-csi-link = "a"; + csi-mode = "1x4"; + st-vc = <0>; + vc-id = <1>; + num-lanes = <2>; + }; + }; + + ds5_2: ds5@1c { + status = "ok"; + def-addr = <0x10>; + reg = <0x1c>; + override_reg = <0x1a>; + compatible = "intel,d4xx"; + //vcc-supply = <&p2822_vdd_sys_en>; + cam-type = "Y8"; + maxim,gmsl-ser-device = <&ser_a>; + maxim,gmsl-dser-device = <&dser>; + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + ds5_2_out: endpoint { + port-index = <2>; + bus-width = <2>; + remote-endpoint = <&csi_in2>; + vc-id = <2>; + }; + }; + }; + /* mode0: Y8, mode1: depth D16 */ + mode0 { + pixel_t = "grey_y16"; + num_lanes = "2"; + csi_pixel_bit_depth = "16"; + active_w = "128"; + active_h = "0"; + tegra_sinterface = "serial_b"; + mclk_khz = "24000"; + pix_clk_hz = "74250000"; + line_length = "1280"; /* 2200 */ + embedded_metadata_height = "1"; + }; + gmsl-link { + src-csi-port = "b"; + dst-csi-port = "a"; + serdes-csi-link = "a"; + csi-mode = "1x4"; + st-vc = <0>; + vc-id = <2>; + num-lanes = <2>; + }; + }; + + ds5_3: ds5@1d { + status = "ok"; + def-addr = <0x10>; + reg = <0x1d>; + override_reg = <0x1a>; + compatible = "intel,d4xx"; + //vcc-supply = <&p2822_vdd_sys_en>; + cam-type = "IMU"; + maxim,gmsl-ser-device = <&ser_a>; + maxim,gmsl-dser-device = <&dser>; + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + ds5_3_out: endpoint { + port-index = <3>; + bus-width = <2>; + remote-endpoint = <&csi_in3>; + vc-id = <3>; + }; + }; + }; + mode0 { + pixel_t = "grey_y16"; + num_lanes = "2"; + csi_pixel_bit_depth = "16"; + active_w = "128"; + active_h = "0"; + tegra_sinterface = "serial_b"; + mclk_khz = "24000"; + pix_clk_hz = "74250000"; + line_length = "1280"; /* 2200 */ + embedded_metadata_height = "0"; + }; + gmsl-link { + src-csi-port = "b"; + dst-csi-port = "a"; + serdes-csi-link = "a"; + csi-mode = "1x4"; + st-vc = <0>; + vc-id = <3>; + num-lanes = <2>; + }; + }; + }; + }; + }; + + host1x@13e00000 { + nvcsi@15a00000 { + #address-cells = <0x1>; + #size-cells = <0x0>; + + num-channels = <4>; + + channel@0 { + reg = <0x0>; + status = "ok"; + + ports { + #address-cells = <0x1>; + #size-cells = <0x0>; + + port@0 { + reg = <0>; + status = "ok"; + + csi_in0: endpoint@0 { + status = "ok"; + port-index = <0>; + bus-width = <2>; + remote-endpoint = <&ds5_0_out>; + }; + }; + port@1 { + reg = <1>; + status = "ok"; + csi_out0: endpoint@1 { + status = "ok"; + remote-endpoint = <&vi_in0>; + }; + }; + + }; + }; + channel@1 { + reg = <0x1>; + status = "ok"; + + ports { + #address-cells = <0x1>; + #size-cells = <0x0>; + + port@0 { + reg = <0>; + status = "ok"; + + csi_in1: endpoint@2 { + status = "ok"; + port-index = <0>; + bus-width = <2>; + remote-endpoint = <&ds5_1_out>; + }; + }; + port@1 { + reg = <1>; + status = "ok"; + csi_out1: endpoint@3 { + status = "ok"; + remote-endpoint = <&vi_in1>; + }; + }; + + }; + }; + channel@2 { + reg = <0x2>; + status = "ok"; + + ports { + #address-cells = <0x1>; + #size-cells = <0x0>; + + port@0 { + reg = <0>; + status = "ok"; + + csi_in2: endpoint@4 { + status = "ok"; + port-index = <0>; + bus-width = <2>; + remote-endpoint = <&ds5_2_out>; + }; + }; + port@1 { + reg = <1>; + status = "ok"; + csi_out2: endpoint@5 { + status = "ok"; + remote-endpoint = <&vi_in2>; + }; + }; + }; + }; + channel@3 { + reg = <0x3>; + status = "ok"; + + ports { + #address-cells = <0x1>; + #size-cells = <0x0>; + + port@0 { + reg = <0>; + status = "ok"; + + csi_in3: endpoint@6 { + status = "ok"; + port-index = <0>; + bus-width = <2>; + remote-endpoint = <&ds5_3_out>; + }; + }; + port@1 { + reg = <1>; + status = "ok"; + csi_out3: endpoint@7 { + status = "ok"; + remote-endpoint = <&vi_in3>; + }; + }; + }; + }; + }; + }; +}; diff --git a/hardware/realsense/tegra234-camera-d4xx-overlay-fg12-16ch-dual.dts b/hardware/realsense/tegra234-camera-d4xx-overlay-fg12-16ch-dual.dts new file mode 100644 index 00000000..ee7f94d1 --- /dev/null +++ b/hardware/realsense/tegra234-camera-d4xx-overlay-fg12-16ch-dual.dts @@ -0,0 +1,794 @@ +// SPDX-License-Identifier: GPL-2.0-only +// SPDX-FileCopyrightText: Copyright (c) 2018-2023, INTEL CORPORATION. All rights reserved. + +/dts-v1/; +/plugin/; + +#include +#include +#include + +#define CAM0_PWDN TEGRA234_MAIN_GPIO(H, 6) //MAX96712_1 PWDN +#define CAM1_PWDN TEGRA234_MAIN_GPIO(H, 3) //MAX96712_2 PWDN +//#define CAM2_PWDN TEGRA234_MAIN_GPIO(AC, 0) //MAX96712_3 PWDN +//#define CAM3_PWDN TEGRA234_MAIN_GPIO(AC, 1) //MAX96712_4 PWDN +#define CAM12V_POC TEGRA234_MAIN_GPIO(AC, 7) + +#define CAMERA_I2C_MUX_BUS(x) (0x1E + x) + + + +/* camera control gpio definitions */ +/ { + overlay-name = "Jetson RealSense Camera D457"; + jetson-header-name = "Jetson AGX CSI Connector"; + compatible = JETSON_COMPATIBLE; + + fragment@1 { + target-path = "/"; + __overlay__ { + vdd_cam12v_poc: regulator-vdd-cam12v-poc { + compatible = "regulator-fixed"; + regulator-name = "vdd-cam12v-poc"; + regulator-min-microvolt = <12000000>; + regulator-max-microvolt = <12000000>; + gpio = <&gpio CAM12V_POC GPIO_ACTIVE_HIGH>; + enable-active-high; + }; + }; + }; + fragment@0 { + target-path = "/"; + __overlay__ { + tegra-capture-vi { + num-channels = <8>; + ports { + status = "okay"; + port@0 { + status = "okay"; + reg = <0>; + d4xx_vi_in0: endpoint { + status = "okay"; + vc-id = <0>; + port-index = <0>; + bus-width = <2>; + remote-endpoint = <&d4xx_csi_out0>; + }; + }; + port@1 { + status = "okay"; + reg = <1>; + d4xx_vi_in1: endpoint { + status = "okay"; + vc-id = <1>; + port-index = <0>; + bus-width = <2>; + remote-endpoint = <&d4xx_csi_out1>; + }; + }; + port@2 { + status = "okay"; + reg = <2>; + d4xx_vi_in2: endpoint { + status = "okay"; + vc-id = <2>; + port-index = <0>; + bus-width = <2>; + remote-endpoint = <&d4xx_csi_out2>; + }; + }; + port@3 { + status = "okay"; + reg = <3>; + d4xx_vi_in3: endpoint { + status = "okay"; + vc-id = <3>; + port-index = <0>; + bus-width = <2>; + remote-endpoint = <&d4xx_csi_out3>; + }; + }; + port@4 { + status = "okay"; + reg = <4>; + d4xx_vi_in4: endpoint { + status = "okay"; + vc-id = <0>; + port-index = <2>; + bus-width = <2>; + remote-endpoint = <&d4xx_csi_out4>; + }; + }; + port@5 { + status = "okay"; + reg = <5>; + d4xx_vi_in5: endpoint { + status = "okay"; + vc-id = <1>; + port-index = <2>; + bus-width = <2>; + remote-endpoint = <&d4xx_csi_out5>; + }; + }; + port@6 { + status = "okay"; + reg = <6>; + d4xx_vi_in6: endpoint { + status = "okay"; + vc-id = <2>; + port-index = <2>; + bus-width = <2>; + remote-endpoint = <&d4xx_csi_out6>; + }; + }; + port@7 { + status = "okay"; + reg = <7>; + d4xx_vi_in7: endpoint { + status = "okay"; + vc-id = <3>; + port-index = <2>; + bus-width = <2>; + remote-endpoint = <&d4xx_csi_out7>; + }; + }; + }; + }; + + bus@0 { + host1x@13e00000 { + nvcsi@15a00000 { + num-channels = <8>; + channel@0 { + status = "okay"; + reg = <0>; + ports { + status = "okay"; + port@0 { + status = "okay"; + reg = <0>; + d4xx_csi_in0: endpoint@0 { + status = "okay"; + port-index = <0>; + bus-width = <2>; + remote-endpoint = <&ds5_0_out>; + }; + }; + port@1 { + status = "okay"; + reg = <1>; + d4xx_csi_out0: endpoint@1 { + status = "okay"; + remote-endpoint = <&d4xx_vi_in0>; + }; + }; + }; + }; + channel@1 { + status = "okay"; + reg = <1>; + ports { + status = "okay"; + port@0 { + status = "okay"; + reg = <0>; + d4xx_csi_in1: endpoint@2 { + status = "okay"; + port-index = <0>; + bus-width = <2>; + remote-endpoint = <&ds5_1_out>; + }; + }; + port@1 { + status = "okay"; + reg = <1>; + d4xx_csi_out1: endpoint@3 { + status = "okay"; + remote-endpoint = <&d4xx_vi_in1>; + }; + }; + }; + }; + channel@2 { + status = "okay"; + reg = <2>; + ports { + status = "okay"; + port@0 { + status = "okay"; + reg = <0>; + d4xx_csi_in2: endpoint@4 { + status = "okay"; + port-index = <0>; + bus-width = <2>; + remote-endpoint = <&ds5_2_out>; + }; + }; + port@1 { + status = "okay"; + reg = <1>; + d4xx_csi_out2: endpoint@5 { + status = "okay"; + remote-endpoint = <&d4xx_vi_in2>; + }; + }; + }; + }; + channel@3 { + status = "okay"; + reg = <3>; + ports { + status = "okay"; + port@0 { + status = "okay"; + reg = <0>; + d4xx_csi_in3: endpoint@6 { + status = "okay"; + port-index = <0>; + bus-width = <2>; + remote-endpoint = <&ds5_3_out>; + }; + }; + port@1 { + status = "okay"; + reg = <1>; + d4xx_csi_out3: endpoint@7 { + status = "okay"; + remote-endpoint = <&d4xx_vi_in3>; + }; + }; + }; + }; + channel@4 { + status = "okay"; + reg = <4>; + ports { + status = "okay"; + port@0 { + status = "okay"; + reg = <0>; + d4xx_csi_in4: endpoint@8 { + status = "okay"; + port-index = <2>; + bus-width = <2>; + remote-endpoint = <&ds5_4_out>; + }; + }; + port@1 { + status = "okay"; + reg = <1>; + d4xx_csi_out4: endpoint@9 { + status = "okay"; + remote-endpoint = <&d4xx_vi_in4>; + }; + }; + }; + }; + channel@5 { + status = "okay"; + reg = <5>; + ports { + status = "okay"; + port@0 { + status = "okay"; + reg = <0>; + d4xx_csi_in5: endpoint@10 { + status = "okay"; + port-index = <2>; + bus-width = <2>; + remote-endpoint = <&ds5_5_out>; + }; + }; + port@1 { + status = "okay"; + reg = <1>; + d4xx_csi_out5: endpoint@11 { + status = "okay"; + remote-endpoint = <&d4xx_vi_in5>; + }; + }; + }; + }; + channel@6 { + status = "okay"; + reg = <6>; + ports { + status = "okay"; + port@0 { + status = "okay"; + reg = <0>; + d4xx_csi_in6: endpoint@12 { + status = "okay"; + port-index = <2>; + bus-width = <2>; + remote-endpoint = <&ds5_6_out>; + }; + }; + port@1 { + status = "okay"; + reg = <1>; + d4xx_csi_out6: endpoint@13 { + status = "okay"; + remote-endpoint = <&d4xx_vi_in6>; + }; + }; + }; + }; + channel@7 { + status = "okay"; + reg = <7>; + ports { + status = "okay"; + port@0 { + status = "okay"; + reg = <0>; + d4xx_csi_in7: endpoint@14 { + status = "okay"; + port-index = <2>; + bus-width = <2>; + remote-endpoint = <&ds5_7_out>; + }; + }; + port@1 { + status = "okay"; + reg = <1>; + d4xx_csi_out7: endpoint@15 { + status = "okay"; + remote-endpoint = <&d4xx_vi_in7>; + }; + }; + }; + }; + }; + }; + + i2c@3180000 { + clock-frequency = <100000>; + tca9546@70 { + status = "okay"; + reg = <0x70>; + compatible = "nxp,pca9546"; + #address-cells = <1>; + #size-cells = <0>; + skip_mux_detect = "yes"; + /*vcc-pullup-supply = <&battery_reg>;*/ + force_bus_start = ; + vcc_lp = "vcc"; + i2c@0 { + status = "okay"; + reg = <0>; + i2c-mux,deselect-on-exit; + #address-cells = <1>; + #size-cells = <0>; + + dser_a: max96712@29 { + status = "okay"; + reg = <0x29>; + compatible = "maxim,max96712"; + csi-mode = "2x4"; + max-src = <1>; + channel = "a"; + pwdn-gpios = <&gpio CAM0_PWDN GPIO_ACTIVE_HIGH>; + }; + + ser_a: max9295_a@40 { + status = "okay"; + compatible = "maxim,max9295"; + reg = <0x40>; + maxim,gmsl-dser-device = <&dser_a>; + }; + + ds5_3: ds5@1d { + status = "okay"; + def-addr = <0x10>; + reg = <0x1d>; + override_reg = <0x1a>; + compatible = "intel,d4xx"; + use_sensor_mode_id = "true"; + vcc-supply = <&vdd_cam12v_poc>; + cam-type = "IMU"; + nvidia,gmsl-ser-device = <&ser_a>; + nvidia,gmsl-dser-device = <&dser_a>; + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + ds5_3_out: endpoint { + vc-id = <3>; + port-index = <3>; + bus-width = <2>; + remote-endpoint = <&d4xx_csi_in3>; + }; + }; + }; + mode0 { + pixel_t = "grey_y16"; + num_lanes = "2"; + csi_pixel_bit_depth = "16"; + active_w = "640"; + active_h = "480"; + tegra_sinterface = "serial_b"; + mclk_khz = "24000"; + pix_clk_hz = "74250000"; + line_length = "1280"; /* 2200 */ + embedded_metadata_height = "0"; + }; + gmsl-link { + src-csi-port = "b"; + dst-csi-port = "a"; + serdes-csi-link = "a"; + csi-mode = "1x4"; + st-vc = <0>; + vc-id = <3>; + num-lanes = <2>; + }; + }; + + ds5_2: ds5@1c { + status = "okay"; + def-addr = <0x10>; + reg = <0x1c>; + override_reg = <0x1a>; + compatible = "intel,d4xx"; + use_sensor_mode_id = "true"; + vcc-supply = <&vdd_cam12v_poc>; + cam-type = "Y8"; + nvidia,gmsl-ser-device = <&ser_a>; + nvidia,gmsl-dser-device = <&dser_a>; + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + ds5_2_out: endpoint { + vc-id = <2>; + port-index = <2>; + bus-width = <2>; + remote-endpoint = <&d4xx_csi_in2>; + }; + }; + }; + /* mode0: Y8, mode1: depth D16 */ + mode0 { + pixel_t = "grey_y16"; + num_lanes = "2"; + csi_pixel_bit_depth = "16"; + active_w = "1280"; + active_h = "720"; + tegra_sinterface = "serial_b"; + mclk_khz = "24000"; + pix_clk_hz = "74250000"; + line_length = "1280"; /* 2200 */ + embedded_metadata_height = "1"; + }; + gmsl-link { + src-csi-port = "b"; + dst-csi-port = "a"; + serdes-csi-link = "a"; + csi-mode = "1x4"; + st-vc = <0>; + vc-id = <2>; + num-lanes = <2>; + }; + }; + + ds5_1: ds5@1b { + status = "okay"; + def-addr = <0x10>; + reg = <0x1b>; + override_reg = <0x1a>; + compatible = "intel,d4xx"; + use_sensor_mode_id = "true"; + vcc-supply = <&vdd_cam12v_poc>; + cam-type = "RGB"; + nvidia,gmsl-ser-device = <&ser_a>; + nvidia,gmsl-dser-device = <&dser_a>; + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + ds5_1_out: endpoint { + vc-id = <1>; + port-index = <1>; + bus-width = <2>; + remote-endpoint = <&d4xx_csi_in1>; + }; + }; + }; + mode0 { + pixel_t = "grey_y16"; + num_lanes = "2"; + csi_pixel_bit_depth = "16"; + active_w = "1920"; + active_h = "1080"; + tegra_sinterface = "serial_e"; + mclk_khz = "24000"; + pix_clk_hz = "74250000"; + line_length = "1280"; /* 2200 */ + embedded_metadata_height = "1"; + }; + gmsl-link { + src-csi-port = "b"; + dst-csi-port = "a"; + serdes-csi-link = "a"; + csi-mode = "1x4"; + st-vc = <0>; + vc-id = <1>; + num-lanes = <2>; + }; + }; + + ds5_0: ds5@1a { + status = "okay"; + def-addr = <0x10>; + reg = <0x1a>; + compatible = "intel,d4xx"; + use_sensor_mode_id = "true"; + vcc-supply = <&vdd_cam12v_poc>; + cam-type = "Depth"; + nvidia,gmsl-ser-device = <&ser_a>; + nvidia,gmsl-dser-device = <&dser_a>; + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + ds5_0_out: endpoint { + vc-id = <0>; + port-index = <0>; + bus-width = <2>; + remote-endpoint = <&d4xx_csi_in0>; + }; + }; + }; + mode0 { + pixel_t = "grey_y16"; + num_lanes = "2"; + csi_pixel_bit_depth = "16"; + active_w = "1280"; + active_h = "720"; + tegra_sinterface = "serial_a"; + mclk_khz = "24000"; + pix_clk_hz = "74250000"; + line_length = "1280"; /* 2200 */ + embedded_metadata_height = "1"; + }; + gmsl-link { + src-csi-port = "b"; + dst-csi-port = "a"; + serdes-csi-link = "a"; + csi-mode = "1x4"; + st-vc = <0>; + vc-id = <0>; + num-lanes = <2>; + }; + }; + }; + i2c@1 { + status = "okay"; + reg = <1>; + i2c-mux,deselect-on-exit; + #address-cells = <1>; + #size-cells = <0>; + + dser_b: max96712@29 { + status = "okay"; + reg = <0x29>; + compatible = "maxim,max96712"; + csi-mode = "2x4"; + max-src = <1>; + channel = "b"; + pwdn-gpios = <&gpio CAM1_PWDN GPIO_ACTIVE_HIGH>; + }; + + ser_b: max9295_a@40 { + status = "okay"; + compatible = "maxim,max9295"; + reg = <0x40>; + maxim,gmsl-dser-device = <&dser_b>; + }; + + ds5_7: ds5@1d { + status = "okay"; + def-addr = <0x10>; + reg = <0x1d>; + override_reg = <0x1a>; + compatible = "intel,d4xx"; + use_sensor_mode_id = "true"; + vcc-supply = <&vdd_cam12v_poc>; + cam-type = "IMU"; + nvidia,gmsl-ser-device = <&ser_b>; + nvidia,gmsl-dser-device = <&dser_b>; + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + ds5_7_out: endpoint { + vc-id = <3>; + port-index = <7>; + bus-width = <2>; + remote-endpoint = <&d4xx_csi_in7>; + }; + }; + }; + mode0 { + pixel_t = "grey_y16"; + num_lanes = "2"; + csi_pixel_bit_depth = "16"; + active_w = "640"; + active_h = "480"; + tegra_sinterface = "serial_c"; + mclk_khz = "24000"; + pix_clk_hz = "74250000"; + line_length = "1280"; /* 2200 */ + embedded_metadata_height = "0"; + }; + gmsl-link { + src-csi-port = "b"; + dst-csi-port = "c"; + serdes-csi-link = "a"; + csi-mode = "1x4"; + st-vc = <0>; + vc-id = <3>; + num-lanes = <2>; + }; + }; + + ds5_6: ds5@1c { + status = "okay"; + def-addr = <0x10>; + reg = <0x1c>; + override_reg = <0x1a>; + compatible = "intel,d4xx"; + use_sensor_mode_id = "true"; + vcc-supply = <&vdd_cam12v_poc>; + cam-type = "Y8"; + nvidia,gmsl-ser-device = <&ser_b>; + nvidia,gmsl-dser-device = <&dser_b>; + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + ds5_6_out: endpoint { + vc-id = <2>; + port-index = <6>; + bus-width = <2>; + remote-endpoint = <&d4xx_csi_in6>; + }; + }; + }; + /* mode0: Y8, mode1: depth D16 */ + mode0 { + pixel_t = "grey_y16"; + num_lanes = "2"; + csi_pixel_bit_depth = "16"; + active_w = "1280"; + active_h = "720"; + tegra_sinterface = "serial_c"; + mclk_khz = "24000"; + pix_clk_hz = "74250000"; + line_length = "1280"; /* 2200 */ + embedded_metadata_height = "1"; + }; + gmsl-link { + src-csi-port = "b"; + dst-csi-port = "c"; + serdes-csi-link = "a"; + csi-mode = "1x4"; + st-vc = <0>; + vc-id = <2>; + num-lanes = <2>; + }; + }; + + ds5_5: ds5@1b { + status = "okay"; + def-addr = <0x10>; + reg = <0x1b>; + override_reg = <0x1a>; + compatible = "intel,d4xx"; + use_sensor_mode_id = "true"; + vcc-supply = <&vdd_cam12v_poc>; + cam-type = "RGB"; + nvidia,gmsl-ser-device = <&ser_b>; + nvidia,gmsl-dser-device = <&dser_b>; + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + ds5_5_out: endpoint { + vc-id = <1>; + port-index = <5>; + bus-width = <2>; + remote-endpoint = <&d4xx_csi_in5>; + }; + }; + }; + mode0 { + pixel_t = "grey_y16"; + num_lanes = "2"; + csi_pixel_bit_depth = "16"; + active_w = "1920"; + active_h = "1080"; + tegra_sinterface = "serial_c"; + mclk_khz = "24000"; + pix_clk_hz = "74250000"; + line_length = "1280"; /* 2200 */ + embedded_metadata_height = "1"; + }; + gmsl-link { + src-csi-port = "b"; + dst-csi-port = "c"; + serdes-csi-link = "a"; + csi-mode = "1x4"; + st-vc = <0>; + vc-id = <1>; + num-lanes = <2>; + }; + }; + + ds5_4: ds5@1a { + status = "okay"; + def-addr = <0x10>; + reg = <0x1a>; + compatible = "intel,d4xx"; + use_sensor_mode_id = "true"; + vcc-supply = <&vdd_cam12v_poc>; + cam-type = "Depth"; + nvidia,gmsl-ser-device = <&ser_b>; + nvidia,gmsl-dser-device = <&dser_b>; + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + ds5_4_out: endpoint { + vc-id = <0>; + port-index = <4>; + bus-width = <2>; + remote-endpoint = <&d4xx_csi_in4>; + }; + }; + }; + mode0 { + pixel_t = "grey_y16"; + num_lanes = "2"; + csi_pixel_bit_depth = "16"; + active_w = "1280"; + active_h = "720"; + tegra_sinterface = "serial_c"; + mclk_khz = "24000"; + pix_clk_hz = "74250000"; + line_length = "1280"; /* 2200 */ + embedded_metadata_height = "1"; + }; + gmsl-link { + src-csi-port = "b"; + dst-csi-port = "c"; + serdes-csi-link = "a"; + csi-mode = "1x4"; + st-vc = <0>; + vc-id = <0>; + num-lanes = <2>; + }; + }; + }; + }; + }; + }; + }; + }; +}; diff --git a/hardware/realsense/tegra234-camera-d4xx-overlay-fg12-16ch-quad.dts b/hardware/realsense/tegra234-camera-d4xx-overlay-fg12-16ch-quad.dts new file mode 100644 index 00000000..a1e131a6 --- /dev/null +++ b/hardware/realsense/tegra234-camera-d4xx-overlay-fg12-16ch-quad.dts @@ -0,0 +1,1514 @@ +// SPDX-License-Identifier: GPL-2.0-only +// SPDX-FileCopyrightText: Copyright (c) 2018-2023, INTEL CORPORATION. All rights reserved. + +/dts-v1/; +/plugin/; + +#include +#include +#include + +#define CAM0_PWDN TEGRA234_MAIN_GPIO(H, 6) //MAX96712_1 PWDN +#define CAM1_PWDN TEGRA234_MAIN_GPIO(H, 3) //MAX96712_2 PWDN +#define CAM2_PWDN TEGRA234_MAIN_GPIO(AC, 0) //MAX96712_3 PWDN +#define CAM3_PWDN TEGRA234_MAIN_GPIO(AC, 1) //MAX96712_4 PWDN +#define CAM12V_POC TEGRA234_MAIN_GPIO(AC, 7) + +#define CAMERA_I2C_MUX_BUS(x) (0x1E + x) + + + +/* camera control gpio definitions */ +/ { + overlay-name = "Jetson RealSense Camera D457"; + jetson-header-name = "Jetson AGX CSI Connector"; + compatible = JETSON_COMPATIBLE; + + fragment@1 { + target-path = "/"; + __overlay__ { + vdd_cam12v_poc: regulator-vdd-cam12v-poc { + compatible = "regulator-fixed"; + regulator-name = "vdd-cam12v-poc"; + regulator-min-microvolt = <12000000>; + regulator-max-microvolt = <12000000>; + gpio = <&gpio CAM12V_POC GPIO_ACTIVE_HIGH>; + enable-active-high; + }; + }; + }; + fragment@0 { + target-path = "/"; + __overlay__ { + tegra-capture-vi { + num-channels = <16>; + ports { + status = "okay"; + port@0 { + status = "okay"; + reg = <0>; + d4xx_vi_in0: endpoint { + status = "okay"; + vc-id = <0>; + port-index = <0>; + bus-width = <2>; + remote-endpoint = <&d4xx_csi_out0>; + }; + }; + port@1 { + status = "okay"; + reg = <1>; + d4xx_vi_in1: endpoint { + status = "okay"; + vc-id = <1>; + port-index = <0>; + bus-width = <2>; + remote-endpoint = <&d4xx_csi_out1>; + }; + }; + port@2 { + status = "okay"; + reg = <2>; + d4xx_vi_in2: endpoint { + status = "okay"; + vc-id = <2>; + port-index = <0>; + bus-width = <2>; + remote-endpoint = <&d4xx_csi_out2>; + }; + }; + port@3 { + status = "okay"; + reg = <3>; + d4xx_vi_in3: endpoint { + status = "okay"; + vc-id = <3>; + port-index = <0>; + bus-width = <2>; + remote-endpoint = <&d4xx_csi_out3>; + }; + }; + port@4 { + status = "okay"; + reg = <4>; + d4xx_vi_in4: endpoint { + status = "okay"; + vc-id = <0>; + port-index = <2>; + bus-width = <2>; + remote-endpoint = <&d4xx_csi_out4>; + }; + }; + port@5 { + status = "okay"; + reg = <5>; + d4xx_vi_in5: endpoint { + status = "okay"; + vc-id = <1>; + port-index = <2>; + bus-width = <2>; + remote-endpoint = <&d4xx_csi_out5>; + }; + }; + port@6 { + status = "okay"; + reg = <6>; + d4xx_vi_in6: endpoint { + status = "okay"; + vc-id = <2>; + port-index = <2>; + bus-width = <2>; + remote-endpoint = <&d4xx_csi_out6>; + }; + }; + port@7 { + status = "okay"; + reg = <7>; + d4xx_vi_in7: endpoint { + status = "okay"; + vc-id = <3>; + port-index = <2>; + bus-width = <2>; + remote-endpoint = <&d4xx_csi_out7>; + }; + }; + port@8 { + status = "okay"; + reg = <8>; + d4xx_vi_in8: endpoint { + status = "okay"; + vc-id = <0>; + port-index = <4>; + bus-width = <2>; + remote-endpoint = <&d4xx_csi_out8>; + }; + }; + port@9 { + status = "okay"; + reg = <9>; + d4xx_vi_in9: endpoint { + status = "okay"; + vc-id = <1>; + port-index = <4>; + bus-width = <2>; + remote-endpoint = <&d4xx_csi_out9>; + }; + }; + port@10 { + status = "okay"; + reg = <10>; + d4xx_vi_in10: endpoint { + status = "okay"; + vc-id = <2>; + port-index = <4>; + bus-width = <2>; + remote-endpoint = <&d4xx_csi_out10>; + }; + }; + port@11 { + status = "okay"; + reg = <11>; + d4xx_vi_in11: endpoint { + status = "okay"; + vc-id = <3>; + port-index = <4>; + bus-width = <2>; + remote-endpoint = <&d4xx_csi_out11>; + }; + }; + port@12 { + status = "okay"; + reg = <12>; + d4xx_vi_in12: endpoint { + status = "okay"; + vc-id = <0>; + port-index = <5>; + bus-width = <2>; + remote-endpoint = <&d4xx_csi_out12>; + }; + }; + port@13 { + status = "okay"; + reg = <13>; + d4xx_vi_in13: endpoint { + status = "okay"; + vc-id = <1>; + port-index = <5>; + bus-width = <2>; + remote-endpoint = <&d4xx_csi_out13>; + }; + }; + port@14 { + status = "okay"; + reg = <14>; + d4xx_vi_in14: endpoint { + status = "okay"; + vc-id = <2>; + port-index = <5>; + bus-width = <2>; + remote-endpoint = <&d4xx_csi_out14>; + }; + }; + port@15 { + status = "okay"; + reg = <15>; + d4xx_vi_in15: endpoint { + status = "okay"; + vc-id = <3>; + port-index = <5>; + bus-width = <2>; + remote-endpoint = <&d4xx_csi_out15>; + }; + }; + }; + }; + + bus@0 { + host1x@13e00000 { + nvcsi@15a00000 { + num-channels = <16>; + channel@0 { + status = "okay"; + reg = <0>; + ports { + status = "okay"; + port@0 { + status = "okay"; + reg = <0>; + d4xx_csi_in0: endpoint@0 { + status = "okay"; + port-index = <0>; + bus-width = <2>; + remote-endpoint = <&ds5_0_out>; + }; + }; + port@1 { + status = "okay"; + reg = <1>; + d4xx_csi_out0: endpoint@1 { + status = "okay"; + remote-endpoint = <&d4xx_vi_in0>; + }; + }; + }; + }; + channel@1 { + status = "okay"; + reg = <1>; + ports { + status = "okay"; + port@0 { + status = "okay"; + reg = <0>; + d4xx_csi_in1: endpoint@2 { + status = "okay"; + port-index = <0>; + bus-width = <2>; + remote-endpoint = <&ds5_1_out>; + }; + }; + port@1 { + status = "okay"; + reg = <1>; + d4xx_csi_out1: endpoint@3 { + status = "okay"; + remote-endpoint = <&d4xx_vi_in1>; + }; + }; + }; + }; + channel@2 { + status = "okay"; + reg = <2>; + ports { + status = "okay"; + port@0 { + status = "okay"; + reg = <0>; + d4xx_csi_in2: endpoint@4 { + status = "okay"; + port-index = <0>; + bus-width = <2>; + remote-endpoint = <&ds5_2_out>; + }; + }; + port@1 { + status = "okay"; + reg = <1>; + d4xx_csi_out2: endpoint@5 { + status = "okay"; + remote-endpoint = <&d4xx_vi_in2>; + }; + }; + }; + }; + channel@3 { + status = "okay"; + reg = <3>; + ports { + status = "okay"; + port@0 { + status = "okay"; + reg = <0>; + d4xx_csi_in3: endpoint@6 { + status = "okay"; + port-index = <0>; + bus-width = <2>; + remote-endpoint = <&ds5_3_out>; + }; + }; + port@1 { + status = "okay"; + reg = <1>; + d4xx_csi_out3: endpoint@7 { + status = "okay"; + remote-endpoint = <&d4xx_vi_in3>; + }; + }; + }; + }; + channel@4 { + status = "okay"; + reg = <4>; + ports { + status = "okay"; + port@0 { + status = "okay"; + reg = <0>; + d4xx_csi_in4: endpoint@8 { + status = "okay"; + port-index = <2>; + bus-width = <2>; + remote-endpoint = <&ds5_4_out>; + }; + }; + port@1 { + status = "okay"; + reg = <1>; + d4xx_csi_out4: endpoint@9 { + status = "okay"; + remote-endpoint = <&d4xx_vi_in4>; + }; + }; + }; + }; + channel@5 { + status = "okay"; + reg = <5>; + ports { + status = "okay"; + port@0 { + status = "okay"; + reg = <0>; + d4xx_csi_in5: endpoint@10 { + status = "okay"; + port-index = <2>; + bus-width = <2>; + remote-endpoint = <&ds5_5_out>; + }; + }; + port@1 { + status = "okay"; + reg = <1>; + d4xx_csi_out5: endpoint@11 { + status = "okay"; + remote-endpoint = <&d4xx_vi_in5>; + }; + }; + }; + }; + channel@6 { + status = "okay"; + reg = <6>; + ports { + status = "okay"; + port@0 { + status = "okay"; + reg = <0>; + d4xx_csi_in6: endpoint@12 { + status = "okay"; + port-index = <2>; + bus-width = <2>; + remote-endpoint = <&ds5_6_out>; + }; + }; + port@1 { + status = "okay"; + reg = <1>; + d4xx_csi_out6: endpoint@13 { + status = "okay"; + remote-endpoint = <&d4xx_vi_in6>; + }; + }; + }; + }; + channel@7 { + status = "okay"; + reg = <7>; + ports { + status = "okay"; + port@0 { + status = "okay"; + reg = <0>; + d4xx_csi_in7: endpoint@14 { + status = "okay"; + port-index = <2>; + bus-width = <2>; + remote-endpoint = <&ds5_7_out>; + }; + }; + port@1 { + status = "okay"; + reg = <1>; + d4xx_csi_out7: endpoint@15 { + status = "okay"; + remote-endpoint = <&d4xx_vi_in7>; + }; + }; + }; + }; + channel@8 { + status = "okay"; + reg = <8>; + ports { + status = "okay"; + port@0 { + status = "okay"; + reg = <0>; + d4xx_csi_in8: endpoint@16 { + status = "okay"; + port-index = <4>; + bus-width = <2>; + remote-endpoint = <&ds5_8_out>; + }; + }; + port@1 { + status = "okay"; + reg = <1>; + d4xx_csi_out8: endpoint@17 { + status = "okay"; + remote-endpoint = <&d4xx_vi_in8>; + }; + }; + }; + }; + channel@9 { + status = "okay"; + reg = <9>; + ports { + status = "okay"; + port@0 { + status = "okay"; + reg = <0>; + d4xx_csi_in9: endpoint@18 { + status = "okay"; + port-index = <4>; + bus-width = <2>; + remote-endpoint = <&ds5_9_out>; + }; + }; + port@1 { + status = "okay"; + reg = <1>; + d4xx_csi_out9: endpoint@19 { + status = "okay"; + remote-endpoint = <&d4xx_vi_in9>; + }; + }; + }; + }; + channel@10 { + status = "okay"; + reg = <10>; + ports { + status = "okay"; + port@0 { + status = "okay"; + reg = <0>; + d4xx_csi_in10: endpoint@20 { + status = "okay"; + port-index = <4>; + bus-width = <2>; + remote-endpoint = <&ds5_10_out>; + }; + }; + port@1 { + status = "okay"; + reg = <1>; + d4xx_csi_out10: endpoint@21 { + status = "okay"; + remote-endpoint = <&d4xx_vi_in10>; + }; + }; + }; + }; + channel@11 { + status = "okay"; + reg = <11>; + ports { + status = "okay"; + port@0 { + status = "okay"; + reg = <0>; + d4xx_csi_in11: endpoint@22 { + status = "okay"; + port-index = <4>; + bus-width = <2>; + remote-endpoint = <&ds5_11_out>; + }; + }; + port@1 { + status = "okay"; + reg = <1>; + d4xx_csi_out11: endpoint@23 { + status = "okay"; + remote-endpoint = <&d4xx_vi_in11>; + }; + }; + }; + }; + channel@12 { + status = "okay"; + reg = <12>; + ports { + status = "okay"; + port@0 { + status = "okay"; + reg = <0>; + d4xx_csi_in12: endpoint@24 { + status = "okay"; + port-index = <6>; + bus-width = <2>; + remote-endpoint = <&ds5_12_out>; + }; + }; + port@1 { + status = "okay"; + reg = <1>; + d4xx_csi_out12: endpoint@25 { + status = "okay"; + remote-endpoint = <&d4xx_vi_in12>; + }; + }; + }; + }; + channel@13 { + status = "okay"; + reg = <13>; + ports { + status = "okay"; + port@0 { + status = "okay"; + reg = <0>; + d4xx_csi_in13: endpoint@26 { + status = "okay"; + port-index = <6>; + bus-width = <2>; + remote-endpoint = <&ds5_13_out>; + }; + }; + port@1 { + status = "okay"; + reg = <1>; + d4xx_csi_out13: endpoint@27 { + status = "okay"; + remote-endpoint = <&d4xx_vi_in13>; + }; + }; + }; + }; + channel@14 { + status = "okay"; + reg = <14>; + ports { + status = "okay"; + port@0 { + status = "okay"; + reg = <0>; + d4xx_csi_in14: endpoint@28 { + status = "okay"; + port-index = <6>; + bus-width = <2>; + remote-endpoint = <&ds5_14_out>; + }; + }; + port@1 { + status = "okay"; + reg = <1>; + d4xx_csi_out14: endpoint@29 { + status = "okay"; + remote-endpoint = <&d4xx_vi_in14>; + }; + }; + }; + }; + channel@15 { + status = "okay"; + reg = <15>; + ports { + status = "okay"; + port@0 { + status = "okay"; + reg = <0>; + d4xx_csi_in15: endpoint@30 { + status = "okay"; + port-index = <6>; + bus-width = <2>; + remote-endpoint = <&ds5_15_out>; + }; + }; + port@1 { + status = "okay"; + reg = <1>; + d4xx_csi_out15: endpoint@31 { + status = "okay"; + remote-endpoint = <&d4xx_vi_in15>; + }; + }; + }; + }; + }; + }; + + i2c@3180000 { + clock-frequency = <100000>; + tca9546@70 { + status = "okay"; + reg = <0x70>; + compatible = "nxp,pca9546"; + #address-cells = <1>; + #size-cells = <0>; + skip_mux_detect = "yes"; + /*vcc-pullup-supply = <&battery_reg>;*/ + force_bus_start = ; + vcc_lp = "vcc"; + i2c@0 { + status = "okay"; + reg = <0>; + i2c-mux,deselect-on-exit; + #address-cells = <1>; + #size-cells = <0>; + + dser_a: max96712@29 { + status = "okay"; + reg = <0x29>; + compatible = "maxim,max96712"; + csi-mode = "2x4"; + max-src = <1>; + channel = "a"; + pwdn-gpios = <&gpio CAM0_PWDN GPIO_ACTIVE_HIGH>; + }; + + ser_a: max9295_a@40 { + status = "okay"; + compatible = "maxim,max9295"; + reg = <0x40>; + maxim,gmsl-dser-device = <&dser_a>; + }; + + ds5_3: ds5@1d { + status = "okay"; + def-addr = <0x10>; + reg = <0x1d>; + override_reg = <0x1a>; + compatible = "intel,d4xx"; + use_sensor_mode_id = "true"; + vcc-supply = <&vdd_cam12v_poc>; + cam-type = "IMU"; + nvidia,gmsl-ser-device = <&ser_a>; + nvidia,gmsl-dser-device = <&dser_a>; + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + ds5_3_out: endpoint { + vc-id = <3>; + port-index = <3>; + bus-width = <2>; + remote-endpoint = <&d4xx_csi_in3>; + }; + }; + }; + mode0 { + pixel_t = "grey_y16"; + num_lanes = "2"; + csi_pixel_bit_depth = "16"; + active_w = "640"; + active_h = "480"; + tegra_sinterface = "serial_a"; + mclk_khz = "24000"; + pix_clk_hz = "74250000"; + line_length = "1280"; /* 2200 */ + embedded_metadata_height = "0"; + }; + gmsl-link { + src-csi-port = "b"; + dst-csi-port = "a"; + serdes-csi-link = "a"; + csi-mode = "1x4"; + st-vc = <0>; + vc-id = <3>; + num-lanes = <2>; + }; + }; + + ds5_2: ds5@1c { + status = "okay"; + def-addr = <0x10>; + reg = <0x1c>; + override_reg = <0x1a>; + compatible = "intel,d4xx"; + use_sensor_mode_id = "true"; + vcc-supply = <&vdd_cam12v_poc>; + cam-type = "Y8"; + nvidia,gmsl-ser-device = <&ser_a>; + nvidia,gmsl-dser-device = <&dser_a>; + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + ds5_2_out: endpoint { + vc-id = <2>; + port-index = <2>; + bus-width = <2>; + remote-endpoint = <&d4xx_csi_in2>; + }; + }; + }; + /* mode0: Y8, mode1: depth D16 */ + mode0 { + pixel_t = "grey_y16"; + num_lanes = "2"; + csi_pixel_bit_depth = "16"; + active_w = "1280"; + active_h = "720"; + tegra_sinterface = "serial_a"; + mclk_khz = "24000"; + pix_clk_hz = "74250000"; + line_length = "1280"; /* 2200 */ + embedded_metadata_height = "1"; + }; + gmsl-link { + src-csi-port = "b"; + dst-csi-port = "a"; + serdes-csi-link = "a"; + csi-mode = "1x4"; + st-vc = <0>; + vc-id = <2>; + num-lanes = <2>; + }; + }; + + ds5_1: ds5@1b { + status = "okay"; + def-addr = <0x10>; + reg = <0x1b>; + override_reg = <0x1a>; + compatible = "intel,d4xx"; + use_sensor_mode_id = "true"; + vcc-supply = <&vdd_cam12v_poc>; + cam-type = "RGB"; + nvidia,gmsl-ser-device = <&ser_a>; + nvidia,gmsl-dser-device = <&dser_a>; + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + ds5_1_out: endpoint { + vc-id = <1>; + port-index = <1>; + bus-width = <2>; + remote-endpoint = <&d4xx_csi_in1>; + }; + }; + }; + mode0 { + pixel_t = "grey_y16"; + num_lanes = "2"; + csi_pixel_bit_depth = "16"; + active_w = "1920"; + active_h = "1080"; + tegra_sinterface = "serial_a"; + mclk_khz = "24000"; + pix_clk_hz = "74250000"; + line_length = "1280"; /* 2200 */ + embedded_metadata_height = "1"; + }; + gmsl-link { + src-csi-port = "b"; + dst-csi-port = "a"; + serdes-csi-link = "a"; + csi-mode = "1x4"; + st-vc = <0>; + vc-id = <1>; + num-lanes = <2>; + }; + }; + + ds5_0: ds5@1a { + status = "okay"; + def-addr = <0x10>; + reg = <0x1a>; + compatible = "intel,d4xx"; + use_sensor_mode_id = "true"; + vcc-supply = <&vdd_cam12v_poc>; + cam-type = "Depth"; + nvidia,gmsl-ser-device = <&ser_a>; + nvidia,gmsl-dser-device = <&dser_a>; + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + ds5_0_out: endpoint { + vc-id = <0>; + port-index = <0>; + bus-width = <2>; + remote-endpoint = <&d4xx_csi_in0>; + }; + }; + }; + mode0 { + pixel_t = "grey_y16"; + num_lanes = "2"; + csi_pixel_bit_depth = "16"; + active_w = "1280"; + active_h = "720"; + tegra_sinterface = "serial_a"; + mclk_khz = "24000"; + pix_clk_hz = "74250000"; + line_length = "1280"; /* 2200 */ + embedded_metadata_height = "1"; + }; + gmsl-link { + src-csi-port = "b"; + dst-csi-port = "a"; + serdes-csi-link = "a"; + csi-mode = "1x4"; + st-vc = <0>; + vc-id = <0>; + num-lanes = <2>; + }; + }; + }; + i2c@1 { + status = "okay"; + reg = <1>; + i2c-mux,deselect-on-exit; + #address-cells = <1>; + #size-cells = <0>; + + dser_b: max96712@29 { + status = "okay"; + reg = <0x29>; + compatible = "maxim,max96712"; + csi-mode = "2x4"; + max-src = <1>; + channel = "b"; + pwdn-gpios = <&gpio CAM1_PWDN GPIO_ACTIVE_HIGH>; + }; + + ser_b: max9295_b@40 { + status = "okay"; + compatible = "maxim,max9295"; + reg = <0x40>; + maxim,gmsl-dser-device = <&dser_b>; + }; + + ds5_7: ds5@1d { + status = "okay"; + def-addr = <0x10>; + reg = <0x1d>; + override_reg = <0x1a>; + compatible = "intel,d4xx"; + use_sensor_mode_id = "true"; + vcc-supply = <&vdd_cam12v_poc>; + cam-type = "IMU"; + nvidia,gmsl-ser-device = <&ser_b>; + nvidia,gmsl-dser-device = <&dser_b>; + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + ds5_7_out: endpoint { + vc-id = <3>; + port-index = <7>; + bus-width = <2>; + remote-endpoint = <&d4xx_csi_in7>; + }; + }; + }; + mode0 { + pixel_t = "grey_y16"; + num_lanes = "2"; + csi_pixel_bit_depth = "16"; + active_w = "640"; + active_h = "480"; + tegra_sinterface = "serial_c"; + mclk_khz = "24000"; + pix_clk_hz = "74250000"; + line_length = "1280"; /* 2200 */ + embedded_metadata_height = "0"; + }; + gmsl-link { + src-csi-port = "b"; + dst-csi-port = "a"; + serdes-csi-link = "a"; + csi-mode = "1x4"; + st-vc = <0>; + vc-id = <3>; + num-lanes = <2>; + }; + }; + + ds5_6: ds5@1c { + status = "okay"; + def-addr = <0x10>; + reg = <0x1c>; + override_reg = <0x1a>; + compatible = "intel,d4xx"; + use_sensor_mode_id = "true"; + vcc-supply = <&vdd_cam12v_poc>; + cam-type = "Y8"; + nvidia,gmsl-ser-device = <&ser_b>; + nvidia,gmsl-dser-device = <&dser_b>; + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + ds5_6_out: endpoint { + vc-id = <2>; + port-index = <6>; + bus-width = <2>; + remote-endpoint = <&d4xx_csi_in6>; + }; + }; + }; + /* mode0: Y8, mode1: depth D16 */ + mode0 { + pixel_t = "grey_y16"; + num_lanes = "2"; + csi_pixel_bit_depth = "16"; + active_w = "1280"; + active_h = "720"; + tegra_sinterface = "serial_c"; + mclk_khz = "24000"; + pix_clk_hz = "74250000"; + line_length = "1280"; /* 2200 */ + embedded_metadata_height = "1"; + }; + gmsl-link { + src-csi-port = "b"; + dst-csi-port = "a"; + serdes-csi-link = "a"; + csi-mode = "1x4"; + st-vc = <0>; + vc-id = <2>; + num-lanes = <2>; + }; + }; + + ds5_5: ds5@1b { + status = "okay"; + def-addr = <0x10>; + reg = <0x1b>; + override_reg = <0x1a>; + compatible = "intel,d4xx"; + use_sensor_mode_id = "true"; + vcc-supply = <&vdd_cam12v_poc>; + cam-type = "RGB"; + nvidia,gmsl-ser-device = <&ser_b>; + nvidia,gmsl-dser-device = <&dser_b>; + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + ds5_5_out: endpoint { + vc-id = <1>; + port-index = <5>; + bus-width = <2>; + remote-endpoint = <&d4xx_csi_in5>; + }; + }; + }; + mode0 { + pixel_t = "grey_y16"; + num_lanes = "2"; + csi_pixel_bit_depth = "16"; + active_w = "1920"; + active_h = "1080"; + tegra_sinterface = "serial_c"; + mclk_khz = "24000"; + pix_clk_hz = "74250000"; + line_length = "1280"; /* 2200 */ + embedded_metadata_height = "1"; + }; + gmsl-link { + src-csi-port = "b"; + dst-csi-port = "a"; + serdes-csi-link = "a"; + csi-mode = "1x4"; + st-vc = <0>; + vc-id = <1>; + num-lanes = <2>; + }; + }; + + ds5_4: ds5@1a { + status = "okay"; + def-addr = <0x10>; + reg = <0x1a>; + compatible = "intel,d4xx"; + use_sensor_mode_id = "true"; + vcc-supply = <&vdd_cam12v_poc>; + cam-type = "Depth"; + nvidia,gmsl-ser-device = <&ser_b>; + nvidia,gmsl-dser-device = <&dser_b>; + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + ds5_4_out: endpoint { + vc-id = <0>; + port-index = <4>; + bus-width = <2>; + remote-endpoint = <&d4xx_csi_in4>; + }; + }; + }; + mode0 { + pixel_t = "grey_y16"; + num_lanes = "2"; + csi_pixel_bit_depth = "16"; + active_w = "1280"; + active_h = "720"; + tegra_sinterface = "serial_c"; + mclk_khz = "24000"; + pix_clk_hz = "74250000"; + line_length = "1280"; /* 2200 */ + embedded_metadata_height = "1"; + }; + gmsl-link { + src-csi-port = "b"; + dst-csi-port = "a"; + serdes-csi-link = "a"; + csi-mode = "1x4"; + st-vc = <0>; + vc-id = <0>; + num-lanes = <2>; + }; + }; + }; + i2c@2 { + status = "okay"; + reg = <2>; + i2c-mux,deselect-on-exit; + #address-cells = <1>; + #size-cells = <0>; + + dser_c: max96712@29 { + status = "okay"; + reg = <0x29>; + compatible = "maxim,max96712"; + csi-mode = "2x4"; + max-src = <1>; + channel = "c"; + pwdn-gpios = <&gpio CAM2_PWDN GPIO_ACTIVE_HIGH>; + }; + + ser_c: max9295_c@40 { + status = "okay"; + compatible = "maxim,max9295"; + reg = <0x40>; + maxim,gmsl-dser-device = <&dser_c>; + }; + + ds5_11: ds5@1d { + status = "okay"; + def-addr = <0x10>; + reg = <0x1d>; + override_reg = <0x1a>; + compatible = "intel,d4xx"; + use_sensor_mode_id = "true"; + vcc-supply = <&vdd_cam12v_poc>; + cam-type = "IMU"; + nvidia,gmsl-ser-device = <&ser_c>; + nvidia,gmsl-dser-device = <&dser_c>; + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + ds5_11_out: endpoint { + vc-id = <3>; + port-index = <11>; + bus-width = <2>; + remote-endpoint = <&d4xx_csi_in11>; + }; + }; + }; + mode0 { + pixel_t = "grey_y16"; + num_lanes = "2"; + csi_pixel_bit_depth = "16"; + active_w = "640"; + active_h = "480"; + tegra_sinterface = "serial_e"; + mclk_khz = "24000"; + pix_clk_hz = "74250000"; + line_length = "1280"; /* 2200 */ + embedded_metadata_height = "0"; + }; + gmsl-link { + src-csi-port = "b"; + dst-csi-port = "a"; + serdes-csi-link = "a"; + csi-mode = "1x4"; + st-vc = <0>; + vc-id = <3>; + num-lanes = <2>; + }; + }; + + ds5_10: ds5@1c { + status = "okay"; + def-addr = <0x10>; + reg = <0x1c>; + override_reg = <0x1a>; + compatible = "intel,d4xx"; + use_sensor_mode_id = "true"; + vcc-supply = <&vdd_cam12v_poc>; + cam-type = "Y8"; + nvidia,gmsl-ser-device = <&ser_c>; + nvidia,gmsl-dser-device = <&dser_c>; + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + ds5_10_out: endpoint { + vc-id = <2>; + port-index = <10>; + bus-width = <2>; + remote-endpoint = <&d4xx_csi_in10>; + }; + }; + }; + /* mode0: Y8, mode1: depth D16 */ + mode0 { + pixel_t = "grey_y16"; + num_lanes = "2"; + csi_pixel_bit_depth = "16"; + active_w = "1280"; + active_h = "720"; + tegra_sinterface = "serial_e"; + mclk_khz = "24000"; + pix_clk_hz = "74250000"; + line_length = "1280"; /* 2200 */ + embedded_metadata_height = "1"; + }; + gmsl-link { + src-csi-port = "b"; + dst-csi-port = "a"; + serdes-csi-link = "a"; + csi-mode = "1x4"; + st-vc = <0>; + vc-id = <2>; + num-lanes = <2>; + }; + }; + + ds5_9: ds5@1b { + status = "okay"; + def-addr = <0x10>; + reg = <0x1b>; + override_reg = <0x1a>; + compatible = "intel,d4xx"; + use_sensor_mode_id = "true"; + vcc-supply = <&vdd_cam12v_poc>; + cam-type = "RGB"; + nvidia,gmsl-ser-device = <&ser_c>; + nvidia,gmsl-dser-device = <&dser_c>; + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + ds5_9_out: endpoint { + vc-id = <1>; + port-index = <9>; + bus-width = <2>; + remote-endpoint = <&d4xx_csi_in9>; + }; + }; + }; + mode0 { + pixel_t = "grey_y16"; + num_lanes = "2"; + csi_pixel_bit_depth = "16"; + active_w = "1920"; + active_h = "1080"; + tegra_sinterface = "serial_e"; + mclk_khz = "24000"; + pix_clk_hz = "74250000"; + line_length = "1280"; /* 2200 */ + embedded_metadata_height = "1"; + }; + gmsl-link { + src-csi-port = "b"; + dst-csi-port = "a"; + serdes-csi-link = "a"; + csi-mode = "1x4"; + st-vc = <0>; + vc-id = <1>; + num-lanes = <2>; + }; + }; + + ds5_8: ds5@1a { + status = "okay"; + def-addr = <0x10>; + reg = <0x1a>; + compatible = "intel,d4xx"; + use_sensor_mode_id = "true"; + vcc-supply = <&vdd_cam12v_poc>; + cam-type = "Depth"; + nvidia,gmsl-ser-device = <&ser_c>; + nvidia,gmsl-dser-device = <&dser_c>; + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + ds5_8_out: endpoint { + vc-id = <0>; + port-index = <8>; + bus-width = <2>; + remote-endpoint = <&d4xx_csi_in8>; + }; + }; + }; + mode0 { + pixel_t = "grey_y16"; + num_lanes = "2"; + csi_pixel_bit_depth = "16"; + active_w = "1280"; + active_h = "720"; + tegra_sinterface = "serial_e"; + mclk_khz = "24000"; + pix_clk_hz = "74250000"; + line_length = "1280"; /* 2200 */ + embedded_metadata_height = "1"; + }; + gmsl-link { + src-csi-port = "b"; + dst-csi-port = "a"; + serdes-csi-link = "a"; + csi-mode = "1x4"; + st-vc = <0>; + vc-id = <0>; + num-lanes = <2>; + }; + }; + }; + i2c@3 { + status = "okay"; + reg = <3>; + i2c-mux,deselect-on-exit; + #address-cells = <1>; + #size-cells = <0>; + + dser_d: max96712@29 { + status = "okay"; + reg = <0x29>; + compatible = "maxim,max96712"; + csi-mode = "2x4"; + max-src = <1>; + channel = "d"; + pwdn-gpios = <&gpio CAM3_PWDN GPIO_ACTIVE_HIGH>; + }; + + ser_d: max9295_d@40 { + status = "okay"; + compatible = "maxim,max9295"; + reg = <0x40>; + maxim,gmsl-dser-device = <&dser_d>; + }; + + ds5_15: ds5@1d { + status = "okay"; + def-addr = <0x10>; + reg = <0x1d>; + override_reg = <0x1a>; + compatible = "intel,d4xx"; + use_sensor_mode_id = "true"; + vcc-supply = <&vdd_cam12v_poc>; + cam-type = "IMU"; + nvidia,gmsl-ser-device = <&ser_d>; + nvidia,gmsl-dser-device = <&dser_d>; + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + ds5_15_out: endpoint { + vc-id = <3>; + port-index = <15>; + bus-width = <2>; + remote-endpoint = <&d4xx_csi_in15>; + }; + }; + }; + mode0 { + pixel_t = "grey_y16"; + num_lanes = "2"; + csi_pixel_bit_depth = "16"; + active_w = "640"; + active_h = "480"; + tegra_sinterface = "serial_g"; + mclk_khz = "24000"; + pix_clk_hz = "74250000"; + line_length = "1280"; /* 2200 */ + embedded_metadata_height = "0"; + }; + gmsl-link { + src-csi-port = "b"; + dst-csi-port = "a"; + serdes-csi-link = "a"; + csi-mode = "1x4"; + st-vc = <0>; + vc-id = <3>; + num-lanes = <2>; + }; + }; + + ds5_14: ds5@1c { + status = "okay"; + def-addr = <0x10>; + reg = <0x1c>; + override_reg = <0x1a>; + compatible = "intel,d4xx"; + use_sensor_mode_id = "true"; + vcc-supply = <&vdd_cam12v_poc>; + cam-type = "Y8"; + nvidia,gmsl-ser-device = <&ser_d>; + nvidia,gmsl-dser-device = <&dser_d>; + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + ds5_14_out: endpoint { + vc-id = <2>; + port-index = <14>; + bus-width = <2>; + remote-endpoint = <&d4xx_csi_in14>; + }; + }; + }; + /* mode0: Y8, mode1: depth D16 */ + mode0 { + pixel_t = "grey_y16"; + num_lanes = "2"; + csi_pixel_bit_depth = "16"; + active_w = "1280"; + active_h = "720"; + tegra_sinterface = "serial_g"; + mclk_khz = "24000"; + pix_clk_hz = "74250000"; + line_length = "1280"; /* 2200 */ + embedded_metadata_height = "1"; + }; + gmsl-link { + src-csi-port = "b"; + dst-csi-port = "a"; + serdes-csi-link = "a"; + csi-mode = "1x4"; + st-vc = <0>; + vc-id = <2>; + num-lanes = <2>; + }; + }; + + ds5_13: ds5@1b { + status = "okay"; + def-addr = <0x10>; + reg = <0x1b>; + override_reg = <0x1a>; + compatible = "intel,d4xx"; + use_sensor_mode_id = "true"; + vcc-supply = <&vdd_cam12v_poc>; + cam-type = "RGB"; + nvidia,gmsl-ser-device = <&ser_d>; + nvidia,gmsl-dser-device = <&dser_d>; + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + ds5_13_out: endpoint { + vc-id = <1>; + port-index = <13>; + bus-width = <2>; + remote-endpoint = <&d4xx_csi_in13>; + }; + }; + }; + mode0 { + pixel_t = "grey_y16"; + num_lanes = "2"; + csi_pixel_bit_depth = "16"; + active_w = "1920"; + active_h = "1080"; + tegra_sinterface = "serial_g"; + mclk_khz = "24000"; + pix_clk_hz = "74250000"; + line_length = "1280"; /* 2200 */ + embedded_metadata_height = "1"; + }; + gmsl-link { + src-csi-port = "b"; + dst-csi-port = "a"; + serdes-csi-link = "a"; + csi-mode = "1x4"; + st-vc = <0>; + vc-id = <1>; + num-lanes = <2>; + }; + }; + + ds5_12: ds5@1a { + status = "okay"; + def-addr = <0x10>; + reg = <0x1a>; + compatible = "intel,d4xx"; + use_sensor_mode_id = "true"; + vcc-supply = <&vdd_cam12v_poc>; + cam-type = "Depth"; + nvidia,gmsl-ser-device = <&ser_d>; + nvidia,gmsl-dser-device = <&dser_d>; + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + ds5_12_out: endpoint { + vc-id = <0>; + port-index = <12>; + bus-width = <2>; + remote-endpoint = <&d4xx_csi_in12>; + }; + }; + }; + mode0 { + pixel_t = "grey_y16"; + num_lanes = "2"; + csi_pixel_bit_depth = "16"; + active_w = "1280"; + active_h = "720"; + tegra_sinterface = "serial_g"; + mclk_khz = "24000"; + pix_clk_hz = "74250000"; + line_length = "1280"; /* 2200 */ + embedded_metadata_height = "1"; + }; + gmsl-link { + src-csi-port = "b"; + dst-csi-port = "a"; + serdes-csi-link = "a"; + csi-mode = "1x4"; + st-vc = <0>; + vc-id = <0>; + num-lanes = <2>; + }; + }; + }; + }; + }; + }; + }; + }; +}; diff --git a/hardware/realsense/tegra234-camera-d4xx-overlay-fg12-16ch.dts b/hardware/realsense/tegra234-camera-d4xx-overlay-fg12-16ch.dts new file mode 100644 index 00000000..e00885b4 --- /dev/null +++ b/hardware/realsense/tegra234-camera-d4xx-overlay-fg12-16ch.dts @@ -0,0 +1,434 @@ +// SPDX-License-Identifier: GPL-2.0-only +// SPDX-FileCopyrightText: Copyright (c) 2018-2023, INTEL CORPORATION. All rights reserved. + +/dts-v1/; +/plugin/; + +#include +#include +#include + +#define CAM0_PWDN TEGRA234_MAIN_GPIO(H, 6) //MAX96712_1 PWDN +//#define CAM1_PWDN TEGRA234_MAIN_GPIO(H, 3) //MAX96712_2 PWDN +//#define CAM2_PWDN TEGRA234_MAIN_GPIO(AC, 0) //MAX96712_3 PWDN +//#define CAM3_PWDN TEGRA234_MAIN_GPIO(AC, 1) //MAX96712_4 PWDN +#define CAM12V_POC TEGRA234_MAIN_GPIO(AC, 7) + +#define CAMERA_I2C_MUX_BUS(x) (0x1E + x) + + + +/* camera control gpio definitions */ +/ { + overlay-name = "Jetson RealSense Camera D457"; + jetson-header-name = "Jetson AGX CSI Connector"; + compatible = JETSON_COMPATIBLE; + + fragment@1 { + target-path = "/"; + __overlay__ { + vdd_cam12v_poc: regulator-vdd-cam12v-poc { + compatible = "regulator-fixed"; + regulator-name = "vdd-cam12v-poc"; + regulator-min-microvolt = <12000000>; + regulator-max-microvolt = <12000000>; + gpio = <&gpio CAM12V_POC GPIO_ACTIVE_HIGH>; + enable-active-high; + }; + }; + }; + fragment@0 { + target-path = "/"; + __overlay__ { + tegra-capture-vi { + num-channels = <4>; + ports { + status = "okay"; + port@0 { + status = "okay"; + reg = <0>; + d4xx_vi_in0: endpoint { + status = "okay"; + vc-id = <0>; + port-index = <0>; + bus-width = <2>; + remote-endpoint = <&d4xx_csi_out0>; + }; + }; + port@1 { + status = "okay"; + reg = <1>; + d4xx_vi_in1: endpoint { + status = "okay"; + vc-id = <1>; + port-index = <0>; + bus-width = <2>; + remote-endpoint = <&d4xx_csi_out1>; + }; + }; + port@2 { + status = "okay"; + reg = <2>; + d4xx_vi_in2: endpoint { + status = "okay"; + vc-id = <2>; + port-index = <0>; + bus-width = <2>; + remote-endpoint = <&d4xx_csi_out2>; + }; + }; + port@3 { + status = "okay"; + reg = <3>; + d4xx_vi_in3: endpoint { + status = "okay"; + vc-id = <3>; + port-index = <0>; + bus-width = <2>; + remote-endpoint = <&d4xx_csi_out3>; + }; + }; + }; + }; + + bus@0 { + host1x@13e00000 { + nvcsi@15a00000 { + num-channels = <4>; + channel@0 { + status = "okay"; + reg = <0>; + ports { + status = "okay"; + port@0 { + status = "okay"; + reg = <0>; + d4xx_csi_in0: endpoint@0 { + status = "okay"; + port-index = <0>; + bus-width = <2>; + remote-endpoint = <&ds5_0_out>; + }; + }; + port@1 { + status = "okay"; + reg = <1>; + d4xx_csi_out0: endpoint@1 { + status = "okay"; + remote-endpoint = <&d4xx_vi_in0>; + }; + }; + }; + }; + channel@1 { + status = "okay"; + reg = <1>; + ports { + status = "okay"; + port@0 { + status = "okay"; + reg = <0>; + d4xx_csi_in1: endpoint@2 { + status = "okay"; + port-index = <0>; + bus-width = <2>; + remote-endpoint = <&ds5_1_out>; + }; + }; + port@1 { + status = "okay"; + reg = <1>; + d4xx_csi_out1: endpoint@3 { + status = "okay"; + remote-endpoint = <&d4xx_vi_in1>; + }; + }; + }; + }; + channel@2 { + status = "okay"; + reg = <2>; + ports { + status = "okay"; + port@0 { + status = "okay"; + reg = <0>; + d4xx_csi_in2: endpoint@4 { + status = "okay"; + port-index = <0>; + bus-width = <2>; + remote-endpoint = <&ds5_2_out>; + }; + }; + port@1 { + status = "okay"; + reg = <1>; + d4xx_csi_out2: endpoint@5 { + status = "okay"; + remote-endpoint = <&d4xx_vi_in2>; + }; + }; + }; + }; + channel@3 { + status = "okay"; + reg = <3>; + ports { + status = "okay"; + port@0 { + status = "okay"; + reg = <0>; + d4xx_csi_in3: endpoint@6 { + status = "okay"; + port-index = <0>; + bus-width = <2>; + remote-endpoint = <&ds5_3_out>; + }; + }; + port@1 { + status = "okay"; + reg = <1>; + d4xx_csi_out3: endpoint@7 { + status = "okay"; + remote-endpoint = <&d4xx_vi_in3>; + }; + }; + }; + }; + }; + }; + + i2c@3180000 { + clock-frequency = <100000>; + tca9546@70 { + status = "okay"; + reg = <0x70>; + compatible = "nxp,pca9546"; + #address-cells = <1>; + #size-cells = <0>; + skip_mux_detect = "yes"; + /*vcc-pullup-supply = <&battery_reg>;*/ + force_bus_start = ; + vcc_lp = "vcc"; + i2c@0 { + status = "okay"; + reg = <0>; + i2c-mux,deselect-on-exit; + #address-cells = <1>; + #size-cells = <0>; + + dser: max96712@29 { + status = "okay"; + reg = <0x29>; + compatible = "maxim,max96712"; + csi-mode = "2x4"; + max-src = <1>; + channel = "a"; + pwdn-gpios = <&gpio CAM0_PWDN GPIO_ACTIVE_HIGH>; + }; + + ser_a: max9295_a@40 { + status = "okay"; + compatible = "maxim,max9295"; + reg = <0x40>; + maxim,gmsl-dser-device = <&dser>; + }; + + ds5_3: ds5@1d { + status = "okay"; + def-addr = <0x10>; + reg = <0x1d>; + override_reg = <0x1a>; + compatible = "intel,d4xx"; + use_sensor_mode_id = "true"; + vcc-supply = <&vdd_cam12v_poc>; + cam-type = "IMU"; + nvidia,gmsl-ser-device = <&ser_a>; + nvidia,gmsl-dser-device = <&dser>; + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + ds5_3_out: endpoint { + vc-id = <3>; + port-index = <3>; + bus-width = <2>; + remote-endpoint = <&d4xx_csi_in3>; + }; + }; + }; + mode0 { + pixel_t = "grey_y16"; + num_lanes = "2"; + csi_pixel_bit_depth = "16"; + active_w = "640"; + active_h = "480"; + tegra_sinterface = "serial_b"; + mclk_khz = "24000"; + pix_clk_hz = "74250000"; + line_length = "1280"; /* 2200 */ + embedded_metadata_height = "0"; + }; + gmsl-link { + src-csi-port = "b"; + dst-csi-port = "a"; + serdes-csi-link = "a"; + csi-mode = "1x4"; + st-vc = <0>; + vc-id = <3>; + num-lanes = <2>; + }; + }; + + ds5_2: ds5@1c { + status = "okay"; + def-addr = <0x10>; + reg = <0x1c>; + override_reg = <0x1a>; + compatible = "intel,d4xx"; + use_sensor_mode_id = "true"; + vcc-supply = <&vdd_cam12v_poc>; + cam-type = "Y8"; + nvidia,gmsl-ser-device = <&ser_a>; + nvidia,gmsl-dser-device = <&dser>; + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + ds5_2_out: endpoint { + vc-id = <2>; + port-index = <2>; + bus-width = <2>; + remote-endpoint = <&d4xx_csi_in2>; + }; + }; + }; + /* mode0: Y8, mode1: depth D16 */ + mode0 { + pixel_t = "grey_y16"; + num_lanes = "2"; + csi_pixel_bit_depth = "16"; + active_w = "1280"; + active_h = "720"; + tegra_sinterface = "serial_b"; + mclk_khz = "24000"; + pix_clk_hz = "74250000"; + line_length = "1280"; /* 2200 */ + embedded_metadata_height = "1"; + }; + gmsl-link { + src-csi-port = "b"; + dst-csi-port = "a"; + serdes-csi-link = "a"; + csi-mode = "1x4"; + st-vc = <0>; + vc-id = <2>; + num-lanes = <2>; + }; + }; + + ds5_1: ds5@1b { + status = "okay"; + def-addr = <0x10>; + reg = <0x1b>; + override_reg = <0x1a>; + compatible = "intel,d4xx"; + use_sensor_mode_id = "true"; + vcc-supply = <&vdd_cam12v_poc>; + cam-type = "RGB"; + nvidia,gmsl-ser-device = <&ser_a>; + nvidia,gmsl-dser-device = <&dser>; + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + ds5_1_out: endpoint { + vc-id = <1>; + port-index = <1>; + bus-width = <2>; + remote-endpoint = <&d4xx_csi_in1>; + }; + }; + }; + mode0 { + pixel_t = "grey_y16"; + num_lanes = "2"; + csi_pixel_bit_depth = "16"; + active_w = "1920"; + active_h = "1080"; + tegra_sinterface = "serial_e"; + mclk_khz = "24000"; + pix_clk_hz = "74250000"; + line_length = "1280"; /* 2200 */ + embedded_metadata_height = "1"; + }; + gmsl-link { + src-csi-port = "b"; + dst-csi-port = "a"; + serdes-csi-link = "a"; + csi-mode = "1x4"; + st-vc = <0>; + vc-id = <1>; + num-lanes = <2>; + }; + }; + + ds5_0: ds5@1a { + status = "okay"; + def-addr = <0x10>; + reg = <0x1a>; + compatible = "intel,d4xx"; + use_sensor_mode_id = "true"; + vcc-supply = <&vdd_cam12v_poc>; + cam-type = "Depth"; + nvidia,gmsl-ser-device = <&ser_a>; + nvidia,gmsl-dser-device = <&dser>; + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + ds5_0_out: endpoint { + vc-id = <0>; + port-index = <0>; + bus-width = <2>; + remote-endpoint = <&d4xx_csi_in0>; + }; + }; + }; + mode0 { + pixel_t = "grey_y16"; + num_lanes = "2"; + csi_pixel_bit_depth = "16"; + active_w = "1280"; + active_h = "720"; + tegra_sinterface = "serial_a"; + mclk_khz = "24000"; + pix_clk_hz = "74250000"; + line_length = "1280"; /* 2200 */ + embedded_metadata_height = "1"; + }; + gmsl-link { + src-csi-port = "b"; + dst-csi-port = "a"; + serdes-csi-link = "a"; + csi-mode = "1x4"; + st-vc = <0>; + vc-id = <0>; + num-lanes = <2>; + }; + }; + }; + }; + }; + }; + }; + }; +}; diff --git a/hardware/realsense/tegra234-camera-d4xx-overlay-max96712-EVB.dts b/hardware/realsense/tegra234-camera-d4xx-overlay-max96712-EVB.dts new file mode 100644 index 00000000..e691c434 --- /dev/null +++ b/hardware/realsense/tegra234-camera-d4xx-overlay-max96712-EVB.dts @@ -0,0 +1,409 @@ +// SPDX-License-Identifier: GPL-2.0-only +// SPDX-FileCopyrightText: Copyright (c) 2018-2023, INTEL CORPORATION. All rights reserved. + +/dts-v1/; +/plugin/; + +#include +#include +#include + +/* camera control gpio definitions */ +/ { + overlay-name = "Jetson RealSense Camera D457"; + jetson-header-name = "Jetson AGX CSI Connector"; + compatible = JETSON_COMPATIBLE; + + fragment@0 { + target-path = "/"; + __overlay__ { + tegra-capture-vi { + num-channels = <4>; + ports { + status = "okay"; + port@0 { + status = "okay"; + reg = <0>; + d4xx_vi_in0: endpoint { + status = "okay"; + vc-id = <0>; + port-index = <0>; + bus-width = <2>; + remote-endpoint = <&d4xx_csi_out0>; + }; + }; + port@1 { + status = "okay"; + reg = <1>; + d4xx_vi_in1: endpoint { + status = "okay"; + vc-id = <1>; + port-index = <0>; + bus-width = <2>; + remote-endpoint = <&d4xx_csi_out1>; + }; + }; + port@2 { + status = "okay"; + reg = <2>; + d4xx_vi_in2: endpoint { + status = "okay"; + vc-id = <2>; + port-index = <0>; + bus-width = <2>; + remote-endpoint = <&d4xx_csi_out2>; + }; + }; + port@3 { + status = "okay"; + reg = <3>; + d4xx_vi_in3: endpoint { + status = "okay"; + vc-id = <3>; + port-index = <0>; + bus-width = <2>; + remote-endpoint = <&d4xx_csi_out3>; + }; + }; + }; + }; + + bus@0 { + host1x@13e00000 { + nvcsi@15a00000 { + num-channels = <4>; + channel@0 { + status = "okay"; + reg = <0>; + ports { + status = "okay"; + port@0 { + status = "okay"; + reg = <0>; + d4xx_csi_in0: endpoint@0 { + status = "okay"; + port-index = <0>; + bus-width = <2>; + remote-endpoint = <&ds5_0_out>; + }; + }; + port@1 { + status = "okay"; + reg = <1>; + d4xx_csi_out0: endpoint@1 { + status = "okay"; + remote-endpoint = <&d4xx_vi_in0>; + }; + }; + }; + }; + channel@1 { + status = "okay"; + reg = <1>; + ports { + status = "okay"; + port@0 { + status = "okay"; + reg = <0>; + d4xx_csi_in1: endpoint@2 { + status = "okay"; + port-index = <0>; + bus-width = <2>; + remote-endpoint = <&ds5_1_out>; + }; + }; + port@1 { + status = "okay"; + reg = <1>; + d4xx_csi_out1: endpoint@3 { + status = "okay"; + remote-endpoint = <&d4xx_vi_in1>; + }; + }; + }; + }; + channel@2 { + status = "okay"; + reg = <2>; + ports { + status = "okay"; + port@0 { + status = "okay"; + reg = <0>; + d4xx_csi_in2: endpoint@4 { + status = "okay"; + port-index = <0>; + bus-width = <2>; + remote-endpoint = <&ds5_2_out>; + }; + }; + port@1 { + status = "okay"; + reg = <1>; + d4xx_csi_out2: endpoint@5 { + status = "okay"; + remote-endpoint = <&d4xx_vi_in2>; + }; + }; + }; + }; + channel@3 { + status = "okay"; + reg = <3>; + ports { + status = "okay"; + port@0 { + status = "okay"; + reg = <0>; + d4xx_csi_in3: endpoint@6 { + status = "okay"; + port-index = <0>; + bus-width = <2>; + remote-endpoint = <&ds5_3_out>; + }; + }; + port@1 { + status = "okay"; + reg = <1>; + d4xx_csi_out3: endpoint@7 { + status = "okay"; + remote-endpoint = <&d4xx_vi_in3>; + }; + }; + }; + }; + }; + }; + + i2c@3180000 { + clock-frequency = <100000>; + tca9548@72 { + status = "okay"; + reg = <0x72>; + compatible = "nxp,pca9548"; + #address-cells = <1>; + #size-cells = <0>; + skip_mux_detect = "yes"; + /*vcc-pullup-supply = <&battery_reg>;*/ + vcc_lp = "vcc"; + i2c@0 { + status = "okay"; + reg = <0>; + i2c-mux,deselect-on-exit; + #address-cells = <1>; + #size-cells = <0>; + + dser: max96712@29 { + status = "okay"; + reg = <0x29>; + compatible = "maxim,max96712"; + csi-mode = "2x4"; + max-src = <1>; + channel = "a"; + }; + + ser_a: max9295_a@40 { + status = "okay"; + compatible = "maxim,max9295"; + reg = <0x40>; + maxim,gmsl-dser-device = <&dser>; + }; + + ds5_3: ds5@1d { + status = "okay"; + def-addr = <0x10>; + reg = <0x1d>; + override_reg = <0x1a>; + compatible = "intel,d4xx"; + use_sensor_mode_id = "true"; + //vcc-supply = <&vdd_cam12v_poc>; + cam-type = "IMU"; + nvidia,gmsl-ser-device = <&ser_a>; + nvidia,gmsl-dser-device = <&dser>; + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + ds5_3_out: endpoint { + vc-id = <3>; + port-index = <3>; + bus-width = <2>; + remote-endpoint = <&d4xx_csi_in3>; + }; + }; + }; + mode0 { + pixel_t = "grey_y16"; + num_lanes = "2"; + csi_pixel_bit_depth = "16"; + active_w = "640"; + active_h = "480"; + tegra_sinterface = "serial_b"; + mclk_khz = "24000"; + pix_clk_hz = "74250000"; + line_length = "1280"; /* 2200 */ + embedded_metadata_height = "0"; + }; + gmsl-link { + src-csi-port = "b"; + dst-csi-port = "a"; + serdes-csi-link = "a"; + csi-mode = "1x4"; + st-vc = <0>; + vc-id = <3>; + num-lanes = <2>; + }; + }; + + ds5_2: ds5@1c { + status = "okay"; + def-addr = <0x10>; + reg = <0x1c>; + override_reg = <0x1a>; + compatible = "intel,d4xx"; + use_sensor_mode_id = "true"; + //vcc-supply = <&vdd_cam12v_poc>; + cam-type = "Y8"; + nvidia,gmsl-ser-device = <&ser_a>; + nvidia,gmsl-dser-device = <&dser>; + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + ds5_2_out: endpoint { + vc-id = <2>; + port-index = <2>; + bus-width = <2>; + remote-endpoint = <&d4xx_csi_in2>; + }; + }; + }; + /* mode0: Y8, mode1: depth D16 */ + mode0 { + pixel_t = "grey_y16"; + num_lanes = "2"; + csi_pixel_bit_depth = "16"; + active_w = "1280"; + active_h = "720"; + tegra_sinterface = "serial_b"; + mclk_khz = "24000"; + pix_clk_hz = "74250000"; + line_length = "1280"; /* 2200 */ + embedded_metadata_height = "1"; + }; + gmsl-link { + src-csi-port = "b"; + dst-csi-port = "a"; + serdes-csi-link = "a"; + csi-mode = "1x4"; + st-vc = <0>; + vc-id = <2>; + num-lanes = <2>; + }; + }; + + ds5_1: ds5@1b { + status = "okay"; + def-addr = <0x10>; + reg = <0x1b>; + override_reg = <0x1a>; + compatible = "intel,d4xx"; + use_sensor_mode_id = "true"; + //vcc-supply = <&vdd_cam12v_poc>; + cam-type = "RGB"; + nvidia,gmsl-ser-device = <&ser_a>; + nvidia,gmsl-dser-device = <&dser>; + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + ds5_1_out: endpoint { + vc-id = <1>; + port-index = <1>; + bus-width = <2>; + remote-endpoint = <&d4xx_csi_in1>; + }; + }; + }; + mode0 { + pixel_t = "grey_y16"; + num_lanes = "2"; + csi_pixel_bit_depth = "16"; + active_w = "1920"; + active_h = "1080"; + tegra_sinterface = "serial_e"; + mclk_khz = "24000"; + pix_clk_hz = "74250000"; + line_length = "1280"; /* 2200 */ + embedded_metadata_height = "1"; + }; + gmsl-link { + src-csi-port = "b"; + dst-csi-port = "a"; + serdes-csi-link = "a"; + csi-mode = "1x4"; + st-vc = <0>; + vc-id = <1>; + num-lanes = <2>; + }; + }; + + ds5_0: ds5@1a { + status = "okay"; + def-addr = <0x10>; + reg = <0x1a>; + compatible = "intel,d4xx"; + use_sensor_mode_id = "true"; + //vcc-supply = <&vdd_cam12v_poc>; + cam-type = "Depth"; + nvidia,gmsl-ser-device = <&ser_a>; + nvidia,gmsl-dser-device = <&dser>; + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + ds5_0_out: endpoint { + vc-id = <0>; + port-index = <0>; + bus-width = <2>; + remote-endpoint = <&d4xx_csi_in0>; + }; + }; + }; + mode0 { + pixel_t = "grey_y16"; + num_lanes = "2"; + csi_pixel_bit_depth = "16"; + active_w = "1280"; + active_h = "720"; + tegra_sinterface = "serial_a"; + mclk_khz = "24000"; + pix_clk_hz = "74250000"; + line_length = "1280"; /* 2200 */ + embedded_metadata_height = "1"; + }; + gmsl-link { + src-csi-port = "b"; + dst-csi-port = "a"; + serdes-csi-link = "a"; + csi-mode = "1x4"; + st-vc = <0>; + vc-id = <0>; + num-lanes = <2>; + }; + }; + }; + }; + }; + }; + }; + }; +}; diff --git a/kernel/nvidia/5.0.2/0015-Adding-max96712-support-for-D4xx.patch b/kernel/nvidia/5.0.2/0015-Adding-max96712-support-for-D4xx.patch new file mode 100644 index 00000000..bc351965 --- /dev/null +++ b/kernel/nvidia/5.0.2/0015-Adding-max96712-support-for-D4xx.patch @@ -0,0 +1,406 @@ +From 74a30d41e7972e0e9c2d60744cea1b43dd7c3b08 Mon Sep 17 00:00:00 2001 +From: ejgoldik +Date: Wed, 18 Feb 2026 11:52:13 +0200 +Subject: [PATCH] Adding max96712 support for D4xx + +Signed-off-by: ejgoldik +--- + drivers/media/i2c/max96712.c | 310 ++++++++++++++++++++++++++++++++++- + 1 file changed, 308 insertions(+), 2 deletions(-) + +diff --git a/drivers/media/i2c/max96712.c b/drivers/media/i2c/max96712.c +index 8081385f0..3de1643bc 100644 +--- a/drivers/media/i2c/max96712.c ++++ b/drivers/media/i2c/max96712.c +@@ -21,17 +21,55 @@ + #include + #include + #include ++#include ++#include + ++/* register specifics */ ++ ++#define MAX96712_REG6_ADDR 0x6 ++#define MAX96712_CTRL1_ADDR 0x18 ++ ++#define MAX96712_BACKTOP25_ADDR 0x418 ++ ++#define MAX96712_MIPI_PHY0_ADDR 0x8A0 ++#define MAX96712_MIPI_PHY2_ADDR 0x8A2 ++#define MAX96712_MIPI_PHY3_ADDR 0x8A3 ++#define MAX96712_VIDEO_PIPE_SEL_0_ADDR 0xF0 ++#define MAX96712_VIDEO_PIPE_SEL_1_ADDR 0xF1 ++#define MAX96712_VIDEO_PIPE_EN_ADDR 0xF4 ++#define MAX96712_BACKTOP12_CSI_OUT_EN_ADDR 0x40B ++ ++#define MAX96712_MIPI_TX10_ADDR 0x94A ++#define MAX96712_MIPI_TX11_ADDR 0x90B ++#define MAX96712_MIPI_TX13_SRC_0_MAP_ADDR 0x90D ++#define MAX96712_MIPI_TX14_DST_0_MAP_ADDR 0x90E ++#define MAX96712_MIPI_TX15_SRC_1_MAP_ADDR 0x90F ++#define MAX96712_MIPI_TX16_DST_1_MAP_ADDR 0x910 ++#define MAX96712_MIPI_TX17_SRC_2_MAP_ADDR 0x911 ++#define MAX96712_MIPI_TX18_DST_2_MAP_ADDR 0x912 ++#define MAX96712_MIPI_TX19_SRC_3_MAP_ADDR 0x913 ++#define MAX96712_MIPI_TX20_DST_3_MAP_ADDR 0x914 ++#define MAX96712_MIPI_TX45_MAP_DPHY_DEST_ADDR 0x92D ++#define MAX96712_MIPI_TX51_ADDR 0x973 ++ ++#define MAX96712_VIDEO_RX0_ADDR 0x100 ++ ++#define MAX96712_DPLL_0_ADDR 0x1D00 ++ ++/* data defines */ ++#define MAX96712_MAX_PIPES 4 + + struct max96712 { + struct i2c_client *i2c_client; + struct regmap *regmap; + const char *channel; ++ struct mutex lock; ++ int pwdn_gpio; + }; + struct max96712 *global_priv[4] ; + + +-int max96712_write_reg_Dser(int slaveAddr,int channel, ++int max96712_write_reg_Dser(int slaveAddr, int channel, + u16 addr, u8 val) + { + struct i2c_client *i2c_client = NULL; +@@ -99,6 +137,20 @@ static int max96712_read_reg(struct max96712 *priv, + return err; + } + ++static int max96712_write_reg(struct max96712 *priv, ++ u16 addr, unsigned int val) ++{ ++ struct i2c_client *i2c_client = priv->i2c_client; ++ int err; ++ err = regmap_write(priv->regmap, addr, val); ++ if (err) ++ dev_err(&i2c_client->dev, "%s:i2c write failed, 0x%x = %x\n", ++ __func__, addr, val); ++ ++ /* delay before next i2c command as required for SERDES link */ ++ usleep_range(100, 110); ++ return err; ++} + + static int max96712_stats_show(struct seq_file *s, void *data) + { +@@ -169,7 +221,10 @@ static int max96712_debugfs_init(const char *dir_name, + if (np) { + err = of_property_read_string(np, "channel", &priv->channel); + if (err) ++ { + dev_err(&i2c_client->dev, "channel not found\n"); ++ return -EINVAL; ++ } + + err = snprintf(dev_name, sizeof(dev_name), "max96712_%s", priv->channel); + if (err < 0) +@@ -216,6 +271,7 @@ static int max96712_probe(struct i2c_client *client, + { + struct max96712 *priv; + int err = 0; ++ struct device_node *np = NULL; + + dev_info(&client->dev, "%s: enter\n", __func__); + +@@ -228,10 +284,23 @@ static int max96712_probe(struct i2c_client *client, + "regmap init failed: %ld\n", PTR_ERR(priv->regmap)); + return -ENODEV; + } ++ mutex_init(&priv->lock); ++ ++ np = client->dev.of_node; ++ if (np) { ++ priv->pwdn_gpio = of_get_named_gpio(np, "pwdn-gpios", 0); ++ if (priv->pwdn_gpio < 0) { ++ dev_err(&client->dev,"%s: Could not retrieve pwdn_gpio = %d\n", ++ __func__, priv->pwdn_gpio); ++ } ++ } ++ dev_set_drvdata(&client->dev, priv); + + err = max96712_debugfs_init(NULL, NULL, NULL, priv); + if (err) ++ { + return err; ++ } + + /*set daymode by fault*/ + dev_info(&client->dev, "%s: success\n", __func__); +@@ -243,8 +312,12 @@ static int max96712_probe(struct i2c_client *client, + static int + max96712_remove(struct i2c_client *client) + { ++ struct max96712 *priv; + + if (client != NULL) { ++ priv = dev_get_drvdata(&client->dev); ++ ++ mutex_destroy(&priv->lock); + i2c_unregister_device(client); + client = NULL; + } +@@ -252,13 +325,245 @@ max96712_remove(struct i2c_client *client) + return 0; + } + ++struct reg_pair { ++ u16 addr; ++ u8 val; ++}; ++ ++static int max96712_set_registers(struct max96712 *priv, struct reg_pair *map, u32 count) ++{ ++ int err = 0; ++ u32 j = 0; ++ ++ for (j = 0; j < count; j++) { ++ err = max96712_write_reg(priv, map[j].addr, map[j].val); ++ if (err != 0) ++ break; ++ } ++ ++ return err; ++} ++ ++int max96712_get_available_pipe_id(struct device *dev, int vc_id) ++{ ++ /* TODO EHUD: Currently vc_id == pipe id but that's definitely ++ * not the end goal if we plan to support multiple cameras ++ */ ++ return vc_id; ++} ++EXPORT_SYMBOL(max96712_get_available_pipe_id); ++ ++int max96712_release_pipe(struct device *dev, int pipe_id) ++{ ++ /* TODO EHUD: pipe id? */ ++ return 0; ++} ++EXPORT_SYMBOL(max96712_release_pipe); ++ ++void max96712_reset_oneshot(struct device *dev) ++{ ++ struct max96712 *priv = dev_get_drvdata(dev); ++ max96712_write_reg(priv, MAX96712_CTRL1_ADDR, 0x0F); ++ msleep(100); ++} ++EXPORT_SYMBOL(max96712_reset_oneshot); ++ ++static int __max96712_set_pipe(struct device *dev, int pipe_id, u8 data_type1, ++ u8 data_type2, u32 vc_id) ++{ ++ int err = 0; ++ struct max96712 *priv = dev_get_drvdata(dev); ++ ++ int i = 0; ++ ++ struct reg_pair map_pipe_control[] = { ++ // Enable 4 mappings for Pipe X ++ {MAX96712_MIPI_TX11_ADDR, 0x0F}, ++ // Map data_type1 on vc_id ++ {MAX96712_MIPI_TX13_SRC_0_MAP_ADDR, 0x1E}, ++ {MAX96712_MIPI_TX14_DST_0_MAP_ADDR, 0x1E}, ++ // Map frame_start on vc_id ++ {MAX96712_MIPI_TX15_SRC_1_MAP_ADDR, 0x00}, ++ {MAX96712_MIPI_TX16_DST_1_MAP_ADDR, 0x00}, ++ // Map frame end on vc_id ++ {MAX96712_MIPI_TX17_SRC_2_MAP_ADDR, 0x01}, ++ {MAX96712_MIPI_TX18_DST_2_MAP_ADDR, 0x01}, ++ // Map data_type2 on vc_id ++ {MAX96712_MIPI_TX19_SRC_3_MAP_ADDR, 0x12}, ++ {MAX96712_MIPI_TX20_DST_3_MAP_ADDR, 0x12}, ++ // All mappings to PHY1 (master for port A) ++ {MAX96712_MIPI_TX45_MAP_DPHY_DEST_ADDR, 0x55}, ++ // SEQ_MISS_EN: Disabled / DIS_PKT_DET: Disabled ++ {MAX96712_VIDEO_RX0_ADDR, 0x23}, // pipe X ++ }; ++ ++ for (i = 0; i < (ARRAY_SIZE(map_pipe_control) - 1); i++) { ++ map_pipe_control[i].addr += 0x40 * pipe_id; ++ } ++ map_pipe_control[(ARRAY_SIZE(map_pipe_control) - 1)].addr += 0x12 * pipe_id; ++ ++ if (data_type2 == 0x0) { ++ /* For IMU (which has no metadata) we override mapping ++ * to enable only 3 ++ */ ++ map_pipe_control[0].val = 0x07; ++ } ++ map_pipe_control[1].val = (vc_id << 6) | data_type1; ++ map_pipe_control[2].val = (vc_id << 6) | data_type1; ++ map_pipe_control[3].val = (vc_id << 6) | 0x00; ++ map_pipe_control[4].val = (vc_id << 6) | 0x00; ++ map_pipe_control[5].val = (vc_id << 6) | 0x01; ++ map_pipe_control[6].val = (vc_id << 6) | 0x01; ++ map_pipe_control[7].val = (vc_id << 6) | data_type2; ++ map_pipe_control[8].val = (vc_id << 6) | data_type2; ++ ++ err |= max96712_set_registers(priv, map_pipe_control, ++ ARRAY_SIZE(map_pipe_control)); ++ ++ max96712_reset_oneshot(dev); ++ max96712_write_reg(priv, MAX96712_VIDEO_PIPE_EN_ADDR, 0xF); ++ ++ return err; ++} ++ ++int max96712_init_settings(struct device *dev) ++{ ++ int err = 0; ++ struct max96712 *priv = dev_get_drvdata(dev); ++ struct reg_pair map_pipe_opt[] = ++ { ++ /* ----------Video pipes configure ----------------------*/ ++ {MAX96712_REG6_ADDR, 0xF1}, // Enable link - Why is this needed? ++ {MAX96712_VIDEO_PIPE_SEL_0_ADDR, 0x10}, //0xF0, Link A ID 0 to pipe 0 , Link A ID 1 to pipe 1 ++ {MAX96712_VIDEO_PIPE_SEL_1_ADDR, 0x32}, //0xF1, Link A ID 2 to pipe 2 , Link A ID 3 to pipe 3 ++ {MAX96712_VIDEO_PIPE_EN_ADDR, 0x00}, //0xF4, Enable pipe 0-3, 0xFF ++ }; ++ ++ struct reg_pair map_phy_opt[] = ++ { ++ /* MIPI D-PHY Config */ ++ {MAX96712_MIPI_PHY0_ADDR, 0x04}, //0x8A0 ++ {MAX96712_MIPI_TX10_ADDR, 0x40}, //0x94a - MIPI lane count ++ {MAX96712_MIPI_PHY3_ADDR, 0xe4}, //0x8A3, Lower phys to lower lanes ++ ++ /* Put DPLL in reset before changing MIPI lane rates */ ++ {MAX96712_DPLL_0_ADDR, 0xF4}, //0x1D00 ++ ++ /* 1500Mbps/lane on port A */ ++ {MAX96712_BACKTOP25_ADDR, 0x2f}, //0x418 ++ ++ /* Release DPLL reset */ ++ {MAX96712_DPLL_0_ADDR, 0xF5}, //0x1D00 ++ ++ /* ALT2_MEM_MAP8 */ ++ {MAX96712_MIPI_TX51_ADDR, 0x10}, //MIPI TX1 ++ ++ {MAX96712_MIPI_PHY2_ADDR, 0x34}, //0x8A2 Disable phys 2+3 ++ {MAX96712_BACKTOP12_CSI_OUT_EN_ADDR, 0x02}, // (CSI_OUT_EN): CSI output enabled ++ }; ++ ++ mutex_lock(&priv->lock); ++ ++ err |= max96712_set_registers(priv, map_pipe_opt, ARRAY_SIZE(map_pipe_opt)); ++ err |= max96712_set_registers(priv, map_phy_opt, ARRAY_SIZE(map_phy_opt)); ++ ++ mutex_unlock(&priv->lock); ++ ++ return err; ++} ++EXPORT_SYMBOL(max96712_init_settings); ++ ++int max96712_set_pipe(struct device *dev, int pipe_id, ++ u8 data_type1, u8 data_type2, u32 vc_id) ++{ ++ struct max96712 *priv = dev_get_drvdata(dev); ++ int err = 0; ++ ++ if (pipe_id > (MAX96712_MAX_PIPES - 1)) { ++ dev_info(dev, "%s, input pipe_id: %d exceed max96712 max pipes\n", ++ __func__, pipe_id); ++ return -EINVAL; ++ } ++ ++ dev_dbg(dev, "%s pipe_id %d, data_type1 %u, data_type2 %u, vc_id %u\n", ++ __func__, pipe_id, data_type1, data_type2, vc_id); ++ ++ mutex_lock(&priv->lock); ++ ++ err = __max96712_set_pipe(dev, pipe_id, data_type1, data_type2, vc_id); ++ ++ mutex_unlock(&priv->lock); ++ ++ return err; ++} ++EXPORT_SYMBOL(max96712_set_pipe); ++ ++int max96712_setup_link(struct device *dev, struct device *s_dev) ++{ ++ /* TODO EHUD: Is needed? */ ++ return 0; ++} ++EXPORT_SYMBOL(max96712_setup_link); ++ ++int max96712_setup_control(struct device *dev, struct device *s_dev) ++{ ++ /* TODO EHUD: Is needed? */ ++ return 0; ++} ++EXPORT_SYMBOL(max96712_setup_control); ++ ++int max96712_reset_control(struct device *dev, struct device *s_dev) ++{ ++ /* TODO EHUD: Is needed? */ ++ return 0; ++} ++EXPORT_SYMBOL(max96712_reset_control); ++ ++int max96712_sdev_register(struct device *dev, struct gmsl_link_ctx *g_ctx) ++{ ++ /* TODO EHUD: Is needed? */ ++ return 0; ++} ++EXPORT_SYMBOL(max96712_sdev_register); ++ ++int max96712_sdev_unregister(struct device *dev, struct device *s_dev) ++{ ++ /* TODO EHUD: Is needed? */ ++ return 0; ++} ++EXPORT_SYMBOL(max96712_sdev_unregister); ++ ++int max96712_power_on(struct device *dev) ++{ ++ struct max96712 *priv = dev_get_drvdata(dev); ++ if (priv->pwdn_gpio > 0) { ++ gpio_direction_output(priv->pwdn_gpio, 1); ++ gpio_set_value(priv->pwdn_gpio, 1); ++ msleep(100); ++ } ++ return 0; ++} ++EXPORT_SYMBOL(max96712_power_on); ++ ++void max96712_power_off(struct device *dev) ++{ ++ struct max96712 *priv = dev_get_drvdata(dev); ++ if (priv->pwdn_gpio > 0) { ++ gpio_direction_output(priv->pwdn_gpio, 1); ++ gpio_set_value(priv->pwdn_gpio, 0); ++ msleep(100); ++ } ++ return; ++} ++EXPORT_SYMBOL(max96712_power_off); ++ + static const struct i2c_device_id max96712_id[] = { + { "max96712", 0 }, + { }, + }; + + const struct of_device_id max96712_of_match[] = { +- { .compatible = "nvidia,max96712", }, ++ { .compatible = "maxim,max96712", }, + { }, + }; + +@@ -268,6 +573,7 @@ static struct i2c_driver max96712_i2c_driver = { + .driver = { + .name = "max96712", + .owner = THIS_MODULE, ++ .of_match_table = of_match_ptr(max96712_of_match), + }, + .probe = max96712_probe, + .remove = max96712_remove, +-- +2.43.0 + diff --git a/kernel/nvidia/5.1.2/0006-Adding-max96712-support-for-D4xx.patch b/kernel/nvidia/5.1.2/0006-Adding-max96712-support-for-D4xx.patch new file mode 100644 index 00000000..8d099851 --- /dev/null +++ b/kernel/nvidia/5.1.2/0006-Adding-max96712-support-for-D4xx.patch @@ -0,0 +1,455 @@ +From 317b49f2e4e8838181ae1804547fa1c7662d350b Mon Sep 17 00:00:00 2001 +From: ejgoldik +Date: Wed, 18 Feb 2026 16:30:47 +0200 +Subject: [PATCH] Adding max96712 support for D4xx + +Signed-off-by: ejgoldik +--- + drivers/media/i2c/max96712.c | 333 +++++++++++++++++++++++++++++++---- + 1 file changed, 301 insertions(+), 32 deletions(-) + +diff --git a/drivers/media/i2c/max96712.c b/drivers/media/i2c/max96712.c +index 329a10dfd..48f94c530 100644 +--- a/drivers/media/i2c/max96712.c ++++ b/drivers/media/i2c/max96712.c +@@ -25,28 +25,62 @@ + #include + #include + ++#include ++ ++/* register specifics */ ++ ++#define MAX96712_REG6_ADDR 0x6 ++#define MAX96712_CTRL1_ADDR 0x18 ++ ++#define MAX96712_BACKTOP25_ADDR 0x418 ++ ++#define MAX96712_MIPI_PHY0_ADDR 0x8A0 ++#define MAX96712_MIPI_PHY2_ADDR 0x8A2 ++#define MAX96712_MIPI_PHY3_ADDR 0x8A3 ++#define MAX96712_VIDEO_PIPE_SEL_0_ADDR 0xF0 ++#define MAX96712_VIDEO_PIPE_SEL_1_ADDR 0xF1 ++#define MAX96712_VIDEO_PIPE_EN_ADDR 0xF4 ++#define MAX96712_BACKTOP12_CSI_OUT_EN_ADDR 0x40B ++ ++#define MAX96712_MIPI_TX10_ADDR 0x94A ++#define MAX96712_MIPI_TX11_ADDR 0x90B ++#define MAX96712_MIPI_TX13_SRC_0_MAP_ADDR 0x90D ++#define MAX96712_MIPI_TX14_DST_0_MAP_ADDR 0x90E ++#define MAX96712_MIPI_TX15_SRC_1_MAP_ADDR 0x90F ++#define MAX96712_MIPI_TX16_DST_1_MAP_ADDR 0x910 ++#define MAX96712_MIPI_TX17_SRC_2_MAP_ADDR 0x911 ++#define MAX96712_MIPI_TX18_DST_2_MAP_ADDR 0x912 ++#define MAX96712_MIPI_TX19_SRC_3_MAP_ADDR 0x913 ++#define MAX96712_MIPI_TX20_DST_3_MAP_ADDR 0x914 ++#define MAX96712_MIPI_TX45_MAP_DPHY_DEST_ADDR 0x92D ++#define MAX96712_MIPI_TX51_ADDR 0x973 ++ ++#define MAX96712_VIDEO_RX0_ADDR 0x100 ++ ++#define MAX96712_DPLL_0_ADDR 0x1D00 ++ ++/* data defines */ ++#define MAX96712_MAX_PIPES 4 + + struct max96712 { + struct i2c_client *i2c_client; + struct regmap *regmap; + const char *channel; ++ struct mutex lock; ++ int pwdn_gpio; + }; + struct max96712 *global_priv[4] ; + +-struct mutex max96712_rw; +- + int max96712_write_reg_Dser(int slaveAddr,int channel, + u16 addr, u8 val) + { + struct i2c_client *i2c_client = NULL; + int bak = 0; + int err = 0; +- /* unsigned int ival = 0; */ + + if(channel > 3 || channel < 0 || global_priv[channel] == NULL) + return -1; + +- mutex_lock(&max96712_rw); + i2c_client = global_priv[channel]->i2c_client; + bak = i2c_client->addr; + +@@ -59,7 +93,6 @@ int max96712_write_reg_Dser(int slaveAddr,int channel, + dev_err(&i2c_client->dev, "%s: addr = 0x%x, val = 0x%x\n", + __func__, addr, val); + } +- mutex_unlock(&max96712_rw); + return err; + } + +@@ -75,7 +108,6 @@ int max96712_read_reg_Dser(int slaveAddr,int channel, + if(channel > 3 || channel < 0 || global_priv[channel] == NULL) + return -1; + +- mutex_lock(&max96712_rw); + i2c_client = global_priv[channel]->i2c_client; + bak = i2c_client->addr; + i2c_client->addr = slaveAddr / 2; +@@ -86,7 +118,6 @@ int max96712_read_reg_Dser(int slaveAddr,int channel, + dev_err(&i2c_client->dev, "%s: addr = 0x%x, val = 0x%x\n", + __func__, addr, *val); + } +- mutex_unlock(&max96712_rw); + return err; + } + +@@ -106,6 +137,20 @@ static int max96712_read_reg(struct max96712 *priv, + return err; + } + ++static int max96712_write_reg(struct max96712 *priv, ++ u16 addr, unsigned int val) ++{ ++ struct i2c_client *i2c_client = priv->i2c_client; ++ int err; ++ err = regmap_write(priv->regmap, addr, val); ++ if (err) ++ dev_err(&i2c_client->dev, "%s:i2c write failed, 0x%x = %x\n", ++ __func__, addr, val); ++ ++ /* delay before next i2c command as required for SERDES link */ ++ usleep_range(100, 110); ++ return err; ++} + + static int max96712_stats_show(struct seq_file *s, void *data) + { +@@ -161,24 +206,6 @@ static const struct file_operations max96712_debugfs_fops = { + .release = single_release, + }; + +-static int max96712_power_on(struct max96712 *priv) +-{ +- struct i2c_client *i2c_client = priv->i2c_client; +- struct device_node *np = i2c_client->dev.of_node; +- unsigned int pwdn_gpio = 0; +- +- if(np) { +- pwdn_gpio = of_get_named_gpio(np, "pwdn-gpios", 0); +- dev_info(&i2c_client->dev,"%s: pwdn_gpio = %d\n",__func__,pwdn_gpio); +- } +- if (pwdn_gpio > 0) { +- gpio_direction_output(pwdn_gpio, 1); +- gpio_set_value(pwdn_gpio, 1); +- msleep(100); +- } +- return 0; +-} +- + static int max96712_debugfs_init(const char *dir_name, + struct dentry **d_entry, + struct dentry **f_entry, +@@ -241,6 +268,7 @@ static int max96712_probe(struct i2c_client *client, + { + struct max96712 *priv; + int err = 0; ++ struct device_node *np = NULL; + + dev_info(&client->dev, "%s: enter\n", __func__); + +@@ -254,14 +282,19 @@ static int max96712_probe(struct i2c_client *client, + return -ENODEV; + } + +- mutex_init(&max96712_rw); ++ mutex_init(&priv->lock); + +- err = max96712_power_on(priv); +- if (err) { +- dev_err(&client->dev, "Failed to power on err =%d\n",err); +- return err; ++ np = client->dev.of_node; ++ if (np) { ++ priv->pwdn_gpio = of_get_named_gpio(np, "pwdn-gpios", 0); ++ if (priv->pwdn_gpio < 0) { ++ dev_err(&client->dev,"%s: Could not retrieve pwdn_gpio = %d\n", ++ __func__, priv->pwdn_gpio); ++ } + } + ++ dev_set_drvdata(&client->dev, priv); ++ + err = max96712_debugfs_init(NULL, NULL, NULL, priv); + if (err) + return err; +@@ -276,8 +309,11 @@ static int max96712_probe(struct i2c_client *client, + static int + max96712_remove(struct i2c_client *client) + { +- ++ struct max96712 *priv; + if (client != NULL) { ++ priv = dev_get_drvdata(&client->dev); ++ ++ mutex_destroy(&priv->lock); + i2c_unregister_device(client); + client = NULL; + } +@@ -285,13 +321,245 @@ max96712_remove(struct i2c_client *client) + return 0; + } + ++struct reg_pair { ++ u16 addr; ++ u8 val; ++}; ++ ++static int max96712_set_registers(struct max96712 *priv, struct reg_pair *map, u32 count) ++{ ++ int err = 0; ++ u32 j = 0; ++ ++ for (j = 0; j < count; j++) { ++ err = max96712_write_reg(priv, map[j].addr, map[j].val); ++ if (err != 0) ++ break; ++ } ++ ++ return err; ++} ++ ++int max96712_get_available_pipe_id(struct device *dev, int vc_id) ++{ ++ /* TODO EHUD: Currently vc_id == pipe id but that's definitely ++ * not the end goal if we plan to support multiple cameras ++ */ ++ return vc_id; ++} ++EXPORT_SYMBOL(max96712_get_available_pipe_id); ++ ++int max96712_release_pipe(struct device *dev, int pipe_id) ++{ ++ /* TODO EHUD: pipe id? */ ++ return 0; ++} ++EXPORT_SYMBOL(max96712_release_pipe); ++ ++void max96712_reset_oneshot(struct device *dev) ++{ ++ struct max96712 *priv = dev_get_drvdata(dev); ++ max96712_write_reg(priv, MAX96712_CTRL1_ADDR, 0x0F); ++ msleep(100); ++} ++EXPORT_SYMBOL(max96712_reset_oneshot); ++ ++static int __max96712_set_pipe(struct device *dev, int pipe_id, u8 data_type1, ++ u8 data_type2, u32 vc_id) ++{ ++ int err = 0; ++ struct max96712 *priv = dev_get_drvdata(dev); ++ ++ int i = 0; ++ ++ struct reg_pair map_pipe_control[] = { ++ // Enable 4 mappings for Pipe X ++ {MAX96712_MIPI_TX11_ADDR, 0x0F}, ++ // Map data_type1 on vc_id ++ {MAX96712_MIPI_TX13_SRC_0_MAP_ADDR, 0x1E}, ++ {MAX96712_MIPI_TX14_DST_0_MAP_ADDR, 0x1E}, ++ // Map frame_start on vc_id ++ {MAX96712_MIPI_TX15_SRC_1_MAP_ADDR, 0x00}, ++ {MAX96712_MIPI_TX16_DST_1_MAP_ADDR, 0x00}, ++ // Map frame end on vc_id ++ {MAX96712_MIPI_TX17_SRC_2_MAP_ADDR, 0x01}, ++ {MAX96712_MIPI_TX18_DST_2_MAP_ADDR, 0x01}, ++ // Map data_type2 on vc_id ++ {MAX96712_MIPI_TX19_SRC_3_MAP_ADDR, 0x12}, ++ {MAX96712_MIPI_TX20_DST_3_MAP_ADDR, 0x12}, ++ // All mappings to PHY1 (master for port A) ++ {MAX96712_MIPI_TX45_MAP_DPHY_DEST_ADDR, 0x55}, ++ // SEQ_MISS_EN: Disabled / DIS_PKT_DET: Disabled ++ {MAX96712_VIDEO_RX0_ADDR, 0x23}, // pipe X ++ }; ++ ++ for (i = 0; i < (ARRAY_SIZE(map_pipe_control) - 1); i++) { ++ map_pipe_control[i].addr += 0x40 * pipe_id; ++ } ++ map_pipe_control[(ARRAY_SIZE(map_pipe_control) - 1)].addr += 0x12 * pipe_id; ++ ++ if (data_type2 == 0x0) { ++ /* For IMU (which has no metadata) we override mapping ++ * to enable only 3 ++ */ ++ map_pipe_control[0].val = 0x07; ++ } ++ map_pipe_control[1].val = (vc_id << 6) | data_type1; ++ map_pipe_control[2].val = (vc_id << 6) | data_type1; ++ map_pipe_control[3].val = (vc_id << 6) | 0x00; ++ map_pipe_control[4].val = (vc_id << 6) | 0x00; ++ map_pipe_control[5].val = (vc_id << 6) | 0x01; ++ map_pipe_control[6].val = (vc_id << 6) | 0x01; ++ map_pipe_control[7].val = (vc_id << 6) | data_type2; ++ map_pipe_control[8].val = (vc_id << 6) | data_type2; ++ ++ err |= max96712_set_registers(priv, map_pipe_control, ++ ARRAY_SIZE(map_pipe_control)); ++ ++ max96712_reset_oneshot(dev); ++ max96712_write_reg(priv, MAX96712_VIDEO_PIPE_EN_ADDR, 0xF); ++ ++ return err; ++} ++ ++int max96712_init_settings(struct device *dev) ++{ ++ int err = 0; ++ struct max96712 *priv = dev_get_drvdata(dev); ++ struct reg_pair map_pipe_opt[] = ++ { ++ /* ----------Video pipes configure ----------------------*/ ++ {MAX96712_REG6_ADDR, 0xF1}, // Enable link - Why is this needed? ++ {MAX96712_VIDEO_PIPE_SEL_0_ADDR, 0x10}, //0xF0, Link A ID 0 to pipe 0 , Link A ID 1 to pipe 1 ++ {MAX96712_VIDEO_PIPE_SEL_1_ADDR, 0x32}, //0xF1, Link A ID 2 to pipe 2 , Link A ID 3 to pipe 3 ++ {MAX96712_VIDEO_PIPE_EN_ADDR, 0x00}, //0xF4, Enable pipe 0-3, 0xFF ++ }; ++ ++ struct reg_pair map_phy_opt[] = ++ { ++ /* MIPI D-PHY Config */ ++ {MAX96712_MIPI_PHY0_ADDR, 0x04}, //0x8A0 ++ {MAX96712_MIPI_TX10_ADDR, 0x40}, //0x94a - MIPI lane count ++ {MAX96712_MIPI_PHY3_ADDR, 0xe4}, //0x8A3, Lower phys to lower lanes ++ ++ /* Put DPLL in reset before changing MIPI lane rates */ ++ {MAX96712_DPLL_0_ADDR, 0xF4}, //0x1D00 ++ ++ /* 1500Mbps/lane on port A */ ++ {MAX96712_BACKTOP25_ADDR, 0x2f}, //0x418 ++ ++ /* Release DPLL reset */ ++ {MAX96712_DPLL_0_ADDR, 0xF5}, //0x1D00 ++ ++ /* ALT2_MEM_MAP8 */ ++ {MAX96712_MIPI_TX51_ADDR, 0x10}, //MIPI TX1 ++ ++ {MAX96712_MIPI_PHY2_ADDR, 0x34}, //0x8A2 Disable phys 2+3 ++ {MAX96712_BACKTOP12_CSI_OUT_EN_ADDR, 0x02}, // (CSI_OUT_EN): CSI output enabled ++ }; ++ ++ mutex_lock(&priv->lock); ++ ++ err |= max96712_set_registers(priv, map_pipe_opt, ARRAY_SIZE(map_pipe_opt)); ++ err |= max96712_set_registers(priv, map_phy_opt, ARRAY_SIZE(map_phy_opt)); ++ ++ mutex_unlock(&priv->lock); ++ ++ return err; ++} ++EXPORT_SYMBOL(max96712_init_settings); ++ ++int max96712_set_pipe(struct device *dev, int pipe_id, ++ u8 data_type1, u8 data_type2, u32 vc_id) ++{ ++ struct max96712 *priv = dev_get_drvdata(dev); ++ int err = 0; ++ ++ if (pipe_id > (MAX96712_MAX_PIPES - 1)) { ++ dev_info(dev, "%s, input pipe_id: %d exceed max96712 max pipes\n", ++ __func__, pipe_id); ++ return -EINVAL; ++ } ++ ++ dev_dbg(dev, "%s pipe_id %d, data_type1 %u, data_type2 %u, vc_id %u\n", ++ __func__, pipe_id, data_type1, data_type2, vc_id); ++ ++ mutex_lock(&priv->lock); ++ ++ err = __max96712_set_pipe(dev, pipe_id, data_type1, data_type2, vc_id); ++ ++ mutex_unlock(&priv->lock); ++ ++ return err; ++} ++EXPORT_SYMBOL(max96712_set_pipe); ++ ++int max96712_setup_link(struct device *dev, struct device *s_dev) ++{ ++ /* TODO EHUD: Is needed? */ ++ return 0; ++} ++EXPORT_SYMBOL(max96712_setup_link); ++ ++int max96712_setup_control(struct device *dev, struct device *s_dev) ++{ ++ /* TODO EHUD: Is needed? */ ++ return 0; ++} ++EXPORT_SYMBOL(max96712_setup_control); ++ ++int max96712_reset_control(struct device *dev, struct device *s_dev) ++{ ++ /* TODO EHUD: Is needed? */ ++ return 0; ++} ++EXPORT_SYMBOL(max96712_reset_control); ++ ++int max96712_sdev_register(struct device *dev, struct gmsl_link_ctx *g_ctx) ++{ ++ /* TODO EHUD: Is needed? */ ++ return 0; ++} ++EXPORT_SYMBOL(max96712_sdev_register); ++ ++int max96712_sdev_unregister(struct device *dev, struct device *s_dev) ++{ ++ /* TODO EHUD: Is needed? */ ++ return 0; ++} ++EXPORT_SYMBOL(max96712_sdev_unregister); ++ ++int max96712_power_on(struct device *dev) ++{ ++ struct max96712 *priv = dev_get_drvdata(dev); ++ if (priv->pwdn_gpio > 0) { ++ gpio_direction_output(priv->pwdn_gpio, 1); ++ gpio_set_value(priv->pwdn_gpio, 1); ++ msleep(100); ++ } ++ return 0; ++} ++EXPORT_SYMBOL(max96712_power_on); ++ ++void max96712_power_off(struct device *dev) ++{ ++ struct max96712 *priv = dev_get_drvdata(dev); ++ if (priv->pwdn_gpio > 0) { ++ gpio_direction_output(priv->pwdn_gpio, 1); ++ gpio_set_value(priv->pwdn_gpio, 0); ++ msleep(100); ++ } ++ return; ++} ++EXPORT_SYMBOL(max96712_power_off); ++ + static const struct i2c_device_id max96712_id[] = { + { "max96712", 0 }, + { }, + }; + + const struct of_device_id max96712_of_match[] = { +- { .compatible = "nvidia,max96712", }, ++ { .compatible = "maxim,max96712", }, + { }, + }; + +@@ -301,6 +569,7 @@ static struct i2c_driver max96712_i2c_driver = { + .driver = { + .name = "max96712", + .owner = THIS_MODULE, ++ .of_match_table = of_match_ptr(max96712_of_match), + }, + .probe = max96712_probe, + .remove = max96712_remove, +-- +2.43.0 + diff --git a/kernel/nvidia/max96712.h b/kernel/nvidia/max96712.h new file mode 100644 index 00000000..e917956b --- /dev/null +++ b/kernel/nvidia/max96712.h @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2018-2025, NVIDIA Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope 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 . + */ + +/** + * @file + * MAX96712 API: For Maxim Integrated MAX96712 deserializer + * + * @b Description: Defines elements used to set up and use a + * Maxim Integrated MAX96712 deserializer. + */ + +#ifndef __MAX96712_H__ +#define __MAX96712_H__ + +#include +#include +/** + * \defgroup max96712 MAX96712 deserializer driver + * + * Controls the MAX96712 deserializer module. + * + * @ingroup serdes_group + * @{ + */ + +int max96712_get_available_pipe_id(struct device *dev, int vc_id); +int max96712_set_pipe(struct device *dev, int pipe_id, u8 data_type1, + u8 data_type2, u32 vc_id); +int max96712_release_pipe(struct device *dev, int pipe_id); +void max96712_reset_oneshot(struct device *dev); +int max96712_setup_link(struct device *dev, struct device *s_dev); +int max96712_setup_control(struct device *dev, struct device *s_dev); +int max96712_reset_control(struct device *dev, struct device *s_dev); +int max96712_sdev_register(struct device *dev, struct gmsl_link_ctx *g_ctx); +int max96712_sdev_unregister(struct device *dev, struct device *s_dev); +int max96712_power_on(struct device *dev); +void max96712_power_off(struct device *dev); +int max96712_init_settings(struct device *dev); + +#endif /* __MAX96712_H__ */ diff --git a/kernel/realsense/d4xx.c b/kernel/realsense/d4xx.c index 6a4638c1..83035522 100644 --- a/kernel/realsense/d4xx.c +++ b/kernel/realsense/d4xx.c @@ -39,6 +39,34 @@ #ifdef CONFIG_VIDEO_D4XX_SERDES #include #include +#include + +/* Deserializer interface structure for abstraction */ +struct dser_interface { + /* Pipeline management */ + int (*get_available_pipe_id)(struct device *dev, int vc_id); + int (*set_pipe)(struct device *dev, int pipe_id, u8 data_type1, u8 data_type2, u32 vc_id); + int (*release_pipe)(struct device *dev, int pipe_id); + void (*reset_oneshot)(struct device *dev); + + /* Setup and control */ + int (*setup_link)(struct device *dev, struct device *s_dev); + int (*setup_control)(struct device *dev, struct device *s_dev); + int (*reset_control)(struct device *dev, struct device *s_dev); + + /* Device registration */ + int (*sdev_register)(struct device *dev, struct gmsl_link_ctx *g_ctx); + int (*sdev_unregister)(struct device *dev, struct device *s_dev); + + /* Power management */ + int (*power_on)(struct device *dev); + void (*power_off)(struct device *dev); + int (*init_settings)(struct device *dev); + + /* Identification */ + const char *name; +}; + #else #include #define GMSL_CSI_DT_YUV422_8 0x1E @@ -451,6 +479,7 @@ struct ds5 { struct device *dser_dev; struct i2c_client *ser_i2c; struct i2c_client *dser_i2c; + const struct dser_interface *dser_ops; #endif }; @@ -460,8 +489,44 @@ struct ds5_counters { unsigned int n_ctrl; }; +#ifdef CONFIG_VIDEO_D4XX_SERDES static DEFINE_MUTEX(serdes_lock__); +/* MAX9296 deserializer interface implementation */ +static const struct dser_interface max9296_interface = { + .get_available_pipe_id = max9296_get_available_pipe_id, + .set_pipe = max9296_set_pipe, + .release_pipe = max9296_release_pipe, + .reset_oneshot = max9296_reset_oneshot, + .setup_link = max9296_setup_link, + .setup_control = max9296_setup_control, + .reset_control = max9296_reset_control, + .sdev_register = max9296_sdev_register, + .sdev_unregister = max9296_sdev_unregister, + .power_on = max9296_power_on, + .power_off = max9296_power_off, + .init_settings = max9296_init_settings, + .name = "max9296", +}; + +/* MAX96712 deserializer interface implementation */ +static const struct dser_interface max96712_interface = { + .get_available_pipe_id = max96712_get_available_pipe_id, + .set_pipe = max96712_set_pipe, + .release_pipe = max96712_release_pipe, + .reset_oneshot = max96712_reset_oneshot, + .setup_link = max96712_setup_link, + .setup_control = max96712_setup_control, + .reset_control = max96712_reset_control, + .sdev_register = max96712_sdev_register, + .sdev_unregister = max96712_sdev_unregister, + .power_on = max96712_power_on, + .power_off = max96712_power_off, + .init_settings = max96712_init_settings, + .name = "max96712", +}; +#endif + #define ds5_from_depth_sd(sd) container_of(sd, struct ds5, depth.sd) #define ds5_from_ir_sd(sd) container_of(sd, struct ds5, ir.sd) #define ds5_from_rgb_sd(sd) container_of(sd, struct ds5, rgb.sd) @@ -1616,7 +1681,7 @@ static int ds5_setup_pipeline(struct ds5 *state, u8 data_type1, u8 data_type2, pipe_id, data_type1, data_type2, vc_id); ret |= max9295_set_pipe(state->ser_dev, pipe_id, data_type1, data_type2, vc_id); - ret |= max9296_set_pipe(state->dser_dev, pipe_id, + ret |= state->dser_ops->set_pipe(state->dser_dev, pipe_id, data_type1, data_type2, vc_id); if (ret) dev_warn(&state->client->dev, @@ -1698,7 +1763,7 @@ static int ds5_configure(struct ds5 *state) /* Release old pipe only if it changed and was valid */ if (sensor->pipe_id >= 0) { mutex_lock(&serdes_lock__); - ret = max9296_release_pipe(state->dser_dev, sensor->pipe_id); + ret = state->dser_ops->release_pipe(state->dser_dev, sensor->pipe_id); mutex_unlock(&serdes_lock__); dev_warn(&state->client->dev, "release pipe %d (%d)\n", sensor->pipe_id, ret); sensor->pipe_id = -1; @@ -1708,15 +1773,15 @@ static int ds5_configure(struct ds5 *state) * Serialize SERDES pipe allocation and configuration * across all d4xx instances sharing the same GMSL link. * Without this, concurrent pipe setups race on the shared - * MAX9295/MAX9296 hardware, causing I2C NACKs (-121) that + * Serializer/Deserializer hardware, causing I2C NACKs (-121) that * take down the entire bus. */ mutex_lock(&serdes_lock__); sensor->pipe_id = - max9296_get_available_pipe_id(state->dser_dev, (int)state->g_ctx.dst_vc); + state->dser_ops->get_available_pipe_id(state->dser_dev, (int)state->g_ctx.dst_vc); mutex_unlock(&serdes_lock__); if (sensor->pipe_id < 0) { - dev_err(&state->client->dev, "No free pipe in max9296\n"); + dev_err(&state->client->dev, "No free pipe in %s\n",state->dser_ops->name); ret = -(ENOSR); return ret; } @@ -1725,7 +1790,7 @@ static int ds5_configure(struct ds5 *state) sensor->pipe_id, vc_id); // reset data path when switching to Y12I if (state->is_y8 && data_type1 == GMSL_CSI_DT_RGB_888) - max9296_reset_oneshot(state->dser_dev); + state->dser_ops->reset_oneshot(state->dser_dev); if (ret < 0) return ret; sensor->pipe_configured = true; @@ -2276,7 +2341,7 @@ static int ds5_hw_reset_with_recovery(struct ds5 *state) continue; if (sensor->pipe_id >= 0) { - int release_ret = max9296_release_pipe(state->dser_dev, + int release_ret = state->dser_ops->release_pipe(state->dser_dev, sensor->pipe_id); dev_warn(&state->client->dev, "release pipe %d (%d)\n", sensor->pipe_id, release_ret); @@ -2289,7 +2354,7 @@ static int ds5_hw_reset_with_recovery(struct ds5 *state) dev_info(&state->client->dev, "%s(): Re-initializing SERDES link\n", __func__); - max9296_reset_oneshot(state->dser_dev); + state->dser_ops->reset_oneshot(state->dser_dev); msleep(300); } #endif @@ -3350,7 +3415,6 @@ static int ds5_board_setup(struct ds5 *state) } dser_i2c = of_find_i2c_device_by_node(dser_node); - of_node_put(dser_node); if (dser_i2c == NULL) { err = -EPROBE_DEFER; @@ -3362,6 +3426,19 @@ static int ds5_board_setup(struct ds5 *state) } state->dser_dev = &dser_i2c->dev; + /* Initialize deserializer interface */ + if (!strcmp(dser_node->name, "max9296")) { + state->dser_ops = &max9296_interface; + } else if (!strcmp(dser_node->name, "max96712")) { + state->dser_ops = &max96712_interface; + } else { + dev_err(dev, "%s: Unsupported deserializer = %s\n", __func__, dser_node->name); + /* Should not be used, this is just to make sure we don't have NULL pointers */ + state->dser_ops = &max9296_interface; + goto error; + } + dev_info(dev, "Using deserializer %s\n", state->dser_ops->name); + of_node_put(dser_node); /* populate g_ctx from DT */ gmsl = of_get_child_by_name(node, "gmsl-link"); @@ -3563,6 +3640,9 @@ static int ds5_board_setup(struct ds5 *state) state->dser_dev = &state->dser_i2c->dev; + /* Initialize deserializer interface */ + state->dser_ops = &max9296_interface; + /* populate g_ctx from pdata */ state->g_ctx.dst_csi_port = GMSL_CSI_PORT_A; @@ -3597,19 +3677,6 @@ static int ds5_board_setup(struct ds5 *state) } #endif -static const struct regmap_config ds5_regmap_max9296 = { - .reg_bits = 16, - .val_bits = 8, - .reg_format_endian = REGMAP_ENDIAN_BIG, - .val_format_endian = REGMAP_ENDIAN_NATIVE, -}; - -static const struct regmap_config ds5_regmap_max9295 = { - .reg_bits = 16, - .val_bits = 8, - .reg_format_endian = REGMAP_ENDIAN_BIG, - .val_format_endian = REGMAP_ENDIAN_NATIVE, -}; static int ds5_gmsl_serdes_setup(struct ds5 *state) { @@ -3624,13 +3691,13 @@ static int ds5_gmsl_serdes_setup(struct ds5 *state) mutex_lock(&serdes_lock__); - max9296_power_off(state->dser_dev); + state->dser_ops->power_off(state->dser_dev); /* For now no separate power on required for serializer device */ - max9296_power_on(state->dser_dev); + state->dser_ops->power_on(state->dser_dev); dev_dbg(dev, "Setup SERDES addressing and control pipeline\n"); /* setup serdes addressing and control pipeline */ - err = max9296_setup_link(state->dser_dev, &state->client->dev); + err = state->dser_ops->setup_link(state->dser_dev, &state->client->dev); if (err) { dev_err(dev, "gmsl deserializer link config failed\n"); goto error; @@ -3642,7 +3709,7 @@ static int ds5_gmsl_serdes_setup(struct ds5 *state) if (err) dev_err(dev, "gmsl serializer setup failed\n"); - des_err = max9296_setup_control(state->dser_dev, &state->client->dev); + des_err = state->dser_ops->setup_control(state->dser_dev, &state->client->dev); if (des_err) { dev_err(dev, "gmsl deserializer setup failed\n"); /* overwrite err only if deser setup also failed */ @@ -3675,7 +3742,7 @@ static int ds5_serdes_setup(struct ds5 *state) } /* Register sensor to deserializer dev */ - ret = max9296_sdev_register(state->dser_dev, &state->g_ctx); + ret = state->dser_ops->sdev_register(state->dser_dev, &state->g_ctx); if (ret) { dev_err(&c->dev, "gmsl deserializer register failed\n"); return ret; @@ -3694,10 +3761,10 @@ static int ds5_serdes_setup(struct ds5 *state) return ret; } - ret = max9296_init_settings(state->dser_dev); + ret = state->dser_ops->init_settings(state->dser_dev); if (ret) { - dev_warn(&c->dev, "%s, failed to init max9296 settings\n", - __func__); + dev_warn(&c->dev, "%s, failed to init %s settings\n", + __func__, state->dser_ops->name); return ret; } @@ -4541,7 +4608,7 @@ static int ds5_mux_s_stream(struct v4l2_subdev *sd, int on) if (state->is_y8 && state->ir.sensor.config.format->data_type == GMSL_CSI_DT_RGB_888) { - max9296_reset_oneshot(state->dser_dev); + state->dser_ops->reset_oneshot(state->dser_dev); } #ifndef CONFIG_TEGRA_CAMERA_PLATFORM // reset for IPU6 @@ -4553,8 +4620,8 @@ static int ds5_mux_s_stream(struct v4l2_subdev *sd, int on) } } if (!streaming) { - dev_warn(&state->client->dev, "max9296_reset_oneshot\n"); - max9296_reset_oneshot(state->dser_dev); + dev_warn(&state->client->dev, "deserializer reset oneshot\n"); + state->dser_ops->reset_oneshot(state->dser_dev); } #endif mutex_unlock(&serdes_lock__); @@ -4577,7 +4644,7 @@ static int ds5_mux_s_stream(struct v4l2_subdev *sd, int on) #ifdef CONFIG_VIDEO_D4XX_SERDES if (on && sensor->pipe_id >= 0) { mutex_lock(&serdes_lock__); - if (max9296_release_pipe(state->dser_dev, sensor->pipe_id) < 0) + if (state->dser_ops->release_pipe(state->dser_dev, sensor->pipe_id) < 0) dev_warn(&state->client->dev, "release pipe failed\n"); sensor->pipe_id = -1; mutex_unlock(&serdes_lock__); @@ -5885,7 +5952,7 @@ static int ds5_remove(struct i2c_client *c) if (ret) dev_warn(&c->dev, "failed in 9295 reset control\n"); - ret = max9296_reset_control(state->dser_dev, + ret = state->dser_ops->reset_control(state->dser_dev, state->g_ctx.s_dev); if (ret) dev_warn(&c->dev, @@ -5895,12 +5962,12 @@ static int ds5_remove(struct i2c_client *c) state->g_ctx.s_dev); if (ret) dev_warn(&c->dev, "failed to unpair sdev\n"); - ret = max9296_sdev_unregister(state->dser_dev, + ret = state->dser_ops->sdev_unregister(state->dser_dev, state->g_ctx.s_dev); if (ret) dev_warn(&c->dev, "failed to sdev unregister sdev\n"); - max9296_power_off(state->dser_dev); + state->dser_ops->power_off(state->dser_dev); mutex_unlock(&serdes_lock__); break; @@ -5972,4 +6039,4 @@ MODULE_AUTHOR("Guennadi Liakhovetski ,\n\ Shikun Ding ,\n\ Dmitry Perchanov "); MODULE_LICENSE("GPL v2"); -MODULE_VERSION("1.0.2.8"); +MODULE_VERSION("1.0.2.9"); diff --git a/nvidia-oot/6.0/0004-Adding-max96712-support-for-D4xx.patch b/nvidia-oot/6.0/0004-Adding-max96712-support-for-D4xx.patch new file mode 100644 index 00000000..ecb32a18 --- /dev/null +++ b/nvidia-oot/6.0/0004-Adding-max96712-support-for-D4xx.patch @@ -0,0 +1,460 @@ +From ddbef14471800b69c9ffc6a972a4911cd2c32ceb Mon Sep 17 00:00:00 2001 +From: ejgoldik +Date: Wed, 18 Feb 2026 11:24:20 +0200 +Subject: [PATCH] Adding max96712 support for D4xx + +Signed-off-by: ejgoldik +--- + drivers/media/i2c/max96712.c | 335 +++++++++++++++++++++++++++++++---- + 1 file changed, 300 insertions(+), 35 deletions(-) + +diff --git a/drivers/media/i2c/max96712.c b/drivers/media/i2c/max96712.c +index 8e237eef..38f093e1 100644 +--- a/drivers/media/i2c/max96712.c ++++ b/drivers/media/i2c/max96712.c +@@ -16,32 +16,64 @@ + #include + #include + #include ++#include + ++/* register specifics */ ++ ++#define MAX96712_REG6_ADDR 0x6 ++#define MAX96712_CTRL1_ADDR 0x18 ++ ++#define MAX96712_BACKTOP25_ADDR 0x418 ++ ++#define MAX96712_MIPI_PHY0_ADDR 0x8A0 ++#define MAX96712_MIPI_PHY2_ADDR 0x8A2 ++#define MAX96712_MIPI_PHY3_ADDR 0x8A3 ++#define MAX96712_VIDEO_PIPE_SEL_0_ADDR 0xF0 ++#define MAX96712_VIDEO_PIPE_SEL_1_ADDR 0xF1 ++#define MAX96712_VIDEO_PIPE_EN_ADDR 0xF4 ++#define MAX96712_BACKTOP12_CSI_OUT_EN_ADDR 0x40B ++ ++#define MAX96712_MIPI_TX10_ADDR 0x94A ++#define MAX96712_MIPI_TX11_ADDR 0x90B ++#define MAX96712_MIPI_TX13_SRC_0_MAP_ADDR 0x90D ++#define MAX96712_MIPI_TX14_DST_0_MAP_ADDR 0x90E ++#define MAX96712_MIPI_TX15_SRC_1_MAP_ADDR 0x90F ++#define MAX96712_MIPI_TX16_DST_1_MAP_ADDR 0x910 ++#define MAX96712_MIPI_TX17_SRC_2_MAP_ADDR 0x911 ++#define MAX96712_MIPI_TX18_DST_2_MAP_ADDR 0x912 ++#define MAX96712_MIPI_TX19_SRC_3_MAP_ADDR 0x913 ++#define MAX96712_MIPI_TX20_DST_3_MAP_ADDR 0x914 ++#define MAX96712_MIPI_TX45_MAP_DPHY_DEST_ADDR 0x92D ++#define MAX96712_MIPI_TX51_ADDR 0x973 ++ ++#define MAX96712_VIDEO_RX0_ADDR 0x100 ++ ++#define MAX96712_DPLL_0_ADDR 0x1D00 ++ ++/* data defines */ ++#define MAX96712_MAX_PIPES 4 + + struct max96712 { + struct i2c_client *i2c_client; + struct regmap *regmap; + const char *channel; ++ struct mutex lock; ++ int pwdn_gpio; + }; + static struct max96712 *global_priv[4]; + + int max96712_write_reg_Dser(int slaveAddr, int channel, u16 addr, u8 val); + int max96712_read_reg_Dser(int slaveAddr, int channel, u16 addr, unsigned int *val); + +-struct mutex max96712_rw; +- + int max96712_write_reg_Dser(int slaveAddr, int channel, + u16 addr, u8 val) + { + struct i2c_client *i2c_client = NULL; + int bak = 0; + int err = 0; +- /* unsigned int ival = 0; */ + + if (channel > 3 || channel < 0 || global_priv[channel] == NULL) + return -1; +- +- mutex_lock(&max96712_rw); + i2c_client = global_priv[channel]->i2c_client; + bak = i2c_client->addr; + +@@ -53,7 +85,6 @@ int max96712_write_reg_Dser(int slaveAddr, int channel, + dev_err(&i2c_client->dev, "%s: addr = 0x%x, val = 0x%x\n", + __func__, addr, val); + } +- mutex_unlock(&max96712_rw); + return err; + } + EXPORT_SYMBOL(max96712_write_reg_Dser); +@@ -68,8 +99,6 @@ int max96712_read_reg_Dser(int slaveAddr, int channel, + + if (channel > 3 || channel < 0 || global_priv[channel] == NULL) + return -1; +- +- mutex_lock(&max96712_rw); + i2c_client = global_priv[channel]->i2c_client; + bak = i2c_client->addr; + i2c_client->addr = slaveAddr / 2; +@@ -80,7 +109,6 @@ int max96712_read_reg_Dser(int slaveAddr, int channel, + dev_err(&i2c_client->dev, "%s: addr = 0x%x, val = 0x%x\n", + __func__, addr, *val); + } +- mutex_unlock(&max96712_rw); + return err; + } + EXPORT_SYMBOL(max96712_read_reg_Dser); +@@ -99,6 +127,20 @@ static int max96712_read_reg(struct max96712 *priv, + return err; + } + ++static int max96712_write_reg(struct max96712 *priv, ++ u16 addr, unsigned int val) ++{ ++ struct i2c_client *i2c_client = priv->i2c_client; ++ int err; ++ err = regmap_write(priv->regmap, addr, val); ++ if (err) ++ dev_err(&i2c_client->dev, "%s:i2c write failed, 0x%x = %x\n", ++ __func__, addr, val); ++ ++ /* delay before next i2c command as required for SERDES link */ ++ usleep_range(100, 110); ++ return err; ++} + + static int max96712_stats_show(struct seq_file *s, void *data) + { +@@ -153,24 +195,6 @@ static const struct file_operations max96712_debugfs_fops = { + .release = single_release, + }; + +-static int max96712_power_on(struct max96712 *priv) +-{ +- struct i2c_client *i2c_client = priv->i2c_client; +- struct device_node *np = i2c_client->dev.of_node; +- unsigned int pwdn_gpio = 0; +- +- if(np) { +- pwdn_gpio = of_get_named_gpio(np, "pwdn-gpios", 0); +- dev_info(&i2c_client->dev,"%s: pwdn_gpio = %d\n",__func__,pwdn_gpio); +- } +- if (pwdn_gpio > 0) { +- gpio_direction_output(pwdn_gpio, 1); +- gpio_set_value(pwdn_gpio, 1); +- msleep(100); +- } +- return 0; +-} +- + static int max96712_debugfs_init(const char *dir_name, + struct dentry **d_entry, + struct dentry **f_entry, +@@ -237,6 +261,7 @@ static int max96712_probe(struct i2c_client *client, + { + struct max96712 *priv; + int err = 0; ++ struct device_node *np = NULL; + + dev_info(&client->dev, "%s: enter\n", __func__); + +@@ -249,15 +274,19 @@ static int max96712_probe(struct i2c_client *client, + "regmap init failed: %ld\n", PTR_ERR(priv->regmap)); + return -ENODEV; + } ++ mutex_init(&priv->lock); + +- mutex_init(&max96712_rw); +- +- err = max96712_power_on(priv); +- if (err) { +- dev_err(&client->dev, "Failed to power on err =%d\n",err); +- return err; ++ np = client->dev.of_node; ++ if (np) { ++ priv->pwdn_gpio = of_get_named_gpio(np, "pwdn-gpios", 0); ++ if (priv->pwdn_gpio < 0) { ++ dev_err(&client->dev,"%s: Could not retrieve pwdn_gpio = %d\n", ++ __func__, priv->pwdn_gpio); ++ } + } + ++ dev_set_drvdata(&client->dev, priv); ++ + err = max96712_debugfs_init(NULL, NULL, NULL, priv); + if (err) + return err; +@@ -274,8 +303,11 @@ static int max96712_remove(struct i2c_client *client) + static void max96712_remove(struct i2c_client *client) + #endif + { +- ++ struct max96712 *priv; + if (client != NULL) { ++ priv = dev_get_drvdata(&client->dev); ++ ++ mutex_destroy(&priv->lock); + i2c_unregister_device(client); + client = NULL; + } +@@ -284,13 +316,245 @@ static void max96712_remove(struct i2c_client *client) + #endif + } + ++struct reg_pair { ++ u16 addr; ++ u8 val; ++}; ++ ++static int max96712_set_registers(struct max96712 *priv, struct reg_pair *map, u32 count) ++{ ++ int err = 0; ++ u32 j = 0; ++ ++ for (j = 0; j < count; j++) { ++ err = max96712_write_reg(priv, map[j].addr, map[j].val); ++ if (err != 0) ++ break; ++ } ++ ++ return err; ++} ++ ++int max96712_get_available_pipe_id(struct device *dev, int vc_id) ++{ ++ /* TODO EHUD: Currently vc_id == pipe id but that's definitely ++ * not the end goal if we plan to support multiple cameras ++ */ ++ return vc_id; ++} ++EXPORT_SYMBOL(max96712_get_available_pipe_id); ++ ++int max96712_release_pipe(struct device *dev, int pipe_id) ++{ ++ /* TODO EHUD: pipe id? */ ++ return 0; ++} ++EXPORT_SYMBOL(max96712_release_pipe); ++ ++void max96712_reset_oneshot(struct device *dev) ++{ ++ struct max96712 *priv = dev_get_drvdata(dev); ++ max96712_write_reg(priv, MAX96712_CTRL1_ADDR, 0x0F); ++ msleep(100); ++} ++EXPORT_SYMBOL(max96712_reset_oneshot); ++ ++static int __max96712_set_pipe(struct device *dev, int pipe_id, u8 data_type1, ++ u8 data_type2, u32 vc_id) ++{ ++ int err = 0; ++ struct max96712 *priv = dev_get_drvdata(dev); ++ ++ int i = 0; ++ ++ struct reg_pair map_pipe_control[] = { ++ // Enable 4 mappings for Pipe X ++ {MAX96712_MIPI_TX11_ADDR, 0x0F}, ++ // Map data_type1 on vc_id ++ {MAX96712_MIPI_TX13_SRC_0_MAP_ADDR, 0x1E}, ++ {MAX96712_MIPI_TX14_DST_0_MAP_ADDR, 0x1E}, ++ // Map frame_start on vc_id ++ {MAX96712_MIPI_TX15_SRC_1_MAP_ADDR, 0x00}, ++ {MAX96712_MIPI_TX16_DST_1_MAP_ADDR, 0x00}, ++ // Map frame end on vc_id ++ {MAX96712_MIPI_TX17_SRC_2_MAP_ADDR, 0x01}, ++ {MAX96712_MIPI_TX18_DST_2_MAP_ADDR, 0x01}, ++ // Map data_type2 on vc_id ++ {MAX96712_MIPI_TX19_SRC_3_MAP_ADDR, 0x12}, ++ {MAX96712_MIPI_TX20_DST_3_MAP_ADDR, 0x12}, ++ // All mappings to PHY1 (master for port A) ++ {MAX96712_MIPI_TX45_MAP_DPHY_DEST_ADDR, 0x55}, ++ // SEQ_MISS_EN: Disabled / DIS_PKT_DET: Disabled ++ {MAX96712_VIDEO_RX0_ADDR, 0x23}, // pipe X ++ }; ++ ++ for (i = 0; i < (ARRAY_SIZE(map_pipe_control) - 1); i++) { ++ map_pipe_control[i].addr += 0x40 * pipe_id; ++ } ++ map_pipe_control[(ARRAY_SIZE(map_pipe_control) - 1)].addr += 0x12 * pipe_id; ++ ++ if (data_type2 == 0x0) { ++ /* For IMU (which has no metadata) we override mapping ++ * to enable only 3 ++ */ ++ map_pipe_control[0].val = 0x07; ++ } ++ map_pipe_control[1].val = (vc_id << 6) | data_type1; ++ map_pipe_control[2].val = (vc_id << 6) | data_type1; ++ map_pipe_control[3].val = (vc_id << 6) | 0x00; ++ map_pipe_control[4].val = (vc_id << 6) | 0x00; ++ map_pipe_control[5].val = (vc_id << 6) | 0x01; ++ map_pipe_control[6].val = (vc_id << 6) | 0x01; ++ map_pipe_control[7].val = (vc_id << 6) | data_type2; ++ map_pipe_control[8].val = (vc_id << 6) | data_type2; ++ ++ err |= max96712_set_registers(priv, map_pipe_control, ++ ARRAY_SIZE(map_pipe_control)); ++ ++ max96712_reset_oneshot(dev); ++ max96712_write_reg(priv, MAX96712_VIDEO_PIPE_EN_ADDR, 0xF); ++ ++ return err; ++} ++ ++int max96712_init_settings(struct device *dev) ++{ ++ int err = 0; ++ struct max96712 *priv = dev_get_drvdata(dev); ++ struct reg_pair map_pipe_opt[] = ++ { ++ /* ----------Video pipes configure ----------------------*/ ++ {MAX96712_REG6_ADDR, 0xF1}, // Enable link - Why is this needed? ++ {MAX96712_VIDEO_PIPE_SEL_0_ADDR, 0x10}, //0xF0, Link A ID 0 to pipe 0 , Link A ID 1 to pipe 1 ++ {MAX96712_VIDEO_PIPE_SEL_1_ADDR, 0x32}, //0xF1, Link A ID 2 to pipe 2 , Link A ID 3 to pipe 3 ++ {MAX96712_VIDEO_PIPE_EN_ADDR, 0x00}, //0xF4, Enable pipe 0-3, 0xFF ++ }; ++ ++ struct reg_pair map_phy_opt[] = ++ { ++ /* MIPI D-PHY Config */ ++ {MAX96712_MIPI_PHY0_ADDR, 0x04}, //0x8A0 ++ {MAX96712_MIPI_TX10_ADDR, 0x40}, //0x94a - MIPI lane count ++ {MAX96712_MIPI_PHY3_ADDR, 0xe4}, //0x8A3, Lower phys to lower lanes ++ ++ /* Put DPLL in reset before changing MIPI lane rates */ ++ {MAX96712_DPLL_0_ADDR, 0xF4}, //0x1D00 ++ ++ /* 1500Mbps/lane on port A */ ++ {MAX96712_BACKTOP25_ADDR, 0x2f}, //0x418 ++ ++ /* Release DPLL reset */ ++ {MAX96712_DPLL_0_ADDR, 0xF5}, //0x1D00 ++ ++ /* ALT2_MEM_MAP8 */ ++ {MAX96712_MIPI_TX51_ADDR, 0x10}, //MIPI TX1 ++ ++ {MAX96712_MIPI_PHY2_ADDR, 0x34}, //0x8A2 Disable phys 2+3 ++ {MAX96712_BACKTOP12_CSI_OUT_EN_ADDR, 0x02}, // (CSI_OUT_EN): CSI output enabled ++ }; ++ ++ mutex_lock(&priv->lock); ++ ++ err |= max96712_set_registers(priv, map_pipe_opt, ARRAY_SIZE(map_pipe_opt)); ++ err |= max96712_set_registers(priv, map_phy_opt, ARRAY_SIZE(map_phy_opt)); ++ ++ mutex_unlock(&priv->lock); ++ ++ return err; ++} ++EXPORT_SYMBOL(max96712_init_settings); ++ ++int max96712_set_pipe(struct device *dev, int pipe_id, ++ u8 data_type1, u8 data_type2, u32 vc_id) ++{ ++ struct max96712 *priv = dev_get_drvdata(dev); ++ int err = 0; ++ ++ if (pipe_id > (MAX96712_MAX_PIPES - 1)) { ++ dev_info(dev, "%s, input pipe_id: %d exceed max96712 max pipes\n", ++ __func__, pipe_id); ++ return -EINVAL; ++ } ++ ++ dev_dbg(dev, "%s pipe_id %d, data_type1 %u, data_type2 %u, vc_id %u\n", ++ __func__, pipe_id, data_type1, data_type2, vc_id); ++ ++ mutex_lock(&priv->lock); ++ ++ err = __max96712_set_pipe(dev, pipe_id, data_type1, data_type2, vc_id); ++ ++ mutex_unlock(&priv->lock); ++ ++ return err; ++} ++EXPORT_SYMBOL(max96712_set_pipe); ++ ++int max96712_setup_link(struct device *dev, struct device *s_dev) ++{ ++ /* TODO EHUD: Is needed? */ ++ return 0; ++} ++EXPORT_SYMBOL(max96712_setup_link); ++ ++int max96712_setup_control(struct device *dev, struct device *s_dev) ++{ ++ /* TODO EHUD: Is needed? */ ++ return 0; ++} ++EXPORT_SYMBOL(max96712_setup_control); ++ ++int max96712_reset_control(struct device *dev, struct device *s_dev) ++{ ++ /* TODO EHUD: Is needed? */ ++ return 0; ++} ++EXPORT_SYMBOL(max96712_reset_control); ++ ++int max96712_sdev_register(struct device *dev, struct gmsl_link_ctx *g_ctx) ++{ ++ /* TODO EHUD: Is needed? */ ++ return 0; ++} ++EXPORT_SYMBOL(max96712_sdev_register); ++ ++int max96712_sdev_unregister(struct device *dev, struct device *s_dev) ++{ ++ /* TODO EHUD: Is needed? */ ++ return 0; ++} ++EXPORT_SYMBOL(max96712_sdev_unregister); ++ ++int max96712_power_on(struct device *dev) ++{ ++ struct max96712 *priv = dev_get_drvdata(dev); ++ if (priv->pwdn_gpio > 0) { ++ gpio_direction_output(priv->pwdn_gpio, 1); ++ gpio_set_value(priv->pwdn_gpio, 1); ++ msleep(100); ++ } ++ return 0; ++} ++EXPORT_SYMBOL(max96712_power_on); ++ ++void max96712_power_off(struct device *dev) ++{ ++ struct max96712 *priv = dev_get_drvdata(dev); ++ if (priv->pwdn_gpio > 0) { ++ gpio_direction_output(priv->pwdn_gpio, 1); ++ gpio_set_value(priv->pwdn_gpio, 0); ++ msleep(100); ++ } ++ return; ++} ++EXPORT_SYMBOL(max96712_power_off); ++ + static const struct i2c_device_id max96712_id[] = { + { "max96712", 0 }, + { }, + }; + + static const struct of_device_id max96712_of_match[] = { +- { .compatible = "nvidia,max96712", }, ++ { .compatible = "maxim,max96712", }, + { }, + }; + +@@ -300,6 +564,7 @@ static struct i2c_driver max96712_i2c_driver = { + .driver = { + .name = "max96712", + .owner = THIS_MODULE, ++ .of_match_table = of_match_ptr(max96712_of_match), + }, + .probe = max96712_probe, + .remove = max96712_remove, +-- +2.43.0 + diff --git a/nvidia-oot/6.1/0004-Adding-max96712-support-for-D4xx.patch b/nvidia-oot/6.1/0004-Adding-max96712-support-for-D4xx.patch new file mode 120000 index 00000000..f82b7e20 --- /dev/null +++ b/nvidia-oot/6.1/0004-Adding-max96712-support-for-D4xx.patch @@ -0,0 +1 @@ +../6.0/0004-Adding-max96712-support-for-D4xx.patch \ No newline at end of file diff --git a/nvidia-oot/6.2/0004-Adding-max96712-support-for-D4xx.patch b/nvidia-oot/6.2/0004-Adding-max96712-support-for-D4xx.patch new file mode 120000 index 00000000..f82b7e20 --- /dev/null +++ b/nvidia-oot/6.2/0004-Adding-max96712-support-for-D4xx.patch @@ -0,0 +1 @@ +../6.0/0004-Adding-max96712-support-for-D4xx.patch \ No newline at end of file diff --git a/nvidia-oot/max96712.h b/nvidia-oot/max96712.h new file mode 100644 index 00000000..07fad5e2 --- /dev/null +++ b/nvidia-oot/max96712.h @@ -0,0 +1,40 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* Copyright (c) 2018-2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved. */ + +/** + * @file + * MAX96712 API: For Maxim Integrated MAX96712 deserializer + * + * @b Description: Defines elements used to set up and use a + * Maxim Integrated MAX96712 deserializer. + */ + +#ifndef __MAX96712_H__ +#define __MAX96712_H__ + +#include +#include +/** + * \defgroup max96712 MAX96712 deserializer driver + * + * Controls the MAX96712 deserializer module. + * + * @ingroup serdes_group + * @{ + */ + +int max96712_get_available_pipe_id(struct device *dev, int vc_id); +int max96712_set_pipe(struct device *dev, int pipe_id, u8 data_type1, + u8 data_type2, u32 vc_id); +int max96712_release_pipe(struct device *dev, int pipe_id); +void max96712_reset_oneshot(struct device *dev); +int max96712_setup_link(struct device *dev, struct device *s_dev); +int max96712_setup_control(struct device *dev, struct device *s_dev); +int max96712_reset_control(struct device *dev, struct device *s_dev); +int max96712_sdev_register(struct device *dev, struct gmsl_link_ctx *g_ctx); +int max96712_sdev_unregister(struct device *dev, struct device *s_dev); +int max96712_power_on(struct device *dev); +void max96712_power_off(struct device *dev); +int max96712_init_settings(struct device *dev); + +#endif /* __MAX96712_H__ */