This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

SK-AM68: Adding a new camera sensor

Part Number: SK-AM68
Other Parts Discussed in Thread: AM68

We're assessing the AM68 for creating a smart camera and so would be using sensors other than the two currently supported by the SK-AM68.

We're new to low level kernel work, hardware integration and device trees so there's a somewhat steep learning curve.

I've been supplied with v3 of the rpi camera module (IMX708) and so have been attempting to enable it for the devkit:

  1. Copied across the imx708 i2c source from the raspberrypi project to the ti sdk kernel source tree (drivers/media/i2c/imx708.c)
  2. Updated the i2c Kconfig with a section for the imx708 (drivers/media/i2c/Kconfig)
  3. Added the module to the Makefile (drivers/media/i2c/Makefile)
  4. Added an empty file at include/config/VIDEO_IMX708
  5. Added `CONFIG_VIDEO_IMX708=m` to arch/arm64/configs/defconfig
  6. Added `CONFIG_VIDEO_IMX708=m` to arch/arm/configs/sama7_defconfig
  7. Created a `k3-am68-sk-bb-rpi-cam-imx708.dtso` at arch/arm64/boot/dts/ti/ based on the supplied one for the imx219 (attached below)

I then built the kernel and deployed to the SD card, then modified the uEnv.txt on the boot partition with

name_overlays=ti/k3-j721s2-edgeai-apps.dtbo ti/k3-am68-sk-bb-rpi-cam-imx708.dtbo

So the devkit now looks like it can see the camera


root@am68a-sk:/opt/edgeai-gst-apps# media-ctl -d /dev/media0 -p
...
- entity 17: imx708 (2 pads, 1 link, 0 route)
type V4L2 subdev subtype Sensor flags 0
device node name /dev/v4l-subdev2
pad0: Source
[stream:0 fmt:SRGGB10_1X10/4608x2592 field:none colorspace:raw xfer:none ycbcr:601 quantization:full-range
crop.bounds:(16,24)/4608x2592
crop:(16,24)/4608x2592]
-> "cdns_csi2rx.4504000.csi-bridge":0 [ENABLED,IMMUTABLE]
pad1: Source
[stream:0 fmt:unknown/28800x1 field:none
crop.bounds:(16,24)/4608x2592
crop:(16,24)/4608x2592]
...

root@am68a-sk:/opt/edgeai-gst-apps# v4l2-ctl -d /dev/v4l-subdev2 --list-subdev-mbus-codes
ioctl: VIDIOC_SUBDEV_ENUM_MBUS_CODE (pad=0,stream=0)
0x300f: MEDIA_BUS_FMT_SRGGB10_1X10

root@am68a-sk:/opt/edgeai-gst-apps# v4l2-ctl -d /dev/v4l-subdev2 --list-subdev-framesizes pad=0,code=0x300f
ioctl: VIDIOC_SUBDEV_ENUM_FRAME_SIZE (pad=0,stream=0)
Size Range: 4608x2592 - 4608x2592
Size Range: 2304x1296 - 2304x1296
Size Range: 1536x864 - 1536x864

However all of the format information originates from the imx708 i2c kernel module and is not read from the sensor itself - during boot there is a kernel log message which suggests that the i2c is not working.


[ 5.477570] imx708 5-001a: failed to read chip id 708, with error -5


I assume this is due to a problem with my dtso file?
There are also some errors relating to the supply voltages from the kernel module


[ 5.332492] imx708 4-0010: supply vana1 not found, using dummy regulator
[ 5.421415] imx708 4-0010: supply vana2 not found, using dummy regulator
[ 5.445335] imx708 4-0010: supply vdig not found, using dummy regulator
[ 5.485090] imx708 4-0010: supply vddl not found, using dummy regulator

When I attempt to start streaming from the device the kernel logs show

[ 3980.377812] cdns-csi2rx 4504000.csi-bridge: Failed to start streams 0x1 on subdev
[ 3980.395394] cdns-csi2rx 4504000.csi-bridge: Failed to stop stream0
[ 3980.411592] cdns-csi2rx 4504000.csi-bridge: Failed to stop stream1
[ 3980.427812] cdns-csi2rx 4504000.csi-bridge: Failed to stop stream2
[ 3980.443997] cdns-csi2rx 4504000.csi-bridge: Failed to stop stream3

Any suggestions or links to relevant documentation would be much appreciated.

  • It seems I can't attach a DTSO file to the post, so here it is in full

    // SPDX-License-Identifier: GPL-2.0
    /**
     * DT Overlay for RPi Camera V3 (Sony IMX708) interfaced with CSI2 on AM68-SK board - copied and adjusted from the IMX219 version by Dan
     * datasheets.raspberrypi.com/.../camera-module-3-schematics.pdf
     */
    
    /dts-v1/;
    /plugin/;
    
    #include <dt-bindings/gpio/gpio.h>
    #include "k3-pinctrl.h"
    
    &{/} {
      clk_imx708_fixed: imx708-inclk {
        status = "okay";
        compatible = "fixed-clock";
        #clock-cells = <0>;
        clock-frequency = <24000000>;
      };
    };
    
    &exp3 {
      p01-hog {
        /* CSI_MUX_SEL_2 */
        gpio-hog;
        gpios = ;
        output-high;
        line-name = "CSI_MUX_SEL_2";
      };
    };
    
    
    &main_i2c1 {
      status = "okay";
      #address-cells = ;
      #size-cells = ;
    
      i2c-switch@70 {
        compatible = "nxp,pca9543";
        #address-cells = ;
        #size-cells = ;
        reg = ;
    
        i2c-alias-pool = /bits/ 16 ;
    
        /* CAM0 I2C */
        cam0_i2c: i2c@0 {
          #address-cells = ;
          #size-cells = ;
          reg = ;
    
          imx708_0: imx708_0@1a {
            compatible = "sony,imx708";
            reg = ;
            status = "disabled";
    
            clocks = <&clk_imx708_fixed>;
            clock-names = "inclk";
    
            rotation = ;
            orientation = ;
    
            reset-gpios = <&exp3 3 GPIO_ACTIVE_HIGH>;
    
            port {
              csi2_cam0: endpoint {
                remote-endpoint = <&csi2rx0_in_sensor>;
                link-frequencies = /bits/ 64 ;
                clock-lanes = ;
                data-lanes = ;
              };
            };
          };
        };
    
        /* CAM1 I2C */
        cam1_i2c: i2c@1 {
          #address-cells = ;
          #size-cells = ;
          reg = ;
    
          imx708_1: imx708_1@1a {
            compatible = "sony,imx708";
            reg = ;
    
            clocks = <&clk_imx708_fixed>;
            clock-names = "inclk";
    
            rotation = ;
            orientation = ;
    
            reset-gpios = <&exp3 3 GPIO_ACTIVE_HIGH>;
    
            port {
              csi2_cam1: endpoint {
                remote-endpoint = <&csi2rx1_in_sensor>;
                link-frequencies = /bits/ 64 ;
                clock-lanes = ;
                data-lanes = ;
              };
            };
          };
        };
      };
    };
    
    &csi0_port0 {
      status = "okay";
      csi2rx0_in_sensor: endpoint {
        remote-endpoint = <&csi2_cam0>;
        bus-type = ; /* CSI2 DPHY. */
        clock-lanes = ;
        data-lanes = ;
      };
    };
    
    &csi1_port0 {
      status = "okay";
      csi2rx1_in_sensor: endpoint {
        remote-endpoint = <&csi2_cam1>;
        bus-type = ; /* CSI2 DPHY. */
        clock-lanes = ;
        data-lanes = ;
      };
    };
    
    
  • Hi Dan,

    I would suggest following this guide to enable a new CSI-2 sensor. This is for AM62Ax devices but the idea is the same and are working on creating one for SK-AM68.

    Could you share what changes were made to the imx708 dt files from the imx219 files besides swapping the names?

    imx708_0: imx708_0@1a { compatible = "sony,imx708"; reg = ; status = "disabled";

    What is the reason for having this status set to disabled?

    Thank you,

    Fabiana

  • Hi Fabiana,

    Thanks for the reply. The guide you suggested is the exact one I followed since it was the only documentation I could find related to adding a new sensor.

    The changes to the DTSO were as follows:

    1. The clk section at the top was renamed
    2. The compatible string was changed to refer to the imx708 kernel module.
    3. Changed from "reg = <0x10>" to "reg=<0x1a>" in the imx708_0 and imx708_1 nodes (based on the DTSI in the rpi kernel).
    4. Changed the clock-names from "xclk" to "inclk" since that is a difference I found in the i2c kernel modules.
    5. Changed the link frequencies for the CSI endpoints from 456000000 to 450000000 since that is what was in the DTSI for the rpi kernel configuration.

    The `status="disabled"` was left in accidentally from one of my many attempts to modify the file - but it doesn't work with that removed either.

    Kind regards,

    Dan

  • Hi Dan,

    Thank you for sharing! It would also be helpful if you could send the driver as well as include the values that are missing in the dtso file you shared to better understand what you're currently working with.

    Thank you,

    Fabiana

  • Hi Fabiana,

    This is the i2c driver that I incorporated into the AM68 kernel build using the TI sdk: https://github.com/raspberrypi/linux/blob/rpi-6.1.y/drivers/media/i2c/imx708.c

    Apologies, I hadn't noticed that bits of the dtso were missing - it appears that the forum software makes pasting examples with triangular brackets rather difficult. Since it won't let me attach the dtso file either I've zipped it up instead:


    k3-am68-sk-bb-rpi-cam-imx708.dtso.zip

    Kind regards,

    Dan

  • Hi again,

    I think we have the i2c driver working now :). Having looked over the schematics for the rpi cam module and the documentation for the I2C GPIO Expander Table from the AM68-SK documentation we needed to set the voltage to 3.3V by adding

    p00-hog {
      /* I2C voltage - set to 3.3V */
      gpio-hog;
      gpios = <0 GPIO_ACTIVE_HIGH>;
      output-high;
      line-name = "CSI_VIO_SEL";
    };

    to the "&exp3" section in the overlay. And now in dmesg we see that it has successfully read the chip ID

    [    5.207792] imx708 4-001a: camera module ID 0x0301
    The next issue is that we're unable to actually grab images from it
    root@am68a-sk:/opt/edgeai-gst-apps# gst-launch-1.0 v4l2src device=/dev/video-rpi-cam0 ! video/x-bayer, width=4592, height=2568, format=rggb10 ! fakesink
    Setting pipeline to PAUSED ...
    Pipeline is live and does not need PREROLL ...
    Pipeline is PREROLLED ...
    Setting pipeline to PLAYING ...
    New clock: GstSystemClock
    ERROR: from element /GstPipeline:pipeline0/GstV4l2Src:v4l2src0: Failed to allocate required memory.
    Additional debug info:
    ../gst-plugins-good-1.20.6/sys/v4l2/gstv4l2src.c(777): gst_v4l2src_decide_allocation (): /GstPipeline:pipeline0/GstV4l2Src:v4l2src0:
    Buffer pool activation failed
    Execution ended after 0:00:00.146486541
    Setting pipeline to NULL ...
    ERROR: from element /GstPipeline:pipeline0/GstV4l2Src:v4l2src0: Internal data stream error.
    Additional debug info:
    ../gstreamer-1.20.6/libs/gst/base/gstbasesrc.c(3127): gst_base_src_loop (): /GstPipeline:pipeline0/GstV4l2Src:v4l2src0:
    streaming stopped, reason not-negotiated (-4)
    Freeing pipeline ...
    root@am68a-sk:/opt/edgeai-gst-apps# gst-launch-1.0 v4l2src device=/dev/video-rpi-cam0 ! video/x-bayer, width=4592, height=2568, format=rggb10 ! fakesink
    Setting pipeline to PAUSED ...
    Pipeline is live and does not need PREROLL ...
    Pipeline is PREROLLED ...
    Setting pipeline to PLAYING ...
    New clock: GstSystemClock
    ERROR: from element /GstPipeline:pipeline0/GstV4l2Src:v4l2src0: Failed to allocate required memory.
    Additional debug info:
    ../gst-plugins-good-1.20.6/sys/v4l2/gstv4l2src.c(777): gst_v4l2src_decide_allocation (): /GstPipeline:pipeline0/GstV4l2Src:v4l2src0:
    Buffer pool activation failed
    ERROR: from element /GstPipeline:pipeline0/GstV4l2Src:v4l2src0: Internal data stream error.
    Additional debug info:
    ../gstreamer-1.20.6/libs/gst/base/gstbasesrc.c(3127): gst_base_src_loop (): /GstPipeline:pipeline0/GstV4l2Src:v4l2src0:
    streaming stopped, reason not-negotiated (-4)
    Execution ended after 0:00:00.145680461
    Setting pipeline to NULL ...
    Freeing pipeline ...
    And if I try and grab a frame via v4l2-ctl:
    root@am68a-sk:/opt/edgeai-gst-apps# v4l2-ctl --verbose --device /dev/video-rpi-cam0  --set-fmt-video=width=4608,height=2592 --stream-mmap --stream-to=test-frame.raw --stream-count=1
    VIDIOC_QUERYCAP: ok
    VIDIOC_G_FMT: ok
    VIDIOC_S_FMT: ok
    Format Video Capture:
           Width/Height      : 4608/2592
           Pixel Format      : 'RG10' (10-bit Bayer RGRG/GBGB)
           Field             : None
           Bytes per Line    : 9216
           Size Image        : 23887872
           Colorspace        : sRGB
           Transfer Function : sRGB
           YCbCr/HSV Encoding: ITU-R 601
           Quantization      : Limited Range
           Flags             :  
                   VIDIOC_REQBUFS returned 0 (Success)
                   VIDIOC_QUERYBUF returned 0 (Success)
                   VIDIOC_QUERYBUF returned 0 (Success)
                   VIDIOC_QUERYBUF returned 0 (Success)
                   VIDIOC_QUERYBUF returned 0 (Success)
                   VIDIOC_QBUF returned 0 (Success)
                   VIDIOC_QBUF returned 0 (Success)
                   VIDIOC_QBUF returned 0 (Success)
                   VIDIOC_QBUF returned 0 (Success)
                   VIDIOC_STREAMON returned -1 (Operation not supported)
  • Hi Dan,

    I'm glad you have a working driver! If your sensor produces only raw RGB or RGBD images, it will require further ISP processing which can be handled by the Vision Imaging Sub System (VISS) hardware accelerator. This will involve ISP/sensor tuning activity to produce artifacts that can be understood by the VISS hardware. Your pipeline would look more like the IMX219 pipeline:

    gst-launch-1.0 v4l2src device=/dev/video-rpi-cam0 io-mode=5 ! queue leaky=2 ! video/x-bayer, width=1920, height=1080, format=rggb ! tiovxisp sensor-name=SENSOR_SONY_IMX219_RPI dcc-isp-file=/opt/imaging/imx219/linear/dcc_viss.bin format-msb=7 sink_0::dcc-2a-file=/opt/imaging/imx219/linear/dcc_2a.bin sink_0::device=/dev/v4l-rpi-subdev0 ! video/x-raw,format=NV12, width=1920, height=1080 ! queue ! kmssink driver-name=tidss sync=false

    To perform ISP tuning for a raw camera, please read this ISP tuning guide: AM6xA ISP Tuning Guide (ti.com)

    I hope this helps!

    Thank you,

    Fabiana

  • Hi Fabiana,

    Thanks, but as described in my previous message whilst it looks like the i2c is working now, we're unable to actually grab any data from the sensor. There's no point configuring the ISP layers until we can actually get raw data from the chip. When using a fakesink with gstreamer or --stream-to with v4l2-ctl both fail at the v4l2 capture stage and I'm unable to figure out why. 

    The "VIDIOC_STREAMON returned -1 (Operation not supported)" error message reveals very little when searching on google.

    The "ERROR: from element /GstPipeline:pipeline0/GstV4l2Src:v4l2src0: Failed to allocate required memory" produces more search results but nothing that has been able to help me understand the issue so far.

    I see these errors in the kernel log when trying to capture

    [  172.279031] cdns-csi2rx 4504000.csi-bridge: Failed to start streams 0x1 on subdev
    [  172.296577] cdns-csi2rx 4504000.csi-bridge: Failed to stop stream0
    [  172.312779] cdns-csi2rx 4504000.csi-bridge: Failed to stop stream1
    [  172.328998] cdns-csi2rx 4504000.csi-bridge: Failed to stop stream2
    [  172.345184] cdns-csi2rx 4504000.csi-bridge: Failed to stop stream3

    Kind regards,

    Dan

  • Hi Dan,

    I understand. So, was the only change you made between both driver and overlay files you shared just the below chunk of code to the "&exp3" section in the overlay?

    p00-hog {
      /* I2C voltage - set to 3.3V */
      gpio-hog;
      gpios = <0 GPIO_ACTIVE_HIGH>;
      output-high;
      line-name = "CSI_VIO_SEL";
    };

    Please confirm this while I consult with my team on this.

    Thank you,

    Fabiana

  • Hi,

    Yes that was the only change from the file I previously shared. But I've been examining the DTSO, schematics and register tables further and think there are a number of issues. 

    Firstly the imx219 dtso that I based it on appears to use the 40-pin header and not the flex cable connections so I think the "p01-hog" section needs to be disabled since the imx708 is connected via flex.

    Secondly, the imx708 has a definition for regulator supplies in the i2c module:

    static const char * const imx708_supply_name[] = {
      /* Supplies can be enabled in any order */
      "vana1", /* Analog1 (2.8V) supply */
      "vana2", /* Analog2 (1.8V) supply */
      "vdig", /* Digital Core (1.1V) supply */
      "vddl", /* IF (1.8V) supply */
    };

    These are referred to in the DTS and DTSI for the raspberry pi kernel, but I'm unsure how to specify them for the am68-sk. The schematics for the camera suggest that those voltages are supplied on the camera module itself: https://datasheets.raspberrypi.com/camera/camera-module-3-schematics.pdf

    Kind regards,

    Dan

  • Hi Dan,

    I am currently checking with our imaging experts to see if this issue may be due to a sensor resolution limitation. Expect a response from me later this week.

    Thank you,

    Fabiana