Interfacing sama7g5 with parallel Omnivision ov7740 sensor
This page describes the possibility of connecting a parallel sensor (example given is Omnivision ov7740) to the SAMA7G5 MPU.</br> warning 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.</br> warning Being a parallel sensor, all sensor data lines must be connected to the ISC I/O lines.</br> warning 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.</br> It uses a specific ISC I/O IOSET. One has to adapt this to its own board </br> The example shows how to connect endpoints between the different nodes in the DT, to have everything in place for a parallel capture.</br> hand 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.</br> hand 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
/* 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: </br>
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: <br /> <img src="%PUBURLPATH%/%WEB%/%TOPIC%/graph_ov7740.png" alt="graph_ov7740.png" width="151" height="345" />
Capturing
Capturing YUYV directly from the sensor
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
Capturing RAW from sensor and converting in the ISC
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
Supported sensor formats
We can always query the sensor for which formats it supports:
ioctl: VIDIOC_SUBDEV_ENUM_MBUS_CODE (pad=0)
0x2008: MEDIA_BUS_FMT_YUYV8_2X8
0x3001: MEDIA_BUS_FMT_SBGGR8_1X8
#
Related Topics
Boards
Components
Kernel
linux 5.15
linux 6.1
linux 6.6
Summary
Interfacing sama7g5 with parallel omnivision ov7740 sensor.