This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

PROCESSOR-SDK-AM62X: How to start the OV5647 Live camera on TI Apps Launcher

Part Number: PROCESSOR-SDK-AM62X
Other Parts Discussed in Thread: AM625

/resized-image/__size/640x480/__key/communityserver-discussions-components-files/791/ImportedPhoto_5F00_1715863704579.jpg

Hi,

1. which version of the SDK are you using?

- SDK Version;- 09.02.01.09

2. what did you do to bring up the camera?

by refering this link :- e2e.ti.com/.../sk-am62a-lp-bring-up-ov5647

3. which camera module are you using?

OV5647 5MP 1080P IR-Cut Camera for Raspberry Pi 3/4 with Automatic Day Night Mode 

4. what's the output of "media-ctl -p"?

root@am62xx-evm:~# media-ctl -p
Media controller API version 6.1.80

Media device information
------------------------
driver          j721e-csi2rx
model           TI-CSI2RX
serial
bus info        platform:30102000.ticsi2rx
hw revision     0x1
driver version  6.1.80

Device topology
- entity 1: 30102000.ticsi2rx (5 pads, 5 links, 1 route)
            type V4L2 subdev subtype Unknown flags 0
            device node name /dev/v4l-subdev0
        routes:
                0/0 -> 1/0 [ACTIVE]
        pad0: Sink
                [stream:0 fmt:UYVY8_1X16/640x480 field:none colorspace:srgb xfer:srgb ycbcr:601 quantization:lim-range]
                <- "cdns_csi2rx.30101000.csi-bridge":1 [ENABLED,IMMUTABLE]
        pad1: Source
                [stream:0 fmt:UYVY8_1X16/640x480 field:none colorspace:srgb xfer:srgb ycbcr:601 quantization:lim-range]
                -> "30102000.ticsi2rx context 0":0 [ENABLED,IMMUTABLE]
        pad2: Source
                -> "30102000.ticsi2rx context 1":0 [ENABLED,IMMUTABLE]
        pad3: Source
                -> "30102000.ticsi2rx context 2":0 [ENABLED,IMMUTABLE]
        pad4: Source
                -> "30102000.ticsi2rx context 3":0 [ENABLED,IMMUTABLE]

- entity 7: cdns_csi2rx.30101000.csi-bridge (5 pads, 2 links, 1 route)
            type V4L2 subdev subtype Unknown flags 0
            device node name /dev/v4l-subdev1
        routes:
                0/0 -> 1/0 [ACTIVE]
        pad0: Sink
                [stream:0 fmt:UYVY8_1X16/640x480 field:none colorspace:srgb xfer:srgb ycbcr:601 quantization:lim-range]
                <- "ov5647 4-0036":0 [ENABLED,IMMUTABLE]
        pad1: Source
                [stream:0 fmt:UYVY8_1X16/640x480 field:none colorspace:srgb xfer:srgb ycbcr:601 quantization:lim-range]
                -> "30102000.ticsi2rx":0 [ENABLED,IMMUTABLE]
        pad2: Source
        pad3: Source
        pad4: Source

- entity 13: ov5647 4-0036 (1 pad, 1 link, 0 route)
             type V4L2 subdev subtype Sensor flags 0
             device node name /dev/v4l-subdev2
        pad0: Source
                [stream:0 fmt:SBGGR10_1X10/640x480 field:none colorspace:srgb
                 crop.bounds:(16,16)/2592x1944
                 crop:(32,16)/2560x1920]
                -> "cdns_csi2rx.30101000.csi-bridge":0 [ENABLED,IMMUTABLE]

- entity 19: 30102000.ticsi2rx context 0 (1 pad, 1 link, 0 route)
             type Node subtype V4L flags 0
             device node name /dev/video0
        pad0: Sink
                <- "30102000.ticsi2rx":1 [ENABLED,IMMUTABLE]

- entity 25: 30102000.ticsi2rx context 1 (1 pad, 1 link, 0 route)
             type Node subtype V4L flags 0
             device node name /dev/video1
        pad0: Sink
                <- "30102000.ticsi2rx":2 [ENABLED,IMMUTABLE]

- entity 31: 30102000.ticsi2rx context 2 (1 pad, 1 link, 0 route)
             type Node subtype V4L flags 0
             device node name /dev/video2
        pad0: Sink
                <- "30102000.ticsi2rx":3 [ENABLED,IMMUTABLE]

- entity 37: 30102000.ticsi2rx context 3 (1 pad, 1 link, 0 route)
             type Node subtype V4L flags 0
             device node name /dev/video3
        pad0: Sink
                <- "30102000.ticsi2rx":4 [ENABLED,IMMUTABLE]

Now i wanted to start this camera on TI apps launcher ?

or how i can able to take raw image just for seeing that it is working ?

also want to test for videos ?

Somebody can guide me in this regards ,

I have tried to capture the image but unable to take :- 

root@am62xx-evm:~# cam -c1 -I
[2:10:38.713684168] [9178]  INFO Camera camera_manager.cpp:298 libcamera v0.0.5+dirty (2024-03-23T14:12:31+00:00)
[2:10:38.730666460] [9179]  WARN CameraSensor camera_sensor.cpp:244 'ov5647 4-0036': Recommended V4L2 control 0x009a0922 not supported
[2:10:38.730801587] [9179]  WARN CameraSensor camera_sensor.cpp:311 'ov5647 4-0036': The sensor kernel driver needs to be fixed
[2:10:38.730831947] [9179]  WARN CameraSensor camera_sensor.cpp:313 'ov5647 4-0036': See Documentation/sensor_driver_requirements.rst in the libcamera sources for more information
[2:10:38.732914868] [9179]  WARN CameraSensor camera_sensor.cpp:459 'ov5647 4-0036': Failed to retrieve the camera location
Using camera /base/bus@f0000/i2c@20020000/i2c-switch@71/i2c@1/camera@36 as cam0
0: 640x480-SBGGR10
 * Pixelformat: SBGGR10 (640x480)-(2592x1944)/(+0,+0)
  - 640x480
  - 1296x972
  - 1920x1080
  - 2592x1944
root@am62xx-evm:~# cam -c1 --stream width=1296,height=972,pixelformat=[fmt:SBGGR10_1X10/1296x972 field:none] -C20
Invalid non-option argument 'field:none]'
Options:
  -c, --camera camera ...                               Specify which camera to operate on, by id or by index
  -h, --help                                            Display this help message
  -I, --info                                            Display information about stream(s)
  -l, --list                                            List all cameras
      --list-controls                                   List cameras controls
  -p, --list-properties                                 List cameras properties
  -m, --monitor                                         Monitor for hotplug and unplug camera events

Options valid in the context of --camera:
  -C, --capture[=count]                                 Capture until interrupted by user or until <count> frames captured
  -D, --display[=connector]                             Display viewfinder through DRM/KMS on specified connector
  -F, --file[=filename]                                 Write captured frames to disk
                                                        If the file name ends with a '/', it sets the directory in which
                                                        to write files, using the default file name. Otherwise it sets the
                                                        full file path and name. The first '#' character in the file name
                                                        is expanded to the camera index, stream name and frame sequence number.
                                                        The default file name is 'frame-#.bin'.
  -s, --stream key=value[,key=value,...] ...            Set configuration of a camera stream
          colorspace=string                             Color space
          height=integer                                Height in pixels
          pixelformat=string                            Pixel format name
          role=string                                   Role for the stream (viewfinder, video, still, raw)
          width=integer                                 Width in pixels
      --strict-formats                                  Do not allow requested stream format(s) to be adjusted
      --metadata                                        Print the metadata for completed requests
      --script script                                   Load a capture session configuration script from a file
root@am62xx-evm:~# cam -c1 --stream width=1296,height=972,pixelformat= SBGGR10_1X10/1296x972 -C20
Option pixelformat requires an argument
Can't parse key=value argument for option --stream
Options:
  -c, --camera camera ...                               Specify which camera to operate on, by id or by index
  -h, --help                                            Display this help message
  -I, --info                                            Display information about stream(s)
  -l, --list                                            List all cameras
      --list-controls                                   List cameras controls
  -p, --list-properties                                 List cameras properties
  -m, --monitor                                         Monitor for hotplug and unplug camera events

Options valid in the context of --camera:
  -C, --capture[=count]                                 Capture until interrupted by user or until <count> frames captured
  -D, --display[=connector]                             Display viewfinder through DRM/KMS on specified connector
  -F, --file[=filename]                                 Write captured frames to disk
                                                        If the file name ends with a '/', it sets the directory in which
                                                        to write files, using the default file name. Otherwise it sets the
                                                        full file path and name. The first '#' character in the file name
                                                        is expanded to the camera index, stream name and frame sequence number.
                                                        The default file name is 'frame-#.bin'.
  -s, --stream key=value[,key=value,...] ...            Set configuration of a camera stream
          colorspace=string                             Color space
          height=integer                                Height in pixels
          pixelformat=string                            Pixel format name
          role=string                                   Role for the stream (viewfinder, video, still, raw)
          width=integer                                 Width in pixels
      --strict-formats                                  Do not allow requested stream format(s) to be adjusted
      --metadata                                        Print the metadata for completed requests
      --script script                                   Load a capture session configuration script from a file
root@am62xx-evm:~# cam -c1 --stream width=1296,height=972,pixelformat= SBGGR10_1X10/1296x972 -C20
Option pixelformat requires an argument
Can't parse key=value argument for option --stream
Options:
  -c, --camera camera ...                               Specify which camera to operate on, by id or by index
  -h, --help                                            Display this help message
  -I, --info                                            Display information about stream(s)
  -l, --list                                            List all cameras
      --list-controls                                   List cameras controls
  -p, --list-properties                                 List cameras properties
  -m, --monitor                                         Monitor for hotplug and unplug camera events

Options valid in the context of --camera:
  -C, --capture[=count]                                 Capture until interrupted by user or until <count> frames captured
  -D, --display[=connector]                             Display viewfinder through DRM/KMS on specified connector
  -F, --file[=filename]                                 Write captured frames to disk
                                                        If the file name ends with a '/', it sets the directory in which
                                                        to write files, using the default file name. Otherwise it sets the
                                                        full file path and name. The first '#' character in the file name
                                                        is expanded to the camera index, stream name and frame sequence number.
                                                        The default file name is 'frame-#.bin'.
  -s, --stream key=value[,key=value,...] ...            Set configuration of a camera stream
          colorspace=string                             Color space
          height=integer                                Height in pixels
          pixelformat=string                            Pixel format name
          role=string                                   Role for the stream (viewfinder, video, still, raw)
          width=integer                                 Width in pixels
      --strict-formats                                  Do not allow requested stream format(s) to be adjusted
      --metadata                                        Print the metadata for completed requests
      --script script                                   Load a capture session configuration script from a file
root@am62xx-evm:~# cam -c1 --stream width=1296,height=972,pixelformat= SBGGR10 -C20
Option pixelformat requires an argument
Can't parse key=value argument for option --stream
Options:
  -c, --camera camera ...                               Specify which camera to operate on, by id or by index
  -h, --help                                            Display this help message
  -I, --info                                            Display information about stream(s)
  -l, --list                                            List all cameras
      --list-controls                                   List cameras controls
  -p, --list-properties                                 List cameras properties
  -m, --monitor                                         Monitor for hotplug and unplug camera events

Options valid in the context of --camera:
  -C, --capture[=count]                                 Capture until interrupted by user or until <count> frames captured
  -D, --display[=connector]                             Display viewfinder through DRM/KMS on specified connector
  -F, --file[=filename]                                 Write captured frames to disk
                                                        If the file name ends with a '/', it sets the directory in which
                                                        to write files, using the default file name. Otherwise it sets the
                                                        full file path and name. The first '#' character in the file name
                                                        is expanded to the camera index, stream name and frame sequence number.
                                                        The default file name is 'frame-#.bin'.
  -s, --stream key=value[,key=value,...] ...            Set configuration of a camera stream
          colorspace=string                             Color space
          height=integer                                Height in pixels
          pixelformat=string                            Pixel format name
          role=string                                   Role for the stream (viewfinder, video, still, raw)
          width=integer                                 Width in pixels
      --strict-formats                                  Do not allow requested stream format(s) to be adjusted
      --metadata                                        Print the metadata for completed requests
      --script script                                   Load a capture session configuration script from a file
root@am62xx-evm:~# cam -c1 --stream width=1296,height=972,pixelformat= SBGGR10 -C20
Option pixelformat requires an argument
Can't parse key=value argument for option --stream
Options:
  -c, --camera camera ...                               Specify which camera to operate on, by id or by index
  -h, --help                                            Display this help message
  -I, --info                                            Display information about stream(s)
  -l, --list                                            List all cameras
      --list-controls                                   List cameras controls
  -p, --list-properties                                 List cameras properties
  -m, --monitor                                         Monitor for hotplug and unplug camera events

Options valid in the context of --camera:
  -C, --capture[=count]                                 Capture until interrupted by user or until <count> frames captured
  -D, --display[=connector]                             Display viewfinder through DRM/KMS on specified connector
  -F, --file[=filename]                                 Write captured frames to disk
                                                        If the file name ends with a '/', it sets the directory in which
                                                        to write files, using the default file name. Otherwise it sets the
                                                        full file path and name. The first '#' character in the file name
                                                        is expanded to the camera index, stream name and frame sequence number.
                                                        The default file name is 'frame-#.bin'.
  -s, --stream key=value[,key=value,...] ...            Set configuration of a camera stream
          colorspace=string                             Color space
          height=integer                                Height in pixels
          pixelformat=string                            Pixel format name
          role=string                                   Role for the stream (viewfinder, video, still, raw)
          width=integer                                 Width in pixels
      --strict-formats                                  Do not allow requested stream format(s) to be adjusted
      --metadata                                        Print the metadata for completed requests
      --script script                                   Load a capture session configuration script from a file
root@am62xx-evm:~# ^C
root@am62xx-evm:~# cam -c1 --stream width=1296,height=972,pixelformat=SBGGR10 -C20
[2:17:21.006233446] [9919]  INFO Camera camera_manager.cpp:298 libcamera v0.0.5+dirty (2024-03-23T14:12:31+00:00)
[2:17:21.021617720] [9920]  WARN CameraSensor camera_sensor.cpp:244 'ov5647 4-0036': Recommended V4L2 control 0x009a0922 not supported
[2:17:21.021763627] [9920]  WARN CameraSensor camera_sensor.cpp:311[ 8241.146240] v4l2_get_link_freq: Link frequency estimated using pixel rate: result might be inaccurate
 'ov5647 4-0036': The sensor kernel driver needs to b[ 8241.156253] v4l2_get_link_freq: Consider implementing support for V4L2_CID_LINK_FREQ in the transmitter driver
e fixed
[2:17:21.021792842] [9920]  WARN CameraSensor camera_sensor.cpp:313 'ov5647 4-0036': See Documentation/sensor_driver_requirements.rst in the libcamera sources for more information
[2:17:21.023737081] [9920]  WARN CameraSensor camera_sensor.cpp:459 'ov5647 4-0036': Failed to retrieve the camera location
Using camera /base/bus@f0000/i2c@20020000/i2c-switch@71/i2c@1/camera@36 as cam0
[2:17:21.027388201] [9919]  INFO Camera camera.cpp:1028 configuring streams: (0) 1296x972-SBGGR10
cam0: Capture 20 frames
^CExiting
root@am62xx-evm:~# cam -c1 --stream width=1296,height=972,pixelformat=SBGGR10 -C20 -F#.uyvy
[2:19:11.325540687] [10123]  INFO Camera camera_manager.cpp:298 libcamera v0.0.5+dirty (2024-03-23T14:12:31+00:00)
[2:19:11.337549013] [10124]  WARN CameraSensor camera_sensor.cpp:244 'ov5647 4-0036': Recommended V4L2 control 0x009a0922 not supported
[2:19:11.337674068] [10124]  WARN CameraSensor camera_sensor.cpp:3[ 8351.457930] v4l2_get_link_freq: Link frequency estimated using pixel rate: result might be inaccurate
11 'ov5647 4-0036': The sensor kernel driver needs to[ 8351.471202] v4l2_get_link_freq: Consider implementing support for V4L2_CID_LINK_FREQ in the transmitter driver
 be fixed
[2:19:11.337701764] [10124]  WARN CameraSensor camera_sensor.cpp:313 'ov5647 4-0036': See Documentation/sensor_driver_requirements.rst in the libcamera sources for more information
[2:19:11.339321179] [10124]  WARN CameraSensor camera_sensor.cpp:459 'ov5647 4-0036': Failed to retrieve the camera location
Using camera /base/bus@f0000/i2c@20020000/i2c-switch@71/i2c@1/camera@36 as cam0
[2:19:11.342717457] [10123]  INFO Camera camera.cpp:1028 configuring streams: (0) 1296x972-SBGGR10
cam0: Capture 20 frames
^CExiting
root@am62xx-evm:~# ls *.uyvy
ls: cannot access '*.uyvy': No such file or directory
root@am62xx-evm:~#

  • Hi,

    The cis-bridge in your media pipe has different format to the sensor. Please configure it to be the same format as the sensor.

    media-ctl --set-v4l2 '"cdns_csi2rx.30101000.csi-bridge":0 [fmt:SBGGR10_1X10/640x480 field:none colorspace:srgb xfer:srgb ycbcr:601 quantization:lim-range]]'

    Then you can use yavta to capture the images from the sensor, as documented here: https://software-dl.ti.com/processor-sdk-linux/esd/AM62AX/09_02_00/exports/docs/linux/Foundational_Components/Kernel/Kernel_Drivers/Camera/CSI2RX.html#utilities-to-interact-with-the-driver.

    Regards,

    Jianzhong

  • Hi,

    I have tried to capture the image but not able to capture what can be the problem ?

    root@am62xx-evm:~# media-ctl --set-v4l2 '"cdns_csi2rx.30101000.csi-bridge":0 [fmt:SBGGR10_1X10/640x480 field:none colorspace:srgb xfer:srgb ycbcr:601 quantization:lim-range]'
    root@am62xx-evm:~# media-ctl --set-v4l2 '"ov5647 4-0036":0 [fmt:SBGGR10_1X10/640x480 field:none colorspace:srgb xfer:srgb ycbcr:601 quantization:lim-range]'
    root@am62xx-evm:~# yavta -c -Fcapture -s 640x480 -f UYVY /dev/video0
    Device /dev/video0 opened.
    Device `j721e-csi2rx' on `platform:30102000.ticsi2rx' (driver 'j721e-csi2rx') supports video, capture, without mplanes.
    Video[ 5319.337288] v4l2_get_link_freq: Link frequency estimated using pixel rate: result might be inaccurate
     format set: UYVY (59565955) 640x480 (stride 1280) field none bu[ 5319.348495] v4l2_get_link_freq: Consider implementing support for V4L2_CID_LINK_FREQ in the transmitter driver
    ffer size 614400
    Video format: UYVY (59565955) 640x480 (stride 1280) field none buffer size 614400
    8 buffers requested.
    length: 614400 offset: 0 timestamp type/source: mono/EoF
    Buffer 0/0 mapped at address 0xffff9117a000.
    length: 614400 offset: 614400 timestamp type/source: mono/EoF
    Buffer 1/0 mapped at address 0xffff910e4000.
    length: 614400 offset: 1228800 timestamp type/source: mono/EoF
    Buffer 2/0 mapped at address 0xffff9104e000.
    length: 614400 offset: 1843200 timestamp type/source: mono/EoF
    Buffer 3/0 mapped at address 0xffff90fb8000.
    length: 614400 offset: 2457600 timestamp type/source: mono/EoF
    Buffer 4/0 mapped at address 0xffff90f22000.
    length: 614400 offset: 3072000 timestamp type/source: mono/EoF
    Buffer 5/0 mapped at address 0xffff90e8c000.
    length: 614400 offset: 3686400 timestamp type/source: mono/EoF
    Buffer 6/0 mapped at address 0xffff90df6000.
    length: 614400 offset: 4300800 timestamp type/source: mono/EoF
    Buffer 7/0 mapped at address 0xffff90d60000.
    ^C
    root@am62xx-evm:~# media-ctl --print-dot | dot -Tpng > graph.png
    -sh: dot: command not found
    root@am62xx-evm:~#
    Regards,

    Dnyaneshwar

  • also i am not able to see the output of lsmod | grep ov5647 

    what can be the issue ? 

    root@am62xx-evm:~# lsmod | grep ov5647
    root@am62xx-evm:~# dmesg | grep ov5647
    [    1.796612] ov5647 4-0036: Consider updating driver ov5647 to match on endpoi                                                                             nts
    root@am62xx-evm:~#
    

  • also i am not able to see the 

    Display the supported frame rates for a specific format and frame size ?

    Display the supported frame rates for a specific format and frame size:
    
    # v4l2-ctl -d /dev/v4l-subdev2 --list-subdev-frameintervals pad=0,width=640,height=480,code=0x2006
    ioctl: VIDIOC_SUBDEV_ENUM_FRAME_INTERVAL (pad=0)
  • I have tried to capture the image but not able to capture what can be the problem ?

    I see the following message:

    Video[ 5319.337288] v4l2_get_link_freq: Link frequency estimated using pixel rate: result might be inaccurate
    format set: UYVY (59565955) 640x480 (stride 1280) field none bu[ 5319.348495] v4l2_get_link_freq: Consider implementing support for V4L2_CID_LINK_FREQ in the transmitter driver

    Please try to specify the link frequency in the device tree overlay.

    also i am not able to see the output of lsmod | grep ov5647

    Not sure. If ov5647 was not loaded, you wouldn't be able to see anything from media-ctl -p.

    Display the supported frame rates for a specific format and frame size ?

    What does "v4l2-ctl -d /dev/v4l-subdevX --list-subdev-mbus-codes pad=0" show?

  • Please try to specify the link frequency in the device tree overlay.

    About link frequency in the device tree overlay here you can see my dts file :- 

    // SPDX-License-Identifier: GPL-2.0
    /*
     * IMX219 (RPi v2) Camera Module
     * Copyright (C) 2023 Texas Instruments Incorporated - https://www.ti.com/
     */
    
    /dts-v1/;
    /plugin/;
    
    #include <dt-bindings/gpio/gpio.h>
    
    &{/} {
    	clk_ov5647_fixed: ov5647-xclk {
    		compatible = "fixed-clock";
    		#clock-cells = <0>;
    		clock-frequency = <25000000>;
    	};
    };
    
    &main_i2c2 {
    	#address-cells = <1>;
    	#size-cells = <0>;
    	status = "okay";
    
    	i2c-switch@71 {
    		compatible = "nxp,pca9543";
    		#address-cells = <1>;
    		#size-cells = <0>;
    		reg = <0x71>;
    
    		/* CAM port */
    		i2c@1 {
    			#address-cells = <1>;
    			#size-cells = <0>;
    			reg = <1>;
    
    			ov5640: camera@36 {
    				compatible = "ovti,ov5647";
    				reg = <0x36>;
    
    				clocks = <&clk_ov5647_fixed>;
    				clock-names = "xclk";
    
    				reset-gpios = <&exp1 13 GPIO_ACTIVE_HIGH>;
    
    				port {
    					csi2_cam0: endpoint {
    						remote-endpoint = <&csi2rx0_in_sensor>;
    						link-frequencies = /bits/ 64 <456000000>;
    						clock-lanes = <0>;
    						data-lanes = <1 2>;
    					};
    				};
    			};
    		};
    	};
    };
    
    &csi0_port0 {
    	status = "okay";
    
    	csi2rx0_in_sensor: endpoint {
    		remote-endpoint = <&csi2_cam0>;
    		bus-type = <4>; /* CSI2 DPHY. */
    		clock-lanes = <0>;
    		data-lanes = <1 2>;
    	};
    };
    

    in above dts file you can see i have set linking frequency how can i know that it is compatible or not ?

  • Not sure. If ov5647 was not loaded, you wouldn't be able to see anything from media-ctl -p.

    I can see the same output as previous one :- 

    root@am62xx-evm:~# media-ctl -p
    Media controller API version 6.1.80
    
    Media device information
    ------------------------
    driver          j721e-csi2rx
    model           TI-CSI2RX
    serial
    bus info        platform:30102000.ticsi2rx
    hw revision     0x1
    driver version  6.1.80
    
    Device topology
    - entity 1: 30102000.ticsi2rx (5 pads, 5 links, 1 route)
                type V4L2 subdev subtype Unknown flags 0
                device node name /dev/v4l-subdev0
            routes:
                    0/0 -> 1/0 [ACTIVE]
            pad0: Sink
                    [stream:0 fmt:UYVY8_1X16/640x480 field:none colorspace:srgb xfer:srgb ycbcr:601 quantization:lim-range]
                    <- "cdns_csi2rx.30101000.csi-bridge":1 [ENABLED,IMMUTABLE]
            pad1: Source
                    [stream:0 fmt:UYVY8_1X16/640x480 field:none colorspace:srgb xfer:srgb ycbcr:601 quantization:lim-range]
                    -> "30102000.ticsi2rx context 0":0 [ENABLED,IMMUTABLE]
            pad2: Source
                    -> "30102000.ticsi2rx context 1":0 [ENABLED,IMMUTABLE]
            pad3: Source
                    -> "30102000.ticsi2rx context 2":0 [ENABLED,IMMUTABLE]
            pad4: Source
                    -> "30102000.ticsi2rx context 3":0 [ENABLED,IMMUTABLE]
    
    - entity 7: cdns_csi2rx.30101000.csi-bridge (5 pads, 2 links, 1 route)
                type V4L2 subdev subtype Unknown flags 0
                device node name /dev/v4l-subdev1
            routes:
                    0/0 -> 1/0 [ACTIVE]
            pad0: Sink
                    [stream:0 fmt:UYVY8_1X16/640x480 field:none colorspace:srgb xfer:srgb ycbcr:601 quantization:lim-range]
                    <- "ov5647 4-0036":0 [ENABLED,IMMUTABLE]
            pad1: Source
                    [stream:0 fmt:UYVY8_1X16/640x480 field:none colorspace:srgb xfer:srgb ycbcr:601 quantization:lim-range]
                    -> "30102000.ticsi2rx":0 [ENABLED,IMMUTABLE]
            pad2: Source
            pad3: Source
            pad4: Source
    
    - entity 13: ov5647 4-0036 (1 pad, 1 link, 0 route)
                 type V4L2 subdev subtype Sensor flags 0
                 device node name /dev/v4l-subdev2
            pad0: Source
                    [stream:0 fmt:SBGGR10_1X10/640x480 field:none colorspace:srgb
                     crop.bounds:(16,16)/2592x1944
                     crop:(32,16)/2560x1920]
                    -> "cdns_csi2rx.30101000.csi-bridge":0 [ENABLED,IMMUTABLE]
    
    - entity 19: 30102000.ticsi2rx context 0 (1 pad, 1 link, 0 route)
                 type Node subtype V4L flags 0
                 device node name /dev/video0
            pad0: Sink
                    <- "30102000.ticsi2rx":1 [ENABLED,IMMUTABLE]
    
    - entity 25: 30102000.ticsi2rx context 1 (1 pad, 1 link, 0 route)
                 type Node subtype V4L flags 0
                 device node name /dev/video1
            pad0: Sink
                    <- "30102000.ticsi2rx":2 [ENABLED,IMMUTABLE]
    
    - entity 31: 30102000.ticsi2rx context 2 (1 pad, 1 link, 0 route)
                 type Node subtype V4L flags 0
                 device node name /dev/video2
            pad0: Sink
                    <- "30102000.ticsi2rx":3 [ENABLED,IMMUTABLE]
    
    - entity 37: 30102000.ticsi2rx context 3 (1 pad, 1 link, 0 route)
                 type Node subtype V4L flags 0
                 device node name /dev/video3
            pad0: Sink
                    <- "30102000.ticsi2rx":4 [ENABLED,IMMUTABLE]

  • What does "v4l2-ctl -d /dev/v4l-subdevX --list-subdev-mbus-codes pad=0" show?

    About this one i will reply on monday 

  • About this one i will reply on monday 

    Hello,

    I have tried your command you can see below:- 

    root@am62xx-evm:~# v4l2-ctl -d /dev/v4l-subdev2 --list-subdev-mbus-codes pad=0
    ioctl: VIDIOC_SUBDEV_ENUM_MBUS_CODE (pad=0,stream=0)
    	0x3007: MEDIA_BUS_FMT_SBGGR10_1X10
    root@am62xx-evm:~# yavta -c -Fcapture -s 640x480 -f SBGGR10 /dev/v4l-subdev2
    Device /dev/v4l-subdev2 opened.
    Unable to set format: Inappropriate ioctl for device (25).
    root@am62xx-evm:~# yavta -s 640x480 -f SBGGR10 /dev/v4l-subdev2 -c100
    Device /dev/v4l-subdev2 opened.
    Unable to set format: Inappropriate ioctl for device (25).

  • Hello,

    Just checked the output of dmesg i can able to see this message in it :- ov5647 4-0036: Consider updating driver ov5647 to match on endpoints

    but sdk version comes with already ov5647.c drivers and i have not updated it .

    In this thread you have mentioned to update the drivers :- https://github.com/torvalds/linux/blob/master/drivers/media/i2c/ov5647.c

    Access Denied
    You don't have permission to access "">e2e.ti.com/.../configure on this server.

    due to this error i am uploading the dmesg output here:- 

    root@am62xx-evm:~# dmesg
    [ 0.000000] Booting Linux on physical CPU 0x0000000000 [0x410fd034]
    [ 0.000000] Linux version 6.1.80-dirty (root@renu-Lenovo) (aarch64-none-linux-gnu-gcc (Arm GNU Toolchain 11.3.Rel1) 11.3.1 20220712, GNU ld (Arm GNU Toolchain 11.3.Rel1) 2.38.20220708) #2 SMP PREEMPT Fri May 17 12:40:25 IST 2024
    [ 0.000000] Machine model: Texas Instruments AM625 SK
    [ 0.000000] earlycon: ns16550a0 at MMIO32 0x0000000002800000 (options '')
    [ 0.000000] printk: bootconsole [ns16550a0] enabled
    [ 0.000000] efi: UEFI not found.
    [ 0.000000] Reserved memory: created CMA memory pool at 0x00000000f8000000, size 128 MiB
    [ 0.000000] OF: reserved mem: initialized node linux,cma, compatible id shared-dma-pool
    [ 0.000000] Reserved memory: created DMA memory pool at 0x000000009c800000, size 3 MiB
    [ 0.000000] OF: reserved mem: initialized node ipc-memories@9c800000, compatible id shared-dma-pool
    [ 0.000000] Reserved memory: created DMA memory pool at 0x000000009cb00000, size 1 MiB
    [ 0.000000] OF: reserved mem: initialized node m4f-dma-memory@9cb00000, compatible id shared-dma-pool
    [ 0.000000] Reserved memory: created DMA memory pool at 0x000000009cc00000, size 14 MiB
    [ 0.000000] OF: reserved mem: initialized node m4f-memory@9cc00000, compatible id shared-dma-pool
    [ 0.000000] Reserved memory: created DMA memory pool at 0x000000009da00000, size 1 MiB
    [ 0.000000] OF: reserved mem: initialized node r5f-dma-memory@9da00000, compatible id shared-dma-pool
    [ 0.000000] Reserved memory: created DMA memory pool at 0x000000009db00000, size 12 MiB
    [ 0.000000] OF: reserved mem: initialized node r5f-memory@9db00000, compatible id shared-dma-pool
    [ 0.000000] NUMA: No NUMA configuration found
    [ 0.000000] NUMA: Faking a node at [mem 0x0000000080000000-0x00000000ffffffff]
    [ 0.000000] NUMA: NODE_DATA [mem 0xf7bd4a00-0xf7bd6fff]
    [ 0.000000] Zone ranges:
    [ 0.000000] DMA [mem 0x0000000080000000-0x00000000ffffffff]
    [ 0.000000] DMA32 empty
    [ 0.000000] Normal empty
    [ 0.000000] Movable zone start for each node
    [ 0.000000] Early memory node ranges
    [ 0.000000] node 0: [mem 0x0000000080000000-0x000000009c7fffff]
    [ 0.000000] node 0: [mem 0x000000009c800000-0x000000009e6fffff]
    [ 0.000000] node 0: [mem 0x000000009e700000-0x000000009e77ffff]
    [ 0.000000] node 0: [mem 0x000000009e780000-0x000000009fffffff]
    [ 0.000000] node 0: [mem 0x00000000a0000000-0x00000000ffffffff]
    [ 0.000000] Initmem setup node 0 [mem 0x0000000080000000-0x00000000ffffffff]
    [ 0.000000] psci: probing for conduit method from DT.
    [ 0.000000] psci: PSCIv1.1 detected in firmware.
    [ 0.000000] psci: Using standard PSCI v0.2 function IDs
    [ 0.000000] psci: Trusted OS migration not required
    [ 0.000000] psci: SMC Calling Convention v1.2
    [ 0.000000] percpu: Embedded 21 pages/cpu s48040 r8192 d29784 u86016
    [ 0.000000] pcpu-alloc: s48040 r8192 d29784 u86016 alloc=21*4096
    [ 0.000000] pcpu-alloc: [0] 0 [0] 1 [0] 2 [0] 3
    [ 0.000000] Detected VIPT I-cache on CPU0
    [ 0.000000] CPU features: detected: GIC system register CPU interface
    [ 0.000000] CPU features: detected: ARM erratum 845719
    [ 0.000000] alternatives: applying boot alternatives
    [ 0.000000] Fallback order for Node 0: 0
    [ 0.000000] Built 1 zonelists, mobility grouping on. Total pages: 516096
    [ 0.000000] Policy zone: DMA
    [ 0.000000] Kernel command line: console=ttyS2,115200n8 earlycon=ns16550a,mmio32,0x02800000 root=PARTUUID=0a1bf283-02 rw rootfstype=ext4 rootwait
    [ 0.000000] Dentry cache hash table entries: 262144 (order: 9, 2097152 bytes, linear)
    [ 0.000000] Inode-cache hash table entries: 131072 (order: 8, 1048576 bytes, linear)
    [ 0.000000] mem auto-init: stack:off, heap alloc:off, heap free:off
    [ 0.000000] Memory: 1828492K/2097152K available (17216K kernel code, 3802K rwdata, 9684K rodata, 7680K init, 630K bss, 137588K reserved, 131072K cma-reserved)
    [ 0.000000] SLUB: HWalign=64, Order=0-3, MinObjects=0, CPUs=4, Nodes=1
    [ 0.000000] rcu: Preemptible hierarchical RCU implementation.
    [ 0.000000] rcu: RCU event tracing is enabled.
    [ 0.000000] rcu: RCU restricting CPUs from NR_CPUS=256 to nr_cpu_ids=4.
    [ 0.000000] Trampoline variant of Tasks RCU enabled.
    [ 0.000000] Tracing variant of Tasks RCU enabled.
    [ 0.000000] rcu: RCU calculated value of scheduler-enlistment delay is 25 jiffies.
    [ 0.000000] rcu: Adjusting geometry for rcu_fanout_leaf=16, nr_cpu_ids=4
    [ 0.000000] NR_IRQS: 64, nr_irqs: 64, preallocated irqs: 0
    [ 0.000000] GICv3: GIC: Using split EOI/Deactivate mode
    [ 0.000000] GICv3: 256 SPIs implemented
    [ 0.000000] GICv3: 0 Extended SPIs implemented
    [ 0.000000] Root IRQ handler: gic_handle_irq
    [ 0.000000] GICv3: GICv3 features: 16 PPIs
    [ 0.000000] GICv3: CPU0: found redistributor 0 region 0:0x0000000001880000
    [ 0.000000] ITS [mem 0x01820000-0x0182ffff]
    [ 0.000000] GIC: enabling workaround for ITS: Socionext Synquacer pre-ITS
    [ 0.000000] ITS@0x0000000001820000: Devices Table too large, reduce ids 20->19
    [ 0.000000] ITS@0x0000000001820000: allocated 524288 Devices @80800000 (flat, esz 8, psz 64K, shr 0)
    [ 0.000000] ITS: using cache flushing for cmd queue
    [ 0.000000] GICv3: using LPI property table @0x0000000080040000
    [ 0.000000] GIC: using cache flushing for LPI property table
    [ 0.000000] GICv3: CPU0: using allocated LPI pending table @0x0000000080050000
    [ 0.000000] rcu: srcu_init: Setting srcu_struct sizes based on contention.
    [ 0.000000] arch_timer: cp15 timer(s) running at 200.00MHz (phys).
    [ 0.000000] clocksource: arch_sys_counter: mask: 0x3ffffffffffffff max_cycles: 0x2e2049d3e8, max_idle_ns: 440795210634 ns
    [ 0.000001] sched_clock: 58 bits at 200MHz, resolution 5ns, wraps every 4398046511102ns
    [ 0.009715] Console: colour dummy device 80x25
    [ 0.014354] Calibrating delay loop (skipped), value calculated using timer frequency.. 400.00 BogoMIPS (lpj=800000)
    [ 0.025039] pid_max: default: 32768 minimum: 301
    [ 0.029817] LSM: Security Framework initializing
    [ 0.034662] Mount-cache hash table entries: 4096 (order: 3, 32768 bytes, linear)
    [ 0.042246] Mountpoint-cache hash table entries: 4096 (order: 3, 32768 bytes, linear)
    [ 0.052118] cblist_init_generic: Setting adjustable number of callback queues.
    [ 0.059567] cblist_init_generic: Setting shift to 2 and lim to 1.
    [ 0.065867] cblist_init_generic: Setting adjustable number of callback queues.
    [ 0.073264] cblist_init_generic: Setting shift to 2 and lim to 1.
    [ 0.079682] rcu: Hierarchical SRCU implementation.
    [ 0.084590] rcu: Max phase no-delay instances is 1000.
    [ 0.090187] Platform MSI: msi-controller@1820000 domain created
    [ 0.096506] PCI/MSI: /bus@f0000/interrupt-controller@1800000/msi-controller@1820000 domain created
    [ 0.105783] fsl-mc MSI: msi-controller@1820000 domain created
    [ 0.113791] EFI services will not be available.
    [ 0.118761] smp: Bringing up secondary CPUs ...
    [ 0.132119] Detected VIPT I-cache on CPU1
    [ 0.132237] GICv3: CPU1: found redistributor 1 region 0:0x00000000018a0000
    [ 0.132256] GICv3: CPU1: using allocated LPI pending table @0x0000000080060000
    [ 0.132310] CPU1: Booted secondary processor 0x0000000001 [0x410fd034]
    [ 0.141062] Detected VIPT I-cache on CPU2
    [ 0.141149] GICv3: CPU2: found redistributor 2 region 0:0x00000000018c0000
    [ 0.141163] GICv3: CPU2: using allocated LPI pending table @0x0000000080070000
    [ 0.141196] CPU2: Booted secondary processor 0x0000000002 [0x410fd034]
    [ 0.149865] Detected VIPT I-cache on CPU3
    [ 0.149955] GICv3: CPU3: found redistributor 3 region 0:0x00000000018e0000
    [ 0.149968] GICv3: CPU3: using allocated LPI pending table @0x0000000080080000
    [ 0.149999] CPU3: Booted secondary processor 0x0000000003 [0x410fd034]
    [ 0.150078] smp: Brought up 1 node, 4 CPUs
    [ 0.229791] SMP: Total of 4 processors activated.
    [ 0.234604] CPU features: detected: 32-bit EL0 Support
    [ 0.239868] CPU features: detected: 32-bit EL1 Support
    [ 0.245124] CPU features: detected: CRC32 instructions
    [ 0.250451] CPU: All CPU(s) started at EL2
    [ 0.254662] alternatives: applying system-wide alternatives
    [ 0.262809] devtmpfs: initialized
    [ 0.275035] clocksource: jiffies: mask: 0xffffffff max_cycles: 0xffffffff, max_idle_ns: 7645041785100000 ns
    [ 0.285050] futex hash table entries: 1024 (order: 4, 65536 bytes, linear)
    [ 0.297124] pinctrl core: initialized pinctrl subsystem
    [ 0.304865] DMI not present or invalid.
    [ 0.309554] NET: Registered PF_NETLINK/PF_ROUTE protocol family
    [ 0.316832] DMA: preallocated 256 KiB GFP_KERNEL pool for atomic allocations
    [ 0.324331] DMA: preallocated 256 KiB GFP_KERNEL|GFP_DMA pool for atomic allocations
    [ 0.332393] DMA: preallocated 256 KiB GFP_KERNEL|GFP_DMA32 pool for atomic allocations
    [ 0.340574] audit: initializing netlink subsys (disabled)
    [ 0.346281] audit: type=2000 audit(0.228:1): state=initialized audit_enabled=0 res=1
    [ 0.347711] thermal_sys: Registered thermal governor 'step_wise'
    [ 0.354226] thermal_sys: Registered thermal governor 'power_allocator'
    [ 0.360445] cpuidle: using governor menu
    [ 0.371376] hw-breakpoint: found 6 breakpoint and 4 watchpoint registers.
    [ 0.378419] ASID allocator initialised with 65536 entries
    [ 0.385826] Serial: AMBA PL011 UART driver
    [ 0.408050] platform a40000.pinctrl: Fixed dependency cycle(s) with /bus@f0000/pinctrl@a40000/cpsw-cpts
    [ 0.424378] KASLR disabled due to lack of seed
    [ 0.438028] HugeTLB: registered 1.00 GiB page size, pre-allocated 0 pages
    [ 0.445008] HugeTLB: 0 KiB vmemmap can be freed for a 1.00 GiB page
    [ 0.451447] HugeTLB: registered 32.0 MiB page size, pre-allocated 0 pages
    [ 0.458388] HugeTLB: 0 KiB vmemmap can be freed for a 32.0 MiB page
    [ 0.464796] HugeTLB: registered 2.00 MiB page size, pre-allocated 0 pages
    [ 0.471735] HugeTLB: 0 KiB vmemmap can be freed for a 2.00 MiB page
    [ 0.478143] HugeTLB: registered 64.0 KiB page size, pre-allocated 0 pages
    [ 0.485081] HugeTLB: 0 KiB vmemmap can be freed for a 64.0 KiB page
    [ 0.493505] ACPI: Interpreter disabled.
    [ 0.499531] k3-chipinfo 43000014.chipid: Family:AM62X rev:SR1.0 JTAGID[0x0bb7e02f] Detected
    [ 0.510315] iommu: Default domain type: Translated
    [ 0.515338] iommu: DMA domain TLB invalidation policy: strict mode
    [ 0.522046] SCSI subsystem initialized
    [ 0.526044] libata version 3.00 loaded.
    [ 0.526305] usbcore: registered new interface driver usbfs
    [ 0.531959] usbcore: registered new interface driver hub
    [ 0.537415] usbcore: registered new device driver usb
    [ 0.543895] mc: Linux media interface: v0.10
    [ 0.548316] videodev: Linux video capture interface: v2.00
    [ 0.553964] pps_core: LinuxPPS API ver. 1 registered
    [ 0.559040] pps_core: Software ver. 5.3.6 - Copyright 2005-2007 Rodolfo Giometti <giometti@linux.it>
    [ 0.568392] PTP clock support registered
    [ 0.572546] EDAC MC: Ver: 3.0.0
    [ 0.577665] omap-mailbox 29000000.mailbox: omap mailbox rev 0x66fc9100
    [ 0.585167] FPGA manager framework
    [ 0.588757] Advanced Linux Sound Architecture Driver Initialized.
    [ 0.595959] vgaarb: loaded
    [ 0.599209] clocksource: Switched to clocksource arch_sys_counter
    [ 0.605706] VFS: Disk quotas dquot_6.6.0
    [ 0.609765] VFS: Dquot-cache hash table entries: 512 (order 0, 4096 bytes)
    [ 0.616994] pnp: PnP ACPI: disabled
    [ 0.626374] NET: Registered PF_INET protocol family
    [ 0.631675] IP idents hash table entries: 32768 (order: 6, 262144 bytes, linear)
    [ 0.640945] tcp_listen_portaddr_hash hash table entries: 1024 (order: 2, 16384 bytes, linear)
    [ 0.649759] Table-perturb hash table entries: 65536 (order: 6, 262144 bytes, linear)
    [ 0.657699] TCP established hash table entries: 16384 (order: 5, 131072 bytes, linear)
    [ 0.665914] TCP bind hash table entries: 16384 (order: 7, 524288 bytes, linear)
    [ 0.673913] TCP: Hash tables configured (established 16384 bind 16384)
    [ 0.680832] UDP hash table entries: 1024 (order: 3, 32768 bytes, linear)
    [ 0.687755] UDP-Lite hash table entries: 1024 (order: 3, 32768 bytes, linear)
    [ 0.695292] NET: Registered PF_UNIX/PF_LOCAL protocol family
    [ 0.701581] RPC: Registered named UNIX socket transport module.
    [ 0.707663] RPC: Registered udp transport module.
    [ 0.712473] RPC: Registered tcp transport module.
    [ 0.717282] RPC: Registered tcp NFSv4.1 backchannel transport module.
    [ 0.723873] NET: Registered PF_XDP protocol family
    [ 0.728786] PCI: CLS 0 bytes, default 64
    [ 0.733700] hw perfevents: enabled with armv8_cortex_a53 PMU driver, 7 counters available
    [ 0.742825] kvm [1]: IPA Size Limit: 40 bits
    [ 0.748841] kvm [1]: vgic-v2@100010000
    [ 0.752693] kvm [1]: GIC system register CPU interface enabled
    [ 0.758761] kvm [1]: vgic interrupt IRQ9
    [ 0.762858] kvm [1]: Hyp mode initialized successfully
    [ 0.769654] Initialise system trusted keyrings
    [ 0.774528] workingset: timestamp_bits=42 max_order=19 bucket_order=0
    [ 0.787369] squashfs: version 4.0 (2009/01/31) Phillip Lougher
    [ 0.793985] NFS: Registering the id_resolver key type
    [ 0.799214] Key type id_resolver registered
    [ 0.803491] Key type id_legacy registered
    [ 0.807658] nfs4filelayout_init: NFSv4 File Layout Driver Registering...
    [ 0.814514] nfs4flexfilelayout_init: NFSv4 Flexfile Layout Driver Registering...
    [ 0.822293] 9p: Installing v9fs 9p2000 file system support
    [ 0.862389] Key type asymmetric registered
    [ 0.866594] Asymmetric key parser 'x509' registered
    [ 0.871641] Block layer SCSI generic (bsg) driver version 0.4 loaded (major 243)
    [ 0.879381] io scheduler mq-deadline registered
    [ 0.884021] io scheduler kyber registered
    [ 0.898100] pinctrl-single 4084000.pinctrl: 34 pins, size 136
    [ 0.904646] pinctrl-single f4000.pinctrl: 171 pins, size 684
    [ 0.912120] pinctrl-single a40000.pinctrl: 512 pins, size 2048
    [ 0.927158] EINJ: ACPI disabled.
    [ 0.957075] Serial: 8250/16550 driver, 12 ports, IRQ sharing enabled
    [ 0.968976] SuperH (H)SCI(F) driver initialized
    [ 0.974366] msm_serial: driver initialized
    [ 0.986888] loop: module loaded
    [ 0.992210] megasas: 07.719.03.00-rc1
    [ 1.004255] tun: Universal TUN/TAP device driver, 1.6
    [ 1.010763] thunder_xcv, ver 1.0
    [ 1.014128] thunder_bgx, ver 1.0
    [ 1.017463] nicpf, ver 1.0
    [ 1.021926] hns3: Hisilicon Ethernet Network Driver for Hip08 Family - version
    [ 1.029331] hns3: Copyright (c) 2017 Huawei Corporation.
    [ 1.034931] hclge is initializing
    [ 1.038366] e1000: Intel(R) PRO/1000 Network Driver
    [ 1.043357] e1000: Copyright (c) 1999-2006 Intel Corporation.
    [ 1.049273] e1000e: Intel(R) PRO/1000 Network Driver
    [ 1.054350] e1000e: Copyright(c) 1999 - 2015 Intel Corporation.
    [ 1.060445] igb: Intel(R) Gigabit Ethernet Network Driver
    [ 1.065966] igb: Copyright (c) 2007-2014 Intel Corporation.
    [ 1.071698] igbvf: Intel(R) Gigabit Virtual Function Network Driver
    [ 1.078107] igbvf: Copyright (c) 2009 - 2012 Intel Corporation.
    [ 1.084794] sky2: driver version 1.30
    [ 1.090282] VFIO - User Level meta-driver version: 0.3
    [ 1.098458] usbcore: registered new interface driver usb-storage
    [ 1.108390] i2c_dev: i2c /dev entries driver
    [ 1.124665] sdhci: Secure Digital Host Controller Interface driver
    [ 1.131049] sdhci: Copyright(c) Pierre Ossman
    [ 1.136753] Synopsys Designware Multimedia Card Interface Driver
    [ 1.144332] sdhci-pltfm: SDHCI platform and OF driver helper
    [ 1.153013] ledtrig-cpu: registered to indicate activity on CPUs
    [ 1.161500] SMCCC: SOC_ID: ARCH_SOC_ID not implemented, skipping ....
    [ 1.169024] usbcore: registered new interface driver usbhid
    [ 1.174759] usbhid: USB HID core driver
    [ 1.185301] optee: probing for conduit method.
    [ 1.189918] optee: revision 3.20 (2c20168b)
    [ 1.206598] optee: dynamic shared memory is enabled
    [ 1.216291] optee: initialized driver
    [ 1.224578] Initializing XFRM netlink socket
    [ 1.229019] NET: Registered PF_PACKET protocol family
    [ 1.234336] 9pnet: Installing 9P2000 support
    [ 1.238784] Key type dns_resolver registered
    [ 1.243694] registered taskstats version 1
    [ 1.247927] Loading compiled-in X.509 certificates
    [ 1.292972] ti-sci 44043000.system-controller: ABI: 3.1 (firmware rev 0x0008 '8.6.4--v08.06.04 (Chill Capybar')
    [ 1.396384] omap_i2c 20000000.i2c: bus 0 rev0.12 at 400 kHz
    [ 1.404434] omap_i2c 20010000.i2c: bus 1 rev0.12 at 100 kHz
    [ 1.435487] i2c i2c-2: Added multiplexed i2c bus 3
    [ 1.440834] i2c i2c-2: Added multiplexed i2c bus 4
    [ 1.445754] pca954x 2-0071: registered 2 multiplexed busses for I2C switch pca9543
    [ 1.453646] omap_i2c 20020000.i2c: bus 2 rev0.12 at 400 kHz
    [ 1.460204] ti-sci-intr bus@f0000:interrupt-controller@a00000: Interrupt Router 3 domain created
    [ 1.469861] ti-sci-inta 48000000.interrupt-controller: Interrupt Aggregator domain 28 created
    [ 1.491772] ti-udma 485c0100.dma-controller: Number of rings: 82
    [ 1.500096] ti-udma 485c0100.dma-controller: Channels: 48 (bchan: 18, tchan: 12, rchan: 18)
    [ 1.512466] ti-udma 485c0000.dma-controller: Number of rings: 150
    [ 1.522564] ti-udma 485c0000.dma-controller: Channels: 35 (tchan: 20, rchan: 15)
    [ 1.534502] printk: console [ttyS2] disabled
    [ 1.538970] 2800000.serial: ttyS2 at MMIO 0x2800000 (irq = 240, base_baud = 3000000) is a 8250
    [ 1.547857] printk: console [ttyS2] enabled
    [ 1.556314] printk: bootconsole [ns16550a0] disabled
    [ 1.571537] davinci_mdio 8000f00.mdio: Configuring MDIO in manual mode
    [ 1.615252] davinci_mdio 8000f00.mdio: davinci mdio revision 9.7, bus freq 1000000
    [ 1.625573] davinci_mdio 8000f00.mdio: phy[0]: device 8000f00.mdio:00, driver TI DP83867
    [ 1.633686] davinci_mdio 8000f00.mdio: phy[1]: device 8000f00.mdio:01, driver TI DP83867
    [ 1.641812] am65-cpsw-nuss 8000000.ethernet: initializing am65 cpsw nuss version 0x6BA01103, cpsw version 0x6BA81103 Ports: 3 quirks:00000006
    [ 1.654672] am65-cpsw-nuss 8000000.ethernet: initialized cpsw ale version 1.5
    [ 1.661799] am65-cpsw-nuss 8000000.ethernet: ALE Table size 512
    [ 1.668291] pps pps0: new PPS source ptp0
    [ 1.672614] am65-cpsw-nuss 8000000.ethernet: CPTS ver 0x4e8a010c, freq:500000000, add_val:1 pps:1
    [ 1.683052] am65-cpsw-nuss 8000000.ethernet: set new flow-id-base 19
    [ 1.700416] cdns-csi2rx 30101000.csi-bridge: Probed CSI2RX with 2/4 lanes, 4 streams, external D-PHY
    [ 1.720364] mmc0: CQHCI version 5.10
    [ 1.731867] pca953x 1-0022: supply vcc not found, using dummy regulator
    [ 1.738648] pca953x 1-0022: using AI
    [ 1.765600] mmc0: SDHCI controller on fa10000.mmc [fa10000.mmc] using ADMA 64-bit
    [ 1.796713] ov5647 4-0036: Consider updating driver ov5647 to match on endpoints
    [ 1.810647] spi-nor spi0.0: s28hs512t (65536 Kbytes)
    [ 1.815818] 7 fixed-partitions partitions found on MTD device fc40000.spi.0
    [ 1.822813] Creating 7 MTD partitions on "fc40000.spi.0":
    [ 1.828268] 0x000000000000-0x000000080000 : "ospi.tiboot3"
    [ 1.835121] 0x000000080000-0x000000280000 : "ospi.tispl"
    [ 1.841663] 0x000000280000-0x000000680000 : "ospi.u-boot"
    [ 1.848467] 0x000000680000-0x0000006c0000 : "ospi.env"
    [ 1.854895] 0x0000006c0000-0x000000700000 : "ospi.env.backup"
    [ 1.861774] 0x000000800000-0x000003fc0000 : "ospi.rootfs"
    [ 1.868464] 0x000003fc0000-0x000004000000 : "ospi.phypattern"
    [ 1.876913] mmc0: Command Queue Engine enabled
    [ 1.881465] mmc0: new HS200 MMC card at address 0001
    [ 1.887506] mmcblk0: mmc0:0001 S0J56X 14.8 GiB
    [ 1.896109] mmcblk0: p1 p2 p3 p4 p5 p6 p7 p8 p9 p10 p11 p12 p13 p14
    [ 1.901156] mmc1: CQHCI version 5.10
    [ 1.902989] debugfs: Directory 'pd:182' with parent 'pm_genpd' already present!
    [ 1.903786] mmc2: CQHCI version 5.10
    [ 1.918943] mmcblk0boot0: mmc0:0001 S0J56X 31.5 MiB
    [ 1.919121] debugfs: Directory 'pd:186' with parent 'pm_genpd' already present!
    [ 1.925205] mmcblk0boot1: mmc0:0001 S0J56X 31.5 MiB
    [ 1.937403] mmcblk0rpmb: mmc0:0001 S0J56X 4.00 MiB, chardev (510:0)
    [ 1.943297] mmc1: SDHCI controller on fa00000.mmc [fa00000.mmc] using ADMA 64-bit
    [ 1.943485] ALSA device list:
    [ 1.943492] No soundcards found.
    [ 1.949162] mmc2: SDHCI controller on fa20000.mmc [fa20000.mmc] using ADMA 64-bit
    [ 1.968603] Waiting for root device PARTUUID=0a1bf283-02...
    [ 1.970868] sdhci-am654 fa20000.mmc: card claims to support voltages below defined range
    [ 1.995295] mmc2: new high speed SDIO card at address 0001
    [ 2.029645] mmc1: new ultra high speed SDR104 SDHC card at address aaaa
    [ 2.037458] mmcblk1: mmc1:aaaa SC16G 14.8 GiB
    [ 2.047880] mmcblk1: p1 p2
    [ 2.257260] EXT4-fs (mmcblk1p2): recovery complete
    [ 2.263085] EXT4-fs (mmcblk1p2): mounted filesystem with ordered data mode. Quota mode: none.
    [ 2.271710] VFS: Mounted root (ext4 filesystem) on device 179:98.
    [ 2.281589] devtmpfs: mounted
    [ 2.290560] Freeing unused kernel memory: 7680K
    [ 2.295401] Run /sbin/init as init process
    [ 2.299562] with arguments:
    [ 2.299569] /sbin/init
    [ 2.299576] with environment:
    [ 2.299581] HOME=/
    [ 2.299587] TERM=linux
    [ 2.459682] systemd[1]: System time before build time, advancing clock.
    [ 2.578428] NET: Registered PF_INET6 protocol family
    [ 2.584974] Segment Routing with IPv6
    [ 2.588709] In-situ OAM (IOAM) with IPv6
    [ 2.621446] systemd[1]: systemd 250.5+ running in system mode (+PAM -AUDIT -SELINUX -APPARMOR +IMA -SMACK +SECCOMP -GCRYPT -GNUTLS -OPENSSL +ACL +BLKID -CURL -ELFUTILS -FIDO2 -IDN2 -IDN -IPTC +KMOD -LIBCRYPTSETUP +LIBFDISK -PCRE2 -PWQUALITY -P11KIT -QRENCODE -BZIP2 -LZ4 -XZ -ZLIB +ZSTD -BPF_FRAMEWORK -XKBCOMMON +UTMP +SYSVINIT default-hierarchy=hybrid)
    [ 2.653417] systemd[1]: Detected architecture arm64.
    [ 2.730163] systemd[1]: Hostname set to <am62xx-evm>.
    [ 2.833718] systemd-sysv-generator[162]: SysV service '/etc/init.d/thermal-zone-init' lacks a native systemd unit file. Automatically generating a unit file for compatibility. Please update package to include a native systemd unit file, in order to make it more safe and robust.
    [ 3.014228] systemd[1]: Configuration file /lib/systemd/system/ti-apps-launcher.service is marked executable. Please remove executable permission bits. Proceeding anyway.
    [ 3.046437] systemd[1]: Configuration file /lib/systemd/system/seva-launcher.service is marked executable. Please remove executable permission bits. Proceeding anyway.
    [ 3.127293] systemd[1]: /lib/systemd/system/bt-enable.service:9: Standard output type syslog is obsolete, automatically updating to journal. Please update your unit file, and consider removing the setting altogether.
    [ 3.192526] systemd[1]: /etc/systemd/system/sync-clocks.service:11: Standard output type syslog is obsolete, automatically updating to journal. Please update your unit file, and consider removing the setting altogether.
    [ 3.268975] systemd[1]: Queued start job for default target Graphical Interface.
    [ 3.341566] systemd[1]: Created slice Slice /system/getty.
    [ 3.366602] systemd[1]: Created slice Slice /system/modprobe.
    [ 3.390568] systemd[1]: Created slice Slice /system/serial-getty.
    [ 3.414289] systemd[1]: Created slice User and Session Slice.
    [ 3.441479] systemd[1]: Started Dispatch Password Requests to Console Directory Watch.
    [ 3.467639] systemd[1]: Started Forward Password Requests to Wall Directory Watch.
    [ 3.491998] systemd[1]: Reached target Path Units.
    [ 3.507529] systemd[1]: Reached target Remote File Systems.
    [ 3.527495] systemd[1]: Reached target Slice Units.
    [ 3.543587] systemd[1]: Reached target Swaps.
    [ 3.619113] systemd[1]: Listening on RPCbind Server Activation Socket.
    [ 3.643875] systemd[1]: Reached target RPC Port Mapper.
    [ 3.675649] systemd[1]: Listening on Process Core Dump Socket.
    [ 3.699822] systemd[1]: Listening on initctl Compatibility Named Pipe.
    [ 3.724213] systemd[1]: Listening on Journal Audit Socket.
    [ 3.747984] systemd[1]: Listening on Journal Socket (/dev/log).
    [ 3.772388] systemd[1]: Listening on Journal Socket.
    [ 3.788975] systemd[1]: Listening on Network Service Netlink Socket.
    [ 3.812789] systemd[1]: Listening on udev Control Socket.
    [ 3.836716] systemd[1]: Listening on udev Kernel Socket.
    [ 3.860861] systemd[1]: Listening on User Database Manager Socket.
    [ 3.911958] systemd[1]: Mounting Huge Pages File System...
    [ 3.934409] systemd[1]: Mounting POSIX Message Queue File System...
    [ 3.962971] systemd[1]: Mounting Kernel Debug File System...
    [ 3.980228] systemd[1]: Kernel Trace File System was skipped because of a failed condition check (ConditionPathExists=/sys/kernel/tracing).
    [ 4.001700] systemd[1]: Mounting Temporary Directory /tmp...
    [ 4.028719] systemd[1]: Starting Create List of Static Device Nodes...
    [ 4.058619] systemd[1]: Starting Load Kernel Module configfs...
    [ 4.096335] systemd[1]: Starting Load Kernel Module drm...
    [ 4.118925] systemd[1]: Starting Load Kernel Module fuse...
    [ 4.174982] fuse: init (API version 7.37)
    [ 4.200471] systemd[1]: Starting Start psplash boot splash screen...
    [ 4.248443] systemd[1]: Starting RPC Bind...
    [ 4.263817] systemd[1]: File System Check on Root Device was skipped because of a failed condition check (ConditionPathIsReadWrite=!/).
    [ 4.286191] systemd[1]: Starting Journal Service...
    [ 4.314792] systemd[1]: Starting Load Kernel Modules...
    [ 4.338907] systemd[1]: Starting Generate network units from Kernel command line...
    [ 4.369753] systemd[1]: Starting Remount Root and Kernel File Systems...
    [ 4.396628] EXT4-fs (mmcblk1p2): re-mounted. Quota mode: none.
    [ 4.402466] systemd[1]: Starting Coldplug All udev Devices...
    [ 4.430640] systemd[1]: Started RPC Bind.
    [ 4.444170] systemd[1]: Started Journal Service.
    [ 4.843880] systemd-journald[179]: Received client request to flush runtime journal.
    [ 5.104950] audit: type=1334 audit(1651167747.644:2): prog-id=5 op=LOAD
    [ 5.111762] audit: type=1334 audit(1651167747.652:3): prog-id=6 op=LOAD
    [ 5.796536] systemd-journald[179]: Oldest entry in /run/log/journal/4a852061e7ae485484601dbddf9df771/system.journal is older than the configured file retention duration (1month), suggesting rotation.
    [ 5.822120] systemd-journald[179]: /run/log/journal/4a852061e7ae485484601dbddf9df771/system.journal: Journal header limits reached or header out-of-date, rotating.
    [ 5.887271] random: crng init done
    [ 6.443786] Error: Driver 'cdns-mipi-dphy-rx' is already registered, aborting...
    [ 6.542301] Error: Driver 'cdns-mipi-dphy-rx' is already registered, aborting...
    [ 6.551565] mc: exports duplicate symbol __media_device_register (owned by kernel)
    [ 6.575436] audit: type=1334 audit(1715950528.562:4): prog-id=7 op=LOAD
    [ 6.583022] audit: type=1334 audit(1715950528.570:5): prog-id=8 op=LOAD
    [ 6.825989] platform 78000000.r5f: R5F core may have been powered on by a different host, programmed state (0) != actual state (1)
    [ 6.838948] rtc-ti-k3 2b1f0000.rtc: registered as rtc0
    [ 6.844416] rtc-ti-k3 2b1f0000.rtc: setting system clock to 1970-01-01T00:00:13 UTC (13)
    [ 6.851144] systemd-journald[179]: Time jumped backwards, rotating.
    [ 6.852770] platform 78000000.r5f: configured R5F for IPC-only mode
    [ 6.872578] mc: exports duplicate symbol __media_device_register (owned by kernel)
    [ 6.886958] platform 78000000.r5f: assigned reserved memory node r5f-dma-memory@9da00000
    [ 6.919768] remoteproc remoteproc0: 78000000.r5f is available
    [ 6.928214] remoteproc remoteproc0: attaching to 78000000.r5f
    [ 6.947536] mc: exports duplicate symbol __media_device_register (owned by kernel)
    [ 6.948608] platform 78000000.r5f: R5F core initialized in IPC-only mode
    [ 6.962338] rproc-virtio rproc-virtio.1.auto: assigned reserved memory node r5f-dma-memory@9da00000
    [ 7.060918] mc: exports duplicate symbol __media_device_register (owned by kernel)
    [ 7.163745] mc: exports duplicate symbol __media_device_register (owned by kernel)
    [ 7.164600] virtio_rpmsg_bus virtio0: rpmsg host is online
    [ 7.171594] virtio_rpmsg_bus virtio0: creating channel ti.ipc4.ping-pong addr 0xd
    [ 7.179147] rproc-virtio rproc-virtio.1.auto: registered virtio0 (type 7)
    [ 7.191893] remoteproc remoteproc0: remote processor 78000000.r5f is now attached
    [ 7.201103] virtio_rpmsg_bus virtio0: creating channel rpmsg_chrdev addr 0xe
    [ 7.219884] k3-m4-rproc 5000000.m4fss: assigned reserved memory node m4f-dma-memory@9cb00000
    [ 7.228952] k3-m4-rproc 5000000.m4fss: configured M4 for remoteproc mode
    [ 7.236363] k3-m4-rproc 5000000.m4fss: local reset is deasserted for device
    [ 7.250245] Bluetooth: Core ver 2.22
    [ 7.257132] NET: Registered PF_BLUETOOTH protocol family
    [ 7.262792] Bluetooth: HCI device and connection manager initialized
    [ 7.269609] Bluetooth: HCI socket layer initialized
    [ 7.274886] Bluetooth: L2CAP socket layer initialized
    [ 7.280344] Bluetooth: SCO socket layer initialized
    [ 7.328805] remoteproc remoteproc1: 5000000.m4fss is available
    [ 7.390992] remoteproc remoteproc1: powering up 5000000.m4fss
    [ 7.396995] remoteproc remoteproc1: Booting fw image am62-mcu-m4f0_0-fw, size 55016
    [ 7.416858] rproc-virtio rproc-virtio.2.auto: assigned reserved memory node m4f-dma-memory@9cb00000
    [ 7.465557] virtio_rpmsg_bus virtio1: rpmsg host is online
    [ 7.465827] virtio_rpmsg_bus virtio1: creating channel ti.ipc4.ping-pong addr 0xd
    [ 7.472333] rproc-virtio rproc-virtio.2.auto: registered virtio1 (type 7)
    [ 7.486610] remoteproc remoteproc1: remote processor 5000000.m4fss is now up
    [ 7.513542] virtio_rpmsg_bus virtio1: creating channel rpmsg_chrdev addr 0xe
    [ 7.889689] cfg80211: Loading compiled-in X.509 certificates for regulatory database
    [ 7.912370] cfg80211: Loaded X.509 cert 'sforshee: 00b28ddf47aef9cea7'
    [ 7.920036] cfg80211: Loaded X.509 cert 'wens: 61c038651aabdcf94bd0ac7ff06c7248db18c600'
    [ 7.985669] sii902x 1-003b: supply iovcc not found, using dummy regulator
    [ 7.993531] sii902x 1-003b: supply cvcc12 not found, using dummy regulator
    [ 8.083659] i2c i2c-1: Added multiplexed i2c bus 5
    [ 8.112026] [drm] Initialized tidss 1.0.0 20180215 for 30200000.dss on minor 0
    [ 8.128373] tidss 30200000.dss: [drm] Cannot find any crtc or sizes
    [ 8.134986] am65-cpsw-nuss 8000000.ethernet eth1: PHY [8000f00.mdio:01] driver [TI DP83867] (irq=POLL)
    [ 8.141251] tidss 30200000.dss: [drm] Cannot find any crtc or sizes
    [ 8.145694] am65-cpsw-nuss 8000000.ethernet eth1: configuring for phy/rgmii-rxid link mode
    [ 8.274299] am65-cpsw-nuss 8000000.ethernet eth0: PHY [8000f00.mdio:00] driver [TI DP83867] (irq=POLL)
    [ 8.310226] am65-cpsw-nuss 8000000.ethernet eth0: configuring for phy/rgmii-rxid link mode
    [ 9.711587] audit: type=1334 audit(16.364:6): prog-id=9 op=LOAD
    [ 9.719707] audit: type=1334 audit(16.372:7): prog-id=10 op=LOAD
    [ 10.552774] audit: type=1006 audit(17.204:8): pid=892 uid=0 old-auid=4294967295 auid=1000 tty=(none) old-ses=4294967295 ses=1 res=1
    [ 10.566106] audit: type=1300 audit(17.204:8): arch=c00000b7 syscall=64 success=yes exit=4 a0=8 a1=ffffde9f4ea8 a2=4 a3=ffff88129020 items=0 ppid=1 pid=892 auid=1000 uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=0 fsgid=0 tty=(none) ses=1 comm="(systemd)" exe="/lib/systemd/systemd" key=(null)
    [ 10.592857] audit: type=1327 audit(17.204:8): proctitle="(systemd)"
    [ 11.447451] remoteproc remoteproc2: 30074000.pru is available
    [ 11.455003] remoteproc remoteproc3: 30078000.pru is available
    [ 11.584745] tps6598x 0-003f: Unable to find the interrupt, switching to polling
    [ 11.737661] audit: type=1006 audit(18.388:9): pid=695 uid=0 old-auid=4294967295 auid=1000 tty=tty7 old-ses=4294967295 ses=2 res=1
    [ 11.750335] audit: type=1300 audit(18.388:9): arch=c00000b7 syscall=64 success=yes exit=4 a0=8 a1=ffffde9f4ea8 a2=4 a3=ffff88129020 items=0 ppid=1 pid=695 auid=1000 uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=0 fsgid=0 tty=tty7 ses=2 comm="(weston)" exe="/lib/systemd/systemd" key=(null)
    [ 11.778703] audit: type=1327 audit(18.388:9): proctitle="(weston)"
    [ 11.896027] xhci-hcd xhci-hcd.5.auto: xHCI Host Controller
    [ 11.906037] xhci-hcd xhci-hcd.5.auto: new USB bus registered, assigned bus number 1
    [ 11.915615] xhci-hcd xhci-hcd.5.auto: USB3 root hub has no ports
    [ 11.922695] xhci-hcd xhci-hcd.5.auto: hcc params 0x0258fe6d hci version 0x110 quirks 0x0000008000010010
    [ 11.933289] xhci-hcd xhci-hcd.5.auto: irq 424, io mem 0x31100000
    [ 11.941972] hub 1-0:1.0: USB hub found
    [ 11.945991] hub 1-0:1.0: 1 port detected
    [ 12.124842] wl18xx_driver wl18xx.4.auto: Direct firmware load for ti-connectivity/wl1271-nvs.bin failed with error -2
    [ 12.488287] wlcore: wl18xx HW: 183x or 180x, PG 2.2 (ROM 0x11)
    [ 12.500244] EXT4-fs (mmcblk0p12): mounted filesystem with ordered data mode. Quota mode: none.
    [ 12.501108] wlcore: loaded
    [ 12.740048] EXT4-fs (mmcblk0p13): mounted filesystem with ordered data mode. Quota mode: none.
    [ 13.295307] wlcore: PHY firmware version: Rev 8.2.0.0.245
    [ 13.393916] wlcore: firmware booted (Rev 8.9.0.0.86)
    [ 14.681025] sh (1514): drop_caches: 1
    [ 18.759239] ti-udma 485c0100.dma-controller: chan2 teardown timeout!
    [ 20.174692] audit: type=1006 audit(26.824:10): pid=1523 uid=0 old-auid=4294967295 auid=0 tty=(none) old-ses=4294967295 ses=3 res=1
    [ 20.186574] audit: type=1300 audit(26.824:10): arch=c00000b7 syscall=64 success=yes exit=1 a0=8 a1=ffffde9f4ea8 a2=1 a3=ffff88129020 items=0 ppid=1 pid=1523 auid=0 uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=0 fsgid=0 tty=(none) ses=3 comm="(systemd)" exe="/lib/systemd/systemd" key=(null)
    [ 20.212983] audit: type=1327 audit(26.824:10): proctitle="(systemd)"
    [ 20.219440] audit: type=1334 audit(26.840:11): prog-id=11 op=LOAD
    [ 20.225696] audit: type=1300 audit(26.840:11): arch=c00000b7 syscall=280 success=yes exit=8 a0=5 a1=fffff7374d10 a2=78 a3=0 items=0 ppid=1 pid=1523 auid=0 uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=0 fsgid=0 tty=(none) ses=3 comm="systemd" exe="/lib/systemd/systemd" key=(null)
    [ 20.250526] audit: type=1327 audit(26.840:11): proctitle="(systemd)"
    [ 20.256950] audit: type=1334 audit(26.864:12): prog-id=11 op=UNLOAD
    [ 20.263309] audit: type=1334 audit(26.864:13): prog-id=12 op=LOAD
    [ 20.269482] audit: type=1300 audit(26.864:13): arch=c00000b7 syscall=280 success=yes exit=8 a0=5 a1=fffff7374db0 a2=78 a3=0 items=0 ppid=1 pid=1523 auid=0 uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=0 fsgid=0 tty=(none) ses=3 comm="systemd" exe="/lib/systemd/systemd" key=(null)
    [ 20.294360] audit: type=1327 audit(26.864:13): proctitle="(systemd)"
    [ 20.711249] ti-udma 485c0100.dma-controller: chan1 teardown timeout!
    [ 473.078035] irq 371: nobody cared (try booting with the "irqpoll" option)
    [ 473.084911] CPU: 0 PID: 0 Comm: swapper/0 Not tainted 6.1.80-dirty #2
    [ 473.091391] Hardware name: Texas Instruments AM625 SK (DT)
    [ 473.096893] Call trace:
    [ 473.099356] dump_backtrace.part.0+0xdc/0xf0
    [ 473.103707] show_stack+0x18/0x30
    [ 473.107073] dump_stack_lvl+0x68/0x84
    [ 473.110779] dump_stack+0x18/0x34
    [ 473.114131] __report_bad_irq+0x4c/0xdc
    [ 473.118010] note_interrupt+0x33c/0x3a0
    [ 473.121884] handle_irq_event+0x9c/0xbc
    [ 473.125768] handle_simple_irq+0x9c/0x110
    [ 473.129815] generic_handle_domain_irq+0x2c/0x44
    [ 473.134478] gpio_irq_handler+0x98/0x120
    [ 473.138457] generic_handle_domain_irq+0x2c/0x44
    [ 473.143120] gic_handle_irq+0x50/0x124
    [ 473.146921] call_on_irq_stack+0x24/0x4c
    [ 473.150883] do_interrupt_handler+0x80/0x84
    [ 473.155109] el1_interrupt+0x34/0x70
    [ 473.158723] el1h_64_irq_handler+0x18/0x2c
    [ 473.162862] el1h_64_irq+0x64/0x68
    [ 473.166294] arch_cpu_idle+0x18/0x2c
    [ 473.169912] default_idle_call+0x30/0x6c
    [ 473.173877] do_idle+0x244/0x2c0
    [ 473.177150] cpu_startup_entry+0x38/0x40
    [ 473.181115] kernel_init+0x0/0x12c
    [ 473.184561] arch_post_acpi_subsys_init+0x0/0x18
    [ 473.189226] start_kernel+0x65c/0x69c
    [ 473.192926] __primary_switched+0xbc/0xc4
    [ 473.196977] handlers:
    [ 473.199261] [<000000009c3edff7>] irq_default_primary_handler threaded [<00000000c3d19e36>] pca953x_irq_handler
    [ 473.209371] Disabling IRQ #371
    root@am62xx-evm:~# ^C
    root@am62xx-evm:~#

  • Your yavta command was wrong: 

    root@am62xx-evm:~# yavta -c -Fcapture -s 640x480 -f SBGGR10 /dev/v4l-subdev2

    You need to use /dev/videoX.

  • ok 

    Try with /dev/videoX:- Getting error as Unable to start streaming: Broken pipe (32).

    root@am62xx-evm:~# v4l2-ctl -d /dev/v4l-subdev2 --list-subdev-mbus-codes pad=0
    ioctl: VIDIOC_SUBDEV_ENUM_MBUS_CODE (pad=0,stream=0)
            0x3007: MEDIA_BUS_FMT_SBGGR10_1X10
    root@am62xx-evm:~# media-ctl --set-v4l2 '"ov5647 4-0036":0 [fmt:SBGGR10_1X10/640x480 field:none colorspace:srgb xfer:srgb ycbcr:601 quantization:lim-range]'
    root@am62xx-evm:~# yavta -c -Fcapture -s 640x480 -f SBGGR10 /dev/video0
    Device /dev/video0 opened.
    Device `j721e-csi2rx' on `platform:30102000.ticsi2rx' (driver 'j721e-csi2rx') supports video, capture, without mplanes.
    Video[  845.470356] v4l2_get_link_freq: Link frequency estimated using pixel rate: result might be inaccurate
     format set: SBGGR10 (30314742) 640x480 (stride 1280) field none[  845.480850] v4l2_get_link_freq: Consider implementing support for V4L2_CID_LINK_FREQ in the transmitter driver
     buffer size 614400
    Video format: SBGGR10 (30314742) 640x480 (stride 1280) field none buffer size 614400
    8 buffers requested.
    length: 614400 offset: 0 timestamp type/source: mono/EoF
    Buffer 0/0 mapped at address 0xffff9d8ca000.
    length: 614400 offset: 614400 timestamp type/source: mono/EoF
    Buffer 1/0 mapped at address 0xffff9d834000.
    length: 614400 offset: 1228800 timestamp type/source: mono/EoF
    Buffer 2/0 mapped at address 0xffff9d79e000.
    length: 614400 offset: 1843200 timestamp type/source: mono/EoF
    Buffer 3/0 mapped at address 0xffff9d708000.
    length: 614400 offset: 2457600 timestamp type/source: mono/EoF
    Buffer 4/0 mapped at address 0xffff9d672000.
    length: 614400 offset: 3072000 timestamp type/source: mono/EoF
    Buffer 5/0 mapped at address 0xffff9d5dc000.
    length: 614400 offset: 3686400 timestamp type/source: mono/EoF
    Buffer 6/0 mapped at address 0xffff9d546000.
    length: 614400 offset: 4300800 timestamp type/source: mono/EoF
    Buffer 7/0 mapped at address 0xffff9d4b0000.
    ^C
    root@am62xx-evm:~# yavta -c -Fcapture -s 640x480 -f SBGGR10 /dev/video1
    Device /dev/video1 opened.
    Device `j721e-csi2rx' on `platform:30102000.ticsi2rx' (driver 'j721e-csi2rx') supports video, capture, without mplanes.
    Video format set: SBGGR10 (30314742) 640x480 (stride 1280) field none buffer size 614400
    Video format: SBGGR10 (30314742) 640x480 (stride 1280) field none buffer size 614400
    8 buffers requested.
    length: 614400 offset: 0 timestamp type/source: mono/EoF
    Buffer 0/0 mapped at address 0xffffac6ea000.
    length: 614400 offset: 614400 timestamp type/source: mono/EoF
    Buffer 1/0 mapped at address 0xffffac654000.
    length: 614400 offset: 1228800 timestamp type/source: mono/EoF
    Buffer 2/0 mapped at address 0xffffac5be000.
    length: 614400 offset: 1843200 timestamp type/source: mono/EoF
    Buffer 3/0 mapped at address 0xffffac528000.
    length: 614400 offset: 2457600 timestamp type/source: mono/EoF
    Buffer 4/0 mapped at address 0xffffac492000.
    length: 614400 offset: 3072000 timestamp type/source: mono/EoF
    Buffer 5/0 mapped at address 0xffffac3fc000.
    length: 614400 offset: 3686400 timestamp type/source: mono/EoF
    Buffer 6/0 mapped at address 0xffffac366000.
    length: 614400 offset: 4300800 timestamp type/source: mono/EoF
    Buffer 7/0 mapped at address 0xffffac2d0000.
    Unable to start streaming: No such device (19).
    8 buffers released.
    root@am62xx-evm:~# yavta -c -Fcapture -s 640x480 -f SBGGR10 /dev/video3
    Device /dev/video3 opened.
    Device `j721e-csi2rx' on `platform:30102000.ticsi2rx' (driver 'j721e-csi2rx') supports video, capture, without mplanes.
    Video format set: SBGGR10 (30314742) 640x480 (stride 1280) field none buffer size 614400
    Video format: SBGGR10 (30314742) 640x480 (stride 1280) field none buffer size 614400
    8 buffers requested.
    length: 614400 offset: 0 timestamp type/source: mono/EoF
    Buffer 0/0 mapped at address 0xffffa2f1a000.
    length: 614400 offset: 614400 timestamp type/source: mono/EoF
    Buffer 1/0 mapped at address 0xffffa2e84000.
    length: 614400 offset: 1228800 timestamp type/source: mono/EoF
    Buffer 2/0 mapped at address 0xffffa2dee000.
    length: 614400 offset: 1843200 timestamp type/source: mono/EoF
    Buffer 3/0 mapped at address 0xffffa2d58000.
    length: 614400 offset: 2457600 timestamp type/source: mono/EoF
    Buffer 4/0 mapped at address 0xffffa2cc2000.
    length: 614400 offset: 3072000 timestamp type/source: mono/EoF
    Buffer 5/0 mapped at address 0xffffa2c2c000.
    length: 614400 offset: 3686400 timestamp type/source: mono/EoF
    Buffer 6/0 mapped at address 0xffffa2b96000.
    length: 614400 offset: 4300800 timestamp type/source: mono/EoF
    Buffer 7/0 mapped at address 0xffffa2b00000.
    Unable to start streaming: No such device (19).
    8 buffers released.
    root@am62xx-evm:~# yavta -c -Fcapture -s 640x480 -f SBGGR10 /dev/video2
    Device /dev/video2 opened.
    Device `j721e-csi2rx' on `platform:30102000.ticsi2rx' (driver 'j721e-csi2rx') su                                                                             pports video, capture, without mplanes.
    Video format set: SBGGR10 (30314742) 640x480 (stride 1280) field none buffer siz                                                                             e 614400
    Video format: SBGGR10 (30314742) 640x480 (stride 1280) field none buffer size 61                                                                             4400
    8 buffers requested.
    length: 614400 offset: 0 timestamp type/source: mono/EoF
    Buffer 0/0 mapped at address 0xffffbe42a000.
    length: 614400 offset: 614400 timestamp type/source: mono/EoF
    Buffer 1/0 mapped at address 0xffffbe394000.
    length: 614400 offset: 1228800 timestamp type/source: mono/EoF
    Buffer 2/0 mapped at address 0xffffbe2fe000.
    length: 614400 offset: 1843200 timestamp type/source: mono/EoF
    Buffer 3/0 mapped at address 0xffffbe268000.
    length: 614400 offset: 2457600 timestamp type/source: mono/EoF
    Buffer 4/0 mapped at address 0xffffbe1d2000.
    length: 614400 offset: 3072000 timestamp type/source: mono/EoF
    Buffer 5/0 mapped at address 0xffffbe13c000.
    length: 614400 offset: 3686400 timestamp type/source: mono/EoF
    Buffer 6/0 mapped at address 0xffffbe0a6000.
    length: 614400 offset: 4300800 timestamp type/source: mono/EoF
    Buffer 7/0 mapped at address 0xffffbe010000.
    Unable to start streaming: Broken pipe (32).
    8 buffers released.
    root@am62xx-evm:~# yavta -s 640x480 -f SBGGR10 /dev/video2 -c100
    Device /dev/video2 opened.
    Device `j721e-csi2rx' on `platform:30102000.ticsi2rx' (driver 'j721e-csi2rx') su                                                                             pports video, capture, without mplanes.
    Video format set: SBGGR10 (30314742) 640x480 (stride 1280) field none buffer siz                                                                             e 614400
    Video format: SBGGR10 (30314742) 640x480 (stride 1280) field none buffer size 61                                                                             4400
    8 buffers requested.
    length: 614400 offset: 0 timestamp type/source: mono/EoF
    Buffer 0/0 mapped at address 0xffff89a5a000.
    length: 614400 offset: 614400 timestamp type/source: mono/EoF
    Buffer 1/0 mapped at address 0xffff899c4000.
    length: 614400 offset: 1228800 timestamp type/source: mono/EoF
    Buffer 2/0 mapped at address 0xffff8992e000.
    length: 614400 offset: 1843200 timestamp type/source: mono/EoF
    Buffer 3/0 mapped at address 0xffff89898000.
    length: 614400 offset: 2457600 timestamp type/source: mono/EoF
    Buffer 4/0 mapped at address 0xffff89802000.
    length: 614400 offset: 3072000 timestamp type/source: mono/EoF
    Buffer 5/0 mapped at address 0xffff8976c000.
    length: 614400 offset: 3686400 timestamp type/source: mono/EoF
    Buffer 6/0 mapped at address 0xffff896d6000.
    length: 614400 offset: 4300800 timestamp type/source: mono/EoF
    Buffer 7/0 mapped at address 0xffff89640000.
    Unable to start streaming: Broken pipe (32).
    8 buffers released.
    root@am62xx-evm:~# yavta -s 640x480 -f SBGGR10 /dev/video2 -c5 -Fframe-#.bin
    Device /dev/video2 opened.
    Device `j721e-csi2rx' on `platform:30102000.ticsi2rx' (driver 'j721e-csi2rx') su                                                                             pports video, capture, without mplanes.
    Video format set: SBGGR10 (30314742) 640x480 (stride 1280) field none buffer siz                                                                             e 614400
    Video format: SBGGR10 (30314742) 640x480 (stride 1280) field none buffer size 61                                                                             4400
    8 buffers requested.
    length: 614400 offset: 0 timestamp type/source: mono/EoF
    Buffer 0/0 mapped at address 0xffff838ba000.
    length: 614400 offset: 614400 timestamp type/source: mono/EoF
    Buffer 1/0 mapped at address 0xffff83824000.
    length: 614400 offset: 1228800 timestamp type/source: mono/EoF
    Buffer 2/0 mapped at address 0xffff8378e000.
    length: 614400 offset: 1843200 timestamp type/source: mono/EoF
    Buffer 3/0 mapped at address 0xffff836f8000.
    length: 614400 offset: 2457600 timestamp type/source: mono/EoF
    Buffer 4/0 mapped at address 0xffff83662000.
    length: 614400 offset: 3072000 timestamp type/source: mono/EoF
    Buffer 5/0 mapped at address 0xffff835cc000.
    length: 614400 offset: 3686400 timestamp type/source: mono/EoF
    Buffer 6/0 mapped at address 0xffff83536000.
    length: 614400 offset: 4300800 timestamp type/source: mono/EoF
    Buffer 7/0 mapped at address 0xffff834a0000.
    Unable to start streaming: Broken pipe (32).
    8 buffers released.
    root@am62xx-evm:~# ls -l frame-*.bin
    ls: cannot access 'frame-*.bin': No such file or directory
    root@am62xx-evm:~#

  • Hello ,

    About  Display the supported frame rates for a specific format and frame size:

    1. # v4l2-ctl -d /dev/v4l-subdev2 --list-subdev-frameintervals pad=0,width=640,height=480,code=0x2006
      ioctl: VIDIOC_SUBDEV_ENUM_FRAME_INTERVAL (pad=0)
              Interval: 0.067s (15.000 fps)
              Interval: 0.033s (30.000 fps)
              Interval: 0.017s (60.000 fps)

      root@am62xx-evm:~# v4l2-ctl -d /dev/v4l-subdev2 --list-subdev-mbus-codes pad=0
      ioctl: VIDIOC_SUBDEV_ENUM_MBUS_CODE (pad=0,stream=0)
              0x3007: MEDIA_BUS_FMT_SBGGR10_1X10
      root@am62xx-evm:~# v4l2-ctl -d /dev/v4l-subdev2 --list-subdev-frameintervals pad=0,width=640,height=480,code=0x3007
      ioctl: VIDIOC_SUBDEV_ENUM_FRAME_INTERVAL (pad=0,stream=0)
      root@am62xx-evm:~# v4l2-ctl -d /dev/v4l-subdev2 --list-subdev-framesizes pad=0,code=0x3007
      ioctl: VIDIOC_SUBDEV_ENUM_FRAME_SIZE (pad=0,stream=0)
              Size Range: 2592x1944 - 2592x1944
              Size Range: 1920x1080 - 1920x1080
              Size Range: 1296x972 - 1296x972
              Size Range: 640x480 - 640x480
      root@am62xx-evm:~# v4l2-ctl -d /dev/video2 --list-subdev-frameintervals pad=0,wi
      dth=640,height=480,code=0x3007
      ioctl: VIDIOC_SUBDEV_ENUM_FRAME_INTERVAL (pad=0,stream=0)
      root@am62xx-evm:~# v4l2-ctl -d /dev/video1 --list-subdev-frameintervals pad=0,wi
      dth=640,height=480,code=0x3007
      ioctl: VIDIOC_SUBDEV_ENUM_FRAME_INTERVAL (pad=0,stream=0)
      root@am62xx-evm:~# v4l2-ctl -d /dev/video0 --list-subdev-frameintervals pad=0,wi
      dth=640,height=480,code=0x3007
      ioctl: VIDIOC_SUBDEV_ENUM_FRAME_INTERVAL (pad=0,stream=0)
      root@am62xx-evm:~# v4l2-ctl -d /dev/video3 --list-subdev-frameintervals pad=0,wi
      dth=640,height=480,code=0x3007
      ioctl: VIDIOC_SUBDEV_ENUM_FRAME_INTERVAL (pad=0,stream=0)
      root@am62xx-evm:~# v4l2-ctl -d /dev/v4l-subdev1 --list-subdev-frameintervals pad
      =0,width=640,height=480,code=0x3007
      ioctl: VIDIOC_SUBDEV_ENUM_FRAME_INTERVAL (pad=0,stream=0)
      root@am62xx-evm:~# v4l2-ctl -d /dev/v4l-subdev0 --list-subdev-frameintervals pad
      =0,width=640,height=480,code=0x3007
      ioctl: VIDIOC_SUBDEV_ENUM_FRAME_INTERVAL (pad=0,stream=0)
      root@am62xx-evm:~# v4l2-ctl -d /dev/v4l-subdev3 --list-subdev-frameintervals pad
      =0,width=640,height=480,code=0x3007
      Cannot open device /dev/v4l-subdev3, exiting.
      root@am62xx-evm:~# v4l2-ctl -d /dev/v4l-subdev2 --list-subdev-frameintervals pad=0,width=640,height=480,code=0x3007
      ioctl: VIDIOC_SUBDEV_ENUM_FRAME_INTERVAL (pad=0,stream=0)
      root@am62xx-evm:~#

      why i am not able to see the frame rates of specified formats and frame size ?
  • Also i followed below your thread link for ISP Tuning Guide. but actually we are using AM62X EVK with sdk version 09.02.01.09:- 

    e2e.ti.com/.../sk-am62a-lp-configuring-a-new-csi-2-image-sensor-to-use-isp-vpac-functionality

    what all things needs to do for getting started with Gstreamer ?

    How to get the  image captured from the image sensor ?

    if possible please the pdf for AM62X ISP Tuning Guide .

    Regards,

    Dnyaneshwar 

  • why i am not able to see the frame rates of specified formats and frame size ?

    The sensor driver doesn't support that.

    what all things needs to do for getting started with Gstreamer ?

    How to get the  image captured from the image sensor ?

    Please find some Gstreamer tutorial on the web.

  • The sensor driver doesn't support that.

    so i need to update drivers to get the frame rates of specified formats and frame size ?

    where i will get sensor driver for OV5647 camera which will support for sdk version:- 09.02.01.09 AM62X model ?

    Same problem is coming when whenever i am trying to capture the image:- 

    Error is Unable to start streaming 

    root@am62xx-evm:~# media-ctl --set-v4l2 '"ov5647 4-0036":0 [fmt:SBGGR10_1X10/640x480 field:none colorspace:srgb xfer:srgb ycbcr:601 quantization:lim-range]'
    root@am62xx-evm:~# yavta -c -Fcapture -s 640x480 -f SBGGR10 /dev/video2
    Device /dev/video2 opened.
    Device `j721e-csi2rx' on `platform:30102000.ticsi2rx' (driver 'j721e-csi2rx') supports video, capture, without mplanes.
    Video format set: SBGGR10 (30314742) 640x480 (stride 1280) field none buffer size 614400
    Video format: SBGGR10 (30314742) 640x480 (stride 1280) field none buffer size 614400
    8 buffers requested.
    length: 614400 offset: 0 timestamp type/source: mono/EoF
    Buffer 0/0 mapped at address 0xffff92f6a000.
    length: 614400 offset: 614400 timestamp type/source: mono/EoF
    Buffer 1/0 mapped at address 0xffff92ed4000.
    length: 614400 offset: 1228800 timestamp type/source: mono/EoF
    Buffer 2/0 mapped at address 0xffff92e3e000.
    length: 614400 offset: 1843200 timestamp type/source: mono/EoF
    Buffer 3/0 mapped at address 0xffff92da8000.
    length: 614400 offset: 2457600 timestamp type/source: mono/EoF
    Buffer 4/0 mapped at address 0xffff92d12000.
    length: 614400 offset: 3072000 timestamp type/source: mono/EoF
    Buffer 5/0 mapped at address 0xffff92c7c000.
    length: 614400 offset: 3686400 timestamp type/source: mono/EoF
    Buffer 6/0 mapped at address 0xffff92be6000.
    length: 614400 offset: 4300800 timestamp type/source: mono/EoF
    Buffer 7/0 mapped at address 0xffff92b50000.
    Unable to start streaming: No such device (19).
    8 buffers released.
    root@am62xx-evm:~# ^C
    root@am62xx-evm:~#

  • Please find some Gstreamer tutorial on the web.

    About Gstreamer tutorial actually i am unable to find for AM62X board .

    just try to refering this thread:- https://e2e.ti.com/support/processors-group/processors/f/processors-forum/1296514/sk-am62a-lp-bring-up-ov5647

    to understand how to make /add these files :- 

    • tiovx_sensor_module.c
    • gsttiovxisp.c

    https://e2e.ti.com/support/processors-group/processors/f/processors-forum/1226793/sk-am62a-lp-configuring-a-new-csi-2-image-sensor-to-use-isp-vpac-functionality?keyMatch=OV5647

    root@am62axx-evm:/opt/edgeai-gst-apps/scripts# vi /opt/edgeai-tiovx-modules/src/tiovx_sensor_module.c i can able to open this file but not able to save it says no such files 

    Tried these two command :- getting error as follow

    @am62axx-evm:/opt/edgeai-gst-apps/scripts# vi /opt/edgeai-gst-plugins/ext/tiovx/gsttiovxisp.c
    root@am62axx-evm:/opt/edgeai-gst-apps/scripts# ./install_gst_plugins.sh

    root@am62xx-evm:/opt/edgeai-gst-apps/scripts# vi /opt/edgeai-gst-plugins/ext/tiovx/gsttiovxisp.c
    root@am62xx-evm:/opt/edgeai-gst-apps/scripts# ./install_gst_plugins.sh
    edgeai-gst-plugins
    The Meson build system
    Version: 0.61.3
    Source dir: /opt/edgeai-gst-plugins
    Build dir: /opt/edgeai-gst-plugins/build
    Build type: native build
    Project name: GstTIOVX
    Project version: 0.7.0
    C compiler for the host machine: cc (gcc 11.4.0 "cc (GCC) 11.4.0")
    C linker for the host machine: cc ld.bfd 2.38.20220708
    C++ compiler for the host machine: c++ (gcc 11.4.0 "c++ (GCC) 11.4.0")
    C++ linker for the host machine: c++ ld.bfd 2.38.20220708
    Host machine cpu family: aarch64
    Host machine cpu: aarch64
    Found pkg-config: /usr/bin/pkg-config (0.29.2)
    Run-time dependency gstreamer-1.0 found: YES 1.20.7
    Run-time dependency gstreamer-base-1.0 found: YES 1.20.7
    Run-time dependency gstreamer-video-1.0 found: YES 1.20.7
    Run-time dependency gstreamer-check-1.0 found: YES 1.20.7
    Run-time dependency gstreamer-allocators-1.0 found: YES 1.20.7
    WARNING: You should add the boolean check kwarg to the run_command call.
             It currently defaults to false,
             but it will default to true in future releases of meson.
             See also: https://github.com/mesonbuild/meson/issues/9300
    
    meson.build:35:2: ERROR: Problem encountered: MESON_FAIL SOC not set.
    
    A full log can be found at /opt/edgeai-gst-plugins/build/meson-logs/meson-log.txt
    root@am62xx-evm:/opt/edgeai-gst-apps/scripts#

  • You don't have to go to AM62A to use GStreamer. It's also available on AM62x. Please try the following (you'll need to fill correct information in <>):

    gst-launch-1.0 -v v4l2src num-buffers=5 device=</dev/videoX> io-mode=dmabuf ! video/x-bayer, width=<width>, height=<height>, framerate=<frame rate>, format=<format> ! \ multifilesink location="<file-name>-%d.raw"

  • gst-launch-1.0 -v v4l2src num-buffers=5 device=</dev/videoX> io-mode=dmabuf ! video/x-bayer, width=<width>, height=<height>, framerate=<frame rate>, format=<format> ! \ multifilesink location="<file-name>-%d.raw"

    First of all i am not able to go the direction:- cd /opt/imaging/ov5647/captures

    as you said frame rates are not supported in sensor drivers so it is not possible to execute this commands.

    I have tried you can see below:- 

    root@am62xx-evm:~# cd /opt/imaging/ov5647/captures
    -sh: cd: /opt/imaging/ov5647/captures: No such file or directory
    root@am62xx-evm:~# media-ctl --set-v4l2 '"ov5647 4-0036":0 [fmt:SBGGR10_1X10/640x480 field:none colorspace:srgb xfer:srgb ycbcr:601 quantization:lim-range]'
    root@am62xx-evm:~# yavta -c -Fcapture -s 640x480 -f SBGGR10 /dev/video2
    Device /dev/video2 opened.
    Device `j721e-csi2rx' on `platform:30102000.ticsi2rx' (driver 'j721e-csi2rx') supports video, capture, without mplanes.
    Video format set: SBGGR10 (30314742) 640x480 (stride 1280) field none buffer size 614400
    Video format: SBGGR10 (30314742) 640x480 (stride 1280) field none buffer size 614400
    8 buffers requested.
    length: 614400 offset: 0 timestamp type/source: mono/EoF
    Buffer 0/0 mapped at address 0xffff9fd3a000.
    length: 614400 offset: 614400 timestamp type/source: mono/EoF
    Buffer 1/0 mapped at address 0xffff9fca4000.
    length: 614400 offset: 1228800 timestamp type/source: mono/EoF
    Buffer 2/0 mapped at address 0xffff9fc0e000.
    length: 614400 offset: 1843200 timestamp type/source: mono/EoF
    Buffer 3/0 mapped at address 0xffff9fb78000.
    length: 614400 offset: 2457600 timestamp type/source: mono/EoF
    Buffer 4/0 mapped at address 0xffff9fae2000.
    length: 614400 offset: 3072000 timestamp type/source: mono/EoF
    Buffer 5/0 mapped at address 0xffff9fa4c000.
    length: 614400 offset: 3686400 timestamp type/source: mono/EoF
    Buffer 6/0 mapped at address 0xffff9f9b6000.
    length: 614400 offset: 4300800 timestamp type/source: mono/EoF
    Buffer 7/0 mapped at address 0xffff9f920000.
    Unable to start streaming: No such device (19).
    8 buffers released.
    root@am62xx-evm:~# gst-launch-1.0 -v v4l2src num-buffers=5 device=/dev/video2 io-mode=dmabuf ! video/x-bayer,width=640,height=480,framerate=30/1,format=bggr10 ! multifilesink location="ov5647-image-%d.raw"
    Setting pipeline to PAUSED ...
    Pipeline is live and does not need PREROLL ...
    Pipeline is PREROLLED ...
    Setting pipeline to PLAYING ...
    New clock: GstSystemClock
    /GstPipeline:pipeline0/GstV4l2Src:v4l2src0.GstPad:src: caps = video/x-bayer, width=(int)640, height=(int)480, framerate=(fraction)30/1, format=(string)bggr10, interlace-mode=(string)progressive, colorimetry=(string)2:4:7:1
    /GstPipeline:pipeline0/GstCapsFilter:capsfilter0.GstPad:src: caps = video/x-bayer, width=(int)640, height=(int)480, framerate=(fraction)30/1, format=(string)bggr10, interlace-mode=(string)progressive, colorimetry=(string)2:4:7:1
    /GstPipeline:pipeline0/GstMultiFileSink:multifilesink0.GstPad:sink: caps = video/x-bayer, width=(int)640, height=(int)480, framerate=(fraction)30/1, format=(string)bggr10, interlace-mode=(string)progressive, colorimetry=(string)2:4:7:1
    /GstPipeline:pipeline0/GstCapsFilter:capsfilter0.GstPad:sink: caps = video/x-bayer, width=(int)640, height=(int)480, framerate=(fraction)30/1, format=(string)bggr10, interlace-mode=(string)progressive, colorimetry=(string)2:4:7:1
    ERROR: from element /GstPipeline:pipeline0/GstV4l2Src:v4l2src0: Failed to allocate required memory.
    Additional debug info:
    ../gst-plugins-good-1.20.7/sys/v4l2/gstv4l2src.c(777): gst_v4l2src_decide_allocation (): /GstPipeline:pipeline0/GstV4l2Src:v4l2src0:
    Buffer pool activation failed
    Execution ended after 0:00:00.011403695
    Setting pipeline to NULL ...
    ERROR: from element /GstPipeline:pipeline0/GstV4l2Src:v4l2src0: Internal data stream error.
    Additional debug info:
    ../gstreamer-1.20.7/libs/gst/base/gstbasesrc.c(3127): gst_base_src_loop (): /GstPipeline:pipeline0/GstV4l2Src:v4l2src0:
    streaming stopped, reason not-negotiated (-4)
    Freeing pipeline ...
    root@am62xx-evm:~#

    how can i proceed forward help me 

    Regards,

    Dnyaneshwar 

  • You should use the first video node under j721e-csi2rx (platform:30102000.ticsi2rx) from the output of "v4l2-ctl --list-devices".

  • root@am62xx-evm:~# v4l2-ctl --list-devices
    j721e-csi2rx (platform:30102000.ticsi2rx):
            /dev/video0
            /dev/video1
            /dev/video2
            /dev/video3
            /dev/media0
    
    root@am62xx-evm:~#

    These are my devices .

    I am able to run when i enter platform:30101000.ticsi2rx 

    see below :- 

    root@am62xx-evm:~# media-ctl --set-v4l2 '"cdns_csi2rx.30101000.csi-bridge":0 [fmt:UYVY8_2X8/640x480 field:none colorspace:srgb xfer:srgb ycbcr:601 quantization:lim-range]'
    root@am62xx-evm:~# yavta -c -Fcapture -s 640x480 -f UYVY /dev/video0
    Device /dev/video0 opened.
    Device `j721e-csi2rx' on `platform:30102000.ticsi2rx' (driver 'j721e-csi2rx') supports video, capture, without mplanes.
    Video format set: UYVY (59565955) 640x480 (stride 1280) field none buffer size 614400
    Video format: UYVY (59565955) 640x480 (stride 1280) field none buffer size 614400
    8 buffers requested.
    length: 614400 offset: 0 timestamp type/source: mono/EoF
    Buffer 0/0 mapped at address 0xffff9a70a000.
    length: 614400 offset: 614400 timestamp type/source: mono/EoF
    Buffer 1/0 mapped at address 0xffff9a674000.
    length: 614400 offset: 1228800 timestamp type/source: mono/EoF
    Buffer 2/0 mapped at address 0xffff9a5de000.
    length: 614400 offset: 1843200 timestamp type/source: mono/EoF
    Buffer 3/0 mapped at address 0xffff9a548000.
    length: 614400 offset: 2457600 timestamp type/source: mono/EoF
    Buffer 4/0 mapped at address 0xffff9a4b2000.
    length: 614400 offset: 3072000 timestamp type/source: mono/EoF
    Buffer 5/0 mapped at address 0xffff9a41c000.
    length: 614400 offset: 3686400 timestamp type/source: mono/EoF
    Buffer 6/0 mapped at address 0xffff9a386000.
    length: 614400 offset: 4300800 timestamp type/source: mono/EoF
    Buffer 7/0 mapped at address 0xffff9a2f0000.
    Unable to start streaming: Broken pipe (32).
    8 buffers released.
    root@am62xx-evm:~# media-ctl --set-v4l2 '"cdns_csi2rx.30102000.csi-bridge":0 [fm
    t:UYVY8_2X8/640x480 field:none colorspace:srgb xfer:srgb ycbcr:601 quantization:
    lim-range]'
    Unable to setup formats: Invalid argument (22)
    root@am62xx-evm:~#

  • Why are you setting the format to "UYVY8_2X8/640x480"? The sensor has SBGGR10:

    root@am62xx-evm:~# v4l2-ctl -d /dev/v4l-subdev2 --list-subdev-mbus-codes pad=0
    ioctl: VIDIOC_SUBDEV_ENUM_MBUS_CODE (pad=0,stream=0)
    0x3007: MEDIA_BUS_FMT_SBGGR10_1X10

  • Hello sir,

    Tried but fail to capture:- 

    root@am62xx-evm:~# media-ctl --set-v4l2 '"cdns_csi2rx.30101000.csi-bridge":0 [fmt:SBGGR10/640x480 field:none colorspace:srgb xfer:srgb ycbcr:601 quantization:lim-range]'
    root@am62xx-evm:~# yavta -c -Fcapture -s 640x480 -f SBGGR10 /dev/video0
    Device /dev/video0 opened.
    Device `j721e-csi2rx' on `platform:30102000.ticsi2rx' (driver 'j721e-csi2rx') supports video, capture, without mplanes.
    Video f[   82.936856] v4l2_get_link_freq: Link frequency estimated using pixel rate: result might be inaccurate
    ormat set: SBGGR10 (30314742) 640x480 (stride 1280) field none b[   82.948080] v4l2_get_link_freq: Consider implementing support for V4L2_CID_LINK_FREQ in the transmitter driver
    uffer size 614400
    Video format: SBGGR10 (30314742) 640x480 (stride 1280) field none buffer size 614400
    8 buffers requested.
    length: 614400 offset: 0 timestamp type/source: mono/EoF
    Buffer 0/0 mapped at address 0xffffbcf7a000.
    length: 614400 offset: 614400 timestamp type/source: mono/EoF
    Buffer 1/0 mapped at address 0xffffbcee4000.
    length: 614400 offset: 1228800 timestamp type/source: mono/EoF
    Buffer 2/0 mapped at address 0xffffbce4e000.
    length: 614400 offset: 1843200 timestamp type/source: mono/EoF
    Buffer 3/0 mapped at address 0xffffbcdb8000.
    length: 614400 offset: 2457600 timestamp type/source: mono/EoF
    Buffer 4/0 mapped at address 0xffffbcd22000.
    length: 614400 offset: 3072000 timestamp type/source: mono/EoF
    Buffer 5/0 mapped at address 0xffffbcc8c000.
    length: 614400 offset: 3686400 timestamp type/source: mono/EoF
    Buffer 6/0 mapped at address 0xffffbcbf6000.
    length: 614400 offset: 4300800 timestamp type/source: mono/EoF
    Buffer 7/0 mapped at address 0xffffbcb60000.
    ^C
    root@am62xx-evm:~# media-ctl -p
    Media controller API version 6.1.80
    
    Media device information
    ------------------------
    driver          j721e-csi2rx
    model           TI-CSI2RX
    serial
    bus info        platform:30102000.ticsi2rx
    hw revision     0x1
    driver version  6.1.80
    
    Device topology
    - entity 1: 30102000.ticsi2rx (5 pads, 5 links, 1 route)
                type V4L2 subdev subtype Unknown flags 0
                device node name /dev/v4l-subdev0
            routes:
                    0/0 -> 1/0 [ACTIVE]
            pad0: Sink
                    [stream:0 fmt:UYVY8_1X16/640x480 field:none colorspace:srgb xfer:srgb ycbcr:601 quantization:lim-range]
                    <- "cdns_csi2rx.30101000.csi-bridge":1 [ENABLED,IMMUTABLE]
            pad1: Source
                    [stream:0 fmt:UYVY8_1X16/640x480 field:none colorspace:srgb xfer:srgb ycbcr:601 quantization:lim-range]
                    -> "30102000.ticsi2rx context 0":0 [ENABLED,IMMUTABLE]
            pad2: Source
                    -> "30102000.ticsi2rx context 1":0 [ENABLED,IMMUTABLE]
            pad3: Source
                    -> "30102000.ticsi2rx context 2":0 [ENABLED,IMMUTABLE]
            pad4: Source
                    -> "30102000.ticsi2rx context 3":0 [ENABLED,IMMUTABLE]
    
    - entity 7: cdns_csi2rx.30101000.csi-bridge (5 pads, 2 links, 1 route)
                type V4L2 subdev subtype Unknown flags 0
                device node name /dev/v4l-subdev1
            routes:
                    0/0 -> 1/0 [ACTIVE]
            pad0: Sink
                    [stream:0 fmt:SBGGR10_1X10/640x480 field:none colorspace:srgb xfer:srgb ycbcr:601 quantization:lim-range]
                    <- "ov5647 4-0036":0 [ENABLED,IMMUTABLE]
            pad1: Source
                    [stream:0 fmt:SBGGR10_1X10/640x480 field:none colorspace:srgb xfer:srgb ycbcr:601 quantization:lim-range]
                    -> "30102000.ticsi2rx":0 [ENABLED,IMMUTABLE]
            pad2: Source
            pad3: Source
            pad4: Source
    
    - entity 13: ov5647 4-0036 (1 pad, 1 link, 0 route)
                 type V4L2 subdev subtype Sensor flags 0
                 device node name /dev/v4l-subdev2
            pad0: Source
                    [stream:0 fmt:SBGGR10_1X10/640x480 field:none colorspace:srgb
                     crop.bounds:(16,16)/2592x1944
                     crop:(32,16)/2560x1920]
                    -> "cdns_csi2rx.30101000.csi-bridge":0 [ENABLED,IMMUTABLE]
    
    - entity 19: 30102000.ticsi2rx context 0 (1 pad, 1 link, 0 route)
                 type Node subtype V4L flags 0
                 device node name /dev/video0
            pad0: Sink
                    <- "30102000.ticsi2rx":1 [ENABLED,IMMUTABLE]
    
    - entity 25: 30102000.ticsi2rx context 1 (1 pad, 1 link, 0 route)
                 type Node subtype V4L flags 0
                 device node name /dev/video1
            pad0: Sink
                    <- "30102000.ticsi2rx":2 [ENABLED,IMMUTABLE]
    
    - entity 31: 30102000.ticsi2rx context 2 (1 pad, 1 link, 0 route)
                 type Node subtype V4L flags 0
                 device node name /dev/video2
            pad0: Sink
                    <- "30102000.ticsi2rx":3 [ENABLED,IMMUTABLE]
    
    - entity 37: 30102000.ticsi2rx context 3 (1 pad, 1 link, 0 route)
                 type Node subtype V4L flags 0
                 device node name /dev/video3
            pad0: Sink
                    <- "30102000.ticsi2rx":4 [ENABLED,IMMUTABLE]
    
    root@am62xx-evm:~# v4l2-ctl --list-devices
    j721e-csi2rx (platform:30102000.ticsi2rx):
            /dev/video0
            /dev/video1
            /dev/video2
            /dev/video3
            /dev/media0
    
    root@am62xx-evm:~#

  • Hello,

    You media pipe looks correct. The only thing that I can think of is the link frequency. Can you add a print out after this line of code: https://git.ti.com/cgit/ti-linux-kernel/ti-linux-kernel/tree/drivers/media/platform/cadence/cdns-csi2rx.c?h=ti-linux-6.1.y#n277. For example, you can do:

    pr_warn("%s: Link frequency is %lld\n", __func__, link_freq);

    Then rebuild the kernel according to the instructions at: https://software-dl.ti.com/processor-sdk-linux/esd/AM62X/09_02_01_10/exports/docs/linux/Foundational_Components_Kernel_Users_Guide.html

    Please update what the link frequency is from this test.

    Regards,

    Jianzhong

  • Hello 

    Today i am successfully able to make modules,using above print statments:- 

    pr_warn("%s: Link frequency is %lld\n", __func__, link_freq); // Corrected line 

    what to do next ?

    how to check link frequency ?

    Regards

    Dnyaneshwar

  • If you run the yavta command again, you should see the link frequency printed out. Please share the log of yavta command.

  • Hello, 

    Facing this issue not able to load the ov5647 drivers after booting:- 

    It says Module ov5647 not found in directory .

    root@am62xx-evm:~# modprobe -a ov5647
    modprobe: WARNING: Module ov5647 not found in directory /lib/modules/6.1.80-dirty
    root@am62xx-evm:~# cd /lib/modules
    root@am62xx-evm:/lib/modules# cd 6.1.80-dirty/kernel/drivers/media/i2c
    root@am62xx-evm:/lib/modules/6.1.80-dirty/kernel/drivers/media/i2c# ls
    ds90ub953.ko  ds90ub960.ko  imx219.ko  imx390.ko  ir-kbd-i2c.ko  ov2312.ko  ov5640.ko  ov5645.ko  ox05b1s.ko
    root@am62xx-evm:/lib/modules/6.1.80-dirty/kernel/drivers/media/i2c# insmod ov5647.ko
    insmod: ERROR: could not load module ov5647.ko: No such file or directory
    root@am62xx-evm:/lib/modules/6.1.80-dirty/kernel/drivers/media/i2c# cd
    root@am62xx-evm:~# modprobe -r j721e_csi2rx cdns_csi2rx ov5647
    modprobe: FATAL: Module ov5647 not found.
    root@am62xx-evm:~# modprobe -a j721e_csi2rx cdns_csi2rx ov5647
    [ 1383.561759] mc: Linux media interface: v0.10
    [ 1383.594654] videodev: Linux video capture interface: v2.00
    [ 1383.663320] cdns-csi2rx 30101000.csi-bridge: Probed CSI2RX with 2/4 lanes, 4 streams, external D-PHY
    modprobe: WARNING: Module ov5647 not found in directory /lib/modules/6.1.80-dirty
    root@am62xx-evm:~# insmod /lib/modules/6.1.80-dirty/kernel/drivers/media/i2c/ov5647.ko
    insmod: ERROR: could not load module /lib/modules/6.1.80-dirty/kernel/drivers/media/i2c/ov5647.ko: No such file or directory
    root@am62xx-evm:~#

    How to solve this issue ?

    Does following things also matters :- software-dl.ti.com/.../CSI2RX.html

    The Technexion TEVI-OV5640 module supports this, but it may fail to set the sensor registers in time when built as a module. You can fix this by making it a part of the kernel image:

    diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig
    index 1f402994efed..0f081e5f96c1 100644
    --- a/arch/arm64/configs/defconfig
    +++ b/arch/arm64/configs/defconfig
    @@ -739,14 +739,14 @@ CONFIG_RC_DECODERS=y
     CONFIG_RC_DEVICES=y
     CONFIG_IR_MESON=m
     CONFIG_IR_SUNXI=m
    -CONFIG_MEDIA_SUPPORT=m
    +CONFIG_MEDIA_SUPPORT=y
     # CONFIG_DVB_NET is not set
     CONFIG_MEDIA_USB_SUPPORT=y
     CONFIG_USB_VIDEO_CLASS=m
     CONFIG_V4L_PLATFORM_DRIVERS=y
     CONFIG_SDR_PLATFORM_DRIVERS=y
     CONFIG_V4L_MEM2MEM_DRIVERS=y
    -CONFIG_VIDEO_CADENCE_CSI2RX=m
    +CONFIG_VIDEO_CADENCE_CSI2RX=y
     CONFIG_VIDEO_WAVE_VPU=m
     CONFIG_VIDEO_IMG_VXD_DEC=m
     CONFIG_VIDEO_IMG_VXE_ENC=m
    @@ -764,12 +764,12 @@ CONFIG_VIDEO_SAMSUNG_EXYNOS_GSC=m
     CONFIG_VIDEO_SAMSUNG_S5P_JPEG=m
     CONFIG_VIDEO_SAMSUNG_S5P_MFC=m
     CONFIG_VIDEO_SUN6I_CSI=m
    -CONFIG_VIDEO_TI_J721E_CSI2RX=m
    +CONFIG_VIDEO_TI_J721E_CSI2RX=y
     CONFIG_VIDEO_HANTRO=m
     CONFIG_VIDEO_IMX219=m
     CONFIG_VIDEO_IMX390=m
     CONFIG_VIDEO_OV2312=m
    -CONFIG_VIDEO_OV5640=m
    +CONFIG_VIDEO_OV5640=y
     CONFIG_VIDEO_OV5645=m
     CONFIG_VIDEO_DS90UB953=m
     CONFIG_VIDEO_DS90UB960=m
    @@ -1309,8 +1309,8 @@ CONFIG_PHY_XGENE=y
     CONFIG_PHY_CAN_TRANSCEIVER=m
     CONFIG_PHY_SUN4I_USB=y
     CONFIG_PHY_CADENCE_TORRENT=y
    -CONFIG_PHY_CADENCE_DPHY=m
    -CONFIG_PHY_CADENCE_DPHY_RX=m
    +CONFIG_PHY_CADENCE_DPHY=y
    +CONFIG_PHY_CADENCE_DPHY_RX=y
     CONFIG_PHY_CADENCE_SIERRA=y
     CONFIG_PHY_MIXEL_MIPI_DPHY=m
     CONFIG_PHY_FSL_IMX8M_PCIE=y

    Below is dtso file:-
    // SPDX-License-Identifier: GPL-2.0
    /*
     * Copyright (C) 2022 Texas Instruments Incorporated - https://www.ti.com/
     */
    
    /dts-v1/;
    /plugin/;
    
    #include <dt-bindings/gpio/gpio.h>
    
    / {
    	fragment@101 {
    		target-path = "/";
    
    		_overlay_ {
    			clk_ov5647_fixed: ov5647-xclk {
    				compatible = "fixed-clock";
    				#clock-cells = <0>;
    				clock-frequency = <25000000>;
    			};
    		};
    	};
    };
    
    &main_i2c2 {
    	#address-cells = <1>;
    	#size-cells = <0>;
    	status = "okay";
    
    	i2c-switch@71 {
    		compatible = "nxp,pca9543";
    		#address-cells = <1>;
    		#size-cells = <0>;
    		reg = <0x71>;
    
    		/ CAM port /
    		i2c@1 {
    			#address-cells = <1>;
    			#size-cells = <0>;
    			reg = <1>;
    
    			ov5647: camera@36 {
    				compatible = "ovti,ov5647";
    				reg = <0x36>;
    
    				clocks = <&clk_ov5647_fixed>;
    				clock-names = "xclk";
    				
    				pwdn-gpios = <&exp1 13 GPIO_ACTIVE_LOW>;
    
    				port {
    					csi2_cam0: endpoint {
    						remote-endpoint = <&csi2rx0_in_sensor>;
    						// link-frequencies = /bits/ 64 <456000000>;
    						clock-lanes = <0>;
    						data-lanes = <1 2>;
    					};
    				};
    			};
    		};
    	};
    };
    
    &csi0_port0 {
    	status = "okay";
    
    	csi2rx0_in_sensor: endpoint {
    		remote-endpoint = <&csi2_cam0>;
    		bus-type = <4>; / CSI2 DPHY. /
    		clock-lanes = <0>;
    		data-lanes = <1 2>;
    	};
    };



  • For loading the driver ov5647 what all changes needs to do ?

  • Thanks for always helping me !!!

  • Hello 

    Yes now i am able to see the link frequency using yavta command:- 

    root@am62xx-evm:~# media-ctl --set-v4l2 '"cdns_csi2rx.30101000.csi-bridge":0 [fmt:SBGGR10/640x480 field:none colorspace:srgb xfer:srgb ycbcr:601 quantization:lim-range]'
    root@am62xx-evm:~# yavta -c -Fcapture -s 640x480 -f SBGGR10 /dev/video0
    Device /dev/video0 opened.
    Device `j721e-csi2rx' on `platform:30102000.ticsi2rx' (driver 'j721e-csi2rx') supports video, capture, without mplanes.
    Video f[ 1249.908747] v4l2_get_link_freq: Link frequency estimated using pixel rate: result might be inaccurate
    ormat set: SBGGR10 (30314742) 640x480 (stride 1280) field none b[ 1249.919794] v4l2_get_link_freq: Consider implementing support for V4L2_CID_LINK_FREQ in the transmitter driver
    uffer size 614400
    Video format: SBGGR10 (30314742) 640x480 (str[ 1249.935227] csi2rx_configure_external_dphy: Link frequency is 137500000
    ide 1280) field none buffer size 614400
    8 buffers requested.
    length: 614400 offset: 0 timestamp type/source: mono/EoF
    Buffer 0/0 mapped at address 0xffffae48a000.
    length: 614400 offset: 614400 timestamp type/source: mono/EoF
    Buffer 1/0 mapped at address 0xffffae3f4000.
    length: 614400 offset: 1228800 timestamp type/source: mono/EoF
    Buffer 2/0 mapped at address 0xffffae35e000.
    length: 614400 offset: 1843200 timestamp type/source: mono/EoF
    Buffer 3/0 mapped at address 0xffffae2c8000.
    length: 614400 offset: 2457600 timestamp type/source: mono/EoF
    Buffer 4/0 mapped at address 0xffffae232000.
    length: 614400 offset: 3072000 timestamp type/source: mono/EoF
    Buffer 5/0 mapped at address 0xffffae19c000.
    length: 614400 offset: 3686400 timestamp type/source: mono/EoF
    Buffer 6/0 mapped at address 0xffffae106000.
    length: 614400 offset: 4300800 timestamp type/source: mono/EoF
    Buffer 7/0 mapped at address 0xffffae070000.
    ^C
    root@am62xx-evm:~#

    Now what to do next for capturing the raw images ?

    also you can see media-ctl -p output after setting the media-ctl pipeline:- 

    root@am62xx-evm:~# media-ctl -p
    Media controller API version 6.1.80
    
    Media device information
    ------------------------
    driver          j721e-csi2rx
    model           TI-CSI2RX
    serial
    bus info        platform:30102000.ticsi2rx
    hw revision     0x1
    driver version  6.1.80
    
    Device topology
    - entity 1: 30102000.ticsi2rx (5 pads, 5 links, 1 route)
                type V4L2 subdev subtype Unknown flags 0
                device node name /dev/v4l-subdev0
            routes:
                    0/0 -> 1/0 [ACTIVE]
            pad0: Sink
                    [stream:0 fmt:UYVY8_1X16/640x480 field:none colorspace:srgb xfer:srgb ycbcr:601 quantization:lim-range]
                    <- "cdns_csi2rx.30101000.csi-bridge":1 [ENABLED,IMMUTABLE]
            pad1: Source
                    [stream:0 fmt:UYVY8_1X16/640x480 field:none colorspace:srgb xfer:srgb ycbcr:601 quantization:lim-range]
                    -> "30102000.ticsi2rx context 0":0 [ENABLED,IMMUTABLE]
            pad2: Source
                    -> "30102000.ticsi2rx context 1":0 [ENABLED,IMMUTABLE]
            pad3: Source
                    -> "30102000.ticsi2rx context 2":0 [ENABLED,IMMUTABLE]
            pad4: Source
                    -> "30102000.ticsi2rx context 3":0 [ENABLED,IMMUTABLE]
    
    - entity 7: cdns_csi2rx.30101000.csi-bridge (5 pads, 2 links, 1 route)
                type V4L2 subdev subtype Unknown flags 0
                device node name /dev/v4l-subdev1
            routes:
                    0/0 -> 1/0 [ACTIVE]
            pad0: Sink
                    [stream:0 fmt:SBGGR10_1X10/640x480 field:none colorspace:srgb xfer:srgb ycbcr:601 quantization:lim-range]
                    <- "ov5647 4-0036":0 [ENABLED,IMMUTABLE]
            pad1: Source
                    [stream:0 fmt:SBGGR10_1X10/640x480 field:none colorspace:srgb xfer:srgb ycbcr:601 quantization:lim-range]
                    -> "30102000.ticsi2rx":0 [ENABLED,IMMUTABLE]
            pad2: Source
            pad3: Source
            pad4: Source
    
    - entity 13: ov5647 4-0036 (1 pad, 1 link, 0 route)
                 type V4L2 subdev subtype Sensor flags 0
                 device node name /dev/v4l-subdev2
            pad0: Source
                    [stream:0 fmt:SBGGR10_1X10/640x480 field:none colorspace:srgb
                     crop.bounds:(16,16)/2592x1944
                     crop:(32,16)/2560x1920]
                    -> "cdns_csi2rx.30101000.csi-bridge":0 [ENABLED,IMMUTABLE]
    
    - entity 19: 30102000.ticsi2rx context 0 (1 pad, 1 link, 0 route)
                 type Node subtype V4L flags 0
                 device node name /dev/video0
            pad0: Sink
                    <- "30102000.ticsi2rx":1 [ENABLED,IMMUTABLE]
    
    - entity 25: 30102000.ticsi2rx context 1 (1 pad, 1 link, 0 route)
                 type Node subtype V4L flags 0
                 device node name /dev/video1
            pad0: Sink
                    <- "30102000.ticsi2rx":2 [ENABLED,IMMUTABLE]
    
    - entity 31: 30102000.ticsi2rx context 2 (1 pad, 1 link, 0 route)
                 type Node subtype V4L flags 0
                 device node name /dev/video2
            pad0: Sink
                    <- "30102000.ticsi2rx":3 [ENABLED,IMMUTABLE]
    
    - entity 37: 30102000.ticsi2rx context 3 (1 pad, 1 link, 0 route)
                 type Node subtype V4L flags 0
                 device node name /dev/video3
            pad0: Sink
                    <- "30102000.ticsi2rx":4 [ENABLED,IMMUTABLE]
    
    root@am62xx-evm:~#

  • Ok. The debug print shows the link frequency is 137500000. Why did you comment out the link frequency in you dts?

    // link-frequencies = /bits/ 64 <456000000>;

  • Hello 

    After making changes in dtso file i can see the same output as previous one:- 

    root@am62xx-evm:~# media-ctl --set-v4l2 '"cdns_csi2rx.30101000.csi-bridge":0 [fmt:SBGGR10/640x480 field:none colorspace:srgb xfer:srgb ycbcr:601 quantization:lim-range]'
    root@am62xx-evm:~# yavta -c -Fcapture -s 640x480 -f SBGGR10 /dev/video0
    Device /dev/video0 opened.
    Device `j721e-csi2rx' on `platform:30102000.ticsi2rx' (driver 'j721e-csi2rx') supports video, capture, without mplanes.
    Video f[ 1249.908747] v4l2_get_link_freq: Link frequency estimated using pixel rate: result might be inaccurate
    ormat set: SBGGR10 (30314742) 640x480 (stride 1280) field none b[ 1249.919794] v4l2_get_link_freq: Consider implementing support for V4L2_CID_LINK_FREQ in the transmitter driver
    uffer size 614400
    Video format: SBGGR10 (30314742) 640x480 (str[ 1249.935227] csi2rx_configure_external_dphy: Link frequency is 137500000
    ide 1280) field none buffer size 614400
    8 buffers requested.
    length: 614400 offset: 0 timestamp type/source: mono/EoF
    Buffer 0/0 mapped at address 0xffffae48a000.
    length: 614400 offset: 614400 timestamp type/source: mono/EoF
    Buffer 1/0 mapped at address 0xffffae3f4000.
    length: 614400 offset: 1228800 timestamp type/source: mono/EoF
    Buffer 2/0 mapped at address 0xffffae35e000.
    length: 614400 offset: 1843200 timestamp type/source: mono/EoF
    Buffer 3/0 mapped at address 0xffffae2c8000.
    length: 614400 offset: 2457600 timestamp type/source: mono/EoF
    Buffer 4/0 mapped at address 0xffffae232000.
    length: 614400 offset: 3072000 timestamp type/source: mono/EoF
    Buffer 5/0 mapped at address 0xffffae19c000.
    length: 614400 offset: 3686400 timestamp type/source: mono/EoF
    Buffer 6/0 mapped at address 0xffffae106000.
    length: 614400 offset: 4300800 timestamp type/source: mono/EoF
    Buffer 7/0 mapped at address 0xffffae070000.
    ^C
    root@am62xx-evm:~#

    How to processed further ?

  • Please try to implement support for V4L2_CID_LINK_FREQ in the sensor driver, as the warning message indicated.

  • Hello,

    I have tried to add functions for V4L2_CID_LINK_FREQ in the sensor driver. Below you can find updated ov5647.c file.

    But every time we need to make image and make modules, if error occurs then again need to make the changes and again need to make image, this is somewhat time consuming. 

    // SPDX-License-Identifier: GPL-2.0
    /*
     * A V4L2 driver for OmniVision OV5647 cameras.
     *
     * Based on Samsung S5K6AAFX SXGA 1/6" 1.3M CMOS Image Sensor driver
     * Copyright (C) 2011 Sylwester Nawrocki <s.nawrocki@samsung.com>
     *
     * Based on Omnivision OV7670 Camera Driver
     * Copyright (C) 2006-7 Jonathan Corbet <corbet@lwn.net>
     *
     * Copyright (C) 2016, Synopsys, Inc.
     */
    
    #include <linux/clk.h>
    #include <linux/delay.h>
    #include <linux/gpio/consumer.h>
    #include <linux/i2c.h>
    #include <linux/init.h>
    #include <linux/io.h>
    #include <linux/module.h>
    #include <linux/of_graph.h>
    #include <linux/pm_runtime.h>
    #include <linux/slab.h>
    #include <linux/videodev2.h>
    #include <media/v4l2-ctrls.h>
    #include <media/v4l2-device.h>
    #include <media/v4l2-event.h>
    #include <media/v4l2-fwnode.h>
    #include <media/v4l2-image-sizes.h>
    #include <media/v4l2-mediabus.h>
    
    /*
     * From the datasheet, "20ms after PWDN goes low or 20ms after RESETB goes
     * high if reset is inserted after PWDN goes high, host can access sensor's
     * SCCB to initialize sensor."
     */
    #define PWDN_ACTIVE_DELAY_MS	20
    
    #define MIPI_CTRL00_CLOCK_LANE_GATE		BIT(5)
    #define MIPI_CTRL00_LINE_SYNC_ENABLE		BIT(4)
    #define MIPI_CTRL00_BUS_IDLE			BIT(2)
    #define MIPI_CTRL00_CLOCK_LANE_DISABLE		BIT(0)
    
    #define OV5647_SW_STANDBY		0x0100
    #define OV5647_SW_RESET			0x0103
    #define OV5647_REG_CHIPID_H		0x300a
    #define OV5647_REG_CHIPID_L		0x300b
    #define OV5640_REG_PAD_OUT		0x300d
    #define OV5647_REG_EXP_HI		0x3500
    #define OV5647_REG_EXP_MID		0x3501
    #define OV5647_REG_EXP_LO		0x3502
    #define OV5647_REG_AEC_AGC		0x3503
    #define OV5647_REG_GAIN_HI		0x350a
    #define OV5647_REG_GAIN_LO		0x350b
    #define OV5647_REG_VTS_HI		0x380e
    #define OV5647_REG_VTS_LO		0x380f
    #define OV5647_REG_FRAME_OFF_NUMBER	0x4202
    #define OV5647_REG_MIPI_CTRL00		0x4800
    #define OV5647_REG_MIPI_CTRL14		0x4814
    #define OV5647_REG_AWB			0x5001
    
    #define REG_TERM 0xfffe
    #define VAL_TERM 0xfe
    #define REG_DLY  0xffff
    
    /* OV5647 native and active pixel array size */
    #define OV5647_NATIVE_WIDTH		2624U
    #define OV5647_NATIVE_HEIGHT		1956U
    
    #define OV5647_PIXEL_ARRAY_LEFT		16U
    #define OV5647_PIXEL_ARRAY_TOP		16U
    #define OV5647_PIXEL_ARRAY_WIDTH	2592U
    #define OV5647_PIXEL_ARRAY_HEIGHT	1944U
    
    #define OV5647_VBLANK_MIN		4
    #define OV5647_VTS_MAX			32767
    
    #define OV5647_EXPOSURE_MIN		4
    #define OV5647_EXPOSURE_STEP		1
    #define OV5647_EXPOSURE_DEFAULT		1000
    #define OV5647_EXPOSURE_MAX		65535
    
    struct regval_list {
    	u16 addr;
    	u8 data;
    };
    
    struct ov5647_mode {
    	struct v4l2_mbus_framefmt	format;
    	struct v4l2_rect		crop;
    	u64				pixel_rate;
    	int				hts;
    	int				vts;
    	const struct regval_list	*reg_list;
    	unsigned int			num_regs;
    };
    
    struct ov5647 {
    	struct v4l2_subdev		sd;
    	struct media_pad		pad;
    	struct mutex			lock;
    	struct clk			*xclk;
    	struct gpio_desc		*pwdn;
    	bool				clock_ncont;
    	struct v4l2_ctrl_handler	ctrls;
    	const struct ov5647_mode	*mode;
    	struct v4l2_ctrl		*pixel_rate;
    	struct v4l2_ctrl		*hblank;
    	struct v4l2_ctrl		*vblank;
    	struct v4l2_ctrl		*exposure;
    	bool				streaming;
    };
    
    static inline struct ov5647 *to_sensor(struct v4l2_subdev *sd)
    {
    	return container_of(sd, struct ov5647, sd);
    }
    
    static const struct regval_list sensor_oe_disable_regs[] = {
    	{0x3000, 0x00},
    	{0x3001, 0x00},
    	{0x3002, 0x00},
    };
    
    static const s64 link_freq_menu[] = {
    	137500000,
    };
    
    static const struct regval_list sensor_oe_enable_regs[] = {
    	{0x3000, 0x0f},
    	{0x3001, 0xff},
    	{0x3002, 0xe4},
    };
    
    static struct regval_list ov5647_2592x1944_10bpp[] = {
    	{0x0100, 0x00},
    	{0x0103, 0x01},
    	{0x3034, 0x1a},
    	{0x3035, 0x21},
    	{0x3036, 0x69},
    	{0x303c, 0x11},
    	{0x3106, 0xf5},
    	{0x3821, 0x06},
    	{0x3820, 0x00},
    	{0x3827, 0xec},
    	{0x370c, 0x03},
    	{0x3612, 0x5b},
    	{0x3618, 0x04},
    	{0x5000, 0x06},
    	{0x5002, 0x41},
    	{0x5003, 0x08},
    	{0x5a00, 0x08},
    	{0x3000, 0x00},
    	{0x3001, 0x00},
    	{0x3002, 0x00},
    	{0x3016, 0x08},
    	{0x3017, 0xe0},
    	{0x3018, 0x44},
    	{0x301c, 0xf8},
    	{0x301d, 0xf0},
    	{0x3a18, 0x00},
    	{0x3a19, 0xf8},
    	{0x3c01, 0x80},
    	{0x3b07, 0x0c},
    	{0x380c, 0x0b},
    	{0x380d, 0x1c},
    	{0x3814, 0x11},
    	{0x3815, 0x11},
    	{0x3708, 0x64},
    	{0x3709, 0x12},
    	{0x3808, 0x0a},
    	{0x3809, 0x20},
    	{0x380a, 0x07},
    	{0x380b, 0x98},
    	{0x3800, 0x00},
    	{0x3801, 0x00},
    	{0x3802, 0x00},
    	{0x3803, 0x00},
    	{0x3804, 0x0a},
    	{0x3805, 0x3f},
    	{0x3806, 0x07},
    	{0x3807, 0xa3},
    	{0x3811, 0x10},
    	{0x3813, 0x06},
    	{0x3630, 0x2e},
    	{0x3632, 0xe2},
    	{0x3633, 0x23},
    	{0x3634, 0x44},
    	{0x3636, 0x06},
    	{0x3620, 0x64},
    	{0x3621, 0xe0},
    	{0x3600, 0x37},
    	{0x3704, 0xa0},
    	{0x3703, 0x5a},
    	{0x3715, 0x78},
    	{0x3717, 0x01},
    	{0x3731, 0x02},
    	{0x370b, 0x60},
    	{0x3705, 0x1a},
    	{0x3f05, 0x02},
    	{0x3f06, 0x10},
    	{0x3f01, 0x0a},
    	{0x3a08, 0x01},
    	{0x3a09, 0x28},
    	{0x3a0a, 0x00},
    	{0x3a0b, 0xf6},
    	{0x3a0d, 0x08},
    	{0x3a0e, 0x06},
    	{0x3a0f, 0x58},
    	{0x3a10, 0x50},
    	{0x3a1b, 0x58},
    	{0x3a1e, 0x50},
    	{0x3a11, 0x60},
    	{0x3a1f, 0x28},
    	{0x4001, 0x02},
    	{0x4004, 0x04},
    	{0x4000, 0x09},
    	{0x4837, 0x19},
    	{0x4800, 0x24},
    	{0x3503, 0x03},
    	{0x0100, 0x01},
    };
    
    static struct regval_list ov5647_1080p30_10bpp[] = {
    	{0x0100, 0x00},
    	{0x0103, 0x01},
    	{0x3034, 0x1a},
    	{0x3035, 0x21},
    	{0x3036, 0x62},
    	{0x303c, 0x11},
    	{0x3106, 0xf5},
    	{0x3821, 0x06},
    	{0x3820, 0x00},
    	{0x3827, 0xec},
    	{0x370c, 0x03},
    	{0x3612, 0x5b},
    	{0x3618, 0x04},
    	{0x5000, 0x06},
    	{0x5002, 0x41},
    	{0x5003, 0x08},
    	{0x5a00, 0x08},
    	{0x3000, 0x00},
    	{0x3001, 0x00},
    	{0x3002, 0x00},
    	{0x3016, 0x08},
    	{0x3017, 0xe0},
    	{0x3018, 0x44},
    	{0x301c, 0xf8},
    	{0x301d, 0xf0},
    	{0x3a18, 0x00},
    	{0x3a19, 0xf8},
    	{0x3c01, 0x80},
    	{0x3b07, 0x0c},
    	{0x380c, 0x09},
    	{0x380d, 0x70},
    	{0x3814, 0x11},
    	{0x3815, 0x11},
    	{0x3708, 0x64},
    	{0x3709, 0x12},
    	{0x3808, 0x07},
    	{0x3809, 0x80},
    	{0x380a, 0x04},
    	{0x380b, 0x38},
    	{0x3800, 0x01},
    	{0x3801, 0x5c},
    	{0x3802, 0x01},
    	{0x3803, 0xb2},
    	{0x3804, 0x08},
    	{0x3805, 0xe3},
    	{0x3806, 0x05},
    	{0x3807, 0xf1},
    	{0x3811, 0x04},
    	{0x3813, 0x02},
    	{0x3630, 0x2e},
    	{0x3632, 0xe2},
    	{0x3633, 0x23},
    	{0x3634, 0x44},
    	{0x3636, 0x06},
    	{0x3620, 0x64},
    	{0x3621, 0xe0},
    	{0x3600, 0x37},
    	{0x3704, 0xa0},
    	{0x3703, 0x5a},
    	{0x3715, 0x78},
    	{0x3717, 0x01},
    	{0x3731, 0x02},
    	{0x370b, 0x60},
    	{0x3705, 0x1a},
    	{0x3f05, 0x02},
    	{0x3f06, 0x10},
    	{0x3f01, 0x0a},
    	{0x3a08, 0x01},
    	{0x3a09, 0x4b},
    	{0x3a0a, 0x01},
    	{0x3a0b, 0x13},
    	{0x3a0d, 0x04},
    	{0x3a0e, 0x03},
    	{0x3a0f, 0x58},
    	{0x3a10, 0x50},
    	{0x3a1b, 0x58},
    	{0x3a1e, 0x50},
    	{0x3a11, 0x60},
    	{0x3a1f, 0x28},
    	{0x4001, 0x02},
    	{0x4004, 0x04},
    	{0x4000, 0x09},
    	{0x4837, 0x19},
    	{0x4800, 0x34},
    	{0x3503, 0x03},
    	{0x0100, 0x01},
    };
    
    static struct regval_list ov5647_2x2binned_10bpp[] = {
    	{0x0100, 0x00},
    	{0x0103, 0x01},
    	{0x3034, 0x1a},
    	{0x3035, 0x21},
    	{0x3036, 0x62},
    	{0x303c, 0x11},
    	{0x3106, 0xf5},
    	{0x3827, 0xec},
    	{0x370c, 0x03},
    	{0x3612, 0x59},
    	{0x3618, 0x00},
    	{0x5000, 0x06},
    	{0x5002, 0x41},
    	{0x5003, 0x08},
    	{0x5a00, 0x08},
    	{0x3000, 0x00},
    	{0x3001, 0x00},
    	{0x3002, 0x00},
    	{0x3016, 0x08},
    	{0x3017, 0xe0},
    	{0x3018, 0x44},
    	{0x301c, 0xf8},
    	{0x301d, 0xf0},
    	{0x3a18, 0x00},
    	{0x3a19, 0xf8},
    	{0x3c01, 0x80},
    	{0x3b07, 0x0c},
    	{0x3800, 0x00},
    	{0x3801, 0x00},
    	{0x3802, 0x00},
    	{0x3803, 0x00},
    	{0x3804, 0x0a},
    	{0x3805, 0x3f},
    	{0x3806, 0x07},
    	{0x3807, 0xa3},
    	{0x3808, 0x05},
    	{0x3809, 0x10},
    	{0x380a, 0x03},
    	{0x380b, 0xcc},
    	{0x380c, 0x07},
    	{0x380d, 0x68},
    	{0x3811, 0x0c},
    	{0x3813, 0x06},
    	{0x3814, 0x31},
    	{0x3815, 0x31},
    	{0x3630, 0x2e},
    	{0x3632, 0xe2},
    	{0x3633, 0x23},
    	{0x3634, 0x44},
    	{0x3636, 0x06},
    	{0x3620, 0x64},
    	{0x3621, 0xe0},
    	{0x3600, 0x37},
    	{0x3704, 0xa0},
    	{0x3703, 0x5a},
    	{0x3715, 0x78},
    	{0x3717, 0x01},
    	{0x3731, 0x02},
    	{0x370b, 0x60},
    	{0x3705, 0x1a},
    	{0x3f05, 0x02},
    	{0x3f06, 0x10},
    	{0x3f01, 0x0a},
    	{0x3a08, 0x01},
    	{0x3a09, 0x28},
    	{0x3a0a, 0x00},
    	{0x3a0b, 0xf6},
    	{0x3a0d, 0x08},
    	{0x3a0e, 0x06},
    	{0x3a0f, 0x58},
    	{0x3a10, 0x50},
    	{0x3a1b, 0x58},
    	{0x3a1e, 0x50},
    	{0x3a11, 0x60},
    	{0x3a1f, 0x28},
    	{0x4001, 0x02},
    	{0x4004, 0x04},
    	{0x4000, 0x09},
    	{0x4837, 0x16},
    	{0x4800, 0x24},
    	{0x3503, 0x03},
    	{0x3820, 0x41},
    	{0x3821, 0x07},
    	{0x350a, 0x00},
    	{0x350b, 0x10},
    	{0x3500, 0x00},
    	{0x3501, 0x1a},
    	{0x3502, 0xf0},
    	{0x3212, 0xa0},
    	{0x0100, 0x01},
    };
    
    static struct regval_list ov5647_640x480_10bpp[] = {
    	{0x0100, 0x00},
    	{0x0103, 0x01},
    	{0x3035, 0x11},
    	{0x3036, 0x46},
    	{0x303c, 0x11},
    	{0x3821, 0x07},
    	{0x3820, 0x41},
    	{0x370c, 0x03},
    	{0x3612, 0x59},
    	{0x3618, 0x00},
    	{0x5000, 0x06},
    	{0x5003, 0x08},
    	{0x5a00, 0x08},
    	{0x3000, 0xff},
    	{0x3001, 0xff},
    	{0x3002, 0xff},
    	{0x301d, 0xf0},
    	{0x3a18, 0x00},
    	{0x3a19, 0xf8},
    	{0x3c01, 0x80},
    	{0x3b07, 0x0c},
    	{0x380c, 0x07},
    	{0x380d, 0x3c},
    	{0x3814, 0x35},
    	{0x3815, 0x35},
    	{0x3708, 0x64},
    	{0x3709, 0x52},
    	{0x3808, 0x02},
    	{0x3809, 0x80},
    	{0x380a, 0x01},
    	{0x380b, 0xe0},
    	{0x3800, 0x00},
    	{0x3801, 0x10},
    	{0x3802, 0x00},
    	{0x3803, 0x00},
    	{0x3804, 0x0a},
    	{0x3805, 0x2f},
    	{0x3806, 0x07},
    	{0x3807, 0x9f},
    	{0x3630, 0x2e},
    	{0x3632, 0xe2},
    	{0x3633, 0x23},
    	{0x3634, 0x44},
    	{0x3620, 0x64},
    	{0x3621, 0xe0},
    	{0x3600, 0x37},
    	{0x3704, 0xa0},
    	{0x3703, 0x5a},
    	{0x3715, 0x78},
    	{0x3717, 0x01},
    	{0x3731, 0x02},
    	{0x370b, 0x60},
    	{0x3705, 0x1a},
    	{0x3f05, 0x02},
    	{0x3f06, 0x10},
    	{0x3f01, 0x0a},
    	{0x3a08, 0x01},
    	{0x3a09, 0x2e},
    	{0x3a0a, 0x00},
    	{0x3a0b, 0xfb},
    	{0x3a0d, 0x02},
    	{0x3a0e, 0x01},
    	{0x3a0f, 0x58},
    	{0x3a10, 0x50},
    	{0x3a1b, 0x58},
    	{0x3a1e, 0x50},
    	{0x3a11, 0x60},
    	{0x3a1f, 0x28},
    	{0x4001, 0x02},
    	{0x4004, 0x02},
    	{0x4000, 0x09},
    	{0x3000, 0x00},
    	{0x3001, 0x00},
    	{0x3002, 0x00},
    	{0x3017, 0xe0},
    	{0x301c, 0xfc},
    	{0x3636, 0x06},
    	{0x3016, 0x08},
    	{0x3827, 0xec},
    	{0x3018, 0x44},
    	{0x3035, 0x21},
    	{0x3106, 0xf5},
    	{0x3034, 0x1a},
    	{0x301c, 0xf8},
    	{0x4800, 0x34},
    	{0x3503, 0x03},
    	{0x0100, 0x01},
    };
    /* Function to get link frequency */
    static int ov5647_g_volatile_ctrl(struct v4l2_ctrl *ctrl)
    {
    	struct ov5647 *sensor = container_of(ctrl->handler, struct ov5647, ctrls);
    
    	switch (ctrl->id) {
    		case V4L2_CID_LINK_FREQ;
    	     ctrl->val = 0;
    		 break;
    	default:
    	     return -EINVAL;	 
    	}
    
    	return 0;
    }
    
    /* Function to set link frequency */
    static int ov5647_s_ctrl(struct v4l2_ctrl *ctrl)
    {
    	struct ov5647 *sensor = container_of(ctrl->handler, struct ov5647, ctrls);
    	struct i2c_client *client = v4l2_get_subdevdata(&sensor->sd);
    	int ret = 0;
    
    	switch (ctrl->id) {
        case V4L2_CID_LINK_FREQ:
            dev_info(&client->dev, "Set link frequency to %lld\n", link_freq_menu[ctrl->val]);
            break;
        default:
            return -EINVAL;
        }
        
    	return ret;
    }
    
    static const struct v4l2_ctrl_ops ov5647_ctrl_ops = {
        .g_volatile_ctrl = ov5647_g_volatile_ctrl,
        .s_ctrl = ov5647_s_ctrl,
    };
    
    
    static const struct ov5647_mode ov5647_modes[] = {
    	/* 2592x1944 full resolution full FOV 10-bit mode. */
    	{
    		.format = {
    			.code		= MEDIA_BUS_FMT_SBGGR10_1X10,
    			.colorspace	= V4L2_COLORSPACE_SRGB,
    			.field		= V4L2_FIELD_NONE,
    			.width		= 2592,
    			.height		= 1944
    		},
    		.crop = {
    			.left		= OV5647_PIXEL_ARRAY_LEFT,
    			.top		= OV5647_PIXEL_ARRAY_TOP,
    			.width		= 2592,
    			.height		= 1944
    		},
    		.pixel_rate	= 87500000,
    		.hts		= 2844,
    		.vts		= 0x7b0,
    		.reg_list	= ov5647_2592x1944_10bpp,
    		.num_regs	= ARRAY_SIZE(ov5647_2592x1944_10bpp)
    	},
    	/* 1080p30 10-bit mode. Full resolution centre-cropped down to 1080p. */
    	{
    		.format = {
    			.code		= MEDIA_BUS_FMT_SBGGR10_1X10,
    			.colorspace	= V4L2_COLORSPACE_SRGB,
    			.field		= V4L2_FIELD_NONE,
    			.width		= 1920,
    			.height		= 1080
    		},
    		.crop = {
    			.left		= 348 + OV5647_PIXEL_ARRAY_LEFT,
    			.top		= 434 + OV5647_PIXEL_ARRAY_TOP,
    			.width		= 1928,
    			.height		= 1080,
    		},
    		.pixel_rate	= 81666700,
    		.hts		= 2416,
    		.vts		= 0x450,
    		.reg_list	= ov5647_1080p30_10bpp,
    		.num_regs	= ARRAY_SIZE(ov5647_1080p30_10bpp)
    	},
    	/* 2x2 binned full FOV 10-bit mode. */
    	{
    		.format = {
    			.code		= MEDIA_BUS_FMT_SBGGR10_1X10,
    			.colorspace	= V4L2_COLORSPACE_SRGB,
    			.field		= V4L2_FIELD_NONE,
    			.width		= 1296,
    			.height		= 972
    		},
    		.crop = {
    			.left		= OV5647_PIXEL_ARRAY_LEFT,
    			.top		= OV5647_PIXEL_ARRAY_TOP,
    			.width		= 2592,
    			.height		= 1944,
    		},
    		.pixel_rate	= 81666700,
    		.hts		= 1896,
    		.vts		= 0x59b,
    		.reg_list	= ov5647_2x2binned_10bpp,
    		.num_regs	= ARRAY_SIZE(ov5647_2x2binned_10bpp)
    	},
    	/* 10-bit VGA full FOV 60fps. 2x2 binned and subsampled down to VGA. */
    	{
    		.format = {
    			.code		= MEDIA_BUS_FMT_SBGGR10_1X10,
    			.colorspace	= V4L2_COLORSPACE_SRGB,
    			.field		= V4L2_FIELD_NONE,
    			.width		= 640,
    			.height		= 480
    		},
    		.crop = {
    			.left		= 16 + OV5647_PIXEL_ARRAY_LEFT,
    			.top		= OV5647_PIXEL_ARRAY_TOP,
    			.width		= 2560,
    			.height		= 1920,
    		},
    		.pixel_rate	= 55000000,
    		.hts		= 1852,
    		.vts		= 0x1f8,
    		.reg_list	= ov5647_640x480_10bpp,
    		.num_regs	= ARRAY_SIZE(ov5647_640x480_10bpp)
    	},
    };
    
    /* Default sensor mode is 2x2 binned 640x480 SBGGR10_1X10. */
    #define OV5647_DEFAULT_MODE	(&ov5647_modes[3])
    #define OV5647_DEFAULT_FORMAT	(ov5647_modes[3].format)
    
    static int ov5647_write16(struct v4l2_subdev *sd, u16 reg, u16 val)
    {
    	unsigned char data[4] = { reg >> 8, reg & 0xff, val >> 8, val & 0xff};
    	struct i2c_client *client = v4l2_get_subdevdata(sd);
    	int ret;
    
    	ret = i2c_master_send(client, data, 4);
    	if (ret < 0) {
    		dev_dbg(&client->dev, "%s: i2c write error, reg: %x\n",
    			__func__, reg);
    		return ret;
    	}
    
    	return 0;
    }
    
    static int ov5647_write(struct v4l2_subdev *sd, u16 reg, u8 val)
    {
    	unsigned char data[3] = { reg >> 8, reg & 0xff, val};
    	struct i2c_client *client = v4l2_get_subdevdata(sd);
    	int ret;
    
    	ret = i2c_master_send(client, data, 3);
    	if (ret < 0) {
    		dev_dbg(&client->dev, "%s: i2c write error, reg: %x\n",
    				__func__, reg);
    		return ret;
    	}
    
    	return 0;
    }
    
    static int ov5647_read(struct v4l2_subdev *sd, u16 reg, u8 *val)
    {
    	unsigned char data_w[2] = { reg >> 8, reg & 0xff };
    	struct i2c_client *client = v4l2_get_subdevdata(sd);
    	int ret;
    
    	ret = i2c_master_send(client, data_w, 2);
    	if (ret < 0) {
    		dev_dbg(&client->dev, "%s: i2c write error, reg: %x\n",
    			__func__, reg);
    		return ret;
    	}
    
    	ret = i2c_master_recv(client, val, 1);
    	if (ret < 0) {
    		dev_dbg(&client->dev, "%s: i2c read error, reg: %x\n",
    				__func__, reg);
    		return ret;
    	}
    
    	return 0;
    }
    
    static int ov5647_write_array(struct v4l2_subdev *sd,
    			      const struct regval_list *regs, int array_size)
    {
    	int i, ret;
    
    	for (i = 0; i < array_size; i++) {
    		ret = ov5647_write(sd, regs[i].addr, regs[i].data);
    		if (ret < 0)
    			return ret;
    	}
    
    	return 0;
    }
    
    static int ov5647_set_virtual_channel(struct v4l2_subdev *sd, int channel)
    {
    	u8 channel_id;
    	int ret;
    
    	ret = ov5647_read(sd, OV5647_REG_MIPI_CTRL14, &channel_id);
    	if (ret < 0)
    		return ret;
    
    	channel_id &= ~(3 << 6);
    
    	return ov5647_write(sd, OV5647_REG_MIPI_CTRL14,
    			    channel_id | (channel << 6));
    }
    
    static int ov5647_set_mode(struct v4l2_subdev *sd)
    {
    	struct i2c_client *client = v4l2_get_subdevdata(sd);
    	struct ov5647 *sensor = to_sensor(sd);
    	u8 resetval, rdval;
    	int ret;
    
    	ret = ov5647_read(sd, OV5647_SW_STANDBY, &rdval);
    	if (ret < 0)
    		return ret;
    
    	ret = ov5647_write_array(sd, sensor->mode->reg_list,
    				 sensor->mode->num_regs);
    	if (ret < 0) {
    		dev_err(&client->dev, "write sensor default regs error\n");
    		return ret;
    	}
    
    	ret = ov5647_set_virtual_channel(sd, 0);
    	if (ret < 0)
    		return ret;
    
    	ret = ov5647_read(sd, OV5647_SW_STANDBY, &resetval);
    	if (ret < 0)
    		return ret;
    
    	if (!(resetval & 0x01)) {
    		dev_err(&client->dev, "Device was in SW standby");
    		ret = ov5647_write(sd, OV5647_SW_STANDBY, 0x01);
    		if (ret < 0)
    			return ret;
    	}
    
    	return 0;
    }
    
    static int ov5647_stream_on(struct v4l2_subdev *sd)
    {
    	struct i2c_client *client = v4l2_get_subdevdata(sd);
    	struct ov5647 *sensor = to_sensor(sd);
    	u8 val = MIPI_CTRL00_BUS_IDLE;
    	int ret;
    
    	ret = ov5647_set_mode(sd);
    	if (ret) {
    		dev_err(&client->dev, "Failed to program sensor mode: %d\n", ret);
    		return ret;
    	}
    
    	/* Apply customized values from user when stream starts. */
    	ret =  __v4l2_ctrl_handler_setup(sd->ctrl_handler);
    	if (ret)
    		return ret;
    
    	if (sensor->clock_ncont)
    		val |= MIPI_CTRL00_CLOCK_LANE_GATE |
    		       MIPI_CTRL00_LINE_SYNC_ENABLE;
    
    	ret = ov5647_write(sd, OV5647_REG_MIPI_CTRL00, val);
    	if (ret < 0)
    		return ret;
    
    	ret = ov5647_write(sd, OV5647_REG_FRAME_OFF_NUMBER, 0x00);
    	if (ret < 0)
    		return ret;
    
    	return ov5647_write(sd, OV5640_REG_PAD_OUT, 0x00);
    }
    
    static int ov5647_stream_off(struct v4l2_subdev *sd)
    {
    	int ret;
    
    	ret = ov5647_write(sd, OV5647_REG_MIPI_CTRL00,
    			   MIPI_CTRL00_CLOCK_LANE_GATE | MIPI_CTRL00_BUS_IDLE |
    			   MIPI_CTRL00_CLOCK_LANE_DISABLE);
    	if (ret < 0)
    		return ret;
    
    	ret = ov5647_write(sd, OV5647_REG_FRAME_OFF_NUMBER, 0x0f);
    	if (ret < 0)
    		return ret;
    
    	return ov5647_write(sd, OV5640_REG_PAD_OUT, 0x01);
    }
    
    static int ov5647_power_on(struct device *dev)
    {
    	struct ov5647 *sensor = dev_get_drvdata(dev);
    	int ret;
    
    	dev_dbg(dev, "OV5647 power on\n");
    
    	if (sensor->pwdn) {
    		gpiod_set_value_cansleep(sensor->pwdn, 0);
    		msleep(PWDN_ACTIVE_DELAY_MS);
    	}
    
    	ret = clk_prepare_enable(sensor->xclk);
    	if (ret < 0) {
    		dev_err(dev, "clk prepare enable failed\n");
    		goto error_pwdn;
    	}
    
    	ret = ov5647_write_array(&sensor->sd, sensor_oe_enable_regs,
    				 ARRAY_SIZE(sensor_oe_enable_regs));
    	if (ret < 0) {
    		dev_err(dev, "write sensor_oe_enable_regs error\n");
    		goto error_clk_disable;
    	}
    
    	/* Stream off to coax lanes into LP-11 state. */
    	ret = ov5647_stream_off(&sensor->sd);
    	if (ret < 0) {
    		dev_err(dev, "camera not available, check power\n");
    		goto error_clk_disable;
    	}
    
    	return 0;
    
    error_clk_disable:
    	clk_disable_unprepare(sensor->xclk);
    error_pwdn:
    	gpiod_set_value_cansleep(sensor->pwdn, 1);
    
    	return ret;
    }
    
    static int ov5647_power_off(struct device *dev)
    {
    	struct ov5647 *sensor = dev_get_drvdata(dev);
    	u8 rdval;
    	int ret;
    
    	dev_dbg(dev, "OV5647 power off\n");
    
    	ret = ov5647_write_array(&sensor->sd, sensor_oe_disable_regs,
    				 ARRAY_SIZE(sensor_oe_disable_regs));
    	if (ret < 0)
    		dev_dbg(dev, "disable oe failed\n");
    
    	/* Enter software standby */
    	ret = ov5647_read(&sensor->sd, OV5647_SW_STANDBY, &rdval);
    	if (ret < 0)
    		dev_dbg(dev, "software standby failed\n");
    
    	rdval &= ~0x01;
    	ret = ov5647_write(&sensor->sd, OV5647_SW_STANDBY, rdval);
    	if (ret < 0)
    		dev_dbg(dev, "software standby failed\n");
    
    	clk_disable_unprepare(sensor->xclk);
    	gpiod_set_value_cansleep(sensor->pwdn, 1);
    
    	return 0;
    }
    
    #ifdef CONFIG_VIDEO_ADV_DEBUG
    static int ov5647_sensor_get_register(struct v4l2_subdev *sd,
    				      struct v4l2_dbg_register *reg)
    {
    	int ret;
    	u8 val;
    
    	ret = ov5647_read(sd, reg->reg & 0xff, &val);
    	if (ret < 0)
    		return ret;
    
    	reg->val = val;
    	reg->size = 1;
    
    	return 0;
    }
    
    static int ov5647_sensor_set_register(struct v4l2_subdev *sd,
    				      const struct v4l2_dbg_register *reg)
    {
    	return ov5647_write(sd, reg->reg & 0xff, reg->val & 0xff);
    }
    #endif
    
    /* Subdev core operations registration */
    static const struct v4l2_subdev_core_ops ov5647_subdev_core_ops = {
    	.subscribe_event	= v4l2_ctrl_subdev_subscribe_event,
    	.unsubscribe_event	= v4l2_event_subdev_unsubscribe,
    #ifdef CONFIG_VIDEO_ADV_DEBUG
    	.g_register		= ov5647_sensor_get_register,
    	.s_register		= ov5647_sensor_set_register,
    #endif
    };
    
    static const struct v4l2_rect *
    __ov5647_get_pad_crop(struct ov5647 *ov5647,
    		      struct v4l2_subdev_state *sd_state,
    		      unsigned int pad, enum v4l2_subdev_format_whence which)
    {
    	switch (which) {
    	case V4L2_SUBDEV_FORMAT_TRY:
    		return v4l2_subdev_get_try_crop(&ov5647->sd, sd_state, pad);
    	case V4L2_SUBDEV_FORMAT_ACTIVE:
    		return &ov5647->mode->crop;
    	}
    
    	return NULL;
    }
    
    static int ov5647_s_stream(struct v4l2_subdev *sd, int enable)
    {
    	struct i2c_client *client = v4l2_get_subdevdata(sd);
    	struct ov5647 *sensor = to_sensor(sd);
    	int ret;
    
    	mutex_lock(&sensor->lock);
    	if (sensor->streaming == enable) {
    		mutex_unlock(&sensor->lock);
    		return 0;
    	}
    
    	if (enable) {
    		ret = pm_runtime_resume_and_get(&client->dev);
    		if (ret < 0)
    			goto error_unlock;
    
    		ret = ov5647_stream_on(sd);
    		if (ret < 0) {
    			dev_err(&client->dev, "stream start failed: %d\n", ret);
    			goto error_pm;
    		}
    	} else {
    		ret = ov5647_stream_off(sd);
    		if (ret < 0) {
    			dev_err(&client->dev, "stream stop failed: %d\n", ret);
    			goto error_pm;
    		}
    		pm_runtime_put(&client->dev);
    	}
    
    	sensor->streaming = enable;
    	mutex_unlock(&sensor->lock);
    
    	return 0;
    
    error_pm:
    	pm_runtime_put(&client->dev);
    error_unlock:
    	mutex_unlock(&sensor->lock);
    
    	return ret;
    }
    
    static const struct v4l2_subdev_video_ops ov5647_subdev_video_ops = {
    	.s_stream =		ov5647_s_stream,
    };
    
    static int ov5647_enum_mbus_code(struct v4l2_subdev *sd,
    				 struct v4l2_subdev_state *sd_state,
    				 struct v4l2_subdev_mbus_code_enum *code)
    {
    	if (code->index > 0)
    		return -EINVAL;
    
    	code->code = MEDIA_BUS_FMT_SBGGR10_1X10;
    
    	return 0;
    }
    
    static int ov5647_enum_frame_size(struct v4l2_subdev *sd,
    				  struct v4l2_subdev_state *sd_state,
    				  struct v4l2_subdev_frame_size_enum *fse)
    {
    	const struct v4l2_mbus_framefmt *fmt;
    
    	if (fse->code != MEDIA_BUS_FMT_SBGGR10_1X10 ||
    	    fse->index >= ARRAY_SIZE(ov5647_modes))
    		return -EINVAL;
    
    	fmt = &ov5647_modes[fse->index].format;
    	fse->min_width = fmt->width;
    	fse->max_width = fmt->width;
    	fse->min_height = fmt->height;
    	fse->max_height = fmt->height;
    
    	return 0;
    }
    
    static int ov5647_get_pad_fmt(struct v4l2_subdev *sd,
    			      struct v4l2_subdev_state *sd_state,
    			      struct v4l2_subdev_format *format)
    {
    	struct v4l2_mbus_framefmt *fmt = &format->format;
    	const struct v4l2_mbus_framefmt *sensor_format;
    	struct ov5647 *sensor = to_sensor(sd);
    
    	mutex_lock(&sensor->lock);
    	switch (format->which) {
    	case V4L2_SUBDEV_FORMAT_TRY:
    		sensor_format = v4l2_subdev_get_try_format(sd, sd_state,
    							   format->pad);
    		break;
    	default:
    		sensor_format = &sensor->mode->format;
    		break;
    	}
    
    	*fmt = *sensor_format;
    	mutex_unlock(&sensor->lock);
    
    	return 0;
    }
    
    static int ov5647_set_pad_fmt(struct v4l2_subdev *sd,
    			      struct v4l2_subdev_state *sd_state,
    			      struct v4l2_subdev_format *format)
    {
    	struct v4l2_mbus_framefmt *fmt = &format->format;
    	struct ov5647 *sensor = to_sensor(sd);
    	const struct ov5647_mode *mode;
    
    	mode = v4l2_find_nearest_size(ov5647_modes, ARRAY_SIZE(ov5647_modes),
    				      format.width, format.height,
    				      fmt->width, fmt->height);
    
    	/* Update the sensor mode and apply at it at streamon time. */
    	mutex_lock(&sensor->lock);
    	if (format->which == V4L2_SUBDEV_FORMAT_TRY) {
    		*v4l2_subdev_get_try_format(sd, sd_state, format->pad) = mode->format;
    	} else {
    		int exposure_max, exposure_def;
    		int hblank, vblank;
    
    		sensor->mode = mode;
    		__v4l2_ctrl_modify_range(sensor->pixel_rate, mode->pixel_rate,
    					 mode->pixel_rate, 1, mode->pixel_rate);
    
    		hblank = mode->hts - mode->format.width;
    		__v4l2_ctrl_modify_range(sensor->hblank, hblank, hblank, 1,
    					 hblank);
    
    		vblank = mode->vts - mode->format.height;
    		__v4l2_ctrl_modify_range(sensor->vblank, OV5647_VBLANK_MIN,
    					 OV5647_VTS_MAX - mode->format.height,
    					 1, vblank);
    		__v4l2_ctrl_s_ctrl(sensor->vblank, vblank);
    
    		exposure_max = mode->vts - 4;
    		exposure_def = min(exposure_max, OV5647_EXPOSURE_DEFAULT);
    		__v4l2_ctrl_modify_range(sensor->exposure,
    					 sensor->exposure->minimum,
    					 exposure_max, sensor->exposure->step,
    					 exposure_def);
    	}
    	*fmt = mode->format;
    	mutex_unlock(&sensor->lock);
    
    	return 0;
    }
    
    static int ov5647_get_selection(struct v4l2_subdev *sd,
    				struct v4l2_subdev_state *sd_state,
    				struct v4l2_subdev_selection *sel)
    {
    	switch (sel->target) {
    	case V4L2_SEL_TGT_CROP: {
    		struct ov5647 *sensor = to_sensor(sd);
    
    		mutex_lock(&sensor->lock);
    		sel->r = *__ov5647_get_pad_crop(sensor, sd_state, sel->pad,
    						sel->which);
    		mutex_unlock(&sensor->lock);
    
    		return 0;
    	}
    
    	case V4L2_SEL_TGT_NATIVE_SIZE:
    		sel->r.top = 0;
    		sel->r.left = 0;
    		sel->r.width = OV5647_NATIVE_WIDTH;
    		sel->r.height = OV5647_NATIVE_HEIGHT;
    
    		return 0;
    
    	case V4L2_SEL_TGT_CROP_DEFAULT:
    	case V4L2_SEL_TGT_CROP_BOUNDS:
    		sel->r.top = OV5647_PIXEL_ARRAY_TOP;
    		sel->r.left = OV5647_PIXEL_ARRAY_LEFT;
    		sel->r.width = OV5647_PIXEL_ARRAY_WIDTH;
    		sel->r.height = OV5647_PIXEL_ARRAY_HEIGHT;
    
    		return 0;
    	}
    
    	return -EINVAL;
    }
    
    static const struct v4l2_subdev_pad_ops ov5647_subdev_pad_ops = {
    	.enum_mbus_code		= ov5647_enum_mbus_code,
    	.enum_frame_size	= ov5647_enum_frame_size,
    	.set_fmt		= ov5647_set_pad_fmt,
    	.get_fmt		= ov5647_get_pad_fmt,
    	.get_selection		= ov5647_get_selection,
    };
    
    static const struct v4l2_subdev_ops ov5647_subdev_ops = {
    	.core		= &ov5647_subdev_core_ops,
    	.video		= &ov5647_subdev_video_ops,
    	.pad		= &ov5647_subdev_pad_ops,
    };
    
    static int ov5647_detect(struct v4l2_subdev *sd)
    {
    	struct i2c_client *client = v4l2_get_subdevdata(sd);
    	u8 read;
    	int ret;
    
    	ret = ov5647_write(sd, OV5647_SW_RESET, 0x01);
    	if (ret < 0)
    		return ret;
    
    	ret = ov5647_read(sd, OV5647_REG_CHIPID_H, &read);
    	if (ret < 0)
    		return ret;
    
    	if (read != 0x56) {
    		dev_err(&client->dev, "ID High expected 0x56 got %x", read);
    		return -ENODEV;
    	}
    
    	ret = ov5647_read(sd, OV5647_REG_CHIPID_L, &read);
    	if (ret < 0)
    		return ret;
    
    	if (read != 0x47) {
    		dev_err(&client->dev, "ID Low expected 0x47 got %x", read);
    		return -ENODEV;
    	}
    
    	return ov5647_write(sd, OV5647_SW_RESET, 0x00);
    }
    
    static int ov5647_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
    {
    	struct v4l2_mbus_framefmt *format =
    				v4l2_subdev_get_try_format(sd, fh->state, 0);
    	struct v4l2_rect *crop = v4l2_subdev_get_try_crop(sd, fh->state, 0);
    
    	crop->left = OV5647_PIXEL_ARRAY_LEFT;
    	crop->top = OV5647_PIXEL_ARRAY_TOP;
    	crop->width = OV5647_PIXEL_ARRAY_WIDTH;
    	crop->height = OV5647_PIXEL_ARRAY_HEIGHT;
    
    	*format = OV5647_DEFAULT_FORMAT;
    
    	return 0;
    }
    
    static const struct v4l2_subdev_internal_ops ov5647_subdev_internal_ops = {
    	.open = ov5647_open,
    };
    
    static int ov5647_s_auto_white_balance(struct v4l2_subdev *sd, u32 val)
    {
    	return ov5647_write(sd, OV5647_REG_AWB, val ? 1 : 0);
    }
    
    static int ov5647_s_autogain(struct v4l2_subdev *sd, u32 val)
    {
    	int ret;
    	u8 reg;
    
    	/* Non-zero turns on AGC by clearing bit 1.*/
    	ret = ov5647_read(sd, OV5647_REG_AEC_AGC, &reg);
    	if (ret)
    		return ret;
    
    	return ov5647_write(sd, OV5647_REG_AEC_AGC, val ? reg & ~BIT(1)
    							: reg | BIT(1));
    }
    
    static int ov5647_s_exposure_auto(struct v4l2_subdev *sd, u32 val)
    {
    	int ret;
    	u8 reg;
    
    	/*
    	 * Everything except V4L2_EXPOSURE_MANUAL turns on AEC by
    	 * clearing bit 0.
    	 */
    	ret = ov5647_read(sd, OV5647_REG_AEC_AGC, &reg);
    	if (ret)
    		return ret;
    
    	return ov5647_write(sd, OV5647_REG_AEC_AGC,
    			    val == V4L2_EXPOSURE_MANUAL ? reg | BIT(0)
    							: reg & ~BIT(0));
    }
    
    static int ov5647_s_analogue_gain(struct v4l2_subdev *sd, u32 val)
    {
    	int ret;
    
    	/* 10 bits of gain, 2 in the high register. */
    	ret = ov5647_write(sd, OV5647_REG_GAIN_HI, (val >> 8) & 3);
    	if (ret)
    		return ret;
    
    	return ov5647_write(sd, OV5647_REG_GAIN_LO, val & 0xff);
    }
    
    static int ov5647_s_exposure(struct v4l2_subdev *sd, u32 val)
    {
    	int ret;
    
    	/*
    	 * Sensor has 20 bits, but the bottom 4 bits are fractions of a line
    	 * which we leave as zero (and don't receive in "val").
    	 */
    	ret = ov5647_write(sd, OV5647_REG_EXP_HI, (val >> 12) & 0xf);
    	if (ret)
    		return ret;
    
    	ret = ov5647_write(sd, OV5647_REG_EXP_MID, (val >> 4) & 0xff);
    	if (ret)
    		return ret;
    
    	return ov5647_write(sd, OV5647_REG_EXP_LO, (val & 0xf) << 4);
    }
    
    static int ov5647_s_ctrl(struct v4l2_ctrl *ctrl)
    {
    	struct ov5647 *sensor = container_of(ctrl->handler,
    					    struct ov5647, ctrls);
    	struct v4l2_subdev *sd = &sensor->sd;
    	struct i2c_client *client = v4l2_get_subdevdata(sd);
    	int ret = 0;
    
    
    	/* v4l2_ctrl_lock() locks our own mutex */
    
    	if (ctrl->id == V4L2_CID_VBLANK) {
    		int exposure_max, exposure_def;
    
    		/* Update max exposure while meeting expected vblanking */
    		exposure_max = sensor->mode->format.height + ctrl->val - 4;
    		exposure_def = min(exposure_max, OV5647_EXPOSURE_DEFAULT);
    		__v4l2_ctrl_modify_range(sensor->exposure,
    					 sensor->exposure->minimum,
    					 exposure_max, sensor->exposure->step,
    					 exposure_def);
    	}
    
    	/*
    	 * If the device is not powered up do not apply any controls
    	 * to H/W at this time. Instead the controls will be restored
    	 * at s_stream(1) time.
    	 */
    	if (pm_runtime_get_if_in_use(&client->dev) == 0)
    		return 0;
    
    	switch (ctrl->id) {
    	case V4L2_CID_AUTO_WHITE_BALANCE:
    		ret = ov5647_s_auto_white_balance(sd, ctrl->val);
    		break;
    	case V4L2_CID_AUTOGAIN:
    		ret = ov5647_s_autogain(sd, ctrl->val);
    		break;
    	case V4L2_CID_EXPOSURE_AUTO:
    		ret = ov5647_s_exposure_auto(sd, ctrl->val);
    		break;
    	case V4L2_CID_ANALOGUE_GAIN:
    		ret =  ov5647_s_analogue_gain(sd, ctrl->val);
    		break;
    	case V4L2_CID_EXPOSURE:
    		ret = ov5647_s_exposure(sd, ctrl->val);
    		break;
    	case V4L2_CID_VBLANK:
    		ret = ov5647_write16(sd, OV5647_REG_VTS_HI,
    				     sensor->mode->format.height + ctrl->val);
    		break;
    
    	/* Read-only, but we adjust it based on mode. */
    	case V4L2_CID_PIXEL_RATE:
    	case V4L2_CID_HBLANK:
    		/* Read-only, but we adjust it based on mode. */
    		break;
    
    	default:
    		dev_info(&client->dev,
    			 "Control (id:0x%x, val:0x%x) not supported\n",
    			 ctrl->id, ctrl->val);
    		return -EINVAL;
    	}
    
    	pm_runtime_put(&client->dev);
    
    	return ret;
    }
    
    static const struct v4l2_ctrl_ops ov5647_ctrl_ops = {
    	.s_ctrl = ov5647_s_ctrl,
    };
    
    static int ov5647_init_controls(struct ov5647 *sensor)
    {
        struct i2c_client *client = v4l2_get_subdevdata(&sensor->sd);
        int hblank, exposure_max, exposure_def;
    
        v4l2_ctrl_handler_init(&sensor->ctrls, 9);
    
        v4l2_ctrl_new_std(&sensor->ctrls, &ov5647_ctrl_ops,
                          V4L2_CID_AUTOGAIN, 0, 1, 1, 0);
    
        v4l2_ctrl_new_std(&sensor->ctrls, &ov5647_ctrl_ops,
                          V4L2_CID_AUTO_WHITE_BALANCE, 0, 1, 1, 0);
    
        v4l2_ctrl_new_std_menu(&sensor->ctrls, &ov5647_ctrl_ops,
                               V4L2_CID_EXPOSURE_AUTO, V4L2_EXPOSURE_MANUAL,
                               0, V4L2_EXPOSURE_MANUAL);
    
        exposure_max = sensor->mode->vts - 4;
        exposure_def = min(exposure_max, OV5647_EXPOSURE_DEFAULT);
        sensor->exposure = v4l2_ctrl_new_std(&sensor->ctrls, &ov5647_ctrl_ops,
                                             V4L2_CID_EXPOSURE,
                                             OV5647_EXPOSURE_MIN,
                                             exposure_max, OV5647_EXPOSURE_STEP,
                                             exposure_def);
    
        /* min: 16 = 1.0x; max (10 bits); default: 32 = 2.0x. */
        v4l2_ctrl_new_std(&sensor->ctrls, &ov5647_ctrl_ops,
                          V4L2_CID_ANALOGUE_GAIN, 16, 1023, 1, 32);
    
        /* By default, PIXEL_RATE is read only, but it does change per mode */
        sensor->pixel_rate = v4l2_ctrl_new_std(&sensor->ctrls, &ov5647_ctrl_ops,
                                               V4L2_CID_PIXEL_RATE,
                                               sensor->mode->pixel_rate,
                                               sensor->mode->pixel_rate, 1,
                                               sensor->mode->pixel_rate);
    
        sensor->link_freq = v4l2_ctrl_new_int_menu(&sensor->ctrls, &ov5647_ctrl_ops,
                                                   V4L2_CID_LINK_FREQ, 1, 0,
                                                   link_freq_menu);
    
        /* By default, HBLANK is read only, but it does change per mode. */
        hblank = sensor->mode->hts - sensor->mode->format.width;
        sensor->hblank = v4l2_ctrl_new_std(&sensor->ctrls, &ov5647_ctrl_ops,
                                           V4L2_CID_HBLANK, hblank, hblank, 1,
                                           hblank);
    
        sensor->vblank = v4l2_ctrl_new_std(&sensor->ctrls, &ov5647_ctrl_ops,
                                           V4L2_CID_VBLANK, OV5647_VBLANK_MIN,
                                           OV5647_VTS_MAX - sensor->mode->format.height, 1,
                                           sensor->mode->vts - sensor->mode->format.height);
    
        if (sensor->ctrls.error) {
            dev_err(&client->dev, "control init failed: %d\n", sensor->ctrls.error);
            goto handler_free;
        }
    
        sensor->pixel_rate->flags |= V4L2_CTRL_FLAG_READ_ONLY;
        sensor->hblank->flags |= V4L2_CTRL_FLAG_READ_ONLY;
        sensor->sd.ctrl_handler = &sensor->ctrls;
    
        return 0;
    
    handler_free:
        dev_err(&client->dev, "%s Controls initialization failed (%d)\n",
                __func__, sensor->ctrls.error);
        v4l2_ctrl_handler_free(&sensor->ctrls);
    
        return sensor->ctrls.error;
    }
    
    
    static int ov5647_parse_dt(struct ov5647 *sensor, struct device_node *np)
    {
    	struct v4l2_fwnode_endpoint bus_cfg = {
    		.bus_type = V4L2_MBUS_CSI2_DPHY,
    	};
    	struct device_node *ep;
    	int ret;
    
    	ep = of_graph_get_next_endpoint(np, NULL);
    	if (!ep)
    		return -EINVAL;
    
    	ret = v4l2_fwnode_endpoint_parse(of_fwnode_handle(ep), &bus_cfg);
    	if (ret)
    		goto out;
    
    	sensor->clock_ncont = bus_cfg.bus.mipi_csi2.flags &
    			      V4L2_MBUS_CSI2_NONCONTINUOUS_CLOCK;
    
    out:
    	of_node_put(ep);
    
    	return ret;
    }
    
    static int ov5647_probe(struct i2c_client *client)
    {
    	struct device_node *np = client->dev.of_node;
    	struct device *dev = &client->dev;
    	struct ov5647 *sensor;
    	struct v4l2_subdev *sd;
    	u32 xclk_freq;
    	int ret;
    
    	sensor = devm_kzalloc(dev, sizeof(*sensor), GFP_KERNEL);
    	if (!sensor)
    		return -ENOMEM;
    
    	if (IS_ENABLED(CONFIG_OF) && np) {
    		ret = ov5647_parse_dt(sensor, np);
    		if (ret) {
    			dev_err(dev, "DT parsing error: %d\n", ret);
    			return ret;
    		}
    	}
    
    	sensor->xclk = devm_clk_get(dev, NULL);
    	if (IS_ERR(sensor->xclk)) {
    		dev_err(dev, "could not get xclk");
    		return PTR_ERR(sensor->xclk);
    	}
    
    	xclk_freq = clk_get_rate(sensor->xclk);
    	if (xclk_freq != 25000000) {
    		dev_err(dev, "Unsupported clock frequency: %u\n", xclk_freq);
    		return -EINVAL;
    	}
    
    	/* Request the power down GPIO asserted. */
    	sensor->pwdn = devm_gpiod_get_optional(dev, "pwdn", GPIOD_OUT_HIGH);
    	if (IS_ERR(sensor->pwdn)) {
    		dev_err(dev, "Failed to get 'pwdn' gpio\n");
    		return -EINVAL;
    	}
    
    	mutex_init(&sensor->lock);
    
    	sensor->mode = OV5647_DEFAULT_MODE;
    
    	ret = ov5647_init_controls(sensor);
    	if (ret)
    		goto mutex_destroy;
    
    	sd = &sensor->sd;
    	v4l2_i2c_subdev_init(sd, client, &ov5647_subdev_ops);
    	sd->internal_ops = &ov5647_subdev_internal_ops;
    	sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE | V4L2_SUBDEV_FL_HAS_EVENTS;
    
    	sensor->pad.flags = MEDIA_PAD_FL_SOURCE;
    	sd->entity.function = MEDIA_ENT_F_CAM_SENSOR;
    	ret = media_entity_pads_init(&sd->entity, 1, &sensor->pad);
    	if (ret < 0)
    		goto ctrl_handler_free;
    
    	ret = ov5647_power_on(dev);
    	if (ret)
    		goto entity_cleanup;
    
    	ret = ov5647_detect(sd);
    	if (ret < 0)
    		goto power_off;
    
    	ret = v4l2_async_register_subdev(sd);
    	if (ret < 0)
    		goto power_off;
    
    	/* Enable runtime PM and turn off the device */
    	pm_runtime_set_active(dev);
    	pm_runtime_enable(dev);
    	pm_runtime_idle(dev);
    
    	dev_dbg(dev, "OmniVision OV5647 camera driver probed\n");
    
    	return 0;
    
    power_off:
    	ov5647_power_off(dev);
    entity_cleanup:
    	media_entity_cleanup(&sd->entity);
    ctrl_handler_free:
    	v4l2_ctrl_handler_free(&sensor->ctrls);
    mutex_destroy:
    	mutex_destroy(&sensor->lock);
    
    	return ret;
    }
    
    static void ov5647_remove(struct i2c_client *client)
    {
    	struct v4l2_subdev *sd = i2c_get_clientdata(client);
    	struct ov5647 *sensor = to_sensor(sd);
    
    	v4l2_async_unregister_subdev(&sensor->sd);
    	media_entity_cleanup(&sensor->sd.entity);
    	v4l2_ctrl_handler_free(&sensor->ctrls);
    	v4l2_device_unregister_subdev(sd);
    	pm_runtime_disable(&client->dev);
    	mutex_destroy(&sensor->lock);
    }
    
    static const struct dev_pm_ops ov5647_pm_ops = {
    	SET_RUNTIME_PM_OPS(ov5647_power_off, ov5647_power_on, NULL)
    };
    
    static const struct i2c_device_id ov5647_id[] = {
    	{ "ov5647", 0 },
    	{ /* sentinel */ }
    };
    MODULE_DEVICE_TABLE(i2c, ov5647_id);
    
    #if IS_ENABLED(CONFIG_OF)
    static const struct of_device_id ov5647_of_match[] = {
    	{ .compatible = "ovti,ov5647" },
    	{ /* sentinel */ },
    };
    MODULE_DEVICE_TABLE(of, ov5647_of_match);
    #endif
    
    static struct i2c_driver ov5647_driver = {
    	.driver = {
    		.of_match_table = of_match_ptr(ov5647_of_match),
    		.name	= "ov5647",
    		.pm	= &ov5647_pm_ops,
    	},
    	.probe_new	= ov5647_probe,
    	.remove		= ov5647_remove,
    	.id_table	= ov5647_id,
    };
    
    module_i2c_driver(ov5647_driver);
    
    MODULE_AUTHOR("Ramiro Oliveira <roliveir@synopsys.com>");
    MODULE_DESCRIPTION("A low-level driver for OmniVision ov5647 sensors");
    MODULE_LICENSE("GPL v2");
    

    You can see specific changes below that i did in above ov5647_updated.c file.

    int ov5647_init_controls(struct ov5647 *sensor)
    {
        struct i2c_client *client = v4l2_get_subdevdata(&sensor->sd);
        int hblank, exposure_max, exposure_def;
    
        v4l2_ctrl_handler_init(&sensor->ctrls, 9);  // Incremented the handler count
    
        v4l2_ctrl_new_std(&sensor->ctrls, &ov5647_ctrl_ops,
                          V4L2_CID_AUTOGAIN, 0, 1, 1, 0);
    
        v4l2_ctrl_new_std(&sensor->ctrls, &ov5647_ctrl_ops,
                          V4L2_CID_AUTO_WHITE_BALANCE, 0, 1, 1, 0);
    
        v4l2_ctrl_new_std_menu(&sensor->ctrls, &ov5647_ctrl_ops,
                               V4L2_CID_EXPOSURE_AUTO, V4L2_EXPOSURE_MANUAL,
                               0, V4L2_EXPOSURE_MANUAL);
    
        exposure_max = sensor->mode->vts - 4;
        exposure_def = min(exposure_max, OV5647_EXPOSURE_DEFAULT);
        sensor->exposure = v4l2_ctrl_new_std(&sensor->ctrls, &ov5647_ctrl_ops,
                                             V4L2_CID_EXPOSURE,
                                             OV5647_EXPOSURE_MIN,
                                             exposure_max, OV5647_EXPOSURE_STEP,
                                             exposure_def);
    
        / min: 16 = 1.0x; max (10 bits); default: 32 = 2.0x. /
        v4l2_ctrl_new_std(&sensor->ctrls, &ov5647_ctrl_ops,
                          V4L2_CID_ANALOGUE_GAIN, 16, 1023, 1, 32);
    
        / By default, PIXEL_RATE is read only, but it does change per mode /
        sensor->pixel_rate = v4l2_ctrl_new_std(&sensor->ctrls, &ov5647_ctrl_ops,
                                               V4L2_CID_PIXEL_RATE,
                                               sensor->mode->pixel_rate);
    
        / Add support for LINK_FREQ /
        sensor->link_freq = v4l2_ctrl_new_int_menu(&sensor->ctrls, &ov5647_ctrl_ops,
                                                   V4L2_CID_LINK_FREQ, 1, 0,
                                                   &link_freq_menu);
    
        if (sensor->ctrls.error) {
            dev_err(&client->dev, "control init failed: %d\n", sensor->ctrls.error);
            return sensor->ctrls.error;
        }
    
        sensor->sd.ctrl_handler = &sensor->ctrls;
        return 0;
    }
    
    / Link frequency menu values /
    static const s64 link_freq_menu[] = {
        137500000,
        / Add other frequencies as needed /
    };
    
    / Function to get link frequency /
    static int ov5647_g_volatile_ctrl(struct v4l2_ctrl *ctrl)
    {
        struct ov5647 *sensor = container_of(ctrl->handler, struct ov5647, ctrls);
    
        switch (ctrl->id) {
        case V4L2_CID_LINK_FREQ:
            ctrl->val = 0;  // Return the current index of link frequency
            break;
        default:
            return -EINVAL;
        }
    
        return 0;
    }
    
    / Function to set link frequency /
    static int ov5647_s_ctrl(struct v4l2_ctrl *ctrl)
    {
        struct ov5647 *sensor = container_of(ctrl->handler, struct ov5647, ctrls);
        struct i2c_client *client = v4l2_get_subdevdata(&sensor->sd);
        int ret = 0;
    
        switch (ctrl->id) {
        case V4L2_CID_LINK_FREQ:
            // Handle setting the link frequency here
            dev_info(&client->dev, "Set link frequency to %lld\n", link_freq_menu[ctrl->val]);
            break;
        default:
            return -EINVAL;
        }
    
        return ret;
    }
    
    / Control operations structure /
    static const struct v4l2_ctrl_ops ov5647_ctrl_ops = {
        .g_volatile_ctrl = ov5647_g_volatile_ctrl,
        .s_ctrl = ov5647_s_ctrl,
    };
    

    But when i started making the modules it is giving errors ? 

    What is appropriate changes needs to make in drivers ?

  • We're not a sensor vendor and I'm afraid that I won't be able to help you with the sensor driver.

  • Ok 

    Now i have made the changes in sensor driver ov5647.c . Now i am not able to see the v4l2_get_link_freq: Consider implementing support for V4L2_CID_LINK_FREQ in the transmitter driver error. Instead of that i am seeing some different error, below you can see:- 

    root@am62xx-evm:~# media-ctl --set-v4l2 '"cdns_csi2rx.30101000.csi-bridge":0 [fmt:SBGGR10/640x480 field:none colorspace:srgb xfer:srgb ycbcr:601 quantization:lim-range]'
    root@am62xx-evm:~# yavta -c -Fcapture -s 640x480 -f SBGGR10 /dev/video0
    Device /dev/video0 opened.
    Device `j721e-csi2rx' on `platform:30102000.ticsi2rx' (driver 'j721e-csi2rx') supports video, capture, without mplanes.
    Video f[   72.011900] csi2rx_configure_external_dphy: Link frequency is 137500000
    ormat set: SBGGR10 (30314742) 640x480 (stride 1280) field none buffer size 614400
    Video format: SBGGR10 (30314742) 640x480 (stride 1280) field none buffer size 614400
    8 buffers requested.
    length: 614400 offset: 0 timestamp type/source: mono/EoF
    Buffer 0/0 mapped at address 0xffff8acba000.
    length: 614400 offset: 614400 timestamp type/source: mono/EoF
    Buffer 1/0 mapped at address 0xffff8ac24000.
    length: 614400 offset: 1228800 timestamp type/source: mono/EoF
    Buffer 2/0 mapped at address 0xffff8ab8e000.[   72.060183] ov5647 4-0036: stream start failed: -22
    
    length: 614400 offset: 1843200 timestamp type/source: mono/EoF[   72.069315] cdns-csi2rx 30101000.csi-bridge: Failed to start streams 0x1 on subdev
    
    Buffer 3/0 mapped at address 0xffff8aaf8000.
    length: 614400 offset: 2457600 timestamp type/source: mono/EoF
    Buffer 4/0 mappe[   72.092410] cdns-csi2rx 30101000.csi-bridge: Failed to stop stream0
    d at address 0xffff8aa62000.
    length: 614400 offset: 3072000 timestamp type/source: mono/EoF
    Buffer 5/0 mapped at address 0xfff[   72.109644] cdns-csi2rx 30101000.csi-bridge: Failed to stop stream1
    f8a9cc000.
    length: 614400 offset: 3686400 timestamp type/source: mono/EoF
    Buffer 6/0 mapped at address 0xffff8a936000.
    length[   72.127058] cdns-csi2rx 30101000.csi-bridge: Failed to stop stream2
    : 614400 offset: 4300800 timestamp type/source: mono/EoF
    Buffer 7/0 mapped at address 0xffff8a8a0000.
    [   72.144358] cdns-csi2rx 30101000.csi-bridge: Failed to stop stream3
    Unable to start streaming: Invalid argument (22).
    8 buffers released.
    root@am62xx-evm:~#

    See below updated driver:- 

    // SPDX-License-Identifier: GPL-2.0
    /*
     * A V4L2 driver for OmniVision OV5647 cameras.
     *
     * Based on Samsung S5K6AAFX SXGA 1/6" 1.3M CMOS Image Sensor driver
     * Copyright (C) 2011 Sylwester Nawrocki <s.nawrocki@samsung.com>
     *
     * Based on Omnivision OV7670 Camera Driver
     * Copyright (C) 2006-7 Jonathan Corbet <corbet@lwn.net>
     *
     * Copyright (C) 2016, Synopsys, Inc.
     */
    
    #include <linux/clk.h>
    #include <linux/delay.h>
    #include <linux/gpio/consumer.h>
    #include <linux/i2c.h>
    #include <linux/init.h>
    #include <linux/io.h>
    #include <linux/module.h>
    #include <linux/of_graph.h>
    #include <linux/pm_runtime.h>
    #include <linux/slab.h>
    #include <linux/videodev2.h>
    #include <media/v4l2-ctrls.h>
    #include <media/v4l2-device.h>
    #include <media/v4l2-event.h>
    #include <media/v4l2-fwnode.h>
    #include <media/v4l2-image-sizes.h>
    #include <media/v4l2-mediabus.h>
    
    /*
     * From the datasheet, "20ms after PWDN goes low or 20ms after RESETB goes
     * high if reset is inserted after PWDN goes high, host can access sensor's
     * SCCB to initialize sensor."
     */
    #define PWDN_ACTIVE_DELAY_MS	20
    
    #define MIPI_CTRL00_CLOCK_LANE_GATE		BIT(5)
    #define MIPI_CTRL00_LINE_SYNC_ENABLE		BIT(4)
    #define MIPI_CTRL00_BUS_IDLE			BIT(2)
    #define MIPI_CTRL00_CLOCK_LANE_DISABLE		BIT(0)
    
    #define OV5647_SW_STANDBY		0x0100
    #define OV5647_SW_RESET			0x0103
    #define OV5647_REG_CHIPID_H		0x300a
    #define OV5647_REG_CHIPID_L		0x300b
    #define OV5640_REG_PAD_OUT		0x300d
    #define OV5647_REG_EXP_HI		0x3500
    #define OV5647_REG_EXP_MID		0x3501
    #define OV5647_REG_EXP_LO		0x3502
    #define OV5647_REG_AEC_AGC		0x3503
    #define OV5647_REG_GAIN_HI		0x350a
    #define OV5647_REG_GAIN_LO		0x350b
    #define OV5647_REG_VTS_HI		0x380e
    #define OV5647_REG_VTS_LO		0x380f
    #define OV5647_REG_FRAME_OFF_NUMBER	0x4202
    #define OV5647_REG_MIPI_CTRL00		0x4800
    #define OV5647_REG_MIPI_CTRL14		0x4814
    #define OV5647_REG_AWB			0x5001
    
    #define REG_TERM 0xfffe
    #define VAL_TERM 0xfe
    #define REG_DLY  0xffff
    
    /* OV5647 native and active pixel array size */
    #define OV5647_NATIVE_WIDTH		2624U
    #define OV5647_NATIVE_HEIGHT		1956U
    
    #define OV5647_PIXEL_ARRAY_LEFT		16U
    #define OV5647_PIXEL_ARRAY_TOP		16U
    #define OV5647_PIXEL_ARRAY_WIDTH	2592U
    #define OV5647_PIXEL_ARRAY_HEIGHT	1944U
    
    #define OV5647_VBLANK_MIN		4
    #define OV5647_VTS_MAX			32767
    
    #define OV5647_EXPOSURE_MIN		4
    #define OV5647_EXPOSURE_STEP		1
    #define OV5647_EXPOSURE_DEFAULT		1000
    #define OV5647_EXPOSURE_MAX		65535
    
    struct regval_list {
    	u16 addr;
    	u8 data;
    };
    
    struct ov5647_mode {
    	struct v4l2_mbus_framefmt	format;
    	struct v4l2_rect		crop;
    	u64				pixel_rate;
    	int				hts;
    	int				vts;
    	const struct regval_list	*reg_list;
    	unsigned int			num_regs;
    };
    
    struct ov5647 {
    	struct v4l2_subdev		sd;
    	struct media_pad		pad;
    	struct mutex			lock;
    	struct clk			*xclk;
    	struct gpio_desc		*pwdn;
    	bool				clock_ncont;
    	struct v4l2_ctrl_handler	ctrls;
    	const struct ov5647_mode	*mode;
    	struct v4l2_ctrl		*pixel_rate;
    	struct v4l2_ctrl		*hblank;
    	struct v4l2_ctrl		*vblank;
    	struct v4l2_ctrl		*exposure;
    	struct v4l2_ctrl        *link_freq;
    	bool				streaming;
    };
    
    static inline struct ov5647 *to_sensor(struct v4l2_subdev *sd)
    {
    	return container_of(sd, struct ov5647, sd);
    }
    
    static const struct regval_list sensor_oe_disable_regs[] = {
    	{0x3000, 0x00},
    	{0x3001, 0x00},
    	{0x3002, 0x00},
    };
    
    static const s64 link_freq_menu[] = {
    	137500000,
    };
    
    static const struct regval_list sensor_oe_enable_regs[] = {
    	{0x3000, 0x0f},
    	{0x3001, 0xff},
    	{0x3002, 0xe4},
    };
    
    static struct regval_list ov5647_2592x1944_10bpp[] = {
    	{0x0100, 0x00},
    	{0x0103, 0x01},
    	{0x3034, 0x1a},
    	{0x3035, 0x21},
    	{0x3036, 0x69},
    	{0x303c, 0x11},
    	{0x3106, 0xf5},
    	{0x3821, 0x06},
    	{0x3820, 0x00},
    	{0x3827, 0xec},
    	{0x370c, 0x03},
    	{0x3612, 0x5b},
    	{0x3618, 0x04},
    	{0x5000, 0x06},
    	{0x5002, 0x41},
    	{0x5003, 0x08},
    	{0x5a00, 0x08},
    	{0x3000, 0x00},
    	{0x3001, 0x00},
    	{0x3002, 0x00},
    	{0x3016, 0x08},
    	{0x3017, 0xe0},
    	{0x3018, 0x44},
    	{0x301c, 0xf8},
    	{0x301d, 0xf0},
    	{0x3a18, 0x00},
    	{0x3a19, 0xf8},
    	{0x3c01, 0x80},
    	{0x3b07, 0x0c},
    	{0x380c, 0x0b},
    	{0x380d, 0x1c},
    	{0x3814, 0x11},
    	{0x3815, 0x11},
    	{0x3708, 0x64},
    	{0x3709, 0x12},
    	{0x3808, 0x0a},
    	{0x3809, 0x20},
    	{0x380a, 0x07},
    	{0x380b, 0x98},
    	{0x3800, 0x00},
    	{0x3801, 0x00},
    	{0x3802, 0x00},
    	{0x3803, 0x00},
    	{0x3804, 0x0a},
    	{0x3805, 0x3f},
    	{0x3806, 0x07},
    	{0x3807, 0xa3},
    	{0x3811, 0x10},
    	{0x3813, 0x06},
    	{0x3630, 0x2e},
    	{0x3632, 0xe2},
    	{0x3633, 0x23},
    	{0x3634, 0x44},
    	{0x3636, 0x06},
    	{0x3620, 0x64},
    	{0x3621, 0xe0},
    	{0x3600, 0x37},
    	{0x3704, 0xa0},
    	{0x3703, 0x5a},
    	{0x3715, 0x78},
    	{0x3717, 0x01},
    	{0x3731, 0x02},
    	{0x370b, 0x60},
    	{0x3705, 0x1a},
    	{0x3f05, 0x02},
    	{0x3f06, 0x10},
    	{0x3f01, 0x0a},
    	{0x3a08, 0x01},
    	{0x3a09, 0x28},
    	{0x3a0a, 0x00},
    	{0x3a0b, 0xf6},
    	{0x3a0d, 0x08},
    	{0x3a0e, 0x06},
    	{0x3a0f, 0x58},
    	{0x3a10, 0x50},
    	{0x3a1b, 0x58},
    	{0x3a1e, 0x50},
    	{0x3a11, 0x60},
    	{0x3a1f, 0x28},
    	{0x4001, 0x02},
    	{0x4004, 0x04},
    	{0x4000, 0x09},
    	{0x4837, 0x19},
    	{0x4800, 0x24},
    	{0x3503, 0x03},
    	{0x0100, 0x01},
    };
    
    static struct regval_list ov5647_1080p30_10bpp[] = {
    	{0x0100, 0x00},
    	{0x0103, 0x01},
    	{0x3034, 0x1a},
    	{0x3035, 0x21},
    	{0x3036, 0x62},
    	{0x303c, 0x11},
    	{0x3106, 0xf5},
    	{0x3821, 0x06},
    	{0x3820, 0x00},
    	{0x3827, 0xec},
    	{0x370c, 0x03},
    	{0x3612, 0x5b},
    	{0x3618, 0x04},
    	{0x5000, 0x06},
    	{0x5002, 0x41},
    	{0x5003, 0x08},
    	{0x5a00, 0x08},
    	{0x3000, 0x00},
    	{0x3001, 0x00},
    	{0x3002, 0x00},
    	{0x3016, 0x08},
    	{0x3017, 0xe0},
    	{0x3018, 0x44},
    	{0x301c, 0xf8},
    	{0x301d, 0xf0},
    	{0x3a18, 0x00},
    	{0x3a19, 0xf8},
    	{0x3c01, 0x80},
    	{0x3b07, 0x0c},
    	{0x380c, 0x09},
    	{0x380d, 0x70},
    	{0x3814, 0x11},
    	{0x3815, 0x11},
    	{0x3708, 0x64},
    	{0x3709, 0x12},
    	{0x3808, 0x07},
    	{0x3809, 0x80},
    	{0x380a, 0x04},
    	{0x380b, 0x38},
    	{0x3800, 0x01},
    	{0x3801, 0x5c},
    	{0x3802, 0x01},
    	{0x3803, 0xb2},
    	{0x3804, 0x08},
    	{0x3805, 0xe3},
    	{0x3806, 0x05},
    	{0x3807, 0xf1},
    	{0x3811, 0x04},
    	{0x3813, 0x02},
    	{0x3630, 0x2e},
    	{0x3632, 0xe2},
    	{0x3633, 0x23},
    	{0x3634, 0x44},
    	{0x3636, 0x06},
    	{0x3620, 0x64},
    	{0x3621, 0xe0},
    	{0x3600, 0x37},
    	{0x3704, 0xa0},
    	{0x3703, 0x5a},
    	{0x3715, 0x78},
    	{0x3717, 0x01},
    	{0x3731, 0x02},
    	{0x370b, 0x60},
    	{0x3705, 0x1a},
    	{0x3f05, 0x02},
    	{0x3f06, 0x10},
    	{0x3f01, 0x0a},
    	{0x3a08, 0x01},
    	{0x3a09, 0x4b},
    	{0x3a0a, 0x01},
    	{0x3a0b, 0x13},
    	{0x3a0d, 0x04},
    	{0x3a0e, 0x03},
    	{0x3a0f, 0x58},
    	{0x3a10, 0x50},
    	{0x3a1b, 0x58},
    	{0x3a1e, 0x50},
    	{0x3a11, 0x60},
    	{0x3a1f, 0x28},
    	{0x4001, 0x02},
    	{0x4004, 0x04},
    	{0x4000, 0x09},
    	{0x4837, 0x19},
    	{0x4800, 0x34},
    	{0x3503, 0x03},
    	{0x0100, 0x01},
    };
    
    static struct regval_list ov5647_2x2binned_10bpp[] = {
    	{0x0100, 0x00},
    	{0x0103, 0x01},
    	{0x3034, 0x1a},
    	{0x3035, 0x21},
    	{0x3036, 0x62},
    	{0x303c, 0x11},
    	{0x3106, 0xf5},
    	{0x3827, 0xec},
    	{0x370c, 0x03},
    	{0x3612, 0x59},
    	{0x3618, 0x00},
    	{0x5000, 0x06},
    	{0x5002, 0x41},
    	{0x5003, 0x08},
    	{0x5a00, 0x08},
    	{0x3000, 0x00},
    	{0x3001, 0x00},
    	{0x3002, 0x00},
    	{0x3016, 0x08},
    	{0x3017, 0xe0},
    	{0x3018, 0x44},
    	{0x301c, 0xf8},
    	{0x301d, 0xf0},
    	{0x3a18, 0x00},
    	{0x3a19, 0xf8},
    	{0x3c01, 0x80},
    	{0x3b07, 0x0c},
    	{0x3800, 0x00},
    	{0x3801, 0x00},
    	{0x3802, 0x00},
    	{0x3803, 0x00},
    	{0x3804, 0x0a},
    	{0x3805, 0x3f},
    	{0x3806, 0x07},
    	{0x3807, 0xa3},
    	{0x3808, 0x05},
    	{0x3809, 0x10},
    	{0x380a, 0x03},
    	{0x380b, 0xcc},
    	{0x380c, 0x07},
    	{0x380d, 0x68},
    	{0x3811, 0x0c},
    	{0x3813, 0x06},
    	{0x3814, 0x31},
    	{0x3815, 0x31},
    	{0x3630, 0x2e},
    	{0x3632, 0xe2},
    	{0x3633, 0x23},
    	{0x3634, 0x44},
    	{0x3636, 0x06},
    	{0x3620, 0x64},
    	{0x3621, 0xe0},
    	{0x3600, 0x37},
    	{0x3704, 0xa0},
    	{0x3703, 0x5a},
    	{0x3715, 0x78},
    	{0x3717, 0x01},
    	{0x3731, 0x02},
    	{0x370b, 0x60},
    	{0x3705, 0x1a},
    	{0x3f05, 0x02},
    	{0x3f06, 0x10},
    	{0x3f01, 0x0a},
    	{0x3a08, 0x01},
    	{0x3a09, 0x28},
    	{0x3a0a, 0x00},
    	{0x3a0b, 0xf6},
    	{0x3a0d, 0x08},
    	{0x3a0e, 0x06},
    	{0x3a0f, 0x58},
    	{0x3a10, 0x50},
    	{0x3a1b, 0x58},
    	{0x3a1e, 0x50},
    	{0x3a11, 0x60},
    	{0x3a1f, 0x28},
    	{0x4001, 0x02},
    	{0x4004, 0x04},
    	{0x4000, 0x09},
    	{0x4837, 0x16},
    	{0x4800, 0x24},
    	{0x3503, 0x03},
    	{0x3820, 0x41},
    	{0x3821, 0x07},
    	{0x350a, 0x00},
    	{0x350b, 0x10},
    	{0x3500, 0x00},
    	{0x3501, 0x1a},
    	{0x3502, 0xf0},
    	{0x3212, 0xa0},
    	{0x0100, 0x01},
    };
    
    static struct regval_list ov5647_640x480_10bpp[] = {
    	{0x0100, 0x00},
    	{0x0103, 0x01},
    	{0x3035, 0x11},
    	{0x3036, 0x46},
    	{0x303c, 0x11},
    	{0x3821, 0x07},
    	{0x3820, 0x41},
    	{0x370c, 0x03},
    	{0x3612, 0x59},
    	{0x3618, 0x00},
    	{0x5000, 0x06},
    	{0x5003, 0x08},
    	{0x5a00, 0x08},
    	{0x3000, 0xff},
    	{0x3001, 0xff},
    	{0x3002, 0xff},
    	{0x301d, 0xf0},
    	{0x3a18, 0x00},
    	{0x3a19, 0xf8},
    	{0x3c01, 0x80},
    	{0x3b07, 0x0c},
    	{0x380c, 0x07},
    	{0x380d, 0x3c},
    	{0x3814, 0x35},
    	{0x3815, 0x35},
    	{0x3708, 0x64},
    	{0x3709, 0x52},
    	{0x3808, 0x02},
    	{0x3809, 0x80},
    	{0x380a, 0x01},
    	{0x380b, 0xe0},
    	{0x3800, 0x00},
    	{0x3801, 0x10},
    	{0x3802, 0x00},
    	{0x3803, 0x00},
    	{0x3804, 0x0a},
    	{0x3805, 0x2f},
    	{0x3806, 0x07},
    	{0x3807, 0x9f},
    	{0x3630, 0x2e},
    	{0x3632, 0xe2},
    	{0x3633, 0x23},
    	{0x3634, 0x44},
    	{0x3620, 0x64},
    	{0x3621, 0xe0},
    	{0x3600, 0x37},
    	{0x3704, 0xa0},
    	{0x3703, 0x5a},
    	{0x3715, 0x78},
    	{0x3717, 0x01},
    	{0x3731, 0x02},
    	{0x370b, 0x60},
    	{0x3705, 0x1a},
    	{0x3f05, 0x02},
    	{0x3f06, 0x10},
    	{0x3f01, 0x0a},
    	{0x3a08, 0x01},
    	{0x3a09, 0x2e},
    	{0x3a0a, 0x00},
    	{0x3a0b, 0xfb},
    	{0x3a0d, 0x02},
    	{0x3a0e, 0x01},
    	{0x3a0f, 0x58},
    	{0x3a10, 0x50},
    	{0x3a1b, 0x58},
    	{0x3a1e, 0x50},
    	{0x3a11, 0x60},
    	{0x3a1f, 0x28},
    	{0x4001, 0x02},
    	{0x4004, 0x02},
    	{0x4000, 0x09},
    	{0x3000, 0x00},
    	{0x3001, 0x00},
    	{0x3002, 0x00},
    	{0x3017, 0xe0},
    	{0x301c, 0xfc},
    	{0x3636, 0x06},
    	{0x3016, 0x08},
    	{0x3827, 0xec},
    	{0x3018, 0x44},
    	{0x3035, 0x21},
    	{0x3106, 0xf5},
    	{0x3034, 0x1a},
    	{0x301c, 0xf8},
    	{0x4800, 0x34},
    	{0x3503, 0x03},
    	{0x0100, 0x01},
    };
    
    /* Function to get link frequency */
    static int ov5647_g_volatile_ctrl(struct v4l2_ctrl *ctrl)
    {
    	switch (ctrl->id) {
    		case V4L2_CID_LINK_FREQ:
    	     ctrl->val = 0;
    		 break;
    	default:
    	     return -EINVAL;	 
    	}
    
    	return 0;
    }
    
    static const struct ov5647_mode ov5647_modes[] = {
    	/* 2592x1944 full resolution full FOV 10-bit mode. */
    	{
    		.format = {
    			.code		= MEDIA_BUS_FMT_SBGGR10_1X10,
    			.colorspace	= V4L2_COLORSPACE_SRGB,
    			.field		= V4L2_FIELD_NONE,
    			.width		= 2592,
    			.height		= 1944
    		},
    		.crop = {
    			.left		= OV5647_PIXEL_ARRAY_LEFT,
    			.top		= OV5647_PIXEL_ARRAY_TOP,
    			.width		= 2592,
    			.height		= 1944
    		},
    		.pixel_rate	= 87500000,
    		.hts		= 2844,
    		.vts		= 0x7b0,
    		.reg_list	= ov5647_2592x1944_10bpp,
    		.num_regs	= ARRAY_SIZE(ov5647_2592x1944_10bpp)
    	},
    	/* 1080p30 10-bit mode. Full resolution centre-cropped down to 1080p. */
    	{
    		.format = {
    			.code		= MEDIA_BUS_FMT_SBGGR10_1X10,
    			.colorspace	= V4L2_COLORSPACE_SRGB,
    			.field		= V4L2_FIELD_NONE,
    			.width		= 1920,
    			.height		= 1080
    		},
    		.crop = {
    			.left		= 348 + OV5647_PIXEL_ARRAY_LEFT,
    			.top		= 434 + OV5647_PIXEL_ARRAY_TOP,
    			.width		= 1928,
    			.height		= 1080,
    		},
    		.pixel_rate	= 81666700,
    		.hts		= 2416,
    		.vts		= 0x450,
    		.reg_list	= ov5647_1080p30_10bpp,
    		.num_regs	= ARRAY_SIZE(ov5647_1080p30_10bpp)
    	},
    	/* 2x2 binned full FOV 10-bit mode. */
    	{
    		.format = {
    			.code		= MEDIA_BUS_FMT_SBGGR10_1X10,
    			.colorspace	= V4L2_COLORSPACE_SRGB,
    			.field		= V4L2_FIELD_NONE,
    			.width		= 1296,
    			.height		= 972
    		},
    		.crop = {
    			.left		= OV5647_PIXEL_ARRAY_LEFT,
    			.top		= OV5647_PIXEL_ARRAY_TOP,
    			.width		= 2592,
    			.height		= 1944,
    		},
    		.pixel_rate	= 81666700,
    		.hts		= 1896,
    		.vts		= 0x59b,
    		.reg_list	= ov5647_2x2binned_10bpp,
    		.num_regs	= ARRAY_SIZE(ov5647_2x2binned_10bpp)
    	},
    	/* 10-bit VGA full FOV 60fps. 2x2 binned and subsampled down to VGA. */
    	{
    		.format = {
    			.code		= MEDIA_BUS_FMT_SBGGR10_1X10,
    			.colorspace	= V4L2_COLORSPACE_SRGB,
    			.field		= V4L2_FIELD_NONE,
    			.width		= 640,
    			.height		= 480
    		},
    		.crop = {
    			.left		= 16 + OV5647_PIXEL_ARRAY_LEFT,
    			.top		= OV5647_PIXEL_ARRAY_TOP,
    			.width		= 2560,
    			.height		= 1920,
    		},
    		.pixel_rate	= 55000000,
    		.hts		= 1852,
    		.vts		= 0x1f8,
    		.reg_list	= ov5647_640x480_10bpp,
    		.num_regs	= ARRAY_SIZE(ov5647_640x480_10bpp)
    	},
    };
    
    /* Default sensor mode is 2x2 binned 640x480 SBGGR10_1X10. */
    #define OV5647_DEFAULT_MODE	(&ov5647_modes[3])
    #define OV5647_DEFAULT_FORMAT	(ov5647_modes[3].format)
    
    static int ov5647_write16(struct v4l2_subdev *sd, u16 reg, u16 val)
    {
    	unsigned char data[4] = { reg >> 8, reg & 0xff, val >> 8, val & 0xff};
    	struct i2c_client *client = v4l2_get_subdevdata(sd);
    	int ret;
    
    	ret = i2c_master_send(client, data, 4);
    	if (ret < 0) {
    		dev_dbg(&client->dev, "%s: i2c write error, reg: %x\n",
    			__func__, reg);
    		return ret;
    	}
    
    	return 0;
    }
    
    static int ov5647_write(struct v4l2_subdev *sd, u16 reg, u8 val)
    {
    	unsigned char data[3] = { reg >> 8, reg & 0xff, val};
    	struct i2c_client *client = v4l2_get_subdevdata(sd);
    	int ret;
    
    	ret = i2c_master_send(client, data, 3);
    	if (ret < 0) {
    		dev_dbg(&client->dev, "%s: i2c write error, reg: %x\n",
    				__func__, reg);
    		return ret;
    	}
    
    	return 0;
    }
    
    static int ov5647_read(struct v4l2_subdev *sd, u16 reg, u8 *val)
    {
    	unsigned char data_w[2] = { reg >> 8, reg & 0xff };
    	struct i2c_client *client = v4l2_get_subdevdata(sd);
    	int ret;
    
    	ret = i2c_master_send(client, data_w, 2);
    	if (ret < 0) {
    		dev_dbg(&client->dev, "%s: i2c write error, reg: %x\n",
    			__func__, reg);
    		return ret;
    	}
    
    	ret = i2c_master_recv(client, val, 1);
    	if (ret < 0) {
    		dev_dbg(&client->dev, "%s: i2c read error, reg: %x\n",
    				__func__, reg);
    		return ret;
    	}
    
    	return 0;
    }
    
    static int ov5647_write_array(struct v4l2_subdev *sd,
    			      const struct regval_list *regs, int array_size)
    {
    	int i, ret;
    
    	for (i = 0; i < array_size; i++) {
    		ret = ov5647_write(sd, regs[i].addr, regs[i].data);
    		if (ret < 0)
    			return ret;
    	}
    
    	return 0;
    }
    
    static int ov5647_set_virtual_channel(struct v4l2_subdev *sd, int channel)
    {
    	u8 channel_id;
    	int ret;
    
    	ret = ov5647_read(sd, OV5647_REG_MIPI_CTRL14, &channel_id);
    	if (ret < 0)
    		return ret;
    
    	channel_id &= ~(3 << 6);
    
    	return ov5647_write(sd, OV5647_REG_MIPI_CTRL14,
    			    channel_id | (channel << 6));
    }
    
    static int ov5647_set_mode(struct v4l2_subdev *sd)
    {
    	struct i2c_client *client = v4l2_get_subdevdata(sd);
    	struct ov5647 *sensor = to_sensor(sd);
    	u8 resetval, rdval;
    	int ret;
    
    	ret = ov5647_read(sd, OV5647_SW_STANDBY, &rdval);
    	if (ret < 0)
    		return ret;
    
    	ret = ov5647_write_array(sd, sensor->mode->reg_list,
    				 sensor->mode->num_regs);
    	if (ret < 0) {
    		dev_err(&client->dev, "write sensor default regs error\n");
    		return ret;
    	}
    
    	ret = ov5647_set_virtual_channel(sd, 0);
    	if (ret < 0)
    		return ret;
    
    	ret = ov5647_read(sd, OV5647_SW_STANDBY, &resetval);
    	if (ret < 0)
    		return ret;
    
    	if (!(resetval & 0x01)) {
    		dev_err(&client->dev, "Device was in SW standby");
    		ret = ov5647_write(sd, OV5647_SW_STANDBY, 0x01);
    		if (ret < 0)
    			return ret;
    	}
    
    	return 0;
    }
    
    static int ov5647_stream_on(struct v4l2_subdev *sd)
    {
    	struct i2c_client *client = v4l2_get_subdevdata(sd);
    	struct ov5647 *sensor = to_sensor(sd);
    	u8 val = MIPI_CTRL00_BUS_IDLE;
    	int ret;
    
    	ret = ov5647_set_mode(sd);
    	if (ret) {
    		dev_err(&client->dev, "Failed to program sensor mode: %d\n", ret);
    		return ret;
    	}
    
    	/* Apply customized values from user when stream starts. */
    	ret =  __v4l2_ctrl_handler_setup(sd->ctrl_handler);
    	if (ret)
    		return ret;
    
    	if (sensor->clock_ncont)
    		val |= MIPI_CTRL00_CLOCK_LANE_GATE |
    		       MIPI_CTRL00_LINE_SYNC_ENABLE;
    
    	ret = ov5647_write(sd, OV5647_REG_MIPI_CTRL00, val);
    	if (ret < 0)
    		return ret;
    
    	ret = ov5647_write(sd, OV5647_REG_FRAME_OFF_NUMBER, 0x00);
    	if (ret < 0)
    		return ret;
    
    	return ov5647_write(sd, OV5640_REG_PAD_OUT, 0x00);
    }
    
    static int ov5647_stream_off(struct v4l2_subdev *sd)
    {
    	int ret;
    
    	ret = ov5647_write(sd, OV5647_REG_MIPI_CTRL00,
    			   MIPI_CTRL00_CLOCK_LANE_GATE | MIPI_CTRL00_BUS_IDLE |
    			   MIPI_CTRL00_CLOCK_LANE_DISABLE);
    	if (ret < 0)
    		return ret;
    
    	ret = ov5647_write(sd, OV5647_REG_FRAME_OFF_NUMBER, 0x0f);
    	if (ret < 0)
    		return ret;
    
    	return ov5647_write(sd, OV5640_REG_PAD_OUT, 0x01);
    }
    
    static int ov5647_power_on(struct device *dev)
    {
    	struct ov5647 *sensor = dev_get_drvdata(dev);
    	int ret;
    
    	dev_dbg(dev, "OV5647 power on\n");
    
    	if (sensor->pwdn) {
    		gpiod_set_value_cansleep(sensor->pwdn, 0);
    		msleep(PWDN_ACTIVE_DELAY_MS);
    	}
    
    	ret = clk_prepare_enable(sensor->xclk);
    	if (ret < 0) {
    		dev_err(dev, "clk prepare enable failed\n");
    		goto error_pwdn;
    	}
    
    	ret = ov5647_write_array(&sensor->sd, sensor_oe_enable_regs,
    				 ARRAY_SIZE(sensor_oe_enable_regs));
    	if (ret < 0) {
    		dev_err(dev, "write sensor_oe_enable_regs error\n");
    		goto error_clk_disable;
    	}
    
    	/* Stream off to coax lanes into LP-11 state. */
    	ret = ov5647_stream_off(&sensor->sd);
    	if (ret < 0) {
    		dev_err(dev, "camera not available, check power\n");
    		goto error_clk_disable;
    	}
    
    	return 0;
    
    error_clk_disable:
    	clk_disable_unprepare(sensor->xclk);
    error_pwdn:
    	gpiod_set_value_cansleep(sensor->pwdn, 1);
    
    	return ret;
    }
    
    static int ov5647_power_off(struct device *dev)
    {
    	struct ov5647 *sensor = dev_get_drvdata(dev);
    	u8 rdval;
    	int ret;
    
    	dev_dbg(dev, "OV5647 power off\n");
    
    	ret = ov5647_write_array(&sensor->sd, sensor_oe_disable_regs,
    				 ARRAY_SIZE(sensor_oe_disable_regs));
    	if (ret < 0)
    		dev_dbg(dev, "disable oe failed\n");
    
    	/* Enter software standby */
    	ret = ov5647_read(&sensor->sd, OV5647_SW_STANDBY, &rdval);
    	if (ret < 0)
    		dev_dbg(dev, "software standby failed\n");
    
    	rdval &= ~0x01;
    	ret = ov5647_write(&sensor->sd, OV5647_SW_STANDBY, rdval);
    	if (ret < 0)
    		dev_dbg(dev, "software standby failed\n");
    
    	clk_disable_unprepare(sensor->xclk);
    	gpiod_set_value_cansleep(sensor->pwdn, 1);
    
    	return 0;
    }
    
    #ifdef CONFIG_VIDEO_ADV_DEBUG
    static int ov5647_sensor_get_register(struct v4l2_subdev *sd,
    				      struct v4l2_dbg_register *reg)
    {
    	int ret;
    	u8 val;
    
    	ret = ov5647_read(sd, reg->reg & 0xff, &val);
    	if (ret < 0)
    		return ret;
    
    	reg->val = val;
    	reg->size = 1;
    
    	return 0;
    }
    
    static int ov5647_sensor_set_register(struct v4l2_subdev *sd,
    				      const struct v4l2_dbg_register *reg)
    {
    	return ov5647_write(sd, reg->reg & 0xff, reg->val & 0xff);
    }
    #endif
    
    /* Subdev core operations registration */
    static const struct v4l2_subdev_core_ops ov5647_subdev_core_ops = {
    	.subscribe_event	= v4l2_ctrl_subdev_subscribe_event,
    	.unsubscribe_event	= v4l2_event_subdev_unsubscribe,
    #ifdef CONFIG_VIDEO_ADV_DEBUG
    	.g_register		= ov5647_sensor_get_register,
    	.s_register		= ov5647_sensor_set_register,
    #endif
    };
    
    static const struct v4l2_rect *
    __ov5647_get_pad_crop(struct ov5647 *ov5647,
    		      struct v4l2_subdev_state *sd_state,
    		      unsigned int pad, enum v4l2_subdev_format_whence which)
    {
    	switch (which) {
    	case V4L2_SUBDEV_FORMAT_TRY:
    		return v4l2_subdev_get_try_crop(&ov5647->sd, sd_state, pad);
    	case V4L2_SUBDEV_FORMAT_ACTIVE:
    		return &ov5647->mode->crop;
    	}
    
    	return NULL;
    }
    
    static int ov5647_s_stream(struct v4l2_subdev *sd, int enable)
    {
    	struct i2c_client *client = v4l2_get_subdevdata(sd);
    	struct ov5647 *sensor = to_sensor(sd);
    	int ret;
    
    	mutex_lock(&sensor->lock);
    	if (sensor->streaming == enable) {
    		mutex_unlock(&sensor->lock);
    		return 0;
    	}
    
    	if (enable) {
    		ret = pm_runtime_resume_and_get(&client->dev);
    		if (ret < 0)
    			goto error_unlock;
    
    		ret = ov5647_stream_on(sd);
    		if (ret < 0) {
    			dev_err(&client->dev, "stream start failed: %d\n", ret);
    			goto error_pm;
    		}
    	} else {
    		ret = ov5647_stream_off(sd);
    		if (ret < 0) {
    			dev_err(&client->dev, "stream stop failed: %d\n", ret);
    			goto error_pm;
    		}
    		pm_runtime_put(&client->dev);
    	}
    
    	sensor->streaming = enable;
    	mutex_unlock(&sensor->lock);
    
    	return 0;
    
    error_pm:
    	pm_runtime_put(&client->dev);
    error_unlock:
    	mutex_unlock(&sensor->lock);
    
    	return ret;
    }
    
    static const struct v4l2_subdev_video_ops ov5647_subdev_video_ops = {
    	.s_stream =		ov5647_s_stream,
    };
    
    static int ov5647_enum_mbus_code(struct v4l2_subdev *sd,
    				 struct v4l2_subdev_state *sd_state,
    				 struct v4l2_subdev_mbus_code_enum *code)
    {
    	if (code->index > 0)
    		return -EINVAL;
    
    	code->code = MEDIA_BUS_FMT_SBGGR10_1X10;
    
    	return 0;
    }
    
    static int ov5647_enum_frame_size(struct v4l2_subdev *sd,
    				  struct v4l2_subdev_state *sd_state,
    				  struct v4l2_subdev_frame_size_enum *fse)
    {
    	const struct v4l2_mbus_framefmt *fmt;
    
    	if (fse->code != MEDIA_BUS_FMT_SBGGR10_1X10 ||
    	    fse->index >= ARRAY_SIZE(ov5647_modes))
    		return -EINVAL;
    
    	fmt = &ov5647_modes[fse->index].format;
    	fse->min_width = fmt->width;
    	fse->max_width = fmt->width;
    	fse->min_height = fmt->height;
    	fse->max_height = fmt->height;
    
    	return 0;
    }
    
    static int ov5647_get_pad_fmt(struct v4l2_subdev *sd,
    			      struct v4l2_subdev_state *sd_state,
    			      struct v4l2_subdev_format *format)
    {
    	struct v4l2_mbus_framefmt *fmt = &format->format;
    	const struct v4l2_mbus_framefmt *sensor_format;
    	struct ov5647 *sensor = to_sensor(sd);
    
    	mutex_lock(&sensor->lock);
    	switch (format->which) {
    	case V4L2_SUBDEV_FORMAT_TRY:
    		sensor_format = v4l2_subdev_get_try_format(sd, sd_state,
    							   format->pad);
    		break;
    	default:
    		sensor_format = &sensor->mode->format;
    		break;
    	}
    
    	*fmt = *sensor_format;
    	mutex_unlock(&sensor->lock);
    
    	return 0;
    }
    
    static int ov5647_set_pad_fmt(struct v4l2_subdev *sd,
    			      struct v4l2_subdev_state *sd_state,
    			      struct v4l2_subdev_format *format)
    {
    	struct v4l2_mbus_framefmt *fmt = &format->format;
    	struct ov5647 *sensor = to_sensor(sd);
    	const struct ov5647_mode *mode;
    
    	mode = v4l2_find_nearest_size(ov5647_modes, ARRAY_SIZE(ov5647_modes),
    				      format.width, format.height,
    				      fmt->width, fmt->height);
    
    	/* Update the sensor mode and apply at it at streamon time. */
    	mutex_lock(&sensor->lock);
    	if (format->which == V4L2_SUBDEV_FORMAT_TRY) {
    		*v4l2_subdev_get_try_format(sd, sd_state, format->pad) = mode->format;
    	} else {
    		int exposure_max, exposure_def;
    		int hblank, vblank;
    
    		sensor->mode = mode;
    		__v4l2_ctrl_modify_range(sensor->pixel_rate, mode->pixel_rate,
    					 mode->pixel_rate, 1, mode->pixel_rate);
    
    		hblank = mode->hts - mode->format.width;
    		__v4l2_ctrl_modify_range(sensor->hblank, hblank, hblank, 1,
    					 hblank);
    
    		vblank = mode->vts - mode->format.height;
    		__v4l2_ctrl_modify_range(sensor->vblank, OV5647_VBLANK_MIN,
    					 OV5647_VTS_MAX - mode->format.height,
    					 1, vblank);
    		__v4l2_ctrl_s_ctrl(sensor->vblank, vblank);
    
    		exposure_max = mode->vts - 4;
    		exposure_def = min(exposure_max, OV5647_EXPOSURE_DEFAULT);
    		__v4l2_ctrl_modify_range(sensor->exposure,
    					 sensor->exposure->minimum,
    					 exposure_max, sensor->exposure->step,
    					 exposure_def);
    	}
    	*fmt = mode->format;
    	mutex_unlock(&sensor->lock);
    
    	return 0;
    }
    
    static int ov5647_get_selection(struct v4l2_subdev *sd,
    				struct v4l2_subdev_state *sd_state,
    				struct v4l2_subdev_selection *sel)
    {
    	switch (sel->target) {
    	case V4L2_SEL_TGT_CROP: {
    		struct ov5647 *sensor = to_sensor(sd);
    
    		mutex_lock(&sensor->lock);
    		sel->r = *__ov5647_get_pad_crop(sensor, sd_state, sel->pad,
    						sel->which);
    		mutex_unlock(&sensor->lock);
    
    		return 0;
    	}
    
    	case V4L2_SEL_TGT_NATIVE_SIZE:
    		sel->r.top = 0;
    		sel->r.left = 0;
    		sel->r.width = OV5647_NATIVE_WIDTH;
    		sel->r.height = OV5647_NATIVE_HEIGHT;
    
    		return 0;
    
    	case V4L2_SEL_TGT_CROP_DEFAULT:
    	case V4L2_SEL_TGT_CROP_BOUNDS:
    		sel->r.top = OV5647_PIXEL_ARRAY_TOP;
    		sel->r.left = OV5647_PIXEL_ARRAY_LEFT;
    		sel->r.width = OV5647_PIXEL_ARRAY_WIDTH;
    		sel->r.height = OV5647_PIXEL_ARRAY_HEIGHT;
    
    		return 0;
    	}
    
    	return -EINVAL;
    }
    
    static const struct v4l2_subdev_pad_ops ov5647_subdev_pad_ops = {
    	.enum_mbus_code		= ov5647_enum_mbus_code,
    	.enum_frame_size	= ov5647_enum_frame_size,
    	.set_fmt		= ov5647_set_pad_fmt,
    	.get_fmt		= ov5647_get_pad_fmt,
    	.get_selection		= ov5647_get_selection,
    };
    
    static const struct v4l2_subdev_ops ov5647_subdev_ops = {
    	.core		= &ov5647_subdev_core_ops,
    	.video		= &ov5647_subdev_video_ops,
    	.pad		= &ov5647_subdev_pad_ops,
    };
    
    static int ov5647_detect(struct v4l2_subdev *sd)
    {
    	struct i2c_client *client = v4l2_get_subdevdata(sd);
    	u8 read;
    	int ret;
    
    	ret = ov5647_write(sd, OV5647_SW_RESET, 0x01);
    	if (ret < 0)
    		return ret;
    
    	ret = ov5647_read(sd, OV5647_REG_CHIPID_H, &read);
    	if (ret < 0)
    		return ret;
    
    	if (read != 0x56) {
    		dev_err(&client->dev, "ID High expected 0x56 got %x", read);
    		return -ENODEV;
    	}
    
    	ret = ov5647_read(sd, OV5647_REG_CHIPID_L, &read);
    	if (ret < 0)
    		return ret;
    
    	if (read != 0x47) {
    		dev_err(&client->dev, "ID Low expected 0x47 got %x", read);
    		return -ENODEV;
    	}
    
    	return ov5647_write(sd, OV5647_SW_RESET, 0x00);
    }
    
    static int ov5647_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
    {
    	struct v4l2_mbus_framefmt *format =
    				v4l2_subdev_get_try_format(sd, fh->state, 0);
    	struct v4l2_rect *crop = v4l2_subdev_get_try_crop(sd, fh->state, 0);
    
    	crop->left = OV5647_PIXEL_ARRAY_LEFT;
    	crop->top = OV5647_PIXEL_ARRAY_TOP;
    	crop->width = OV5647_PIXEL_ARRAY_WIDTH;
    	crop->height = OV5647_PIXEL_ARRAY_HEIGHT;
    
    	*format = OV5647_DEFAULT_FORMAT;
    
    	return 0;
    }
    
    static const struct v4l2_subdev_internal_ops ov5647_subdev_internal_ops = {
    	.open = ov5647_open,
    };
    
    static int ov5647_s_auto_white_balance(struct v4l2_subdev *sd, u32 val)
    {
    	return ov5647_write(sd, OV5647_REG_AWB, val ? 1 : 0);
    }
    
    static int ov5647_s_autogain(struct v4l2_subdev *sd, u32 val)
    {
    	int ret;
    	u8 reg;
    
    	/* Non-zero turns on AGC by clearing bit 1.*/
    	ret = ov5647_read(sd, OV5647_REG_AEC_AGC, &reg);
    	if (ret)
    		return ret;
    
    	return ov5647_write(sd, OV5647_REG_AEC_AGC, val ? reg & ~BIT(1)
    							: reg | BIT(1));
    }
    
    static int ov5647_s_exposure_auto(struct v4l2_subdev *sd, u32 val)
    {
    	int ret;
    	u8 reg;
    
    	/*
    	 * Everything except V4L2_EXPOSURE_MANUAL turns on AEC by
    	 * clearing bit 0.
    	 */
    	ret = ov5647_read(sd, OV5647_REG_AEC_AGC, &reg);
    	if (ret)
    		return ret;
    
    	return ov5647_write(sd, OV5647_REG_AEC_AGC,
    			    val == V4L2_EXPOSURE_MANUAL ? reg | BIT(0)
    							: reg & ~BIT(0));
    }
    
    static int ov5647_s_analogue_gain(struct v4l2_subdev *sd, u32 val)
    {
    	int ret;
    
    	/* 10 bits of gain, 2 in the high register. */
    	ret = ov5647_write(sd, OV5647_REG_GAIN_HI, (val >> 8) & 3);
    	if (ret)
    		return ret;
    
    	return ov5647_write(sd, OV5647_REG_GAIN_LO, val & 0xff);
    }
    
    static int ov5647_s_exposure(struct v4l2_subdev *sd, u32 val)
    {
    	int ret;
    
    	/*
    	 * Sensor has 20 bits, but the bottom 4 bits are fractions of a line
    	 * which we leave as zero (and don't receive in "val").
    	 */
    	ret = ov5647_write(sd, OV5647_REG_EXP_HI, (val >> 12) & 0xf);
    	if (ret)
    		return ret;
    
    	ret = ov5647_write(sd, OV5647_REG_EXP_MID, (val >> 4) & 0xff);
    	if (ret)
    		return ret;
    
    	return ov5647_write(sd, OV5647_REG_EXP_LO, (val & 0xf) << 4);
    }
    
    /* Function to set the link frequency */
    static int ov5647_s_ctrl(struct v4l2_ctrl *ctrl)
    {
        struct ov5647 *sensor = container_of(ctrl->handler, struct ov5647, ctrls);
        struct v4l2_subdev *sd = &sensor->sd;
        struct i2c_client *client = v4l2_get_subdevdata(sd);
        int ret = 0;
    
        switch (ctrl->id) {
        case V4L2_CID_LINK_FREQ:
            dev_info(&client->dev, "Set link frequency to %lld\n", link_freq_menu[ctrl->val]);
            break;
        default:
            return -EINVAL;
        }
    
        // Lock our own mutex
        v4l2_ctrl_lock(ctrl);
    
        if (ctrl->id == V4L2_CID_VBLANK) {
            int exposure_max, exposure_def;
    
            // Update max exposure while meeting expected vblanking
            exposure_max = sensor->mode->format.height + ctrl->val - 4;
            exposure_def = min(exposure_max, OV5647_EXPOSURE_DEFAULT);
            __v4l2_ctrl_modify_range(sensor->exposure,
                                     sensor->exposure->minimum,
                                     exposure_max, sensor->exposure->step,
                                     exposure_def);
        }
    
        // If the device is not powered up do not apply any controls
        // to H/W at this time. Instead the controls will be restored
        // at s_stream(1) time.
        if (pm_runtime_get_if_in_use(&client->dev) == 0)
            return 0;
    
        switch (ctrl->id) {
        case V4L2_CID_AUTO_WHITE_BALANCE:
            ret = ov5647_s_auto_white_balance(sd, ctrl->val);
            break;
        case V4L2_CID_AUTOGAIN:
            ret = ov5647_s_autogain(sd, ctrl->val);
            break;
        case V4L2_CID_EXPOSURE_AUTO:
            ret = ov5647_s_exposure_auto(sd, ctrl->val);
            break;
        case V4L2_CID_ANALOGUE_GAIN:
            ret = ov5647_s_analogue_gain(sd, ctrl->val);
            break;
        case V4L2_CID_EXPOSURE:
            ret = ov5647_s_exposure(sd, ctrl->val);
            break;
        case V4L2_CID_VBLANK:
            ret = ov5647_write16(sd, OV5647_REG_VTS_HI,
                                 sensor->mode->format.height + ctrl->val);
            break;
    
        // Read-only, but we adjust it based on mode.
        case V4L2_CID_PIXEL_RATE:
        case V4L2_CID_HBLANK:
            // Read-only, but we adjust it based on mode.
            break;
    
        default:
            dev_info(&client->dev,
                     "Control (id:0x%x, val:0x%x) not supported\n",
                     ctrl->id, ctrl->val);
            return -EINVAL;
        }
    
        pm_runtime_put(&client->dev);
    
        return ret;
    }
    
    // Control operations structure
    static const struct v4l2_ctrl_ops ov5647_ctrl_ops = {
        .g_volatile_ctrl = ov5647_g_volatile_ctrl,
        .s_ctrl = ov5647_s_ctrl,
    };
    
    static int ov5647_init_controls(struct ov5647 *sensor)
    {
        struct i2c_client *client = v4l2_get_subdevdata(&sensor->sd);
        int hblank, exposure_max, exposure_def;
    
        v4l2_ctrl_handler_init(&sensor->ctrls, 9);
    
        v4l2_ctrl_new_std(&sensor->ctrls, &ov5647_ctrl_ops,
                          V4L2_CID_AUTOGAIN, 0, 1, 1, 0);
    
        v4l2_ctrl_new_std(&sensor->ctrls, &ov5647_ctrl_ops,
                          V4L2_CID_AUTO_WHITE_BALANCE, 0, 1, 1, 0);
    
        v4l2_ctrl_new_std_menu(&sensor->ctrls, &ov5647_ctrl_ops,
                               V4L2_CID_EXPOSURE_AUTO, V4L2_EXPOSURE_MANUAL,
                               0, V4L2_EXPOSURE_MANUAL);
    
        exposure_max = sensor->mode->vts - 4;
        exposure_def = min(exposure_max, OV5647_EXPOSURE_DEFAULT);
        sensor->exposure = v4l2_ctrl_new_std(&sensor->ctrls, &ov5647_ctrl_ops,
                                             V4L2_CID_EXPOSURE,
                                             OV5647_EXPOSURE_MIN,
                                             exposure_max, OV5647_EXPOSURE_STEP,
                                             exposure_def);
    
        /* min: 16 = 1.0x; max (10 bits); default: 32 = 2.0x. */
        v4l2_ctrl_new_std(&sensor->ctrls, &ov5647_ctrl_ops,
                          V4L2_CID_ANALOGUE_GAIN, 16, 1023, 1, 32);
    
        /* By default, PIXEL_RATE is read only, but it does change per mode */
        sensor->pixel_rate = v4l2_ctrl_new_std(&sensor->ctrls, &ov5647_ctrl_ops,
                                               V4L2_CID_PIXEL_RATE,
                                               sensor->mode->pixel_rate,
                                               sensor->mode->pixel_rate, 1,
                                               sensor->mode->pixel_rate);
    
        sensor->link_freq = v4l2_ctrl_new_int_menu(&sensor->ctrls, &ov5647_ctrl_ops,
                                                   V4L2_CID_LINK_FREQ, 1, 0,
                                                   link_freq_menu);
    
        /* By default, HBLANK is read only, but it does change per mode. */
        hblank = sensor->mode->hts - sensor->mode->format.width;
        sensor->hblank = v4l2_ctrl_new_std(&sensor->ctrls, &ov5647_ctrl_ops,
                                           V4L2_CID_HBLANK, hblank, hblank, 1,
                                           hblank);
    
        sensor->vblank = v4l2_ctrl_new_std(&sensor->ctrls, &ov5647_ctrl_ops,
                                           V4L2_CID_VBLANK, OV5647_VBLANK_MIN,
                                           OV5647_VTS_MAX - sensor->mode->format.height, 1,
                                           sensor->mode->vts - sensor->mode->format.height);
    
        if (sensor->ctrls.error) {
            dev_err(&client->dev, "control init failed: %d\n", sensor->ctrls.error);
            goto handler_free;
        }
    
        sensor->pixel_rate->flags |= V4L2_CTRL_FLAG_READ_ONLY;
        sensor->hblank->flags |= V4L2_CTRL_FLAG_READ_ONLY;
        sensor->sd.ctrl_handler = &sensor->ctrls;
    
        return 0;
    
    handler_free:
        dev_err(&client->dev, "%s Controls initialization failed (%d)\n",
                __func__, sensor->ctrls.error);
        v4l2_ctrl_handler_free(&sensor->ctrls);
    
        return sensor->ctrls.error;
    }
    
    
    static int ov5647_parse_dt(struct ov5647 *sensor, struct device_node *np)
    {
    	struct v4l2_fwnode_endpoint bus_cfg = {
    		.bus_type = V4L2_MBUS_CSI2_DPHY,
    	};
    	struct device_node *ep;
    	int ret;
    
    	ep = of_graph_get_next_endpoint(np, NULL);
    	if (!ep)
    		return -EINVAL;
    
    	ret = v4l2_fwnode_endpoint_parse(of_fwnode_handle(ep), &bus_cfg);
    	if (ret)
    		goto out;
    
    	sensor->clock_ncont = bus_cfg.bus.mipi_csi2.flags &
    			      V4L2_MBUS_CSI2_NONCONTINUOUS_CLOCK;
    
    out:
    	of_node_put(ep);
    
    	return ret;
    }
    
    static int ov5647_probe(struct i2c_client *client)
    {
    	struct device_node *np = client->dev.of_node;
    	struct device *dev = &client->dev;
    	struct ov5647 *sensor;
    	struct v4l2_subdev *sd;
    	u32 xclk_freq;
    	int ret;
    
    	sensor = devm_kzalloc(dev, sizeof(*sensor), GFP_KERNEL);
    	if (!sensor)
    		return -ENOMEM;
    
    	if (IS_ENABLED(CONFIG_OF) && np) {
    		ret = ov5647_parse_dt(sensor, np);
    		if (ret) {
    			dev_err(dev, "DT parsing error: %d\n", ret);
    			return ret;
    		}
    	}
    
    	sensor->xclk = devm_clk_get(dev, NULL);
    	if (IS_ERR(sensor->xclk)) {
    		dev_err(dev, "could not get xclk");
    		return PTR_ERR(sensor->xclk);
    	}
    
    	xclk_freq = clk_get_rate(sensor->xclk);
    	if (xclk_freq != 25000000) {
    		dev_err(dev, "Unsupported clock frequency: %u\n", xclk_freq);
    		return -EINVAL;
    	}
    
    	/* Request the power down GPIO asserted. */
    	sensor->pwdn = devm_gpiod_get_optional(dev, "pwdn", GPIOD_OUT_HIGH);
    	if (IS_ERR(sensor->pwdn)) {
    		dev_err(dev, "Failed to get 'pwdn' gpio\n");
    		return -EINVAL;
    	}
    
    	mutex_init(&sensor->lock);
    
    	sensor->mode = OV5647_DEFAULT_MODE;
    
    	ret = ov5647_init_controls(sensor);
    	if (ret)
    		goto mutex_destroy;
    
    	sd = &sensor->sd;
    	v4l2_i2c_subdev_init(sd, client, &ov5647_subdev_ops);
    	sd->internal_ops = &ov5647_subdev_internal_ops;
    	sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE | V4L2_SUBDEV_FL_HAS_EVENTS;
    
    	sensor->pad.flags = MEDIA_PAD_FL_SOURCE;
    	sd->entity.function = MEDIA_ENT_F_CAM_SENSOR;
    	ret = media_entity_pads_init(&sd->entity, 1, &sensor->pad);
    	if (ret < 0)
    		goto ctrl_handler_free;
    
    	ret = ov5647_power_on(dev);
    	if (ret)
    		goto entity_cleanup;
    
    	ret = ov5647_detect(sd);
    	if (ret < 0)
    		goto power_off;
    
    	ret = v4l2_async_register_subdev(sd);
    	if (ret < 0)
    		goto power_off;
    
    	/* Enable runtime PM and turn off the device */
    	pm_runtime_set_active(dev);
    	pm_runtime_enable(dev);
    	pm_runtime_idle(dev);
    
    	dev_dbg(dev, "OmniVision OV5647 camera driver probed\n");
    
    	return 0;
    
    power_off:
    	ov5647_power_off(dev);
    entity_cleanup:
    	media_entity_cleanup(&sd->entity);
    ctrl_handler_free:
    	v4l2_ctrl_handler_free(&sensor->ctrls);
    mutex_destroy:
    	mutex_destroy(&sensor->lock);
    
    	return ret;
    }
    
    static void ov5647_remove(struct i2c_client *client)
    {
    	struct v4l2_subdev *sd = i2c_get_clientdata(client);
    	struct ov5647 *sensor = to_sensor(sd);
    
    	v4l2_async_unregister_subdev(&sensor->sd);
    	media_entity_cleanup(&sensor->sd.entity);
    	v4l2_ctrl_handler_free(&sensor->ctrls);
    	v4l2_device_unregister_subdev(sd);
    	pm_runtime_disable(&client->dev);
    	mutex_destroy(&sensor->lock);
    }
    
    static const struct dev_pm_ops ov5647_pm_ops = {
    	SET_RUNTIME_PM_OPS(ov5647_power_off, ov5647_power_on, NULL)
    };
    
    static const struct i2c_device_id ov5647_id[] = {
    	{ "ov5647", 0 },
    	{ /* sentinel */ }
    };
    MODULE_DEVICE_TABLE(i2c, ov5647_id);
    
    #if IS_ENABLED(CONFIG_OF)
    static const struct of_device_id ov5647_of_match[] = {
    	{ .compatible = "ovti,ov5647" },
    	{ /* sentinel */ },
    };
    MODULE_DEVICE_TABLE(of, ov5647_of_match);
    #endif
    
    static struct i2c_driver ov5647_driver = {
    	.driver = {
    		.of_match_table = of_match_ptr(ov5647_of_match),
    		.name	= "ov5647",
    		.pm	= &ov5647_pm_ops,
    	},
    	.probe_new	= ov5647_probe,
    	.remove		= ov5647_remove,
    	.id_table	= ov5647_id,
    };
    
    module_i2c_driver(ov5647_driver);
    
    MODULE_AUTHOR("Ramiro Oliveira <roliveir@synopsys.com>");
    MODULE_DESCRIPTION("A low-level driver for OmniVision ov5647 sensors");
    MODULE_LICENSE("GPL v2");
    

    dmesg output:-

    Last line i can see the below errors:- 

    [ 72.060183] ov5647 4-0036: stream start failed: -22
    [ 72.069315] cdns-csi2rx 30101000.csi-bridge: Failed to start streams 0x1 on subdev
    [ 72.092410] cdns-csi2rx 30101000.csi-bridge: Failed to stop stream0
    [ 72.109644] cdns-csi2rx 30101000.csi-bridge: Failed to stop stream1
    [ 72.127058] cdns-csi2rx 30101000.csi-bridge: Failed to stop stream2
    [ 72.144358] cdns-csi2rx 30101000.csi-bridge: Failed to stop stream3

    Any idea why this is occuring ? 

  • Ok thanks,

    Whatever information you have provide that is helpful for me. Now just give the link for supporting camera's for AM62X EVK, so that i can able to capture the image and video. Now close these thread also.

    Thanks

    Regards,

    Dnyaneshwar