Skip to main content

IMX93 TEVS Camera Usage Guide

πŸš€ Introduction​

This guide shows you how to get started using TechNexion camera modules on AXON-WB-IMX93 board. 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 (Scarthgap) 2025Q3 Release with Linux kernel version 6.12.20-2.0.0.


πŸ“Έ Supported Camera Modules​

Camera SeriesProducts
TEVS
TEVS-AR0144
TEVS-AR0145
TEVS-AR0234
TEVS-AR0521
TEVS-AR0522
TEVS-AR0821
TEVS-AR0822
TEVS-AR1335
e.g.

This article uses the TEVS-AR0521 as an example.


🧩 Supported Boards​

SoMBoard
EDM-IMX93EDM-WB-IMX93
AXON-IMX93AXON-WB-IMX93
PICO-IMX93PICO-SK

πŸ”§ 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 LCD1 connector or LVDS1 connector on the board.
About display

The provided DTBs include configuration for 10.1-inch and 15.6-inch LVDS display panels, as well as 5-inch and 8-inch LCD panels. This allows the system to output video, which is useful for verifying camera streaming on screen.


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.

πŸ”— Supported Release List for EDM-IMX93
πŸ”— Supported Release List for AXON-IMX93
πŸ”— Supported Release List for PICO-IMX93

πŸ’Ύ 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

Boot Mode

Before flashing, ensure the board is set to Serial Download Mode in the boot configuration.


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

U-Boot Requirement

The board must be booted with a version of U-Boot that supports the ums command. Typically, this is done from the existing e.MMC.


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.20tn-imx_6.12.20_2.0.0-stable

πŸ“ Source and Build Instructions​

πŸ”— Fetch Yocto Source
πŸ“– Build Yocto for EDM-IMX93
πŸ“– Build Yocto for AXON-IMX93
πŸ“– Build Yocto for PICO-IMX93


πŸ“Έ 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
  1. Continue boot process.
u-boot=> saveenv
u-boot=> boot
tip

Remember to append the overlay for the display panel, if you want to see the camera output on screen.
e.g.

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

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

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 mxc-isi
model FSL Capture Media Device
serial
bus info platform:4ae40000.isi
hw revision 0x0
driver version 6.12.20

Device topology
- entity 1: crossbar (3 pads, 3 links, 1 route)
type V4L2 subdev subtype Unknown flags 0
device node name /dev/v4l-subdev0
routes:
0/0 -> 2/0 [ACTIVE]
pad0: SINK,MUST_CONNECT
[stream:0 fmt:UYVY8_1X16/1920x1080 field:none colorspace:srgb xfer:srgb ycbcr:601 quantization:lim-range]
<- "csidev-4ae00000.csi":1 [ENABLED,IMMUTABLE]
pad1: SINK,MUST_CONNECT
<- "mxc_isi.output":0 [ENABLED,IMMUTABLE]
pad2: SOURCE
[stream:0 fmt:UYVY8_1X16/1920x1080 field:none colorspace:srgb xfer:srgb ycbcr:601 quantization:lim-range]
-> "mxc_isi.0":0 [ENABLED,IMMUTABLE]

- entity 5: mxc_isi.0 (2 pads, 2 links, 0 routes)
type V4L2 subdev subtype Unknown flags 0
device node name /dev/v4l-subdev1
pad0: SINK
[stream:0 fmt:UYVY8_1X16/1920x1080 field:none colorspace:jpeg xfer:srgb ycbcr:601 quantization:full-range
compose.bounds:(0,0)/1920x1080
compose:(0,0)/1920x1080]
<- "crossbar":2 [ENABLED,IMMUTABLE]
pad1: SOURCE
[stream:0 fmt:YUV8_1X24/1920x1080 field:none colorspace:jpeg xfer:srgb ycbcr:601 quantization:full-range
crop.bounds:(0,0)/1920x1080
crop:(0,0)/1920x1080]
-> "mxc_isi.0.capture":0 [ENABLED,IMMUTABLE]

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

- entity 16: mxc_isi.output (1 pad, 1 link)
type Node subtype V4L flags 0
pad0: SOURCE
-> "crossbar":1 [ENABLED,IMMUTABLE]

- entity 23: csidev-4ae00000.csi (2 pads, 2 links, 1 route)
type V4L2 subdev subtype Unknown flags 0
device node name /dev/v4l-subdev2
routes:
0/0 -> 1/0 [ACTIVE]
pad0: SINK
[stream:0 fmt:UYVY8_1X16/1920x1080 field:none colorspace:smpte170m xfer:709 ycbcr:601 quantization:lim-range]
<- "tevs 1-0048":0 []
pad1: SOURCE
[stream:0 fmt:UYVY8_1X16/1920x1080 field:none colorspace:smpte170m xfer:709 ycbcr:601 quantization:lim-range]
-> "crossbar":0 [ENABLED,IMMUTABLE]

- entity 28: tevs 1-0048 (1 pad, 1 link, 0 routes)
type V4L2 subdev subtype Sensor flags 0
device node name /dev/v4l-subdev3
pad0: SOURCE
[stream:0 fmt:UYVY8_1X16/640x480@1/60 field:none colorspace:srgb xfer:srgb ycbcr:601 quantization:full-range
crop.bounds:(0,0)/640x480
crop:(0,0)/640x480]
-> "csidev-4ae00000.csi":0 []

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

note

If you want to see the graph, you can use the --print-dot option.

$ media-ctl --print-dot > graph.dot
$ dot -Tpng graph.dot > graph.png
# If you don't have the tool, you need to install it as follows.
# sudo apt-get install -y graphviz.

We can observe that the link between β€˜tevs 1-0048 ’ to β€˜csidev-4ae00000.csi ’ is a dotted line. This means it's not available.

You need to enable the link between the TEVS and CSI device.

$ media-ctl -l "'tevs 1-0048':0 -> 'csidev-4ae00000.csi':0 [1]"

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-subdev3 --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-subdev3 --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-subdev3 --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-subdev3 --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-subdev3 --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-subdev3 --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-subdev3 --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-subdev3 --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 "'crossbar':0 [fmt:UYVY8_1X16/1280x720 field:none colorspace:srgb xfer:srgb ycbcr:601]"
$ media-ctl -V "'mxc_isi.0':0 [fmt:UYVY8_1X16/1280x720 field:none colorspace:srgb xfer:srgb ycbcr:601]"
$ media-ctl -V "'csidev-4ae00000.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/video0 ! \
"video/x-raw, format=YUY2, 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 mxc-isi
model FSL Capture Media Device
serial
bus info platform:4ae40000.isi
hw revision 0x0
driver version 6.12.20

Device topology
- entity 1: crossbar (3 pads, 3 links, 1 route)
type V4L2 subdev subtype Unknown flags 0
device node name /dev/v4l-subdev0
routes:
0/0 -> 2/0 [ACTIVE]
pad0: SINK,MUST_CONNECT
[stream:0 fmt:UYVY8_1X16/1280x720 field:none colorspace:srgb xfer:srgb ycbcr:601]
<- "csidev-4ae00000.csi":1 [ENABLED,IMMUTABLE]
pad1: SINK,MUST_CONNECT
<- "mxc_isi.output":0 [ENABLED,IMMUTABLE]
pad2: SOURCE
[stream:0 fmt:UYVY8_1X16/1280x720 field:none colorspace:srgb xfer:srgb ycbcr:601]
-> "mxc_isi.0":0 [ENABLED,IMMUTABLE]

- entity 5: mxc_isi.0 (2 pads, 2 links, 0 routes)
type V4L2 subdev subtype Unknown flags 0
device node name /dev/v4l-subdev1
pad0: SINK
[stream:0 fmt:UYVY8_1X16/1280x720 field:none colorspace:srgb xfer:srgb ycbcr:601
compose.bounds:(0,0)/1280x720
compose:(0,0)/1280x720]
<- "crossbar":2 [ENABLED,IMMUTABLE]
pad1: SOURCE
[stream:0 fmt:YUV8_1X24/1280x720 field:none colorspace:jpeg xfer:srgb ycbcr:601 quantization:full-range
crop.bounds:(0,0)/1280x720
crop:(0,0)/1280x720]
-> "mxc_isi.0.capture":0 [ENABLED,IMMUTABLE]

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

- entity 16: mxc_isi.output (1 pad, 1 link)
type Node subtype V4L flags 0
pad0: SOURCE
-> "crossbar":1 [ENABLED,IMMUTABLE]

- entity 23: csidev-4ae00000.csi (2 pads, 2 links, 1 route)
type V4L2 subdev subtype Unknown flags 0
device node name /dev/v4l-subdev2
routes:
0/0 -> 1/0 [ACTIVE]
pad0: SINK
[stream:0 fmt:UYVY8_1X16/1280x720 field:none colorspace:srgb xfer:srgb ycbcr:601 quantization:full-range]
<- "tevs 1-0048":0 [ENABLED]
pad1: SOURCE
[stream:0 fmt:UYVY8_1X16/1280x720 field:none colorspace:srgb xfer:srgb ycbcr:601 quantization:full-range]
-> "crossbar":0 [ENABLED,IMMUTABLE]

- entity 28: tevs 1-0048 (1 pad, 1 link, 0 routes)
type V4L2 subdev subtype Sensor flags 0
device node name /dev/v4l-subdev3
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]
-> "csidev-4ae00000.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
tip

The vxt-vl050-070-8048nt is an overlay for 5-inch LCD display panel.

Verify Camera Initialization​

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

  $ dmesg -t | grep tevs
/soc@0/bus@44000000/i2c@44350000/tevs@48: Fixed dependency cycle(s) with /soc@0/bus@42800000/csi@4ae00000
/soc@0/bus@42800000/csi@4ae00000: Fixed dependency cycle(s) with /soc@0/bus@44000000/i2c@44350000/tevs@48
/soc@0/bus@44000000/i2c@44350000/tevs@48: Fixed dependency cycle(s) with /soc@0/bus@42800000/csi@4ae00000
/soc@0/bus@44000000/i2c@44350000/tevs@48: Fixed dependency cycle(s) with /soc@0/bus@42800000/csi@4ae00000
/soc@0/bus@42800000/csi@4ae00000: Fixed dependency cycle(s) with /soc@0/bus@44000000/i2c@44350000/tevs@48
/soc@0/bus@44000000/i2c@44350000/tevs@48: Fixed dependency cycle(s) with /soc@0/bus@42800000/csi@4ae00000
/soc@0/bus@42800000/csi@4ae00000: Fixed dependency cycle(s) with /soc@0/bus@44000000/i2c@44350000/tevs@48
/soc@0/bus@42800000/csi@4ae00000: Fixed dependency cycle(s) with /soc@0/bus@44000000/i2c@44350000/tevs@48
/soc@0/bus@44000000/i2c@44350000/tevs@48: Fixed dependency cycle(s) with /soc@0/bus@42800000/csi@4ae00000
tevs 1-0048: tevs_probe() device node: tevs@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.

  $ dmesg -t | grep -i model
Machine model: TechNexion AXON-IMX93 and WB baseboard
exc3000 2-002a: Retry 1 get EETI EXC3000 model: -5
exc3000 2-002a: Retry 2 get EETI EXC3000 model: -5
exc3000 2-002a: Retry 3 get EETI EXC3000 model: -5

Check Available Video Devices​

Verify that the video devices are available.

  $ v4l2-ctl --list-device

Example output:

mxc-isi-cap (platform:4ae40000.isi):
/dev/video0
/dev/video1
/dev/media0

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