Wally Yeh

A Simple tutor for writing i.MX6 mipi driver, use adv7480 as an example

Discussion created by Wally Yeh on Feb 25, 2016
Latest reply on Apr 11, 2018 by Jason Gaiser

Hello, folks:

   It's been a month since fighting with the i.MX6 mipi driver, I realize how dumb I am during writing i.MX6 device mipi driver; so I write this article for someone like me - whom is hopeless and frighten by this damn mipi protocol.

 

    Our case is using adv7480 as TV-in function(HDMI in, and yuv422 out) on i.MX6DL, 2 mipi data lanes, attach to <CSI0, IPU0, virtual channel 0>, and wanna grab some picture form it. I choose v4l2grab for grab picture from mipi, download location: GitHub - twam/v4l2grab: utility for grabbing JPEGs from V4L2 devices

 

    By the way, the SDK I'm using is SDK_3.0.35-4.1.0; you may use different SDK but you need to fight with arm device tree files by yourself.

 

   OK, the first step is to tell kernel you have the device, one can see how to do this by reference my patch file: 0001-add-adv7480-platform-data.patch

I strongly recommend using CSI0, IPU0, and virtual channel 0.  since every device *must* set the virtual channel, and the reasonable default value is 0; so if you doesn't know how to set your device's virtual channel, just use 0 on your board file.

 

   Second, the mipi driver, I also attached it(adv7480_mipi_driver_patches.zip).

patch 0001 is just add an V4L2 ID for adv7480.

patch 0002 add an func "mipi_csi2_reset_with_dphy_freq" for driver use. the main idea is dynamic change i.MX6 Dphy frequency to match the adv7480 mipi data lane output.

if someone is confused with "pixel clock", "mipi clock lane frequency", "mipi data lane frequency", following is an simple explanation:

unnamed.jpg

and pixel clock can get from this website: VGA Signal Timing

 

patch 0003 is for v4l2grab only, don't know why it call v4l2 ioctl "VIDIOC_S_FMT" but kernel will use "VIDIOC_TRY_FMT" instead.

patch 0004 is the entire adv7480 driver, basically I just swallow the i2c commends from ov5640_mipi.c and fill my own, then change it's func name with "adv7480"。

I will explain some important part:

1. adv7480_init_mode(), I found after mipi_csi2_reset_with_dphy_freq() or mipi_csi2_reset() called, you *must* turn off device's output and turn it on again! or you will got

mipi_csi2_dphy_status alwaly be 0x200 or 0x230, it means i.MX6 can't get the clock form device.

2. most v4l2 ioctl is not implemented, only ioctl_s_parm() and ioctl_g_parm() are implemented.

3. adv7480 have totally 12 i2c clients inside the chip, so we also need to add a argument "address" for different sub i2c client's address.

 

   adv7480_mipi_tvin.c will register an v4l2 device by mxc_v4l2_capture.c called. and mxc_v4l2_capture.c will make a device node - /dev/video0. that's the node we can use v4l2grac to grab some picture - ./vl42grab -o /tmp/test.jpg.

 

p.s: since i.MX6 DL mipi bandwidth is small, you can only retrieve picture while input resolution is lower than 1280x800. if anyone want grab 1920x1080. you must use i.MX6Q and use 4 mipi data lanes.

Original Attachment has been moved to: 0001-add-adv7480-platform-data.patch.zip

Original Attachment has been moved to: adv7480_mipi_driver_patches.zip

Outcomes