The CSI (CMOS Sensor Interface) hardware block is partially supported in mainline Linux. Support for the hardware block found on A31 and later generations is already upstream, while the one found on A10/A20 is being worked on, as of 2019/04/12.
Currently parallel and BT.656 (embedded sync) interfaces are supported. MIPI CSI-2 is not.
The mainline driver uses v4l2 with the sub-device API and media controller API.
To enable the driver, please first check if you have the VIDEO_DEV, MEDIA_CONTROLLER and VIDEO_V4L2_SUBDEV_API Kconfig options enabled.
Then once you enable V4L_PLATFORM_DRIVERS you should be able to enable VIDEO_SUN6I_CSI for the A31 CSI driver. For the A10/A20 CSI driver, enable VIDEO_SUN4I_CSI. (Provided you have the patches applied.)
It is recommended to use an up-to-date version of v4l-utils, as older versions, such as the one in Debian Stable (1.12.x) has some bugs, and doesn't understand all formats or knobs.
The usage of the media controller and sub-device API means configuration of the capture options is slightly complicated. The media-ctl and v4l2-ctl are used.
To see the current settings of the media bus, use
$ media-ctl --print-topology
Media controller API version 5.1.0
Media device information
------------------------
driver sun6i-csi
model Allwinner Video Capture Device
serial
bus info
hw revision 0x0
driver version 5.1.0
Device topology
- entity 1: sun6i-csi (1 pad, 1 link)
type Node subtype V4L flags 0
device node name /dev/video0
pad0: Sink
<- "ov5640 1-003c":0 [ENABLED,IMMUTABLE]
- entity 5: ov5640 1-003c (1 pad, 1 link)
type V4L2 subdev subtype Sensor flags 0
device node name /dev/v4l-subdev0
pad0: Source
[fmt:UYVY8_2X8/640x480 field:none]
-> "sun6i-csi":0 [ENABLED,IMMUTABLE]
root@linux:/ # media-ctl --print-topology
Media controller API version 4.14.86
Media device information
------------------------
driver rcar_vin
model renesas,vin-r8a7795
serial
bus info platform:e6ef4000.video
hw revision 0x0
driver version 4.14.86
Device topology
- entity 1: rcar_csi2 feab0000.csi2 (5 pads, 3 links)
type V4L2 subdev subtype Unknown flags 0
device node name /dev/v4l-subdev31
pad0: Sink
[fmt:RGB888_1X24/1280x720 field:none colorspace:smpte170m]
<- "gmsl-csi2-link 0-004c":0 [ENABLED,IMMUTABLE]
pad1: Source
[fmt:RGB888_1X24/1280x720 field:none colorspace:smpte170m]
-> "VIN4 output":0 [ENABLED]
pad2: Source
[fmt:RGB888_1X24/1280x720 field:none colorspace:smpte170m]
-> "VIN4 output":0 []
pad3: Source
[fmt:RGB888_1X24/1280x720 field:none colorspace:smpte170m]
pad4: Source
[fmt:RGB888_1X24/1280x720 field:none colorspace:smpte170m]
- entity 7: gmsl-csi2-link 0-004c (2 pads, 1 link)
type V4L2 subdev subtype Unknown flags 0
device node name /dev/v4l-subdev32
pad0: Source
[fmt:RGB888_1X24/1280x720 field:none colorspace:srgb]
-> "rcar_csi2 feab0000.csi2":0 [ENABLED,IMMUTABLE]
pad1: Sink
- entity 16: VIN4 output (1 pad, 2 links)
type Node subtype V4L flags 0
device node name /dev/video16
pad0: Sink
<- "rcar_csi2 feab0000.csi2":1 [ENABLED]
<- "rcar_csi2 feab0000.csi2":2 []
On systems with the Cedrus driver enabled, the media device may not be the default one, in which case you should use
$ media-ctl --device /dev/mediaN --print-topology
To set the capture format (including the bus format and capture size), you specify the properties of the source pad.
$ media-ctl --set-v4l2 '"ov5640 1-003c":0[fmt:UYVY8_2X8/720x480]'
media-ctl --set-v4l2 "'rcar_csi2 feab0000.csi2':1 [fmt:UYVY8_2X8/1280x720 field:none colorspace:smpte170m]"
media-ctl --set-v4l2 "'rcar_csi2 feab0000.csi2':1 [fmt:RGB888_1X24/1280x720 field:none colorspace:smpte170m]"
Here the entity name "ov5640 1-003c" can also be replaced with the entity ID 5.
This configures a capture size of 720x480 pixels with the UYVY8_2X8 bus format, which is YUV 4:2:0. See Media Bus Formats for a list and description of formats.
The capture resolution specified here must match what is requested by the capture application, otherwise the kernel driver will report an error and refuse to capture.
此处指定的捕获分辨率必须与捕获应用程序所要求的匹配,否则内核驱动程序将报告错误并拒绝捕获。
Sensors can have a number of control knobs that can be configured from userspace. These range from image orientation to power line frequency to test patterns.
To see the full list of control knobs along with menu item descriptions, use
$ v4l2-ctl --list-ctrls-menus
User Controls
contrast (int) : min=0 max=255 step=1 default=0 value=0 flags=slider
saturation (int) : min=0 max=255 step=1 default=64 value=64 flags=slider
hue (int) : min=0 max=359 step=1 default=0 value=0 flags=slider
white_balance_automatic (bool) : default=1 value=1 flags=update
red_balance (int) : min=0 max=4095 step=1 default=0 value=0 flags=inactive, slider
blue_balance (int) : min=0 max=4095 step=1 default=0 value=0 flags=inactive, slider
exposure (int) : min=0 max=65535 step=1 default=0 value=885 flags=inactive, volatile
gain_automatic (bool) : default=1 value=1 flags=update
gain (int) : min=0 max=1023 step=1 default=0 value=248 flags=inactive, volatile
horizontal_flip (bool) : default=0 value=0
vertical_flip (bool) : default=0 value=0
power_line_frequency (menu) : min=0 max=3 default=1 value=1
0: Disabled
1: 50 Hz
2: 60 Hz
3: Auto
Camera Controls
auto_exposure (menu) : min=0 max=1 default=0 value=0 flags=update
0: Auto Mode
1: Manual Mode
Image Processing Controls
test_pattern (menu) : min=0 max=4 default=0 value=0
0: Disabled
1: Color bars
2: Color bars w/ rolling bar
3: Color squares
4: Color squares w/ rolling bar
Note that if the system has multiple video devices, you may need to specify which one to use:
$ v4l2-ctl --device=/dev/videoN --list-ctrls-menus
To set an option, use
$ v4l2-ctl --set-ctrl=vertical_flip=1
Or multiple options at once
$ v4l2-ctl --set-ctrl=power_line_frequency=2,vertical_flip=1,horizontal_flip=1
FFMpeg supports capturing from v4l2 devices. However it does not support configuration of the media bus or sub-devices. Please use the commands shown in the previous sections instead.
To capture from the first video device, use
$ ffmpeg -s WxH -i /dev/video0 output.mjpg
This captures and encodes a video of W by H pixels from the first video device to an M-JPEG file.
Note that W and H must match what you previously set with media-ctl. The system default is 640x480.
If you also specified a different bus format, such as JPEG_1X8, you will need to tell FFMpeg as well, using
$ ffmpeg -input_format mjpeg -s WxH -i /dev/video0 output.mjpg
The JPEG media bus format support in the driver does not trim the returned buffer. In other words, the full buffer is passed back to userspace, with trailing zeros. This means the user will end up with enormous JPEG files without post-processing.
There are already several JPEG parsers in the kernel. A proposal was made to combine and generalize them, which could then be used in our CSI driver to detect the end of the JPEG stream. This has not been implemented yet.
While a few Allwinner SoCs support MIPI CSI-2, details on the hardware is sparse. No one has attempted to support this yet.