Ov5647 is not getting detected and driver is not loading in Jetson Nano

Hello,
I’m trying to interface ov5647 mipi sensor with Jetson Nano, so I followed some procedure,
first I took dts reference of imx219, and what I did is replaced imx219 with ov5647 using find and replace, and reg value 10 with 36.

   these are the locations of where added new file and changed some files
       1. Linux_for_Tegra/source/public/kernel_src/hardware/nvidia/platform/t210/porg/kernel-dts/tegra210-p3448-all-p3449-0000-camera-ov5647-dual.dts

      2. Linux_for_Tegra/source/public/kernel_src/hardware/nvidia/platform/t210/porg/kernel-dts/porg-platforms/tegra210-porg-camera-rbpcv2-dual-ov5647.dtsi

     3. Linux_for_Tegra/source/public/kernel_src/hardware/nvidia/platform/t210/porg/kernel-dts/porg-platforms/tegra210-camera-rbpcv2-dual-ov5647.dtsi

    4. Linux_for_Tegra/source/public/kernel_src/hardware/nvidia/platform/t210/porg/kernel-dts/porg-platforms/tegra210-camera-rbpcv2-ov5647.dtsi

   5. Linux_for_Tegra/source/public/kernel_src/hardware/nvidia/platform/t210/porg/kernel-dts/porg-platforms/tegra210-porg-camera-rbpcv2-ov5647.dtsi

  6. Linux_for_Tegra/source/public/kernel_src/kernel/nvidia/drivers/media/i2c/ov5647.c

and I created ov5647.c file, which does not have any complicated functions, it has only 2 functions probe and remove,

static const struct of_device_id ov5647_of_match[] = {
	{ .compatible = "nvidia,ov5647", },
	{ },
};
MODULE_DEVICE_TABLE(of, ov5647_of_match);
static int ov5647_probe(struct i2c_client *client,
	const struct i2c_device_id *id)
{

        printk("ov5647 Driver Loaded\n");

	return 0;
}

static int ov5647_remove(struct i2c_client *client)
{

        printk("ov5647 Driver UnLoaded\n");


	return 0;
}

static const struct i2c_device_id ov5647_id[] = {
	{ "ov5647", 0 },
	{ }
};
MODULE_DEVICE_TABLE(i2c, ov5647_id);

static struct i2c_driver ov5647_i2c_driver = {
	.driver = {
		.name = "ov5647",
		.owner = THIS_MODULE,
		.of_match_table = of_match_ptr(ov5647_of_match),
	},
	.probe = ov5647_probe,
	.remove = ov5647_remove,
	.id_table = ov5647_id,
};
module_i2c_driver(ov5647_i2c_driver);

MODULE_DESCRIPTION("Media Controller driver for Sony IMX219");
MODULE_AUTHOR("NVIDIA Corporation");
MODULE_LICENSE("GPL v2");

Linux_for_Tegra.zip (16.8 KB)
the above zip contains files which I added and changed for ov5647
and BSP package I’m using is R32.7.2

can any one tell me, what mistakes I had done?

Have a check below document to add the device tree.

https://docs.nvidia.com/jetson/archives/r35.1/DeveloperGuide/text/SD/CameraDevelopment/SensorSoftwareDriverProgramming.html#using-the-main-platform-device-tree-file

@ShaneCCC as suggested in Sensor Software Driver Programming — Jetson Linux<br/>Developer Guide 34.1 documentation I added

OVERLAY_DTB_FILE="${OVERLAY_DTB_FILE},tegra210-p3448-common-ov5647.dtbo”;

to jetson-nano-qspi-sd.conf

but still I’m unable to detect ov5647

I would suggest using the “using the main platform device tree file” the dtbo need run the jetson-io to enable it not just compile the file only.

@ShaneCCC
are you saying to follow this

./hardware/nvidia/platform/t210/jetson/kernel-dts/jetson-platforms/tegra210-camera-imx185-a00.dtsi

I think I’m not in a perfect direction now, isnt the dts files present in zip file, which I had shared is not correct? did you checked it?

I mean follow below document to add your device tree instead implement dtbo file

https://docs.nvidia.com/jetson/archives/r35.1/DeveloperGuide/text/SD/CameraDevelopment/SensorSoftwareDriverProgramming.html#using-the-main-platform-device-tree-file

@ShaneCCC ,
I checked which dts file is being used in Jetson Nano with,
dmesg | grep dts
and I found that tegra210-p3448-0000-p3449-0000-a02.dts is being used, but the document you have refred uses tegra194-p2888-0001-p2822-0000.dtsi, which does not even present in BSP package,
inside tegra210-p3448-0000-p3449-0000-a02.dts I tried to check whether plugin manager dtsi file present or not, I didn’t see any dtsi being included there realated to plugin manger

but in package I found that this
./hardware/nvidia/platform/t210/jetson/kernel-dts/tegra210-jetson-cv-base-p2597-2180-a00.dts

file uses tegra210-jetson-cv-camera-plugin-manager.dtsi

but I’m not sure whether this dts file is being utilized by jetson nano or not.

The document is using Xavier as sample. For Nano you can remove the imx219 and imx477 and add ov5647 only to enable it.

@ShaneCCC

Thanks for suggestion,

I followed what you said,

  1. Remove imx219 and imx477 dtsi which are included in

./hardware/nvidia/platform/t210/porg/kernel-dts/tegra210-p3448-0000-p3449-0000-a02.dts
Initlally :

#include "tegra210-porg-p3448-common.dtsi"
#include "porg-platforms/tegra210-porg-camera-rbpcv3-imx477.dtsi"
#include "porg-platforms/tegra210-porg-camera-rbpcv2-imx219.dtsi"
#include "porg-platforms/tegra210-porg-pinmux-p3448-0000-a02.dtsi"
#include "porg-platforms/tegra210-porg-gpio-p3448-0000-a02.dtsi"
#include "porg-platforms/tegra210-porg-p3448-emc-a00.dtsi"

After changing: commented imx477 and imx219 lines and added ov5647 line

#include "tegra210-porg-p3448-common.dtsi"
#include "porg-platforms/tegra210-porg-camera-rbpcv2-ov5647.dtsi"
#include "porg-platforms/tegra210-porg-pinmux-p3448-0000-a02.dtsi"
#include "porg-platforms/tegra210-porg-gpio-p3448-0000-a02.dtsi"
#include "porg-platforms/tegra210-porg-p3448-emc-a00.dtsi"
  1. Took below 2 files

    1. tegra210-porg-camera-rbpcv2-imx219.dtsi
    2. tegra210-camera-rbpcv2-imx219.dtsi
      and copied as
    3. tegra210-porg-camera-rbpcv2-ov5647.dtsi
    4. tegra210-camera-rbpcv2-ov5647.dtsi
      and inside these copied files imx219 is replaced with ov5647 and reg address 10 replaced with 36
  2. Took
    1. tegra210-p3448-all-p3449-0000-camera-imx219-dual.dts
    2. tegra210-p3448-common-imx219.dts
    and
    copied as

    1. tegra210-p3448-all-p3449-0000-camera-ov5647-dual.dts
    2. tegra210-p3448-common-ov5647.dts

    again I changed imx219 to ov5647 and reg address 10 to 36

  3. and in Makefile
    hardware/nvidia/platform/t210/porg/kernel-dts/Makefile
    Initially it was:

dtbo-$(CONFIG_ARCH_TEGRA_210_SOC) += tegra210-p3448-common-imx477.dtbo
dtbo-$(CONFIG_ARCH_TEGRA_210_SOC) += tegra210-p3448-common-imx219.dtbo
dtbo-$(CONFIG_ARCH_TEGRA_210_SOC) += tegra210-p3448-all-p3449-0000-camera-imx219-dual.dtbo
dtbo-$(CONFIG_ARCH_TEGRA_210_SOC) += tegra210-p3448-all-p3449-0000-camera-imx477-dual.dtbo
dtbo-$(CONFIG_ARCH_TEGRA_210_SOC) += tegra210-p3448-all-p3449-0000-camera-imx477-imx219.dtbo

after that I commented all these, and added lines for ov5647

#dtbo-$(CONFIG_ARCH_TEGRA_210_SOC) += tegra210-p3448-common-imx477.dtbo
#dtbo-$(CONFIG_ARCH_TEGRA_210_SOC) += tegra210-p3448-common-imx219.dtbo
#dtbo-$(CONFIG_ARCH_TEGRA_210_SOC) += tegra210-p3448-all-p3449-0000-camera-imx219-dual.dtbo
#dtbo-$(CONFIG_ARCH_TEGRA_210_SOC) += tegra210-p3448-all-p3449-0000-camera-imx477-dual.dtbo
#dtbo-$(CONFIG_ARCH_TEGRA_210_SOC) += tegra210-p3448-all-p3449-0000-camera-imx477-imx219.dtbo
dtbo-$(CONFIG_ARCH_TEGRA_210_SOC) += tegra210-p3448-common-ov5647.dtbo
dtbo-$(CONFIG_ARCH_TEGRA_210_SOC) += tegra210-p3448-all-p3449-0000-camera-ov5647-dual.dtbo

and this my ov5647.c driver

ov5647.c

#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 <media/tegra_v4l2_camera.h>
#include <media/tegracam_core.h>

#include "../platform/tegra/camera/camera_gpio.h"
static const struct of_device_id ov5647_of_match[] = {
	{ .compatible = "nvidia,ov5647", },
	{ },
};
MODULE_DEVICE_TABLE(of, ov5647_of_match);


static int ov5647_probe(struct i2c_client *client,
	const struct i2c_device_id *id)
{
        printk("ov5647 driver loaded\n");

	return 0;
}

static int ov5647_remove(struct i2c_client *client)
{
        printk("ov5647 driver unloaded\n");
	return 0;
}

static const struct i2c_device_id ov5647_id[] = {
	{ "ov5647", 0 },
	{ }
};
MODULE_DEVICE_TABLE(i2c, ov5647_id);

static struct i2c_driver ov5647_i2c_driver = {
	.driver = {
		.name = "ov5647",
		.owner = THIS_MODULE,
		.of_match_table = of_match_ptr(ov5647_of_match),
	},
	.probe = ov5647_probe,
	.remove = ov5647_remove,
	.id_table = ov5647_id,
};
module_i2c_driver(ov5647_i2c_driver);

MODULE_DESCRIPTION("Media Controller driver for  OV5647");
MODULE_AUTHOR("NVIDIA Corporation");
MODULE_LICENSE("GPL v2");

after these modifications
I tried to load this compiled module
$sudo insmod ov5647.ko
it loaded successfully, but it did not bound with ov5647

Does ov5647 call the tegracam_device_register() and tegracam_v4l2subdev_register()?

@ShaneCCC
So I thinking did not described perfectly.

present I’m using ov5647.ko as dynamic module, and
when I load the module
$ sudo insmod ov5647.ko
or
$ sudo modprobe ov5647
it is loading successfully

when I list of drivers loaded
$ lsmod | grep ov5647
I found out that ov5647 driver is just loaded, this driver is not even used by anything, this means my driver is unable to find the device in dts tree,

So the probelm I need to Solve is with dts files only.

Hey @ShaneCCC,
I took fresh BSP, and did some modifications, look at this driver now, modified imx219, I just opened imx219.c driver file and I chaged

 IMX219_MODEL_ID_ADDR_MSB, IMX219_MODEL_ID_ADDR_LSB values

in imx219_board_setup function I printed some debug messages,

   printk("ov5647 reg1 %X",reg_val[1]);
   printk("ov5647 reg1 %X",regt is_val[1]);

and in imx219_probe I added client->addr=0x36; so when ever driver loads and send write signals or read signal it will to my ov5647.

Now I compiled and loaded, the result is positive in dmesg

    dmesg | grep ov5647
  [1.277352] ov5647 reg0 56
  [1.277358] ov5647 reg1 47

which indicates I successfully read ov5647 chip ID

Note I only did modifications in imx219.c driver file, I did not changed any dts files

#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 <media/tegra_v4l2_camera.h>
#include <media/tegracam_core.h>
#include <media/imx219.h>

#include "../platform/tegra/camera/camera_gpio.h"
#include "imx219_mode_tbls.h"

/* imx219 - sensor parameter limits */
#define IMX219_MIN_GAIN				0x0000
#define IMX219_MAX_GAIN				0x00e8
#define IMX219_MIN_FRAME_LENGTH			0x0100
#define IMX219_MAX_FRAME_LENGTH			0xffff
#define IMX219_MIN_COARSE_EXPOSURE		0x0001
#define IMX219_MAX_COARSE_DIFF			0x0004

/* imx219 sensor register address */
//#define IMX219_MODEL_ID_ADDR_MSB		0x0000
//#define IMX219_MODEL_ID_ADDR_LSB		0x0001
#define IMX219_MODEL_ID_ADDR_MSB		0x300a
#define IMX219_MODEL_ID_ADDR_LSB		0x300b
     
.
.
.
.
.
.
static int imx219_board_setup(struct imx219 *priv)
{
.
.
.
.

	/* Probe sensor model id registers */
	err = imx219_read_reg(s_data, IMX219_MODEL_ID_ADDR_MSB, &reg_val[0]);
        printk("ov5647 reg0 %X",reg_val[0]);
	if (err) {
		dev_err(dev, "%s: error during i2c read probe (%d)\n",
			__func__, err);
		goto err_reg_probe;
	}
	err = imx219_read_reg(s_data, IMX219_MODEL_ID_ADDR_LSB, &reg_val[1]);
        printk("ov5647 reg1 %X",reg_val[1]);
	if (err) {
		dev_err(dev, "%s: error during i2c read probe (%d)\n",
			__func__, err);
		goto err_reg_probe;
	}
	if (!((reg_val[0] == 0x02) && reg_val[1] == 0x19))
		dev_err(dev, "%s: invalid sensor model id: %x%x\n",
			__func__, reg_val[0], reg_val[1]);

	/* Sensor fine integration time */
.
.
.
.


done:
	return err;
}

.
.
.
.
.
static int imx219_probe(struct i2c_client *client,
	const struct i2c_device_id *id)
{
.
.
.
.
.
.
.
	struct device *dev = &client->dev;
	struct tegracam_device *tc_dev;
	struct imx219 *priv;
	int err;

        client->addr=0x36;

.
.
.
.
.
.
.
.
.
.

	return 0;
}

now driver side I can have control, but the problem is still I did not get familiar with handling dts files,

I just need help on creating custom dts files for new MIPI sensors(ov5647)

You can create your dts depend on imx219

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.