SAMA7G5 and Omnivision OV7740
This page describes the possibility of connecting a parallel sensor (example given is Omnivision ov7740) to the SAMA7G5 MPU.
The board
sama7g5-ek does not have a parallel sensor connector. This tutorial is applicable to custom boards which want to use this type of interface.
Introduction
Omnivision OV7740 is a parallel sensor , 8 bit Raw BAYER, that can also stream directly YUYV format.
Being a parallel sensor, all sensor data lines must be connected to the ISC I/O lines.
SAMA7G5 uses
media controller paradigm to configure the pipeline. Please refer to
this tutorial for more information about it.
Device Tree configuration
This is an example Device Tree configuration.
It uses a specific ISC I/O IOSET. One has to adapt this to its own board
The example shows how to connect endpoints between the different nodes in the DT, to have everything in place for a parallel capture.
The snippet below assumes that all nodes in the
sama7g5.dtsi are available as in the Linux Mainline tree. The properties that are already in Linux mainline are not duplicated here.
The below snippet can be added as an overlay or directly to your board
dts file , because it uses references to already existing nodes from
sama7g5.dtsi
&csi2dc {
/* this clock is requested by the csi2dc from the xisc,
* and then it's passed to the sensor. It is mandatory to
* request the same frequency, otherwise the clock subsystem
* will change the frequency to the last one requested */
assigned-clock-rates = <24000000>;
status = "okay";
ports {
port@0 {
csi2dc_in: endpoint {
/* csi2dc will automatically understand from the endpoint if this is a Parallel or CSI2 endpoint connection */
remote-endpoint = <&ov7740_0>;
};
};
};
};
&flx1 {
/* make sure flexcom1 is in TWI mode for the i2c1 subnode below... */
atmel,flexcom-mode = <ATMEL_FLEXCOM_MODE_TWI>;
};
&i2c1 {
#address-cells = <1>;
#size-cells = <0>;
ov7740: camera@21 {
compatible = "ovti,ov7740";
reg = <0x21>;
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_sensor_power &pinctrl_sensor_reset>;
reset-gpios = <&pioA PIN_PA13 GPIO_ACTIVE_LOW>;
powerdown-gpios = <&pioA PIN_PA12 GPIO_ACTIVE_HIGH>;
clocks = <&xisc>;
clock-names = "xvclk"; /* be careful at the clock name, to be the one expected by the driver */
assigned-clocks = <&xisc>;
assigned-clock-rates = <24000000>; /* also requested by csi2dc above */
status = "okay";
port {
ov7740_0: endpoint {
remote-endpoint = <&csi2dc_in>;
hsync-active = <1>;
vsync-active = <0>;
pclk-sample = <1>;
};
};
};
};
&pioA {
pinctrl_sensor_power: sensor_power {
pinmux = <PIN_PA12__GPIO>;
bias-disable;
};
pinctrl_sensor_reset: sensor_reset {
pinmux = <PIN_PA13__GPIO>;
bias-disable;
};
};
&xisc {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_isc_base &pinctrl_isc_data_8bit>;
status = "okay";
port {
xisc_in: endpoint {
hsync-active = <1>;
vsync-active = <0>;
pclk-sample = <1>;
};
};
};
&pioA {
pinctrl_isc_base: isc_base {
pinmux = <PIN_PA27__ISC_PCK>,
<PIN_PA25__ISC_VSYNC>,
<PIN_PA24__ISC_HSYNC>,
<PIN_PA15__ISC_MCK>;
bias-disable;
};
/* ISC uses the top data bits always, if your sensor outputs 10 bits e.g., you need to use D2-D11 */
pinctrl_isc_data_8bit: isc_data_8bit {
pinmux = <PIN_PA31__ISC_D11>,
<PIN_PA30__ISC_D10>,
<PIN_PA29__ISC_D9>,
<PIN_PA28__ISC_D8>,
<PIN_PA23__ISC_D7>,
<PIN_PA22__ISC_D6>,
<PIN_PA21__ISC_D5>,
<PIN_PA20__ISC_D4>;
bias-disable;
};
};
Media controller pipeline
If probed correctly, the media controller pipeline looks like this:
# media-ctl -p
Media controller API version 5.16.0
Media device information
------------------------
driver atmel_isc_commo
model microchip,sama7g5-isc
serial
bus info platform:microchip-sama7g5-xisc
hw revision 0x220
driver version 5.16.0
Device topology
- entity 1: atmel_isc_scaler (2 pads, 2 links)
type V4L2 subdev subtype Unknown flags 0
device node name /dev/v4l-subdev0
pad0: Sink
[fmt:SBGGR8_1X8/3264x2464 field:none colorspace:srgb
crop.bounds:(0,0)/3264x2464
crop:(0,0)/3264x2464]
<- "csi2dc":1 [ENABLED,IMMUTABLE]
pad1: Source
[fmt:SBGGR8_1X8/3264x2464 field:none colorspace:srgb]
-> "atmel_isc_common":0 [ENABLED,IMMUTABLE]
- entity 4: csi2dc (2 pads, 2 links)
type V4L2 subdev subtype Unknown flags 0
device node name /dev/v4l-subdev1
pad0: Sink
[fmt:SRGGB8_1X8/640x480 field:none colorspace:srgb]
<- "ov7740 0-0021":0 [ENABLED]
pad1: Source
[fmt:SRGGB8_1X8/640x480 field:none colorspace:srgb]
-> "atmel_isc_scaler":0 [ENABLED,IMMUTABLE]
- entity 7: ov7740 0-0021 (1 pad, 1 link)
type V4L2 subdev subtype Sensor flags 0
device node name /dev/v4l-subdev2
pad0: Source
[fmt:YUYV8_2X8/640x480@1/60 field:none colorspace:srgb]
-> "csi2dc":0 [ENABLED]
- entity 17: atmel_isc_common (1 pad, 1 link)
type Node subtype V4L flags 1
device node name /dev/video0
pad0: Sink
<- "atmel_isc_scaler":1 [ENABLED,IMMUTABLE]
#
The pipeline can be also represented as a graph, as in the picture below:
Capturing
v4l2-ctl -v pixelformat=YUYV,height=480,width=640 # configure video format to YUYV packed 16 bits per pixel
media-ctl --set-v4l2 '"ov7740 0-0021":0[fmt:YUYV8_2X8/640x480@1/60 field:none colorspace:srgb]' # configure sensor to stream YUYV directly in 2 bytes per pixel 2x8
media-ctl --set-v4l2 '"csi2dc":0[fmt:YUYV8_2X8/640x480 field:none colorspace:srgb]' # configure csi2dc accordingly
media-ctl --set-v4l2 '"atmel_isc_scaler":0[fmt:YUYV8_2X8/640x480 field:none colorspace:srgb]' # configure scaler accordingly
fswebcam -r 640x480 -p YUYV -S 20 test.jpg # capture YUYV packed 2 bytes per pixel at 640x480
v4l2-ctl -v pixelformat=YU12,height=480,width=640 # configure video format to YUV planar 4:2:0
media-ctl --set-v4l2 '"ov7740 0-0021":0[fmt:SBGGR8_1X8/640x480@1/60 field:none colorspace:srgb]' # configure sensor to stream raw bayer BGGR 8 bits
media-ctl --set-v4l2 '"csi2dc":0[fmt:SBGGR8_1X8/640x480 field:none colorspace:srgb]' #configure csi2dc accordingly
media-ctl --set-v4l2 '"atmel_isc_scaler":0[fmt:SBGGR8_1X8/640x480 field:none colorspace:srgb]' # configure scaler accordingly
fswebcam -r 640x480 -p YUV420P -S 20 testplanar.jpg # simple capture at 640x480 in YUV4:2:0 planar
We can always query the sensor for which formats it supports:
# v4l2-ctl -d /dev/v4l-subdev2 --list-subdev-mbus-codes
ioctl: VIDIOC_SUBDEV_ENUM_MBUS_CODE (pad=0)
0x2008: MEDIA_BUS_FMT_YUYV8_2X8
0x3001: MEDIA_BUS_FMT_SBGGR8_1X8
#