Custom device tree and driver for camera

Hello,

I am working on a driver for a camera. Till now I set up the I2C driver and so far so good, the drivers compile.

Since the sensor is outputting in LVDS mode, I have to convert it to CSI-2 using an FPGA.
the sensor’s controls (XCLR, Slave address, Trigger, Master/Slave mode, etc) are driven by an I2C to GPIO expander (a similar TI chip used in the dev carrier board B04/C02).
I use two sensors, both attached on the same I2C bus (since both can have a different slave address).

My dtsi in hardware\nvidia\platform\t18x\common\kernel-dts\t18x-common-platforms</i> looks like this:

#include <t18x-common-modules/tegra186-camera-imx392-dual.dtsi>
#include "dt-bindings/clock/tegra186-clock.h"

#define CAM0_RST_L	TEGRA_MAIN_GPIO(R, 5)
#define CAM0_PWDN	TEGRA_MAIN_GPIO(R, 0)
#define CAM1_RST_L	TEGRA_MAIN_GPIO(R, 1)
#define CAM1_PWDN	TEGRA_MAIN_GPIO(L, 6)
#define CAMERA_I2C_MUX_BUS(x) (0x1E + x)

/* camera control gpio definitions */

/ {
	i2c@3180000 {
		tca9539_74: tca9539@74 { // Carrier board
			compatible = "ti,tca9539";
			gpio-controller;
			#gpio-cells = <2>;
			reg = <0x74>;
			vcc-supply = <&en_vdd_cam>;
			tca9539_74_outlow {
				gpio-hog;
				gpios = <0 0 1 0 2 0 3 0 4 0 5 0 6 0 7 0 8 0 9 0 10 0 11 0 12 0 13 0 14 0 15 0>;
				output-low;
				label = "tca9539_74_outlow_0",
						"tca9539_74_outlow_1",
						"tca9539_74_outlow_2",
						"tca9539_74_outlow_3",
						"tca9539_74_outlow_4",
						"tca9539_74_outlow_5",
						"tca9539_74_outlow_6",
						"tca9539_74_outlow_7";
						"tca9539_74_outlow_8";
						"tca9539_74_outlow_9";
						"tca9539_74_outlow_10";
						"tca9539_74_outlow_11";
						"tca9539_74_outlow_12";
						"tca9539_74_outlow_13";
						"tca9539_74_outlow_14";
						"tca9539_74_outlow_15";
			};
			tca9539_74_outhigh {
				status = "disabled";
			};
			tca9539_74_input {
				status = "disabled";
			};
		};
		tca9546_70: tca9546@70 { // TCA9546 internal?
			compatible = "nxp,pca9546"; // PCA9546?
			reg = <0x70>;
			#address-cells = <1>;
			#size-cells = <0>;
			vcc-supply = <&en_vdd_cam>;
			skip_mux_detect;
			force_bus_start = <CAMERA_I2C_MUX_BUS(0)>;

			i2c@0 {
				reg = <0>;
				i2c-mux,deselect-on-exit;
				#address-cells = <1>;
				#size-cells = <0>;
				imx392_a@36 {
					clocks = <&tegra_car TEGRA186_CLK_EXTPERIPH1>,
						 	 <&tegra_car TEGRA186_CLK_PLLP_OUT0>;
					mclk = "extperiph1";
					vif-supply = <&en_vdd_cam>;
				};

				imx392_a@37 {
					clocks = <&tegra_car TEGRA186_CLK_EXTPERIPH1>,
						 	 <&tegra_car TEGRA186_CLK_PLLP_OUT0>;
					mclk = "extperiph1";
					vif-supply = <&en_vdd_cam>;
				};
			};
		};
	};
};

The part that I don’t really understand in this table is this the definition of the tca9546 and why “nxp,pca9546” is in the compatible tag of a TI chip. (I copied this from another sensor dtsi, it seems like all of them use it)

Next is the compiling:

Error: /home/travis/build/USERNAME/jetson-camera/build/Linux_for_Tegra/sources/kernel/kernel-4.9/../../hardware/nvidia/platform/t18x/common/kernel-dts/t18x-common-platforms/tegra186-quill-camera-imx392-dual.dtsi:12.1-2 syntax error
FATAL ERROR: Unable to parse input tree

What is wrong with the start? It’s exactly like all other sensors.

At last, how do I get control over the I2C to GPIO expander? Where do I define it’s settings when the sensors are turned on? (for example, when XCLR needs to become a high signal, when the Oscillator needs to start oscillating, setting up the slave address for each sensor, etc)?

hello FPSUsername,

please refer to below for understanding.

  1. TCA954x it’s an i2c-bus multiplexers for sharing i2c address to several same camera sensors.
    please refer to below code-snippet,
    this means TCA9548 is using Tegra’s i2c bus at 3180000, and multiplexing six i2c address for six camera devices.
<i>$l4t-r32.2/kernel_src/hardware/nvidia/platform/t18x/common/kernel-dts/t18x-common-platforms/tegra186-quill-camera-modules.dtsi</i>

	i2c@3180000 {
		tca9548@77 {
			i2c@0 {
			i2c@1 {
			i2c@2 {
			i2c@3 {
			i2c@4 {
			i2c@5 {

then, you should also refer to below code-snippet.
here’s multiple camera device tree to detail the property settings.

<i>$l4t-r32.2/kernel_src/hardware/nvidia/platform/t18x/common/kernel-dts/t18x-common-modules/tegra186-camera-e3333-a00.dtsi</i>

	i2c@3180000 {
		tca9548@77 {
			i2c@0 {
				ov5693_a@36 {

			i2c@1 {
				ov5693_b@36 {

			i2c@2 {
				ov5693_c@36 {

			i2c@3 {
				ov5693_d@36 {

			i2c@4 {
				ov5693_e@36 {

			i2c@5 {
				ov5693_f@36 {
  1. I’ve review your code, and found there’s mistake.
    you should have different node naming to distinguish two imx392 devices.
imx392_a@36 {...};
imx392_a@37 {...};
  1. for the compiling issue, you should review the port binding in your sensor device tree to debug dtb compiling failure.

  2. BTW, please check L4T kernel sources for reference camera module device tree,
    such as tegra186-camera-e3333-a00.dtsi and tegra186-camera-imx274-dual.dtsi for implementation reference,
    thanks

Thank you for your answer,

I did spot some mistakes with naming and fixed them, but the dtsi still doesn’t want to be compiled.

I tried compiling the tree using device-tree-compiler on my raspberry pi but no luck there. It also happens on other device trees from the L4T kernel sources:

dtc -@ -I dts -O dtb tegra186-quill-camera-imx392-dual.dtsi

The compiler keeps outputting an error at the first include. When I comment the includes out, the error moves towards the defines.

Hi,
I have seen similar issues compiling device-tree with missing “;” at the end of modules, this may be your case.

As example,

&i2c3 {
	clock-frequency = <100000>;
	pinctrl-names = "default";
	pinctrl-0 = <&pinctrl_i2c3_3>;
	status = "okay";

	/* DS1337 RTC module */
	rtc@0x68 {
		compatible = "dallas,ds1337";
		reg = <0x68>;
	};
};

Check “;” at the end after “}”.
I got similar issues when any of those “;” was deleted by mistake.

Hope this helps.

Regards,
Greivin F.

Hi,

I checked my files and saw a couple of semicolons that should’ve been commas (in the GPIO section). Normally I don’t make such mistakes, but this time it happened because of a quick copy paste expansion.

The issue still remains and it mainly comes down to #define and #include.
I googled a bit on device tree usage and see that all the device trees here use the deprecated v0 (as /dts-v1/; is a needed header for the newer version). Defines and includes now don’t start with # but are placed in between two slashes, like /define/. I tried this as well, but no luck in compiling. I removed every line and started clean.

It seems to compile fine with some warnings on reg properties, but once I add an include or define, it spits out a syntax error.

hello FPSUsername,

these #define and #include macro won’t caused the compile failure.
please check Kernel Customization chapter for configure environment settings correctly.
suggest you also add device tree properties one-by-one for easy checking.
thanks

So it seems like I made a mistake in the file located in t18x-common-platforms. With that issue solved, the syntax error is gone.
The only things I’m getting now are some warnings regarding the reg length and these:

ERROR (phandle_references): Reference to non-existent node or label "cam_module0_drivernode1"
ERROR (phandle_references): Reference to non-existent node or label "cam_module1_drivernode1"
ERROR (phandle_references): Reference to non-existent node or label "vi_base"

Edit:
Solved all issues, device trees are compiled!

Hi,

How do you fixed this issuse We are getting the same.

Thank you

Start by folding each code block. I found out that I did close all opening brackets, but some where in the wrong place, resulting in a faulty device tree.