I’m following the “Sensor Driver Programming Guide R32.1” to build a Sensor Driver in my Jetson TX2 with JetPack 4.2 installed. By now, I have an empty driver just to test the flashing procedure, but I’m not able to see anything yet. I’ve done the following:
- Build the .dtsi and locate it in “\hardware\nvidia\platform\t18x\common\kernel-dts\t18x-common-modules\tegra186-camera-test001-a00.dtsi”.
/* TEST001 */
/ {
host1x {
vi@15700000 {
num-channels = <1>;
ports {
#address-cells = <1>;
#size-cells = <0>;
port@0 {
reg = <0>;
TEST_vi_in0: endpoint {
port-index = <0>;
bus-width = <4>;
remote-endpoint = <&TEST_csi_out0>;
};
};
};
};
nvcsi@150c0000 {
num-channels = <1>;
#address-cells = <1>;
#size-cells = <0>;
channel@0 {
reg = <0>;
ports {
#address-cells = <1>;
#size-cells = <0>;
port@0 {
reg = <0>;
TEST_csi_in0: endpoint@0 {
port-index = <0>;
bus-width = <4>;
remote-endpoint = <&TEST_test001_out0>;
};
};
port@1 {
reg = <1>;
TEST_csi_out0: endpoint@1 {
remote-endpoint = <&TEST_vi_in0>;
};
};
};
};
};
};
}
/ {
i2c@3180000 {
test001@70 {
compatible = "nvidia,test001";
reg = <0x70>;
devnode = "video0";
physical_w = "11.26";
physical_h = "5.98";
sensor_model ="test001";
post_crop_frame_drop = "0";
use_decibel_gain = "true";
delayed_gain = "true";
use_sensor_mode_id = "true";
mode0 {
mclk_khz = "40000";
num_lanes = "4";
tegra_sinterface = "serial_a";
phy_mode = "DPHY";
discontinuous_clk = "no";
dpcm_enable = "false";
cil_settletime = "0";
dynamic_pixel_bit_depth = "12";
csi_pixel_bit_depth = "12";
mode_type = "bayer";
pixel_phase = "rggb";
active_w = "1920";
active_h = "1080";
readout_orientation = "0";
line_length = "2200";
inherent_gain = "1";
mclk_multiplier = "2";
pix_clk_hz = "74250000";
gain_factor = "10";
min_gain_val = "0";
max_gain_val = "600";
step_gain_val = "1.2";
default_gain = "0";
min_hdr_ratio = "1";
max_hdr_ratio = "1";
framerate_factor = "1000000";
min_framerate = "1500000";
max_framerate = "338000000";
step_framerate = "1";
default_framerate = "338000000";
exposure_factor = "1000000";
min_exp_time = "15";
max_exp_time = "660000";
step_exp_time = "1";
default_exp_time = "33334";
embedded_metadata_height = "1";
};
ports {
#address-cells = <1>;
#size-cells = <0>;
port@0 {
reg = <0>;
TEST_test001_out0: endpoint {
port-index = <0>;
bus-width = <4>;
remote-endpoint = <&TEST_csi_in0>;
};
};
};
};
};
};
/ {
tegra-camera-platform {
compatible = "nvidia, tegra-camera-platform";
num_csi_lanes = <4>;
max_lane_speed = <1500000>;
min_bits_per_pixel = <10>;
vi_peak_byte_per_pixel = <2>;
vi_bw_margin_pct = <25>;
isp_peak_byte_per_pixel = <5>;
isp_bw_margin_pct = <25>;
modules {
module0 {
badge = "test001_bottom_TEST";
position = "bottom";
orientation = "0";
drivernode0 {
pcl_id = "v4l2_sensor";
devname = "test001 30-0070";
proc-device-tree = "/proc/device-tree/i2c@3180000/test001@70";
};
};
};
};
};
- Build the .c file and locate it in “\kernel\nvidia\drivers\media\i2c\test001.c”
/*
*test001.c - test001 sensor driver
*
* 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.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#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 <linux/debugfs.h>
#include "../platform/tegra/camera/camera_gpio.h"
struct test001 {
struct i2c_client *i2c_client;
struct v4l2_subdev *subdev;
u8 fuse_id[8];
u32 frame_length;
s64 last_wdr_et_val;
struct camera_common_data *s_data;
struct tegracam_device *tc_dev;
};
static const struct regmap_config test001_regmap_config = {
};
static const u32 ctrl_cid_list[] = {
};
static const struct of_device_id test001_of_match[] = {
{
.compatible = "nvidia,test001",
},
{ },
};
MODULE_DEVICE_TABLE(of, test001_of_match);
static const struct v4l2_subdev_internal_ops test001_subdev_internal_ops = {
};
static int test001_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
struct device *dev = &client->dev;
dev_info(dev, "Probing test001 sensor driver\n");
return 0;
}
static int test001_remove(struct i2c_client *client)
{
return 0;
}
static const struct i2c_device_id test001_id[] = {
{ "test001", 0 },
{ }
};
MODULE_DEVICE_TABLE(i2c, test001_id);
static struct i2c_driver test001_i2c_driver = {
.driver = {
.name = "test001",
.owner = THIS_MODULE,
.of_match_table = of_match_ptr(test001_of_match),
},
.probe = test001_probe,
.remove = test001_remove,
.id_table = test001_id,
};
module_i2c_driver(test001_i2c_driver);
MODULE_DESCRIPTION("Media Controller driver for test001");
MODULE_AUTHOR("Euskadi");
MODULE_LICENSE("GPL v2");
- Add to Makefile at “\kernel\nvidia\drivers\media\i2c\Makefile”
obj-$(CONFIG_VIDEO_TEST001) += test001.o
- Add to Kconfig at “\kernel\nvidia\drivers\media\i2c\Kconfig”
config VIDEO_TEST001
tristate "TEST001 camera sensor support"
depends on I2C && VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API
---help---
This is a Video4Linux2 sensor-level driver for the TEST001
camera.
To compile this driver as a module, choose M here: the module
will be called test001.
-
Build the kernel files. First, activate TEST001 at menuconfig and append “-tegra” to CONFIG_LOCALVERSION , then “make ARCH=arm64 O=$TEGRA_KERNEL_OUT Image -j12” and “make ARCH=arm64 O=$TEGRA_KERNEL_OUT dtbs -j12”
-
Replace dtb files to “Linuf_for_tegra/kernel/dtb” directory, and replace /boot/Image of TX2 with the new one. After that, flash dtb:
sudo ./flash.sh -k kernel-dtb jetson-tx2 mmcblk0p1
Anyway, I am only able to see something related to the TEST001 driver in the /proc/config.gz kernel configuration, verifying it is activated (not as module).
When I do “dmesg”, shouldn’t I be seeing “Probing test001 sensor driver” somewhere? (printed at driver probe() function). And also, shouldn’t “test001@70” appear in the /proc/device-tree/i2c@3180000/ directory?