Skip to main content

IMX8MM Camera Usage Guide

πŸš€ Introduction

This guide shows you how to get started using TechNexion camera modules on TechNexion IMX8MM development kits. You must have the background knowledge to modify the kernel configuration, rebuild, and replace the kernel and the device tree source (DTS). This article is based on the πŸ”— Yocto 5.2 (Walnascar) 2026Q1 Release with Linux kernel version 6.12.49-2.2.0.


πŸ“Έ Supported Camera Modules

Camera SeriesProducts
TEVS
TEVS-AR0144
TEVS-AR0145
TEVS-AR0234
TEVS-AR0235
TEVS-AR0246
TEVS-AR0521
TEVS-AR0522
TEVS-AR0544
TEVS-AR0821
TEVS-AR0822
TEVS-AR0830
TEVS-AR1335
TEVS-AR2020
Camera Sensor Comparison

🧩 Supported Boards

SoMBoard
EDM-G-IMX8M-MINIWB-EDM-G-IMX8M-MINI
PICO-IMX8M-MINIPICO-PI-IMX8M-MINI
PICO-WIZARD-IMX8M-MINI

πŸ”§ Hardware Setup Instructions

1. Power Supply Preparation

  • Use a DC 5V or 12V power cable to supply power to the board.
  • If you're using FPD-Link III SerDes, a 12V power adapter (minimum 3A) is required. Connect it via the barrel jack connector.

2. Debug Console Connection

  • Prepare a USB-to-UART cable if you're connecting to a PC.
  • Connect it to the CONSOLE1 connector.

3. Display Output Connection

  • Prepare a panel for output display.
  • Connect the panel to the LVDS1 connector on the board.

4. Camera Interface (CSI) Overview

  • The board features one MIPI CSI-2 interface, referred to as CSI1.
  • This uses a 70-pin board-to-board connector manufactured by Hirose.

πŸ’» Prepare Yocto demo image for testing TechNexion camera

To test TechNexion cameras, you will need a Yocto-based demo image that includes the necessary device tree blobs and camera drivers.

πŸ”½ Downloading the Demo Image

We provide a pre-built demo image to simplify using TEVS cameras, available for download on TechNexion's official server.

Download Link:

Select Target Board

πŸ’Ύ Flashing the Image

You can flash the image to either e.MMC or an SD Card using one of the following methods:

Mothod 1. Using uuu Tool (Universal Update Utility)

TechNexion provides a guide to flash the image using the uuu tool:
πŸ”— How to Flash with UUU


Mothod 2. Using ums Command in U-Boot (USB Mass Storage)

Alternatively, you can write the image directly to flash storage over USB-OTG using U-Boot’s ums command:
πŸ”— Using UMS in U-Boot


Mothod 3. For Windows Users

Use balenaEtcher to write the image to your SD card:
πŸ”— Using Balena Etcher


πŸ› οΈ Build Yocto

TechNexion supports building a Yocto-based Linux image tailored for camera modules using the following kernel and branch.

If you are using prebuilt demo image, you can skip this section. Please refer to πŸ“Έ Camera Testing Instructions section for camera testing steps.

πŸ“¦ Supported Linux Kernel

Linux Kernel VersionYocto Branch
6.12.49tn-imx_6.12.49_2.2.0-stable

πŸ“ Source and Build Instructions

πŸ”— Fetch Yocto Source

Select Target Board

πŸ“Έ Camera Testing Instructions

🌳 Specify Camera DTBO in U-Boot

  1. Connect the debug console cable to carrier board.
  2. Power on the board and interrupt the boot process. Keep pressing Enter when the following message appears: Hit any key to stop autoboot:
  3. Specify the appropriate device tree for your camera using the fdtfile environment variable in U-Boot:
u-boot=> setenv dtoverlay tevs

4. Continue boot process.

u-boot=> saveenv
u-boot=> boot

πŸŽ›οΈ Setup the media controller before camera streaming

Starting from kernel 6.12, the CSI driver supports media-ctl for configuring the pipeline on the i.MX8M Mini platform.

To verify that the camera has been properly connected and linked, use the media-ctl command:

$ media-ctl -p

This will display media controller information, such as:

Media controller API version 6.12.20

Media device information
------------------------
driver          imx7-csi
model           imx-media
serial
bus info        platform:32e20000.csi
hw revision     0x0
driver version  6.12.20

Device topology
- entity 1: csi (2 pads, 2 links, 0 routes)
            type V4L2 subdev subtype Unknown flags 0
            device node name /dev/v4l-subdev0
        pad0: SINK
                [stream:0 fmt:UYVY8_2X8/640x480 field:none colorspace:srgb xfer:srgb ycbcr:601 quantization:lim-range]
                <- "csis-32e30000.mipi-csi":1 [ENABLED,IMMUTABLE]
        pad1: SOURCE
                [stream:0 fmt:UYVY8_2X8/640x480 field:none colorspace:srgb xfer:srgb ycbcr:601 quantization:lim-range]
                -> "csi capture":0 [ENABLED,IMMUTABLE]

- entity 4: csi capture (1 pad, 1 link)
            type Node subtype V4L flags 0
            device node name /dev/video2
        pad0: SINK
                <- "csi":1 [ENABLED,IMMUTABLE]

- entity 10: csis-32e30000.mipi-csi (2 pads, 2 links, 0 routes)
             type V4L2 subdev subtype Unknown flags 0
             device node name /dev/v4l-subdev1
        pad0: SINK,MUST_CONNECT
                [stream:0 fmt:UYVY8_1X16/640x480 field:none colorspace:smpte170m xfer:709 ycbcr:601 quantization:lim-range]
                <- "tevs 1-0048":0 [ENABLED]
        pad1: SOURCE,MUST_CONNECT
                [stream:0 fmt:UYVY8_1X16/640x480 field:none colorspace:smpte170m xfer:709 ycbcr:601 quantization:lim-range]
                -> "csi":0 [ENABLED,IMMUTABLE]

- entity 15: tevs 1-0048 (1 pad, 1 link, 0 routes)
             type V4L2 subdev subtype Sensor flags 0
             device node name /dev/v4l-subdev2
        pad0: SOURCE
                [stream:0 fmt:SGRBG12_1X12/2592x1944@1/24 field:none colorspace:raw xfer:none ycbcr:601 quantization:full-range
                 crop.bounds:(0,0)/2592x1944
                 crop:(0,0)/2592x1944]
                -> "csis-32e30000.mipi-csi":0 [ENABLED]

Showing the output as an image can make it easier to understand.

Set the resolution and format of all media entities to match the camera's output. This means all components in the media pipeline must align with the camera's output settings.

Use the v4l2-ctl command to check the camera's supported formats, resolutions, and frame intervals.

# formats
$ v4l2-ctl -d /dev/v4l-subdev2 --list-subdev-mbus-codes
  ioctl: VIDIOC_SUBDEV_ENUM_MBUS_CODE (pad=0,stream=0)
          0x200f: MEDIA_BUS_FMT_UYVY8_1X16
          0x300a: MEDIA_BUS_FMT_SGRBG10_1X10
          0x3011: MEDIA_BUS_FMT_SGRBG12_1X12

# resolutions
$ v4l2-ctl -d /dev/v4l-subdev2 --list-subdev-framesize code=0x200f
  ioctl: VIDIOC_SUBDEV_ENUM_FRAME_SIZE (pad=0,stream=0)
          Size Range: 640x480 - 640x480
          Size Range: 1280x720 - 1280x720
          Size Range: 1280x960 - 1280x960
          Size Range: 1920x1080 - 1920x1080
          Size Range: 2560x1440 - 2560x1440
          Size Range: 2592x1944 - 2592x1944

# frame interval of resolution
$ v4l2-ctl -d /dev/v4l-subdev2 --list-subdev-frameintervals width=640,height=480,code=0x200f
  ioctl: VIDIOC_SUBDEV_ENUM_FRAME_INTERVAL (pad=0,stream=0)
          Interval: 0.008s (120.000 fps)

$ v4l2-ctl -d /dev/v4l-subdev2 --list-subdev-frameintervals width=1280,height=720,code=0x200f
  ioctl: VIDIOC_SUBDEV_ENUM_FRAME_INTERVAL (pad=0,stream=0)
          Interval: 0.017s (60.000 fps)

$ v4l2-ctl -d /dev/v4l-subdev2 --list-subdev-frameintervals width=1280,height=960,code=0x200f
  ioctl: VIDIOC_SUBDEV_ENUM_FRAME_INTERVAL (pad=0,stream=0)
          Interval: 0.017s (60.000 fps)

$ v4l2-ctl -d /dev/v4l-subdev2 --list-subdev-frameintervals width=1920,height=1080,code=0x200f
  ioctl: VIDIOC_SUBDEV_ENUM_FRAME_INTERVAL (pad=0,stream=0)
          Interval: 0.017s (60.000 fps)

$ v4l2-ctl -d /dev/v4l-subdev2 --list-subdev-frameintervals width=2560,height=1440,code=0x200f
  ioctl: VIDIOC_SUBDEV_ENUM_FRAME_INTERVAL (pad=0,stream=0)
          Interval: 0.031s (32.000 fps)

$ v4l2-ctl -d /dev/v4l-subdev2 --list-subdev-frameintervals width=2592,height=1944,code=0x200f
  ioctl: VIDIOC_SUBDEV_ENUM_FRAME_INTERVAL (pad=0,stream=0)
          Interval: 0.042s (24.000 fps)

Set resolution to 1280Γ—720 for example.

$ media-ctl -V "'csi':0 [fmt:UYVY8_1X16/1280x720 field:none colorspace:srgb xfer:srgb ycbcr:601]"
$ media-ctl -V "'tevs 1-0048':0 [fmt:UYVY8_1X16/1280x720 field:none colorspace:srgb xfer:srgb ycbcr:601]"

πŸŽ₯ Start Camera Video Stream via GStreamer

🎬 Launch GStreamer Pipeline

Specify the capture device you just get and start gstreamer to get video stream on screen.
Replace <res_w> and <res_h> with your selected resolution(1280x720) and screen dimensions:

$ gst-launch-1.0 v4l2src device=/dev/video2 ! \
  "video/x-raw, format=UYVY, width=<res_w>, height=<res_h>" ! \
  waylandsink sync=false

βœ… Check Media Controller

We can use media-ctl -p to check the media controller again after setting the resolution and media link as shown below:

Media controller API version 6.12.20

Media device information
------------------------
driver          imx7-csi
model           imx-media
serial
bus info        platform:32e20000.csi
hw revision     0x0
driver version  6.12.20

Device topology
- entity 1: csi (2 pads, 2 links, 0 routes)
            type V4L2 subdev subtype Unknown flags 0
            device node name /dev/v4l-subdev0
        pad0: SINK
                [stream:0 fmt:UYVY8_1X16/1280x720 field:none colorspace:srgb xfer:srgb ycbcr:601 quantization:lim-range]
                <- "csis-32e30000.mipi-csi":1 [ENABLED,IMMUTABLE]
        pad1: SOURCE
                [stream:0 fmt:UYVY8_1X16/1280x720 field:none colorspace:srgb xfer:srgb ycbcr:601 quantization:lim-range]
                -> "csi capture":0 [ENABLED,IMMUTABLE]

- entity 4: csi capture (1 pad, 1 link)
            type Node subtype V4L flags 0
            device node name /dev/video2
        pad0: SINK
                <- "csi":1 [ENABLED,IMMUTABLE]

- entity 10: csis-32e30000.mipi-csi (2 pads, 2 links, 0 routes)
             type V4L2 subdev subtype Unknown flags 0
             device node name /dev/v4l-subdev1
        pad0: SINK,MUST_CONNECT
                [stream:0 fmt:UYVY8_1X16/1280x720 field:none colorspace:srgb xfer:srgb ycbcr:601 quantization:full-range]
                <- "tevs 1-0048":0 [ENABLED]
        pad1: SOURCE,MUST_CONNECT
                [stream:0 fmt:UYVY8_1X16/1280x720 field:none colorspace:srgb xfer:srgb ycbcr:601 quantization:full-range]
                -> "csi":0 [ENABLED,IMMUTABLE]

- entity 15: tevs 1-0048 (1 pad, 1 link, 0 routes)
             type V4L2 subdev subtype Sensor flags 0
             device node name /dev/v4l-subdev2
        pad0: SOURCE
                [stream:0 fmt:UYVY8_1X16/1280x720@1/60 field:none colorspace:srgb xfer:srgb ycbcr:601 quantization:full-range
                 crop.bounds:(0,0)/1280x720
                 crop:(0,0)/1280x720]
                -> "csis-32e30000.mipi-csi":0 [ENABLED]

🚨 Troubleshooting

Check DTB Overlay in U-Boot

Make sure the correct Device Tree Blob (DTB) is specified in U-Boot.

  u-boot=> printenv dtoverlay
    dtoverlay=tevs vxt-vl050-070-8048nt

Verify Camera Initialization

Use dmesg to check if the TEVS camera module was initialized correctly.

  $ dmesg -t | grep tevs
    /soc@0/bus@30800000/i2c@30a30000/tevs_mipi@48: Fixed dependency cycle(s) with /soc@0/bus@32c00000/mipi-csi@32e30000
    /soc@0/bus@32c00000/mipi-csi@32e30000: Fixed dependency cycle(s) with /soc@0/bus@30800000/i2c@30a30000/tevs_mipi@48
    /soc@0/bus@30800000/i2c@30a30000/tevs_mipi@48: Fixed dependency cycle(s) with /soc@0/bus@32c00000/mipi-csi@32e30000
    /soc@0/bus@30800000/i2c@30a30000/tevs_mipi@48: Fixed dependency cycle(s) with /soc@0/bus@32c00000/mipi-csi@32e30000
    /soc@0/bus@32c00000/mipi-csi@32e30000: Fixed dependency cycle(s) with /soc@0/bus@30800000/i2c@30a30000/tevs_mipi@48
    /soc@0/bus@30800000/i2c@30a30000/tevs_mipi@48: Fixed dependency cycle(s) with /soc@0/bus@32c00000/mipi-csi@32e30000
    /soc@0/bus@32c00000/mipi-csi@32e30000: Fixed dependency cycle(s) with /soc@0/bus@30800000/i2c@30a30000/tevs_mipi@48
    /soc@0/bus@32c00000/mipi-csi@32e30000: Fixed dependency cycle(s) with /soc@0/bus@30800000/i2c@30a30000/tevs_mipi@48
    /soc@0/bus@30800000/i2c@30a30000/tevs_mipi@48: Fixed dependency cycle(s) with /soc@0/bus@32c00000/mipi-csi@32e30000
    tevs 1-0048: tevs_probe() device node: tevs_mipi@48
    tevs 1-0048: Version:25.3.0.2
    tevs 1-0048: Product:TEVS-AR0521, HeaderVer:3, MIPI_Rate:800
    tevs 1-0048: Chip ID: 0x0000
    tevs 1-0048: probe success

Confirm Board and Camera DTB

Check if the correct DTB is loaded with a matching camera model.

Select Target Board
  $ dmesg -t | grep -i model
    Machine model: TechNexion EDM-G-IMX8MM and WB baseboard
    exc3000 2-002a: Retry 1 get EETI EXC3000 model: -6
    exc3000 2-002a: Retry 2 get EETI EXC3000 model: -6
    exc3000 2-002a: Retry 3 get EETI EXC3000 model: -6

Check Available Video Devices

Verify that the video devices are available.

$ v4l2-ctl --list-device

Example output:

imx-capture (platform:32e20000.csi):
        /dev/video2
        /dev/media0

vsi_v4l2dec (platform:vsi_v4l2dec):
        /dev/video1

vsi_v4l2enc (platform:vsi_v4l2enc):
        /dev/video0

Typically, /dev/video2 is your primary camera capture device when using CSI1.