SOC_CAMERA driver in L4T R24.2.1

Hello,

I have finish developed my camera driver for 24.1 kernel version. Now I want to update to 24.2.1 for getting more performance on deep learning and using NVIDIA multimedia APIs.

After spent time on L4T R24.2 Documentation I got to port driver to new kernel.
I added one dtsi file for my camera modules.
This is my dtsi:

/*
 * Copyright (c) 2016, NVIDIA CORPORATION.  All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; version 2 of the License.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
 * more details.
 *
 */

#include <dt-bindings/media/camera.h>
#include <dt-bindings/platform/t210/t210.h>

#define CAM0_RST_L	TEGRA_GPIO(S, 4)
#define CAM0_PWDN	TEGRA_GPIO(S, 7)
#define CAM1_RST_L	TEGRA_GPIO(S, 5)
#define CAM1_PWDN	TEGRA_GPIO(T, 0)

/ {
	/* set camera gpio direction to output */
	gpio: gpio@6000d000 {
		camera-control {
			gpio-output-low = <
				CAM0_RST_L
				CAM0_PWDN
				CAM1_RST_L
				CAM1_PWDN
				>;
		};
	};

	/* all cameras are disabled by default */
	host1x {
		vi_base: vi {
			num-channels = <2>;
			ports {
				#address-cells = <1>;
				#size-cells = <0>;
				vi_port0: port@0 { /*CSI A*/
					status = "okay";
					reg = <0>;
					vi_in0: endpoint {
						status = "okay";
						csi-port = <0x0>;
						bus-width = <4>;
						remote-endpoint = <&imx135_out0>;
						clock-lanes = <0>;
						data-lanes = <1 2 3 4>;
					};
				};
				vi_port1: port@1 { /*CSI C*/
					status = "okay";
					vi_in1: endpoint {
						status = "okay";
						csi-port = <0x2>;
						bus-width = <4>;
						remote-endpoint = <&ar0261_out0>;
						clock-lanes = <0>;
						data-lanes = <1 2 3 4>;
					};
					};
				};
				vi_port2: port@2 {
					status = "disabled";
					vi_in2: endpoint {
						status = "disabled";
					};
				};
				vi_port3: port@3 {
					status = "disabled";
					vi_in3: endpoint {
						status = "disabled";
					};
				};
				vi_port4: port@4 {
					status = "disabled";
					vi_in4: endpoint {
						status = "disabled";
					};
				};
				vi_port5: port@5 {
					status = "disabled";
					vi_in5: endpoint {
						status = "disabled";
					};
				};
			};
		};
		i2c@546c0000 {
			status = "okay";
			#address-cells = <1>;
			#size-cells = <0>;
			imx135_a@0E {
				compatible = "imx135_v4l2";
				reg = <0x0E>;
				sensor_model ="imx135";
				avdd-reg = "vana";
				iovdd-reg = "vif";
				devnode = "video0";
				post_crop_frame_drop = "0";
				mclk = "cam_mclk1";
				vana-supply = <&en_vdd_cam_hv_2v8>;
				vif-supply = <&en_vdd_cam>;

				ports {
					#address-cells = <1>;
					#size-cells = <0>;
					port@0 {
						reg = <0>;
						imx135_out0: endpoint {
							csi-port = <0>;
							bus-width = <4>;
							remote-endpoint = <&vi_in0>;
						};
					};
				};
			};
			ar0261_a@0F {
				compatible = "ar0261_v4l2";
				reg = <0x0F>;
				sensor_model ="ar0261";
				avdd-reg = "vana";
				iovdd-reg = "vif";
				devnode = "video1";
				post_crop_frame_drop = "0";
				mclk = "cam_mclk1";
				vana-supply = <&en_vdd_cam_hv_2v8>;
				vif-supply = <&en_vdd_cam>;

				ports {
					#address-cells = <1>;
					#size-cells = <0>;
					port@0 {
						reg = <0>;
						ar0261_out0: endpoint {
							csi-port = <2>;
							bus-width = <4>;
							remote-endpoint = <&vi_in0>;
						};
					};
				};
			};			
		};

	tcp: tegra-camera-platform {
		compatible = "nvidia, tegra-camera-platform";
		modules {
			cam_module0: module0 {
				badge = "imx135";
				position = "left";
				orientation = "1";
				status = "okay";
				drivernode0 {
					pcl_id = "v4l2_sensor";
					devname = "imx135 6-0036";
					proc-device-tree = "/proc/device-tree/host1x/i2c@546c0000/imx135_a@0E";
					status = "okay";
				};
				cam_module0_drivernode1: drivernode1 {
					status = "okay";
					pcl_id = "v4l2_focuser_stub";
					proc-device-tree = "";
				};
			};
			cam_module1: module1 {
				badge = "ar0261";
				position = "right";
				orientation = "1";
				status = "okay";
				drivernode0 {
					pcl_id = "v4l2_sensor";
					devname = "ar0261 6-0036";
					proc-device-tree = "/proc/device-tree/host1x/i2c@546c0000/ar0261_a@0E";
					status = "okay";
				};
				cam_module1_drivernode1: drivernode1 {
					status = "okay";
					pcl_id = "v4l2_focuser_stub";
					proc-device-tree = "";
				};
			};			
		};
	};
};

I also enabled these configs :
CONFIG_SOC_CAMERA=y
CONFIG_SOC_CAMERA_PLATFORM=y
CONFIG_SOC_CAMERA_AR0261=y
CONFIG_SOC_CAMERA_IMX135=y

And I modified imx135_v4l2.c and ar0261_v4l2.c as my 2 camera drivers. Finally, I rebuild, update new kernel and dtbs for my device. The log result is below

[ 4.379423] vi vi: vi_probe: ++
[ 4.391393] vi vi: initialized
[ 4.391883] vi vi: parsing node /host1x/vi
[ 4.391889] vi vi: handling endpoint /host1x/vi/ports/port@0/endpoint
[ 4.391958] vi vi: handling endpoint /host1x/vi/ports/port@1/endpoint
[ 4.391993] vi vi: parsing node /i2c@546c0000/imx135_a@0E
[ 4.391998] vi vi: handling endpoint /i2c@546c0000/imx135_a@0E/ports/port@0/endpoint
[ 4.392019] vi vi: parsing node /i2c@546c0000/ar0261_a@0F
[ 4.392024] vi vi: handling endpoint /i2c@546c0000/ar0261_a@0F/ports/port@0/endpoint

It look like my camera drivers (imx135_v4l2 and ar0261_v4l2) are not probed. As L4T R24.2 Documentation , we should modify board file arch/arm64/mach-tegra/board-t210ref-camera.c but I think we no need and this document is out of date because we done everything in device tree.
Please help me to continue.
Thanks

Hello,

Now my device tree can bind camera driver and I cant get /dev/video0. However still something wrong.
In probe function I register as below:

v4l2_i2c_subdev_init(&priv->subdev, client, &isx017_subdev_ops);
static struct v4l2_subdev_ops isx017_subdev_ops = {
	.core	= &isx017_subdev_core_ops,
	.video	= &isx017_subdev_video_ops,
};
static struct v4l2_subdev_video_ops isx017_subdev_video_ops = {
	.s_stream	= isx017_s_stream,
	.s_mbus_fmt	= isx017_s_fmt,
	.g_mbus_fmt	= isx017_g_fmt,
	.try_mbus_fmt	= isx017_try_fmt,
	.enum_mbus_fmt	= isx017_enum_fmt,
	.g_crop		= isx017_g_crop,
	.cropcap	= isx017_cropcap,
	.g_mbus_config	= isx017_g_mbus_config,
};

static struct v4l2_subdev_core_ops isx017_subdev_core_ops = {
	.g_chip_ident	= isx017_g_chip_ident,
	.s_power	= isx017_s_power,
	.unsubscribe_event = isx017_test,
};

But I never saw some functions like isx017_s_fmt, isx017_g_fmt, … are run. This driver work well in 24.1 kernel version and these functions are run as well.
Any suggestion please?
Thanks

Hello,

I found something and maybe this cause problem.
Error log :

isx017_v4l2 6-0010: Dev node doesn't have vdig supply props
isx017_v4l2 6-0010: Dev node doesn't have vif supply props
isx017_v4l2 6-0010: Dev node doesn't have isx017_reg1 supply props
isx017_v4l2 6-0010: Dev node doesn't have isx017_reg2 supply props

Even though I think they already defined in “tegra210-jetson-e-pmic-p2530-0930-e03.dtsi”
as

/*
 * Copyright (c) 2014-2016, NVIDIA CORPORATION.  All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
 * more details.
 */

#include <dt-bindings/mfd/max77620.h>
#include <dt-bindings/regulator/regulator.h>
#include <dt-bindings/gpio/tegra-gpio.h>
#include <dt-bindings/thermal/thermal.h>

/ {
	i2c@7000d000 {
		nvidia,bit-banging-xfer-after-shutdown;

		max77620: max77620@3c {
			compatible = "maxim,max77620";
			reg = <0x3c>;
			interrupts = <0 86 IRQ_TYPE_NONE>;

			#interrupt-cells = <2>;
                        interrupt-controller;

			gpio-controller;
			#gpio-cells = <2>;

			maxim,enable-clock32k-out;

			maxim,system-pmic-power-off;

			maxim,hot-die-threshold-temp = <110000>;
			#thermal-sensor-cells = <0>;

			pinctrl-names = "default";
			pinctrl-0 = <&max77620_default>;

			gpio-init-names = "default";
			gpio-init-0 = <&max77620_gpio_default>;

			max77620_default: pinmux@0 {
				pin_gpio0 {
					pins = "gpio0";
					function = "gpio";
				};

				pin_gpio1 {
					pins = "gpio1";
					function = "fps-out";
					drive-push-pull = <1>;
					maxim,fps-source = <FPS_SRC_0>;
					maxim,fps-power-up-period = <7>;
					maxim,fps-power-down-period = <0>;
				};

				pin_gpio2_3 {
					pins = "gpio2", "gpio3";
					function = "fps-out";
					drive-open-drain = <1>;
					maxim,fps-source = <FPS_SRC_0>;
				};

				pin_gpio4 {
					pins = "gpio4";
					function = "32k-out1";
				};

				pin_gpio5_6_7 {
					pins = "gpio5", "gpio6", "gpio7";
					function = "gpio";
					drive-push-pull = <1>;
				};
			};

			max77620_gpio_default:gpio_default {
				gpio-output-high = <2>;
			};

			watchdog {
				maxim,wdt-boot-timeout = <16>;
				maxim,wdt-clear-time = <13>;
				status = "okay";
				dt-override-status-odm-data = <0x00020000 0x00020000>;
			};

			fps {
				#address-cells = <1>;
				#size-cells = <0>;
				fps@0 {
					reg = <0>;
					maxim,fps-time-period = <2560>;
					maxim,fps-enable-input = <FPS_EN_SRC_EN0>;
				};

				fps@1 {
					reg = <1>;
					maxim,fps-time-period = <2560>;
					maxim,fps-enable-input = <FPS_EN_SRC_EN1>;
					maxim,enable-sleep;
				};

				fps@2 {
					reg = <2>;
					maxim,fps-enable-input = <FPS_EN_SRC_EN0>;
				};
			};

			backup-battery {
				maxim,backup-battery-charging-current = <100>;
				maxim,backup-battery-charging-voltage = <3000000>;
				maxim,backup-battery-output-resister = <100>;
			};

			regulators {
				in-ldo0-1-supply = <&max77620_sd2>;
				in-ldo7-8-supply = <&max77620_sd2>;

				max77620_sd0: sd0 {
					regulator-name = "vdd_core";
					regulator-min-microvolt = <600000>;
					regulator-max-microvolt = <1400000>;
					regulator-boot-on;
					regulator-always-on;
					maxim,fps-source = <FPS_SRC_1>;
					regulator-init-mode = <REGULATOR_MODE_NORMAL>;
				};

				max77620_sd1: sd1 {
					regulator-name = "vddio-ddr";
					regulator-always-on;
					regulator-boot-on;
					regulator-init-mode = <REGULATOR_MODE_NORMAL>;
					maxim,fps-source = <FPS_SRC_0>;
				};

				max77620_sd2: sd2 {
					regulator-name = "vdd-pre-reg";
					regulator-min-microvolt = <1350000>;
					regulator-max-microvolt = <1350000>;
					maxim,fps-source = <FPS_SRC_1>;
				};

				max77620_sd3: sd3 {
					regulator-name = "vdd-1v8";
					regulator-min-microvolt = <1800000>;
					regulator-max-microvolt = <1800000>;
					regulator-always-on;
					regulator-boot-on;
					maxim,fps-source = <FPS_SRC_0>;
					regulator-init-mode = <REGULATOR_MODE_NORMAL>;
					consumers {
						c7 {
							regulator-consumer-supply = "avdd_pll_utmip";
							regulator-consumer-device = "tegra-ehci.0";
						};
						c8 {
							regulator-consumer-supply = "avdd_pll_utmip";
							regulator-consumer-device = "tegra-ehci.1";
						};
						c9 {
							regulator-consumer-supply = "avdd_pll_utmip";
							regulator-consumer-device = "tegra-ehci.2";
						};
						c18 {
							regulator-consumer-supply = "vdd";
							regulator-consumer-device = "2-004c";
						};
						c19 {
							regulator-consumer-supply = "vdd";
							regulator-consumer-device = "0-004c";
						};
					};
				};

				max77620_ldo0: ldo0 {
					regulator-name = "avdd-sys";
					regulator-min-microvolt = <1200000>;
					regulator-max-microvolt = <1200000>;
					regulator-always-on;
					regulator-boot-on;
					maxim,fps-source = <FPS_SRC_NONE>;
					consumers {
						c0 {
							regulator-consumer-supply = "vddio_hsic";
							regulator-consumer-device = "tegra-ehci.1";
						};
						c1 {
							regulator-consumer-supply = "vddio_hsic";
							regulator-consumer-device = "tegra-ehci.2";
						};
						c2 {
							regulator-consumer-supply = "vdig";
						};
						c3 {
							regulator-consumer-supply = "isx017_reg2";
						};
					};
				};

				max77620_ldo1: ldo1 {
					regulator-name = "vdd-pex";
					regulator-min-microvolt = <1050000>;
					regulator-max-microvolt = <1050000>;
					regulator-always-on;
					maxim,fps-source = <FPS_SRC_1>;
				};

				max77620_ldo2: ldo2 {
					regulator-name = "vddio-sdmmc3";
					regulator-min-microvolt = <1800000>;
					regulator-max-microvolt = <3300000>;
					maxim,fps-source = <FPS_SRC_NONE>;
				};

				max77620_ldo3: ldo3 {
					regulator-name = "vdd-cam-hv";
					regulator-min-microvolt = <2800000>;
					regulator-max-microvolt = <2800000>;
					maxim,fps-source = <FPS_SRC_NONE>;
					consumers {
						c1 {
							regulator-consumer-supply = "isx017_reg1";
						};
					};
				};

				max77620_ldo4: ldo4 {
					regulator-name = "vdd-rtc";
					regulator-min-microvolt = <850000>;
					regulator-max-microvolt = <850000>;
					regulator-always-on;
					regulator-boot-on;
					maxim,fps-source = <FPS_SRC_0>;
				};

				max77620_ldo5: ldo5 {
					regulator-name = "avdd-ts-hv";
					regulator-min-microvolt = <3300000>;
					regulator-max-microvolt = <3300000>;
					maxim,fps-source = <FPS_SRC_NONE>;
				};

				max77620_ldo6: ldo6 {
					regulator-name = "vdd-ts";
					regulator-min-microvolt = <1800000>;
					regulator-max-microvolt = <1800000>;
					regulator-always-on;
					regulator-boot-on;
					maxim,fps-source = <FPS_SRC_0>;
					maxim,fps-power-up-period = <7>;
					maxim,fps-power-down-period = <0>;
					consumers {
						c0 {
							regulator-consumer-supply = "vif";
						};
					};
				};

				max77620_ldo7: ldo7 {
					regulator-name = "vdd-gen-pll-edp";
					regulator-min-microvolt = <1050000>;
					regulator-max-microvolt = <1050000>;
					regulator-always-on;
					regulator-boot-on;
					maxim,fps-source = <FPS_SRC_1>;
				};

				max77620_ldo8: ldo8 {
					regulator-name = "vdd-hdmi-dp";
					regulator-min-microvolt = <1050000>;
					regulator-max-microvolt = <1050000>;
					regulator-always-on;
					maxim,fps-source = <FPS_SRC_1>;
				};
			};
		};
	};

	dummy_cool_dev: dummy-cool-dev {
		compatible = "dummy-cooling-dev";
		#cooling-cells = <2>; /* min followed by max */
	};

	thermal-zones {
		PMIC-Die {
			polling-delay = <0>; /* milliseconds */
			polling-delay-passive = <0>; /* milliseconds */

			thermal-sensors = <&max77620>;
			trips {
				die_temp_thresh: hot-die {
					temperature = <120000>;
					type = "active";
					hysteresis = <0>;
				};
			};

			cooling-maps {
				map0 {
					trip = <&die_temp_thresh>;
					cooling-device = <&dummy_cool_dev THERMAL_NO_LIMIT
								THERMAL_NO_LIMIT>;
					contribution = <100>;
					cdev-type = "emergency-balanced";
				};
			};
		};
	};

	extcon {
		compatible = "simple-bus";
		device_type = "external-connection";
		#address-cells = <1>;
		#size-cells = <0>;
	};
};

Please reference to the reference driver …/kernel/driver/i2c/ov5693.c to pass the v4l2-ctl/v4l2-compliance test first. You can also find how to implement you devices tree there.
And for regulator you have to make sure your hardware need to enable it. Also if your HW are always power on then you don’t need to struggle on the regulator.

Please download the document from below link and reference to the “Sensor Driver Programming Guide” chapter

http://developer.nvidia.com/embedded/dlc/l4t-documentation-24-2