Strange problem with Dtb and / or Driver, hoping for some help. (Solved)

Have really strange problem adapting my ported Auvidea J20 and IMX219 camera drivers.
Had this all working on JP3.2 / 28.2 /TX2.

Made the necessary changes to the dtsi on xavier, decompiled my “old” TX2 DTB and compared it to my new flashed and decompiled Xavier dtb ,looks like it should be.
(Also removed camera_plugin_manger before adding my j20.dtsi and imx219.dtsi)

added my j20.c and imx219.c to kernel4.9/drivers/media/i2c, changed kconfig and makefile
made the changes to config and then compiled it.

While compiling i can see it picking up the new j20 and imx219 and compiling it as builtin not a module, just like it should.

then i copy the new image to Boot/Image and do a reboot…

problem is that it never probes, haven’t got anything i dmesg about J20 or Imx219, no errors or failed, no nothing :)

Was there something else changed for driver bringup / porting in JP3.3 or 4.0 DP ? latest porting guide is for 28.2 (3.2) and couldn’t find any changes in the Normal Doc for 3.3 / 4.0 ?

If anyone knows what could be going on here i would love some help :)

Btw, I do compile on target, always done that, feels less messy and never had a problem with it, i know it’s not supported or recommended by Nvidia…

Included the decompiled dtb’s… (88.5 KB)

I also tested :

“Added my j20.c and imx219.c to kernel/nvidia/drivers/media/i2c, changed kconfig and makefile
made the changes to config and then compiled it.”

Looks like this is where Nvidia wants camera files to be now, but got the same results…

Them Imx219 isn’t important at the moment, what i need is the j20 to do it’s probing, witch is very simple in the dtsi and also in the j20.c, don’t understand why the driver doesn’t get picked up, i can see the J20 on the i2c bus as 2-0020 like it should be…

I can still like on the TX2 turn on the J20 manually with:

sudo i2cset -f -y 2 0x20 6 0x3e
sudo i2cset -f -y 2 0x20 7 0x33
sudo i2cset -f -y 2 0x20 2 0xfe
sudo i2cset -f -y 2 0x20 3 0xff

After this the “gpio” led lights up on the J20.

May I know what you mean by compiling? Did you run “make” (without any options)? Or did you run “make Image modules”?

I wanna know if you ran “make dtbs” during your compilation.

Compiled dtb, compared it to the TX2 dtb and it looks perfectly correct.

Added my j20 and imx219.c to /kernel4.9/drivers/media/i2c, modified kconfig and make file in same dir, added in menuconfig.

Compiles just fine and i can modprobe them, so they are in the kernel, but they do not start their probing :(

There must be changes that are not documented yet (missing poring guide for 4.0, might be to early ?)…

@anish.aney :
cd /usr/src/kernel/kernel-4.9
make prepare
make modules_prepare
make modules_install

this was done on the Xavier, then i copied the new image to /boot.

after that i did a “make all”, it generated / compiled the dtsi’s to the new dtb i included above in this thread, compared the dtb to my old TX2 dtb, and everything seem to be in ok and in the right place :)

But no luck, so today i setup a build chain / tools on my host the “Nvidia way” and did it again, same result…

@Nvidia Moderators,

Is there something like a “Preliminary porting guide” for 4.0 DP ? is so i would really appreciate copy.

Would be very nice with some help from the Nvidia crew :)

Is something change one the i2c side and the use of it on Xavier compared to TX2 ?
Is “Compatible” being used the same way, probing ?

Any new definitions needed in the dtsi that was not on TX2 ?

I have disabled / removed the imx219 (raspberry V2.1), so i can just concentrate on the Auvidea J20 "i2c expander camera board, but there is no way i can get it to probe…

hello Spawn32,

please download the [NVIDIA Tegra Linux Driver Package] and check [Release 31.0.1 Development Guide]
you may refer to [Camera Development]-> [Sensor Driver Programming Guide]-> [Camera Sensor Drivers Porting Guide]

I have followed the [Device Registration] / [Using Main Platform Device Tree File] in the [Sensor Driver Programming Guide] to the point, but the probe() never happens:

This is the dtsi for the “camera expander” included like [Using Main Platform Device Tree File] says:

/ {
i2c@3180000 {
j20_6@20 {
compatible = “nvidia,j20”;
/* I2C device address */
reg = <0x20>;
status = “okay”;
//reset-gpios = <&tegra_main_gpio CAM0_PWDN GPIO_ACTIVE_HIGH>;

And this is the j20.c code, works good on Jetpack3.2 /tx2 :

#include <linux/slab.h>
#include <linux/uaccess.h>
#include <linux/gpio.h>
#include <linux/module.h>

#include <linux/seq_file.h>
#include <linux/of.h>
#include <linux/of_device.h>
#include <linux/of_gpio.h>

#include <linux/i2c-dev.h>
#include <linux/fs.h>

#include <media/camera_common.h>
#include <media/soc_camera.h>
#include <dt-bindings/gpio/tegra-gpio.h>

static struct of_device_id j20_of_match = {
{ .compatible = “nvidia,j20”, },
{ },

MODULE_DEVICE_TABLE(of, j20_of_match);

static int j20_probe(struct i2c_client *client,
const struct i2c_device_id *id)
struct device_node *np = client->dev.of_node;
const struct of_device_id *match;
int gpio;

dev_info(&client->dev, “[J20] Driver: Function: %s.\n”, func);

match = of_match_device(j20_of_match, &client->dev);
if (!match) {
dev_info(&client->dev, “Failed to find matching dt id\n”);
return -1;

gpio = of_get_named_gpio(np, “reset-gpios”, 0);
if (gpio < 0) {
dev_err(&client->dev, “reset gpios not in DT\n”);

gpio_set_value(gpio, 1);

dev_info(&client->dev,"[J20]: Enabling GPIO: %i.\n", gpio);

if (i2c_smbus_write_byte_data(client, 6, 0x3e) < 0)
dev_err(&client->dev, “Failed writing to reg: %d val %d\n”, 6, 0x3e);
if (i2c_smbus_write_byte_data(client, 7, 0x33) < 0)
dev_err(&client->dev, “Failed writing to reg: %d val %d\n”, 7, 0x33);
if (i2c_smbus_write_byte_data(client, 2, 0xfe) < 0)
dev_err(&client->dev, “Failed writing to reg: %d val %d\n”, 2, 0xfe);
if (i2c_smbus_write_byte_data(client, 3, 0xff) < 0)
dev_err(&client->dev, “Failed writing to reg: %d val %d\n”, 3, 0xff);

dev_info(&client->dev,"[J20]: Writing setup configuration .\n");

return 0;

static int
j20_remove(struct i2c_client *client)
return 0;

static const struct i2c_device_id j20_id = {
{ “j20”, 0 },
{ }


static struct i2c_driver j20_i2c_driver = {
.driver = {
.name = “j20”,
.owner = THIS_MODULE,
.of_match_table = of_match_ptr(j20_of_match),
.probe = j20_probe,
.remove = j20_remove,
.id_table = j20_id,


The new dtb is flashed from the host with “sudo ./ -r -k kernel-dtb jetson-xavier mmcblk0p1” , and after a reboot and a dtb decompile i find back the j20 entries in it, so the flash went well…

i can also modprobe j20…

Found the solution in this thread:

Thanks :)