TC358743 module with Nano 2GB - no /dev/video

Hi,
I’ve been trying to get this HDMI-to-CSI module that uses the tc358743 chip running for three weeks now and I’m still not able to see video0 in /dev

Here’s my output from media-ctl

bsg1@nano2gb:~$ media-ctl -p -d /dev/media0
Media controller API version 0.1.0

Media device information
------------------------
driver          vi
model           NVIDIA Tegra Video Input Device
serial          
bus info        
hw revision     0x3
driver version  0.0.0

Device topology
- entity 1: nvcsi--1 (2 pads, 0 link)
        type V4L2 subdev subtype Unknown flags 0
	pad0: Sink
	pad1: Source 

Here’s a list of my process and if someone has time to review and let me know where I may have gone wrong that would be greatly appreciated.

I’ve been building a kernel natively on my jetson nano 2gb device using this L4T Jetson Nano + TX1 R32.4.3 Sources as the source.

cd ~/Linux_for_Tegra/source/public/kernel/kernel-4.9

  • make O=~/new-kernel LOCALVERSION=-tegra tegra_defconfig
  • make O=~/new-kernel LOCALVERSION=-tegra menuconfig
-> Device Drivers
  -> Multimedia support (MEDIA_SUPPORT [=Y])
		-> I2C Encoders, decoders, sensors and other helper chips  --->
       <*> Toshiba TC358743 decoder

Save file as .config

From
https://gist.github.com/nyacg/becd94a029355825a05f633f38a25b46
- tc358743.c~/Linux_for_Tegra/source/public/kernel/kernel-4.9/drivers/media/i2c/tc358743.c
- tc358743_regs.h~/Linux_for_Tegra/source/public/kernel/kernel-4.9/drivers/media/i2c/tc358743_regs.h
- tc358743.h~/Linux_for_Tegra/source/public/kernel/kernel-4.9/include/media/i2c/tc358743.h

  • cd ~/Linux_for_Tegra/source/public/hardware/nvidia/platform/t210/porg/kernel-dts/
  • nano tegra210-porg-p3448-common.dtsi
  • Comment out lines:
#include "porg-platforms/tegra210-porg-camera-rbpcv2-imx219.dtsi"
#include "porg-platforms/tegra210-porg-camera-rbpcv2-dual-imx219.dtsi"
#include "porg-plugin-manager/tegra210-porg-plugin-manager.dtsi"
  • cd ~/Linux_for_Tegra/source/public/hardware/nvidia/platform/t210/batuu/kernel-dts
  • wget https://gist.githubusercontent.com/nyacg/becd94a029355825a05f633f38a25b46/raw/74d4bebf7ab3fa7b98fb1007cf8d2936e45db553/tegra210-tc358743.dtsi
  • nano tegra210-p3448-0003-p3542-0000.dts
  • Add line:
#include "tegra210-tc358743.dtsi"
  • make O=~/new-kernel/ LOCALVERSION=-tegra -j4 --output-sync=target
  • sudo cp ~/new-kernel/arch/arm64/boot/Image /boot
  • sudo cp ~/new-kernel/arch/arm64/boot/dts/* /boot/dtb
  • cd ~/Linux_for_Tegra/source/public/kernel/kernel-4.9
  • sudo make O=~/new-kernel LOCALVERSION=-tegra modules_install
  • sudo reboot

Does this process look correct?

Does this device tree for the jetson nano 2gb look correct?

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

/ {
host1x {

    vi_base: vi {
        num-channels = <1>;  // Change 4->2
        ports {
            #address-cells = <1>;
            #size-cells = <0>;

            vi_port1: port@0 {
                status = "okay";
                reg = <0>;
                tc358743_vi_in1: endpoint {
                    status = "okay";
                    port-index = <0>;  /* CSI-B */
                    bus-width = <2>; /* Use CSI-B only */
                    remote-endpoint = <&tc358743_csi_out0>;
                };
            };
        };
    };


    csi_base: nvcsi {
        num-channels = <1>;
        #address-cells = <1>;
        #size-cells = <0>;

        channel@0 {
            reg = <0>;
            ports {
                #address-cells = <1>;
                #size-cells = <0>;
                port@0 {
                    status = "okay";
                    reg = <0>;
                    tc358743_csi_in0: endpoint@0 {
                        status = "okay";
                        port-index = <0>;
                        bus-width = <2>;
                        remote-endpoint = <&tc358743_out1>;
                    };
                };
                port@1 {
                    reg = <1>;
                    status = "okay";
        #address-cells = <1>;
        #size-cells = <0>;
        tc358743@0f {
            status = "okay";
                    tc358743_csi_out0: endpoint@1 {
                        status = "okay";
                        remote-endpoint = <&tc358743_vi_in1>;
                    };
                };
            };
        };
    };

    i2c@546c0000 {  /* I2C_PM, "adapter" 6 */
        status = "okay";
        #address-cells = <1>;
        #size-cells = <0>;
        tc358743@0f {
            status = "okay";
            compatible = "tc358743";
            reg = <0x0f>; /* shifted by 2 */
            mclk = "cam_mclk1";
            reset-gpios = <&gpio 149 0>;
            refclk_hz = <27000000>;  // refclk_hz -> regclk

                interrupt-parent = <&gpio>;
                interrupts = <TEGRA_GPIO(E, 6) GPIO_ACTIVE_HIGH>;

            /* Physical dimensions of sensor */
            physical_w = "4.713";
            physical_h = "3.494";
            /* Sensor Model */
            sensor_model ="tc358743";



            ddc5v_delay = <2>;
            enable_hdcp = "false";
            lineinitcnt = <0xe80>;
            lptxtimecnt = <0x003>;
            tclk_headercnt = <0x1403>;
            tclk_trailcnt = <0x00>;
            ths_headercnt = <0x0103>;
            twakeup = <0x4882>;
            tclk_postcnt = <0x008>;
            ths_trailcnt = <0x02>;
            hstxvregcnt = <0>;

            ports {
                #address-cells = <1>;
                #size-cells = <0>;

                port@0 {
                    reg = <0>;
                    tc358743_out1: endpoint {
                        port-index = <0>; /* CSI A */
                        bus-width = <2>;
                        data-lanes = <1 2>;
                        clock-lanes = <0>;
                        clock-noncontinuous;
                        link-frequencies = /bits/ 64 <297000000>;
                        remote-endpoint = <&tc358743_csi_in0>;
                    };
                };
            };
        };
    };
};

tegra-camera-platform {
    status = "okay";
        compatible = "nvidia, tegra-camera-platform";
        num_csi_lanes = <2>;  // Changed 2 -> 4
        max_lane_speed = <1500000>;
        min_bits_per_pixel = <16>;
        vi_peak_byte_per_pixel = <2>;
        vi_bw_margin_pct = <25>;
        max_pixel_rate = <750000>;
        isp_peak_byte_per_pixel = <5>;
        isp_bw_margin_pct = <25>;

        /**
        * The general guideline for naming badge_info contains 3 parts, and is as follows,
        * The first part is the camera_board_id for the module; if the module is in a FFD
        * platform, then use the platform name for this part.
        * The second part contains the position of the module, ex. “rear” or “front”.
        * The third part contains the last 6 characters of a part number which is found
        * in the module's specsheet from the vender.
        */
        modules {

            module1 {
                status = "okay";
                badge = "tc358743_top_i2c6_b";
                position = "front";
                orientation = "1";
                drivernode0 {
                drivernode0 {
                    status = "okay";
                    /* Declare PCL support driver (classically known as guid)  */
                    pcl_id = "v4l2_sensor";
                    /* Driver's v4l2 device name */
                    devname = "tc358743 6-000f";
                    /* Declare the device-tree hierarchy to driver instance */
                    proc-device-tree = "/proc/device-tree/host1x/i2c@546c0000/tc358743@0f";
                };
            };

        };
};
};

Any suggestions for debugging?

Thanks in advance for the help!
Jamie

Another thing I tried was separating it from the Image kernel and adding it as a module later. I think I was successful but it doesn’t look like it’s used by anything.

bsg1@nano2gb:~$ lsmod
Module                  Size  Used by
bnep                   19078  2
fuse                  116235  3
zram                   29761  4
rtl8821cu            3124466  0
cfg80211              707576  1 rtl8821cu
overlay                53390  0
userspace_alert         6606  0
nvgpu                1724919  18
spidev                 14635  0
bluedroid_pm           16123  0
tc358743               45954  0
ip_tables              21421  0
x_tables               38080  1 ip_tables

How do I get the module to be used?

And one more thing - I’m seeing a discrepancy between i2c addresses. In the .dtsi file it says i2c@546c0000 but when I list i2cdetect -l I see:

|i2c-3|i2c       |7000c700.i2c                    |I2C adapter|
|---|---|---|---|
|i2c-1|i2c       |7000c400.i2c                    |I2C adapter|
|i2c-6|i2c       |Tegra I2C adapter               |I2C adapter|
|i2c-4|i2c       |7000d000.i2c                    |I2C adapter|
|i2c-2|i2c       |7000c500.i2c                    |I2C adapter|
|i2c-0|i2c       |7000c000.i2c                    |I2C adapter|
|i2c-5|i2c       |7000d100.i2c                    |I2C adapter|

should I be using one of these i2c addresses?

i2c@546c0000 is the i2c-6,
Have a check if any probe message from the tc35xx driver to confirm if the Image include this driver.

Thanks for your response.

I decided to build the tc35xx as an external module. Could this be an issue?

Also I used an oscilloscope to verify if I was getting any i2c signals at the module and I get clock and data when I run i2cdetect -y -r 6

here’s the output:
0 1 2 3 4 5 6 7 8 9 a b c d e f
00: – -- – -- – -- – -- – -- – -- 0f
10: – -- – -- – -- – -- – -- – -- – -- – --
20: – -- – -- – -- – -- – -- – -- – -- – --
30: – -- – -- – -- – -- – -- – -- – -- – --
40: – -- – -- – -- – -- – -- – -- – -- – --
50: – -- – -- – -- – -- – -- – -- – -- – --
60: – -- – -- – -- – -- – -- – -- – -- – --
70: – -- – -- – -- – --

Is this what I should expect?

Also how do I probe the tc35xx driver?

Looks like the i2c can detect the device on the bus.(0f should be the device slave address)
Check the probe() function if any output message if not add some message and check the kernel message to confirm it.

Thanks for the response. I’m new to this so I don’t understand exactly what you mean by probe() function but I think I’ve narrowed it down adding a printk statement in the tc358743.c code? Can you send me a link on how to use the probe() function?

Thank you

The probe() is the function in the tc35743.c, you need to check it and maybe add some message to debug it.

thanks. I inserted a printk in the function below. Does this look correct?

static int tc358743_probe(struct i2c_client *client,
                      const struct i2c_device_id *id)
{
    static struct v4l2_dv_timings default_timing =
    // V4L2_DV_BT_CEA_1920X1080P60;
    V4L2_DV_BT_CEA_1920X1080P60;
struct v4l2_subdev_edid sd_edid = {
            .blocks = 2,
            .edid = edid,
    };
    struct tc358743_state *state;
    struct tc358743_platform_data *pdata = client->dev.platform_data;
    struct v4l2_subdev *sd;
    int err;
    u16 chip_id_val;


    printk("=============================== hello init tc358743_probe================================\n");

    if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA))
            return -EIO;
    v4l_dbg(1, debug, client, "chip found @0x%x (%s)\n",
            client->addr, client->adapter->name);

    state = devm_kzalloc(&client->dev, sizeof(struct tc358743_state),
                    GFP_KERNEL);
    if (!state)
            return -ENOMEM;
if (client->dev.of_node) {
    if (!tc358743_parse_dt(&state->pdata, client)) {
        pr_err("Couldn't parse device tree\n");
        return -ENODEV;
    }
}

    state->i2c_client = client;

When I sudo insmod ~/build/drivers/media/i2c/tc358743.ko I don’t see any messages in dmesg or tail -f /var/log/syslog. How and where should I be seeing this printk message?

Thanks in advance!

Usually I use pr_info() for printing kernel message.

I solved the issue with help from linuxdev

Solution

The newly compiled DTB that I placed in the /boot directory was never loading during system boot. To load a DTB file located in /boot, it needs to be indicated in the extlinux.conf file or by default the system will read the device tree that exists in the partition memory.

To load a DTB from system boot up, edit the file extlinux.conf

  • sudo nano /boot/extlinux/extlinux.conf and add FDT line indicated below
LABEL primary
      MENU LABEL primary kernel
      LINUX /boot/Image
      FDT /boot/tegra210-p3448-0003-p3542-0000.dtb
      INITRD /boot/initrd
      APPEND ${cbootargs} quiet root=/dev/mmcblk0p1 rw rootwait rootfstype=ext4 console=ttyS0,115200n8 console=tty0 fbcon=map:0 net.ifnames=0
1 Like