<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[V851S tina linux ov5647 驱动程序没有 dmesg]]></title><description><![CDATA[<p dir="auto">大家好，<br />
在修复了我的 i2c 并使用 i2cDetect 和手动 GPIO 选择手动检测到我的相机后，我正在尝试为相机制作一个驱动程序。<br />
我将它基于已经存在的 OV5468 mipi 驱动程序。 我更改了所有必需的标识符和寄存器/值，以使其符合 ov5647 的要求，我编辑了必要的 makefile 来构建它，并为新传感器配置了板的 DTS。<br />
我的问题是这样的：<br />
当我使用 insmod 加载 ov5647_mipi.ko 内核模块时，没有任何反应。 即使我将日志级别设置为 8，并且我在驱动程序中放置了各种 printk() 调用，但 dmesg 中根本没有出现任何消息，但这些调用实际上都没有显示在日志中。 你们知道我可能错过了什么吗？ 也许是某个特定的配置使日志静音？ DTS 错误？</p>
<pre><code class="language-sh">root@TinaLinux:/lib/modules/4.9.191# ls
ov5640.ko                soc_camera.ko            videobuf-core.ko
ov5647_mipi.ko           soc_camera_platform.ko   videobuf2-dma-contig.ko
ov5648_mipi.ko           soc_mediabus.ko          vin_io.ko
ov5658.ko                uvcvideo.ko              vin_v4l2.ko
root@TinaLinux:/lib/modules/4.9.191# lsmod
Module                  Size  Used by
vin_v4l2              176157  0
vin_io                 19952  1 vin_v4l2
videobuf2_dma_contig     8632  1 vin_v4l2
root@TinaLinux:/lib/modules/4.9.191# insmod ov5647_mipi.ko
root@TinaLinux:/lib/modules/4.9.191# lsmod
Module                  Size  Used by
ov5647_mipi             6469  0
vin_v4l2              176157  0
vin_io                 19952  2 ov5647_mipi,vin_v4l2
videobuf2_dma_contig     8632  1 vin_v4l2
root@TinaLinux:/lib/modules/4.9.191# dmesg | tail
root@TinaLinux:/lib/modules/4.9.191#
</code></pre>
<p dir="auto">我的DTS：</p>
<pre><code class="language-js">soc@03000000 {		
		/*wlan: wlan@0 {
			compatible    = "allwinner,sunxi-wlan";
			pinctrl-names = "default";
			clock-names = "32k-fanout0";
			clocks        = &lt;&amp;clk_fanout0&gt;;
			wlan_busnum    = &lt;0x1&gt;;
			wlan_regon    = &lt;&amp;pio PE 6 1 0x1 0x2 0&gt;;
			wlan_hostwake = &lt;&amp;pio PE 7 14 0x1 0x2 0&gt;;
			chip_en;
			power_en;
			status        = "io_disabled";
			wakeup-source;
		};*/

		vind0:vind@0 {
			vind0_clk = &lt;200000000&gt;;
			status = "okay";

			csi2:csi@2 {
				pinctrl-names = "default","sleep";
				pinctrl-0 = &lt;&amp;ncsi_pins_a&gt;;
				pinctrl-1 = &lt;&amp;ncsi_pins_b&gt;;
				status = "okay";
			};

			tdm0:tdm@0 {
				work_mode = &lt;0&gt;;
			};

			isp00:isp@0 {
				work_mode = &lt;0&gt;;
			};

			scaler00:scaler@0 {
				work_mode = &lt;0&gt;;
			};

			scaler10:scaler@4 {
				work_mode = &lt;0&gt;;
			};

			scaler20:scaler@8 {
				work_mode = &lt;0&gt;;
			};

			scaler30:scaler@12 {
				work_mode = &lt;0&gt;;
			};

			actuator0:actuator@0 {
				device_type = "actuator0";
				actuator0_name = "ad5820_act";
				actuator0_slave = &lt;0x18&gt;;
				actuator0_af_pwdn = &lt;&gt;;
				actuator0_afvdd = "afvcc-csi";
				actuator0_afvdd_vol = &lt;2800000&gt;;
				status = "disabled";
			};
 
			flash0:flash@0 {
				device_type = "flash0";
				flash0_type = &lt;2&gt;;
				flash0_en = &lt;&gt;;
				flash0_mode = &lt;&gt;;
				flash0_flvdd = "";
				flash0_flvdd_vol = &lt;&gt;;
				status = "disabled";
			};

			sensor0:sensor@0 {
				device_type = "sensor0";
				sensor0_mname = "ov5647_mipi";
				sensor0_twi_cci_id = &lt;1&gt;;
				sensor0_twi_addr = &lt;0x6c&gt;;
				sensor0_mclk_id = &lt;0&gt;;
				sensor0_pos = "rear";
				sensor0_isp_used = &lt;1&gt;;
				sensor0_fmt = &lt;1&gt;;
				sensor0_stby_mode = &lt;0&gt;;
				sensor0_vflip = &lt;0&gt;;
				sensor0_hflip = &lt;0&gt;;
				sensor0_iovdd-supply = &lt;1800000&gt;;
				sensor0_iovdd_vol = &lt;&gt;;
				sensor0_avdd-supply = &lt;2800000&gt;;
				sensor0_avdd_vol = &lt;&gt;;
				sensor0_dvdd-supply = &lt;1200000&gt;;
				sensor0_dvdd_vol = &lt;&gt;;
				sensor0_reset = &lt;&gt;;
				//sensor0_power_en = &lt;&gt;;
				//sensor0_pwdn = &lt;&gt;;
				sensor0_power_en = &lt;&amp;pio PA 9 1 0 1 0&gt;;
				sensor0_pwdn = &lt;&amp;pio PA 8 1 0 1 0&gt;;
				/*sensor0_sm_hs = &lt;&amp;pio PE 2 1 0 1 0&gt;;*/
				/*sensor0_sm_vs = &lt;&amp;pio PE 3 1 0 1 0&gt;;*/
				flash_handle = &lt;&amp;flash0&gt;; //&amp;flash0
				act_handle = &lt;&amp;actuator0&gt;;	//&amp;actuator0
				status	= "okay";
			};

			sensor1:sensor@1 {
				device_type = "sensor1";
				sensor1_mname = "ov5640";
				sensor1_twi_cci_id = &lt;2&gt;;
				sensor1_twi_addr = &lt;0x30&gt;;
				sensor1_mclk_id = &lt;1&gt;;
				sensor1_pos = "front";
				sensor1_isp_used = &lt;1&gt;;
				sensor1_fmt = &lt;1&gt;;
				sensor1_stby_mode = &lt;0&gt;;
				sensor1_vflip = &lt;0&gt;;
				sensor1_hflip = &lt;0&gt;;
				sensor1_iovdd-supply = &lt;&gt;;
				sensor1_iovdd_vol = &lt;1800000&gt;;
				sensor1_avdd-supply = &lt;&gt;;
				sensor1_avdd_vol = &lt;2800000&gt;;
				sensor1_dvdd-supply = &lt;&gt;;
				sensor1_dvdd_vol = &lt;1200000&gt;;
				sensor1_power_en = &lt;&gt;;
				sensor1_reset = &lt;&gt;;
				sensor1_pwdn = &lt;&gt;;
				sensor1_sm_hs = &lt;&amp;pio PE 2 1 0 1 0&gt;;
				sensor1_sm_vs = &lt;&amp;pio PE 3 1 0 1 0&gt;;
				flash_handle = &lt;&gt;;
				act_handle = &lt;&gt;;
				status	= "disabled";
			};

			vinc00:vinc@0 {
				vinc0_csi_sel = &lt;0&gt;;
				vinc0_mipi_sel = &lt;0&gt;;
				vinc0_isp_sel = &lt;0&gt;;
				vinc0_isp_tx_ch_ = &lt;0&gt;;
				vinc0_tdm_rx_sel = &lt;0&gt;;
				vinc0_rear_sensor_sel = &lt;0&gt;;
				vinc0_front_sensor_sel = &lt;0&gt;;
				vinc0_sensor_list = &lt;0&gt;;
				work_mode = &lt;0x0&gt;;
				status = "okay";
			};

			vinc01:vinc@1 {
				vinc1_csi_sel = &lt;2&gt;;
				vinc1_mipi_sel = &lt;0xff&gt;;
				vinc1_isp_sel = &lt;1&gt;;
				vinc1_isp_tx_ch = &lt;1&gt;;
				vinc1_tdm_rx_sel = &lt;1&gt;;
				vinc1_rear_sensor_sel = &lt;0&gt;;
				vinc1_front_sensor_sel = &lt;0&gt;;
				vinc1_sensor_list = &lt;0&gt;;
				status = "disabled";
			};

			vinc02:vinc@2 {
				vinc2_csi_sel = &lt;2&gt;;
				vinc2_mipi_sel = &lt;0xff&gt;;
				vinc2_isp_sel = &lt;2&gt;;
				vinc2_isp_tx_ch_ = &lt;2&gt;;
				vinc2_tdm_rx_sel = &lt;2&gt;;
				vinc2_rear_sensor_sel = &lt;0&gt;;
				vinc2_front_sensor_sel = &lt;0&gt;;
				vinc2_sensor_list = &lt;0&gt;;
				status = "disabled";
			};

			vinc03:vinc@3 {
				vinc3_csi_sel = &lt;0&gt;;
				vinc3_mipi_sel = &lt;0xff&gt;;
				vinc3_isp_sel = &lt;0&gt;;
				vinc3_isp_tx_ch_ = &lt;0&gt;;
				vinc3_tdm_rx_sel = &lt;0&gt;;
				vinc3_rear_sensor_sel = &lt;1&gt;;
				vinc3_front_sensor_sel = &lt;1&gt;;
				vinc3_sensor_list = &lt;0&gt;;
				status = "disabled";
			};

			vinc10:vinc@4 {
				vinc4_csi_sel = &lt;0&gt;;
				vinc4_mipi_sel = &lt;0&gt;;
				vinc4_isp_sel = &lt;0&gt;;
				vinc4_isp_tx_ch = &lt;0&gt;;
				vinc4_tdm_rx_sel = &lt;0&gt;;
				vinc4_rear_sensor_sel = &lt;0&gt;;
				vinc4_front_sensor_sel = &lt;0&gt;;
				vinc4_sensor_list = &lt;0&gt;;
				work_mode = &lt;0x0&gt;;
				status = "okay";
			};

			vinc11:vinc@5 {
				vinc5_csi_sel = &lt;2&gt;;
				vinc5_mipi_sel = &lt;0xff&gt;;
				vinc5_isp_sel = &lt;1&gt;;
				vinc5_isp_tx_ch = &lt;1&gt;;
				vinc5_tdm_rx_sel = &lt;1&gt;;
				vinc5_rear_sensor_sel = &lt;0&gt;;
				vinc5_front_sensor_sel = &lt;0&gt;;
				vinc5_sensor_list = &lt;0&gt;;
				status = "disabled";
			};

			vinc12:vinc@6 {
				vinc6_csi_sel = &lt;2&gt;;
				vinc6_mipi_sel = &lt;0xff&gt;;
				vinc6_isp_sel = &lt;0&gt;;
				vinc6_isp_tx_ch = &lt;0&gt;;
				vinc6_tdm_rx_sel = &lt;0&gt;;
				vinc6_rear_sensor_sel = &lt;0&gt;;
				vinc6_front_sensor_sel = &lt;0&gt;;
				vinc6_sensor_list = &lt;0&gt;;
				status = "disabled";
			};

			vinc13:vinc@7 {
				vinc7_csi_sel = &lt;2&gt;;
				vinc7_mipi_sel = &lt;0xff&gt;;
				vinc7_isp_sel = &lt;0&gt;;
				vinc7_isp_tx_ch = &lt;0&gt;;
				vinc7_tdm_rx_sel = &lt;0&gt;;
				vinc7_rear_sensor_sel = &lt;0&gt;;
				vinc7_front_sensor_sel = &lt;0&gt;;
				vinc7_sensor_list = &lt;0&gt;;
				status = "disabled";
			};

			vinc20:vinc@8 {
				vinc8_csi_sel = &lt;0&gt;;
				vinc8_mipi_sel = &lt;0&gt;;
				vinc8_isp_sel = &lt;0&gt;;
				vinc8_isp_tx_ch = &lt;0&gt;;
				vinc8_tdm_rx_sel = &lt;0&gt;;
				vinc8_rear_sensor_sel = &lt;0&gt;;
				vinc8_front_sensor_sel = &lt;0&gt;;
				vinc8_sensor_list = &lt;0&gt;;
				work_mode = &lt;0x0&gt;;
				status = "okay";
			};

			vinc21:vinc@9 {
				vinc9_csi_sel = &lt;2&gt;;
				vinc9_mipi_sel = &lt;0xff&gt;;
				vinc9_isp_sel = &lt;0&gt;;
				vinc9_isp_tx_ch = &lt;0&gt;;
				vinc9_tdm_rx_sel = &lt;0&gt;;
				vinc9_rear_sensor_sel = &lt;0&gt;;
				vinc9_front_sensor_sel = &lt;0&gt;;
				vinc9_sensor_list = &lt;0&gt;;
				status = "disabled";
			};

			vinc22:vinc@10 {
				vinc10_csi_sel = &lt;2&gt;;
				vinc10_mipi_sel = &lt;0xff&gt;;
				vinc10_isp_sel = &lt;0&gt;;
				vinc10_isp_tx_ch = &lt;0&gt;;
				vinc10_tdm_rx_sel = &lt;0&gt;;
				vinc10_rear_sensor_sel = &lt;0&gt;;
				vinc10_front_sensor_sel = &lt;0&gt;;
				vinc10_sensor_list = &lt;0&gt;;
				status = "disabled";
			};

			vinc23:vinc@11 {
				vinc11_csi_sel = &lt;2&gt;;
				vinc11_mipi_sel = &lt;0xff&gt;;
				vinc11_isp_sel = &lt;0&gt;;
				vinc11_isp_tx_ch = &lt;0&gt;;
				vinc11_tdm_rx_sel = &lt;0&gt;;
				vinc11_rear_sensor_sel = &lt;0&gt;;
				vinc11_front_sensor_sel = &lt;0&gt;;
				vinc11_sensor_list = &lt;0&gt;;
				status = "disabled";
			};

			vinc30:vinc@12 {
				vinc12_csi_sel = &lt;0&gt;;
				vinc12_mipi_sel = &lt;0&gt;;
				vinc12_isp_sel = &lt;0&gt;;
				vinc12_isp_tx_ch = &lt;0&gt;;
				vinc12_tdm_rx_sel = &lt;0&gt;;
				vinc12_rear_sensor_sel = &lt;0&gt;;
				vinc12_front_sensor_sel = &lt;0&gt;;
				vinc12_sensor_list = &lt;0&gt;;
				work_mode = &lt;0x0&gt;;
				status = "okay";
			};

			vinc31:vinc@13 {
				vinc13_csi_sel = &lt;2&gt;;
				vinc13_mipi_sel = &lt;0xff&gt;;
				vinc13_isp_sel = &lt;0&gt;;
				vinc13_isp_tx_ch = &lt;0&gt;;
				vinc13_tdm_rx_sel = &lt;0&gt;;
				vinc13_rear_sensor_sel = &lt;0&gt;;
				vinc13_front_sensor_sel = &lt;0&gt;;
				vinc13_sensor_list = &lt;0&gt;;
				status = "disabled";
			};

			vinc32:vinc@14 {
				vinc14_csi_sel = &lt;2&gt;;
				vinc14_mipi_sel = &lt;0xff&gt;;
				vinc14_isp_sel = &lt;0&gt;;
				vinc14_isp_tx_ch = &lt;0&gt;;
				vinc14_tdm_rx_sel = &lt;0&gt;;
				vinc14_rear_sensor_sel = &lt;0&gt;;
				vinc14_front_sensor_sel = &lt;0&gt;;
				vinc14_sensor_list = &lt;0&gt;;
				status = "disabled";
			};

			vinc33:vinc@15 {
				vinc15_csi_sel = &lt;2&gt;;
				vinc15_mipi_sel = &lt;0xff&gt;;
				vinc15_isp_sel = &lt;0&gt;;
				vinc15_isp_tx_ch = &lt;0&gt;;
				vinc15_tdm_rx_sel = &lt;0&gt;;
				vinc15_rear_sensor_sel = &lt;0&gt;;
				vinc15_front_sensor_sel = &lt;0&gt;;
				vinc15_sensor_list = &lt;0&gt;;
				status = "disabled";
			};
		};
	};
</code></pre>
<p dir="auto">最后是我的驱动程序，如您所见，它实现了各种日志：</p>
<pre><code class="language-cpp">#include &lt;linux/init.h&gt;
#include &lt;linux/module.h&gt;
#include &lt;linux/slab.h&gt;
#include &lt;linux/i2c.h&gt;
#include &lt;linux/delay.h&gt;
#include &lt;linux/videodev2.h&gt;
#include &lt;linux/clk.h&gt;
#include &lt;media/v4l2-device.h&gt;
#include &lt;media/v4l2-mediabus.h&gt;
#include &lt;linux/io.h&gt;

#include "camera.h"
#include "sensor_helper.h"

MODULE_AUTHOR("YG");
MODULE_DESCRIPTION("A low-level driver for OV5647 sensors");
MODULE_LICENSE("GPL");

#define MCLK              (24*1000*1000)
#define V4L2_IDENT_SENSOR 0x5647

#define DEV_DBG_EN 1

/*
 * Our nominal (default) frame rate.
 */

#define SENSOR_FRAME_RATE 30

/*
 * The ov5647 i2c address
 */
#define I2C_ADDR 0x6c

#define SENSOR_NAME "ov5647_mipi"


/*
 * The default register settings
 */

static struct regval_list sensor_default_regs[] = {
	/*2lane initial*/
	/*Slave_ID=0x6c*/

	{0x0100, 0x00},
	{0x0103, 0x01},
	// delay(5ms)
	{REG_DLY, 0x25},
	{0x3001, 0x00},
	{0x3002, 0x00},
	{0x3011, 0x02},
	{0x3018, 0x4c},
	{0x3022, 0x00},
	{0x3034, 0x1a},
	{0x3035, 0x21},
	{0x3036, 0x69},
	{0x3037, 0x03},
	{0x3038, 0x00},
	{0x3039, 0x00},
	{0x303a, 0x00},
	{0x303b, 0x19},
	{0x303c, 0x11},
	{0x303d, 0x30},
	{0x3105, 0x11},
	{0x3106, 0x05},
	{REG_DLY, 0x05},
	{0x3304, 0x28},
	{0x3305, 0x41},
	{0x3306, 0x30},
	{0x3308, 0x00},
	{0x3309, 0xc8},
	{0x330a, 0x01},
	{0x330b, 0x90},
	{0x330c, 0x02},
	{0x330d, 0x58},
	{0x330e, 0x03},
	{0x330f, 0x20},
	{0x3300, 0x00},
	{0x3500, 0x00},
	{0x3501, 0x3d},
	{0x3502, 0x00},
	{0x3503, 0x07},
	{0x350a, 0x00},
	{0x350b, 0x40},
	{0x3601, 0x33},
	{0x3602, 0x00},
	{0x3611, 0x0e},
	{0x3612, 0x2b},
	{0x3614, 0x50},
	{0x3620, 0x33},
	{0x3622, 0x00},
	{0x3630, 0xad},
	{0x3631, 0x00},
	{0x3632, 0x94},
	{0x3633, 0x17},
	{0x3634, 0x14},
	{0x3704, 0xc0},
	{0x3705, 0x2a},
	{0x3708, 0x66},
	{0x3709, 0x52},
	{0x370b, 0x23},
	{0x370c, 0xc3},
	{0x370d, 0x00},
	{0x370e, 0x00},
	{0x371c, 0x07},
	{0x3739, 0xd2},
	{0x373c, 0x00},
	{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, 0x0b},
	{0x380d, 0x00},
	{0x380e, 0x03},
	{0x380f, 0xe0},
	{0x3810, 0x00},
	{0x3811, 0x08},
	{0x3812, 0x00},
	{0x3813, 0x04},
	{0x3814, 0x31},
	{0x3815, 0x31},
	{0x3817, 0x00},
	{0x3820, 0x08},
	{0x3821, 0x07},
	{0x3826, 0x03},
	{0x3829, 0x00},
	{0x382b, 0x0b},
	{0x3830, 0x00},
	{0x3836, 0x00},
	{0x3837, 0x00},
	{0x3838, 0x00},
	{0x3839, 0x04},
	{0x383a, 0x00},
	{0x383b, 0x01},
	{0x3b00, 0x00},
	{0x3b02, 0x08},
	{0x3b03, 0x00},
	{0x3b04, 0x04},
	{0x3b05, 0x00},
	{0x3b06, 0x04},
	{0x3b07, 0x08},
	{0x3b08, 0x00},
	{0x3b09, 0x02},
	{0x3b0a, 0x04},
	{0x3b0b, 0x00},
	{0x3b0c, 0x3d},
	{0x3f01, 0x0d},
	{0x3f0f, 0xf5},
	{0x4000, 0x89},
	{0x4001, 0x02},
	{0x4002, 0x45},
	{0x4004, 0x02},
	{0x4005, 0x18},
	{0x4006, 0x08},
	{0x4007, 0x10},
	{0x4008, 0x00},
	{0x4300, 0xf8},
	{0x4303, 0xff},
	{0x4304, 0x00},
	{0x4307, 0xff},
	{0x4520, 0x00},
	{0x4521, 0x00},
	{0x4511, 0x22},
	{0x4800, 0x14},
	{0x481f, 0x3c},
	{0x4826, 0x00},
	{0x4837, 0x18},
	{0x4b00, 0x06},
	{0x4b01, 0x0a},
	{0x5000, 0xff},
	{0x5001, 0x00},
	{0x5002, 0x41},
	{0x5003, 0x0a},
	{0x5004, 0x00},
	{0x5043, 0x00},
	{0x5013, 0x00},
	{0x501f, 0x03},
	{0x503d, 0x00},
	{0x5180, 0x08},
	{0x5a00, 0x08},
	{0x5b00, 0x01},
	{0x5b01, 0x40},
	{0x5b02, 0x00},
	{0x5b03, 0xf0},
	{0x301a, 0xf0},
	{0x0100, 0x01},
	{0x4837, 0x17},

};
static struct regval_list sensor_qsxga_regs[] = {
	/*2592x1944 15fps 2 lane MIPI 420Mbps/lane */
	{0x0100, 0x00},
	{0x3501, 0x7b},
	{0x2502, 0x00},
	{0x3708, 0x63},
	{0x3709, 0x12},
	{0x370c, 0xc0},
	{0x3800, 0x00},
	{0x3801, 0x00},
	{0x3802, 0x00},
	{0x3803, 0x00},
	{0x3804, 0x0a},
	{0x3805, 0x3f},
	{0x3806, 0x07},
	{0x3807, 0xa3},
	{0x3808, 0x0a},
	{0x3809, 0x20},
	{0x380a, 0x07},
	{0x380b, 0x98},
	{0x380c, 0x0b},
	{0x380d, 0x00},
	{0x380e, 0x07},
	{0x380f, 0xc0},
	{0x3810, 0x00},
	{0x3811, 0x10},
	{0x3812, 0x00},
	{0x3813, 0x06},
	{0x3814, 0x11},
	{0x3815, 0x11},
	{0x3817, 0x00},
	{0x3820, 0x40},
	{0x3821, 0x06},
	{0x4004, 0x04},
	{0x4005, 0x1a},
	{0x350b, 0x40},
	{0x4837, 0x17},
	{0x0100, 0x01},
};

static struct regval_list sensor_720p_regs[] = {
	/* 1280x720 30fps 2 lane MIPI 420Mbps/lane */
	{0x0100, 0x00},
	{0x3501, 0x2d},
	{0x3502, 0xc0},
	{0x3708, 0x66},
	{0x3709, 0x52},
	{0x370c, 0xcf},
	{0x3800, 0x00},
	{0x3801, 0x10},
	{0x3802, 0x00},
	{0x3803, 0xfe},
	{0x3804, 0x0a},
	{0x3805, 0x2f},
	{0x3806, 0x06},
	{0x3807, 0xa5},
	{0x3808, 0x05},
	{0x3809, 0x00},
	{0x380a, 0x02},
	{0x380b, 0xd0},
	{0x380c, 0x0e},
	{0x380d, 0xc4},
	{0x380e, 0x02},
	{0x380f, 0xe6},
	{0x3810, 0x00},
	{0x3811, 0x08},
	{0x3812, 0x00},
	{0x3813, 0x02},
	{0x3814, 0x31},
	{0x3815, 0x31},
	{0x3817, 0x00},
	{0x3820, 0x08},
	{0x3821, 0x07},
	{0x4004, 0x02},
	{0x4005, 0x18},
	{0x3b0b, 0x80},
	{0x4837, 0x17},
	{0x0100, 0x01},
};
static struct regval_list sensor_fmt_raw[] = {

};

/*
 * Code for dealing with controls.
 * fill with different sensor module
 * different sensor module has different settings here
 * if not support the follow function ,retrun -EINVAL
 */

static int sensor_g_exp(struct v4l2_subdev *sd, __s32 *value)
{
	struct sensor_info *info = to_state(sd);

	*value = info-&gt;exp;
	sensor_dbg("sensor_get_exposure = %d\n", info-&gt;exp);
	return 0;
}

static int sensor_s_exp(struct v4l2_subdev *sd, unsigned int exp_val)
{
	unsigned char explow, expmid, exphigh;
	struct sensor_info *info = to_state(sd);

	if (exp_val &gt; 0xfffff)
		exp_val = 0xfffff;
	if (exp_val &lt; 7)
		exp_val = 7;

	exphigh = (unsigned char)((0x0f0000 &amp; exp_val) &gt;&gt; 16);
	expmid = (unsigned char)((0x00ff00 &amp; exp_val) &gt;&gt; 8);
	explow = (unsigned char)(0x0000ff &amp; exp_val);

	sensor_write(sd, 0x3502, explow);
	sensor_write(sd, 0x3501, expmid);
	sensor_write(sd, 0x3500, exphigh);

	info-&gt;exp = exp_val;
	return 0;
}

static int sensor_g_gain(struct v4l2_subdev *sd, __s32 *value)
{
	struct sensor_info *info = to_state(sd);
	*value = info-&gt;gain;
	sensor_dbg("sensor_get_gain = %d\n", info-&gt;gain);
	return 0;
}

static int sensor_s_gain(struct v4l2_subdev *sd, unsigned int gain_val)
{
	struct sensor_info *info = to_state(sd);
	unsigned char gainlow = 0;
	unsigned char gainhigh = 0;

	if (gain_val &lt; 1 * 16)
		gain_val = 16;
	if (gain_val &gt; 64 * 16 - 1)
		gain_val = 64 * 16 - 1;

	gainlow = (unsigned char)(gain_val &amp; 0xff);
	gainhigh = (unsigned char)((gain_val &gt;&gt; 8) &amp; 0x3);

	sensor_write(sd, 0x350b, gainlow);
	sensor_write(sd, 0x350a, gainhigh);

	info-&gt;gain = gain_val;

	return 0;
}

static int ov5647_sensor_vts;
static int sensor_s_exp_gain(struct v4l2_subdev *sd,
				struct sensor_exp_gain *exp_gain)
{
	int exp_val, gain_val, shutter, frame_length;
	unsigned char explow = 0, expmid = 0, exphigh = 0;
	unsigned char gainlow = 0, gainhigh = 0;
	struct sensor_info *info = to_state(sd);

	exp_val = exp_gain-&gt;exp_val;
	gain_val = exp_gain-&gt;gain_val;
	if (gain_val &lt; 1*16)
		gain_val = 16;
	if (gain_val &gt; 64*16-1)
		gain_val = 64*16-1;

	if (exp_val &gt; 0xfffff)
		exp_val = 0xfffff;

	gainlow = (unsigned char)(gain_val &amp; 0xff);
	gainhigh = (unsigned char)((gain_val &gt;&gt; 8)&amp;0x3);

	exphigh	= (unsigned char)((0x0f0000&amp;exp_val) &gt;&gt; 16);
	expmid	= (unsigned char)((0x00ff00&amp;exp_val) &gt;&gt; 8);
	explow	= (unsigned char)((0x0000ff&amp;exp_val));

	shutter = exp_val/16;
	if (shutter  &gt; ov5647_sensor_vts - 4)
		frame_length = shutter + 4;
	else
		frame_length = ov5647_sensor_vts;

	sensor_write(sd, 0x3208, 0x00);//enter group write
	sensor_write(sd, 0x3503, 0x07);
	sensor_write(sd, 0x380f, (frame_length &amp; 0xff));
	sensor_write(sd, 0x380e, (frame_length &gt;&gt; 8));
	sensor_write(sd, 0x350b, gainlow);
	sensor_write(sd, 0x350a, gainhigh);

	sensor_write(sd, 0x3502, explow);
	sensor_write(sd, 0x3501, expmid);
	sensor_write(sd, 0x3500, exphigh);
	sensor_write(sd, 0x3208, 0x10);//end group write
	sensor_write(sd, 0x3208, 0xa0);//init group write
	info-&gt;exp = exp_val;
	info-&gt;gain = gain_val;
	return 0;
}

static void sensor_s_sw_stby(struct v4l2_subdev *sd, int on_off)
{
	int ret = 0;
	return ret;
}

/*
 * Stuff that knows about the sensor.
 */
static int sensor_power(struct v4l2_subdev *sd, int on)
{
	int ret = 0;
	printk(KERN_WARNING "entering sensor_power\n");
	sensor_dbg("zzz5648 sensor_power\n");

	switch (on) {
	case STBY_ON:
		printk(KERN_WARNING "entering sensor_power STBY_ON\n");
		sensor_print("STBY_ON!\n");
		cci_lock(sd);
		sensor_s_sw_stby(sd, STBY_ON);
		usleep_range(1000, 1200);
		cci_unlock(sd);
		break;
	case STBY_OFF:
		printk(KERN_WARNING "entering sensor_power STBY_OFF\n");
		sensor_print("STBY_OFF!\n");
		cci_lock(sd);
		usleep_range(1000, 1200);
		sensor_s_sw_stby(sd, STBY_OFF);
		cci_unlock(sd);
		break;
	case PWR_ON:
		printk(KERN_WARNING "entering sensor_power PWR_ON, pins: %d %d\n",PWDN ,POWER_EN);
		gpio_direction_output(GPIOA(8), 0);	//led enable
		gpio_direction_output(GPIOA(9), 0);	//power enable
		sensor_print("PWR_ON!100\n");
		cci_lock(sd);
		vin_gpio_set_status(sd, PWDN, 1);
		//vin_gpio_write(sd, RESET, CSI_GPIO_HIGH);	//not needed for the rpi ov5647 modules
		vin_gpio_set_status(sd, POWER_EN, 1);
		vin_gpio_write(sd, PWDN, CSI_GPIO_HIGH);	//special case, since PWDN is the led we power it ON
		//vin_gpio_write(sd, RESET, CSI_GPIO_LOW);	//ignore reset
		vin_gpio_write(sd, POWER_EN, CSI_GPIO_HIGH);
		usleep_range(7000, 8000);
		vin_set_pmu_channel(sd, IOVDD, ON);
		usleep_range(7000, 8000);
		vin_set_pmu_channel(sd, AVDD, ON);
		vin_set_pmu_channel(sd, AFVDD, ON);
		usleep_range(7000, 8000);
		vin_set_pmu_channel(sd, DVDD, ON);
		usleep_range(7000, 8000);
		vin_set_mclk_freq(sd, MCLK);
		vin_set_mclk(sd, ON);
		usleep_range(10000, 12000);
		//vin_gpio_write(sd, RESET, CSI_GPIO_HIGH);	//these calls are useless as well
		//vin_gpio_write(sd, PWDN, CSI_GPIO_HIGH);
		vin_set_pmu_channel(sd, CAMERAVDD, ON);/*AFVCC ON*/
		usleep_range(10000, 12000);
		cci_unlock(sd);
		break;
	case PWR_OFF:
		sensor_print("PWR_OFF!\n");
		cci_lock(sd);
		vin_gpio_write(sd, PWDN, CSI_GPIO_LOW);	//LED off
		//vin_gpio_write(sd, RESET, CSI_GPIO_HIGH);
		vin_set_mclk(sd, OFF);
		usleep_range(7000, 8000);
		vin_set_pmu_channel(sd, DVDD, OFF);
		//vin_gpio_write(sd, PWDN, CSI_GPIO_LOW);
		//vin_gpio_write(sd, RESET, CSI_GPIO_LOW);
		vin_gpio_write(sd, POWER_EN, CSI_GPIO_LOW);	//turn off power to the camera
		vin_set_pmu_channel(sd, AVDD, OFF);
		vin_set_pmu_channel(sd, IOVDD, OFF);
		vin_set_pmu_channel(sd, AFVDD, OFF);
		vin_set_pmu_channel(sd, CAMERAVDD, OFF);/*AFVCC ON*/
		cci_unlock(sd);
		break;
	default:
		return -EINVAL;
	}

	return 0;
}

static int sensor_reset(struct v4l2_subdev *sd, u32 val)
{
	printk(KERN_WARNING "entering sensor_reset\n");	//this camera modules doesn't need to reset
	/*
	switch (val) {
	case 0:
		vin_gpio_write(sd, RESET, CSI_GPIO_HIGH);
		usleep_range(100, 120);
		break;
	case 1:
		vin_gpio_write(sd, RESET, CSI_GPIO_LOW);
		usleep_range(100, 120);
		break;
	default:
		return -EINVAL;
	}
	*/
	return 0;
}

static int sensor_detect(struct v4l2_subdev *sd)
{
	printk(KERN_WARNING "entering sensor_detect\n");
	data_type rdval;
	unsigned int SENSOR_ID = 0;
	sensor_read(sd, 0x300A, &amp;rdval);
	SENSOR_ID |= rdval;
	SENSOR_ID |= (rdval &lt;&lt; 8);
	sensor_read(sd, 0x300B, &amp;rdval);
	SENSOR_ID |= (rdval);
	sensor_print("V4L2_IDENT_SENSOR = 0x%x\n", SENSOR_ID);
	if (SENSOR_ID != 0x5648) {
		sensor_print("ov5647 %s error, chip found is not an target chip", __func__);
		printk(KERN_WARNING "exiting sensor_detect, not found\n");
		//return -ENODEV;
	}
	printk(KERN_WARNING "exiting sensor_detect, found\n");
	return 0;
}

static int sensor_init(struct v4l2_subdev *sd, u32 val)
{
	printk(KERN_WARNING "entering sensor_init\n");
	int ret;
	struct sensor_info *info = to_state(sd);

	sensor_print("sensor_init\n");

	/*Make sure it is a target sensor */
	ret = sensor_detect(sd);
	if (ret) {
		printk(KERN_WARNING "exiting sensor_init, not found\n");
		sensor_err("chip found is not an target chip.\n");
		return ret;
	}

	info-&gt;focus_status = 0;
	info-&gt;low_speed = 0;
	info-&gt;width = 1280;
	info-&gt;height = 720;
	info-&gt;hflip = 0;
	info-&gt;vflip = 0;
	info-&gt;gain = 0;

	info-&gt;tpf.numerator = 1;
	info-&gt;tpf.denominator = 30;	/* 30fps */

	info-&gt;preview_first_flag = 1;

	return 0;
}

static long sensor_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg)
{
	int ret = 0;
	struct sensor_info *info = to_state(sd);

	switch (cmd) {
	case GET_CURRENT_WIN_CFG:
		if (info-&gt;current_wins != NULL) {
			memcpy(arg, info-&gt;current_wins,
				sizeof(struct sensor_win_size));
			ret = 0;
		} else {
			sensor_err("empty wins!\n");
			ret = -1;
		}
		break;
	case SET_FPS:
		ret = 0;
		break;
	case VIDIOC_VIN_SENSOR_EXP_GAIN:
		ret = sensor_s_exp_gain(sd, (struct sensor_exp_gain *)arg);
		break;
	case VIDIOC_VIN_SENSOR_CFG_REQ:
		sensor_cfg_req(sd, (struct sensor_config *)arg);
		break;
	case VIDIOC_VIN_ACT_INIT:
		ret = actuator_init(sd, (struct actuator_para *)arg);
		break;
	case VIDIOC_VIN_ACT_SET_CODE:
		ret = actuator_set_code(sd, (struct actuator_ctrl *)arg);
		break;
	default:
		return -EINVAL;
	}
	return ret;
}

/*
 * Store information about the video data format.
 */
static struct sensor_format_struct sensor_formats[] = {
	{
		.desc = "Raw RGB Bayer",
		.mbus_code = MEDIA_BUS_FMT_SBGGR10_1X10,
		.regs = sensor_fmt_raw,
		.regs_size = ARRAY_SIZE(sensor_fmt_raw),
		.bpp = 1
	},
};
#define N_FMTS ARRAY_SIZE(sensor_formats)

/*
 * Then there is the issue of window sizes.  Try to capture the info here.
 */

static struct sensor_win_size sensor_win_sizes[] = {
#if 0
/* 720p */
	{
		.width      = HD720_WIDTH,
		.height     = HD720_HEIGHT,
		.hoffset    = 0,
		.voffset    = 0,
		.hts        = 3780,
		.vts        = 742,
		.pclk       = 84*1000*1000,
		.mipi_bps	  = 420*1000*1000,
		.fps_fixed  = 30,
		.bin_factor = 1,
		.intg_min   = 16,
		.intg_max   = (742-4)&lt;&lt;4,
		.gain_min   = 1&lt;&lt;4,
		.gain_max   = 64&lt;&lt;4,
		.regs		  = sensor_720p_regs,//
		.regs_size  = ARRAY_SIZE(sensor_720p_regs),//
		.set_size	  = NULL,
	},
#endif
/* qsxga */
	{
	  .width	  = QSXGA_WIDTH,
	  .height	  = QSXGA_HEIGHT,
	  .hoffset	  = 0,
	  .voffset	  = 0,
	  .hts		  = 2816,
	  .vts		  = 1984,
	  .pclk		  = 84*1000*1000,
	  .mipi_bps   = 420*1000*1000,
	  .fps_fixed  = 15,
	  .bin_factor = 1,
	  .intg_min   = 16,
	  .intg_max   = (1984-4)&lt;&lt;4,
	  .gain_min   = 1&lt;&lt;4,
	  .gain_max   = 64&lt;&lt;4,
	  .regs		  = sensor_qsxga_regs,
	  .regs_size  = ARRAY_SIZE(sensor_qsxga_regs),
	  .set_size   = NULL,
	},

};

#define N_WIN_SIZES (ARRAY_SIZE(sensor_win_sizes))

static int sensor_reg_init(struct sensor_info *info)
{
	int ret;
	struct v4l2_subdev *sd = &amp;info-&gt;sd;
	struct sensor_format_struct *sensor_fmt = info-&gt;fmt;
	struct sensor_win_size *wsize = info-&gt;current_wins;

	ret = sensor_write_array(sd, sensor_default_regs,
				ARRAY_SIZE(sensor_default_regs));
	if (ret &lt; 0) {
		sensor_err("write sensor_default_regs error\n");
		return ret;
	}

	sensor_print("sensor_reg_init\n");

	sensor_write_array(sd, sensor_fmt-&gt;regs, sensor_fmt-&gt;regs_size);

	if (wsize-&gt;regs)
		sensor_write_array(sd, wsize-&gt;regs, wsize-&gt;regs_size);

	if (wsize-&gt;set_size)
		wsize-&gt;set_size(sd);

	info-&gt;width = wsize-&gt;width;
	info-&gt;height = wsize-&gt;height;
	info-&gt;exp = 0;
	info-&gt;gain = 0;
	ov5647_sensor_vts = wsize-&gt;vts;
	sensor_print("s_fmt set width = %d, height = %d\n", wsize-&gt;width,
				wsize-&gt;height);

	return 0;
}

static int sensor_s_stream(struct v4l2_subdev *sd, int enable)
{
	struct sensor_info *info = to_state(sd);

	sensor_print("%s on = %d, %d*%d fps: %d code: %x\n", __func__, enable,
			info-&gt;current_wins-&gt;width, info-&gt;current_wins-&gt;height,
			info-&gt;current_wins-&gt;fps_fixed, info-&gt;fmt-&gt;mbus_code);

	if (!enable)
		return 0;

	return sensor_reg_init(info);
}
static int sensor_g_mbus_config(struct v4l2_subdev *sd,
				struct v4l2_mbus_config *cfg)
{
	cfg-&gt;type = V4L2_MBUS_CSI2;
	cfg-&gt;flags = 0 | V4L2_MBUS_CSI2_2_LANE | V4L2_MBUS_CSI2_CHANNEL_0;

	return 0;
}

static int sensor_g_ctrl(struct v4l2_ctrl *ctrl)
{
	struct sensor_info *info = container_of(ctrl-&gt;handler,
			struct sensor_info, handler);
	struct v4l2_subdev *sd = &amp;info-&gt;sd;

	switch (ctrl-&gt;id) {
	case V4L2_CID_GAIN:
		return sensor_g_gain(sd, &amp;ctrl-&gt;val);
	case V4L2_CID_EXPOSURE:
		return sensor_g_exp(sd, &amp;ctrl-&gt;val);
	}
	return -EINVAL;
}

static int sensor_s_ctrl(struct v4l2_ctrl *ctrl)
{
	struct sensor_info *info = container_of(ctrl-&gt;handler,
			struct sensor_info, handler);
	struct v4l2_subdev *sd = &amp;info-&gt;sd;

	switch (ctrl-&gt;id) {
	case V4L2_CID_GAIN:
		return sensor_s_gain(sd, ctrl-&gt;val);
	case V4L2_CID_EXPOSURE:
		return sensor_s_exp(sd, ctrl-&gt;val);
	}
	return -EINVAL;
}



/* ----------------------------------------------------------------------- */

static const struct v4l2_ctrl_ops sensor_ctrl_ops = {
	.g_volatile_ctrl = sensor_g_ctrl,
	.s_ctrl = sensor_s_ctrl,
};

static const struct v4l2_subdev_core_ops sensor_core_ops = {
	.reset = sensor_reset,
	.init = sensor_init,
	.s_power = sensor_power,
	.ioctl = sensor_ioctl,
#ifdef CONFIG_COMPAT
	.compat_ioctl32 = sensor_compat_ioctl32,
#endif
};

static const struct v4l2_subdev_video_ops sensor_video_ops = {
	.s_parm = sensor_s_parm,
	.g_parm = sensor_g_parm,
	.s_stream = sensor_s_stream,
	.g_mbus_config = sensor_g_mbus_config,
};

static const struct v4l2_subdev_pad_ops sensor_pad_ops = {
	.enum_mbus_code = sensor_enum_mbus_code,
	.enum_frame_size = sensor_enum_frame_size,
	.get_fmt = sensor_get_fmt,
	.set_fmt = sensor_set_fmt,
};

static const struct v4l2_subdev_ops sensor_ops = {
	.core = &amp;sensor_core_ops,
	.video = &amp;sensor_video_ops,
	.pad = &amp;sensor_pad_ops,
};

/* ----------------------------------------------------------------------- */
static struct cci_driver cci_drv = {
		.name = SENSOR_NAME,
		.addr_width = CCI_BITS_16,
		.data_width = CCI_BITS_8,
};

static const struct v4l2_ctrl_config sensor_custom_ctrls[] = {
	{
		.ops = &amp;sensor_ctrl_ops,
		.id = V4L2_CID_FRAME_RATE,
		.name = "frame rate",
		.type = V4L2_CTRL_TYPE_INTEGER,
		.min = 15,
		.max = 120,
		.step = 1,
		.def = 120,
	},
};

static int sensor_init_controls(struct v4l2_subdev *sd,
			const struct v4l2_ctrl_ops *ops)
{
	struct sensor_info *info = to_state(sd);
	struct v4l2_ctrl_handler *handler = &amp;info-&gt;handler;
	struct v4l2_ctrl *ctrl;
	int i;
	int ret = 0;

	v4l2_ctrl_handler_init(handler, 2 + ARRAY_SIZE(sensor_custom_ctrls));

	v4l2_ctrl_new_std(handler, ops, V4L2_CID_GAIN, 1 * 1600,
				256 * 1600, 1, 1 * 1600);
	ctrl = v4l2_ctrl_new_std(handler, ops, V4L2_CID_EXPOSURE, 0,
				65536 * 16, 1, 0);
	if (ctrl != NULL)
		ctrl-&gt;flags |= V4L2_CTRL_FLAG_VOLATILE;
	for (i = 0; i &lt; ARRAY_SIZE(sensor_custom_ctrls); i++)
		v4l2_ctrl_new_custom(handler, &amp;sensor_custom_ctrls[i], NULL);

	if (handler-&gt;error) {
		ret = handler-&gt;error;
		v4l2_ctrl_handler_free(handler);
	}

	sd-&gt;ctrl_handler = handler;

	return ret;
}

static int sensor_probe(struct i2c_client *client,
			const struct i2c_device_id *id)
{
	struct v4l2_subdev *sd;
	struct sensor_info *info;
	printk(KERN_WARNING "entering sensor_probe\n");

	info = kzalloc(sizeof(struct sensor_info), GFP_KERNEL);
	if (info == NULL)
		return -ENOMEM;
	sd = &amp;info-&gt;sd;

	cci_dev_probe_helper(sd, client, &amp;sensor_ops, &amp;cci_drv);
	sensor_init_controls(sd, &amp;sensor_ctrl_ops);

	mutex_init(&amp;info-&gt;lock);
#ifdef CONFIG_SAME_I2C
	info-&gt;sensor_i2c_addr = I2C_ADDR &gt;&gt; 1;
#endif
	info-&gt;fmt = &amp;sensor_formats[0];
	info-&gt;fmt_pt = &amp;sensor_formats[0];
	info-&gt;win_pt = &amp;sensor_win_sizes[0];
	info-&gt;fmt_num = N_FMTS;
	info-&gt;win_size_num = N_WIN_SIZES;
	info-&gt;sensor_field = V4L2_FIELD_NONE;
	info-&gt;stream_seq = MIPI_BEFORE_SENSOR;
	info-&gt;af_first_flag = 1;
	info-&gt;exp = 0;
	info-&gt;gain = 0;

	return 0;
}

static int sensor_remove(struct i2c_client *client)
{
	struct v4l2_subdev *sd;
	printk(KERN_WARNING "entering sensor_remove\n");

	sd = cci_dev_remove_helper(client, &amp;cci_drv);

	kfree(to_state(sd));
	return 0;
}

static const struct i2c_device_id sensor_id[] = {
	{SENSOR_NAME, 0},
	{}
};

MODULE_DEVICE_TABLE(i2c, sensor_id);

static struct i2c_driver sensor_driver = {
		.driver = {
				.owner = THIS_MODULE,
				.name = SENSOR_NAME,
				},
		.probe = sensor_probe,
		.remove = sensor_remove,
		.id_table = sensor_id,
};
static __init int init_sensor(void)
{
	return cci_dev_init_helper(&amp;sensor_driver);
}

static __exit void exit_sensor(void)
{
	cci_dev_exit_helper(&amp;sensor_driver);
}

module_init(init_sensor);
module_exit(exit_sensor);

</code></pre>
]]></description><link>https://bbs.aw-ol.com/topic/4638/v851s-tina-linux-ov5647-驱动程序没有-dmesg</link><generator>RSS for Node</generator><lastBuildDate>Fri, 11 Sep 2026 07:25:42 GMT</lastBuildDate><atom:link href="https://bbs.aw-ol.com/topic/4638.rss" rel="self" type="application/rss+xml"/><pubDate>Fri, 17 Nov 2023 21:45:27 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to V851S tina linux ov5647 驱动程序没有 dmesg on Wed, 13 Mar 2024 02:42:55 GMT]]></title><description><![CDATA[<p dir="auto"><a class="plugin-mentions-user plugin-mentions-a" href="https://bbs.aw-ol.com/uid/4059">@kanken6174</a> 谢谢，哪里可以找到让v851se工作的方法？理论上，除了ephy部分，v851s应该和v851se是一样的。</p>
]]></description><link>https://bbs.aw-ol.com/post/21777</link><guid isPermaLink="true">https://bbs.aw-ol.com/post/21777</guid><dc:creator><![CDATA[allspace123]]></dc:creator><pubDate>Wed, 13 Mar 2024 02:42:55 GMT</pubDate></item><item><title><![CDATA[Reply to V851S tina linux ov5647 驱动程序没有 dmesg on Tue, 12 Mar 2024 20:21:08 GMT]]></title><description><![CDATA[<p dir="auto"><a class="plugin-mentions-user plugin-mentions-a" href="https://bbs.aw-ol.com/uid/1298">@allspace123</a> 不，我没有，我得到的只是黑屏和几条绿线，我放弃了并使用了 GC2053。 我也几乎放弃了 V851S 作为 mipi-csi 转 USB 平台，因为我无法让视频编码器工作，尽管社区已经以某种方式使其能够在 V851SE 上工作。 没有办法获得V851SE芯片，所以我的项目目前陷入困境。</p>
<p dir="auto">您可以在此 github 页面上找到我对驱动程序的失败尝试。<br />
<a href="https://github.com/Kanken6174/V851S-OV5647" target="_blank" rel="noopener noreferrer nofollow ugc">https://github.com/Kanken6174/V851S-OV5647</a></p>
]]></description><link>https://bbs.aw-ol.com/post/21775</link><guid isPermaLink="true">https://bbs.aw-ol.com/post/21775</guid><dc:creator><![CDATA[kanken6174]]></dc:creator><pubDate>Tue, 12 Mar 2024 20:21:08 GMT</pubDate></item><item><title><![CDATA[Reply to V851S tina linux ov5647 驱动程序没有 dmesg on Mon, 11 Mar 2024 14:53:09 GMT]]></title><description><![CDATA[<p dir="auto"><a class="plugin-mentions-user plugin-mentions-a" href="https://bbs.aw-ol.com/uid/4059">@kanken6174</a> 请问你是否已经成功让v851s支持ov5647?</p>
<p dir="auto">另外，请教各位，Linux主线已经包含了对ov5647支持，可以通过在v851s上运行主线来支持ov5647 吗？</p>
<p dir="auto">Tina Linux 基于5.4内核的SDK也包含了ov5647 的驱动，有人试过吗？</p>
]]></description><link>https://bbs.aw-ol.com/post/21755</link><guid isPermaLink="true">https://bbs.aw-ol.com/post/21755</guid><dc:creator><![CDATA[allspace123]]></dc:creator><pubDate>Mon, 11 Mar 2024 14:53:09 GMT</pubDate></item><item><title><![CDATA[Reply to V851S tina linux ov5647 驱动程序没有 dmesg on Thu, 11 Jan 2024 12:32:45 GMT]]></title><description><![CDATA[<p dir="auto"><a class="plugin-mentions-user plugin-mentions-a" href="https://bbs.aw-ol.com/uid/2606">@zheng1</a> 那没有，放弃了，谢谢劝谏</p>
]]></description><link>https://bbs.aw-ol.com/post/20803</link><guid isPermaLink="true">https://bbs.aw-ol.com/post/20803</guid><dc:creator><![CDATA[mysteryli]]></dc:creator><pubDate>Thu, 11 Jan 2024 12:32:45 GMT</pubDate></item><item><title><![CDATA[Reply to V851S tina linux ov5647 驱动程序没有 dmesg on Wed, 27 Dec 2023 07:28:44 GMT]]></title><description><![CDATA[<p dir="auto"><a class="plugin-mentions-user plugin-mentions-a" href="https://bbs.aw-ol.com/uid/4059">@kanken6174</a>  我在v851s平台移植sensor驱动的话，成功点亮sensor的话，就算isp没有调试正确的效果文件，也应该会出图，颜色什么的不正常也不会全黑的才对</p>
]]></description><link>https://bbs.aw-ol.com/post/20583</link><guid isPermaLink="true">https://bbs.aw-ol.com/post/20583</guid><dc:creator><![CDATA[spr2023]]></dc:creator><pubDate>Wed, 27 Dec 2023 07:28:44 GMT</pubDate></item><item><title><![CDATA[Reply to V851S tina linux ov5647 驱动程序没有 dmesg on Mon, 25 Dec 2023 15:05:17 GMT]]></title><description><![CDATA[<p dir="auto"><a class="plugin-mentions-user plugin-mentions-a" href="https://bbs.aw-ol.com/uid/739">@mysteryli</a> 你有灯箱色卡之类的吗，没有的话建议直接放弃。有的话可以加个好友研究下</p>
]]></description><link>https://bbs.aw-ol.com/post/20566</link><guid isPermaLink="true">https://bbs.aw-ol.com/post/20566</guid><dc:creator><![CDATA[zheng1]]></dc:creator><pubDate>Mon, 25 Dec 2023 15:05:17 GMT</pubDate></item><item><title><![CDATA[Reply to V851S tina linux ov5647 驱动程序没有 dmesg on Mon, 25 Dec 2023 11:36:14 GMT]]></title><description><![CDATA[<p dir="auto"><a class="plugin-mentions-user plugin-mentions-a" href="https://bbs.aw-ol.com/uid/2606">@zheng1</a> 在 <a href="/post/20556">V851S tina linux ov5647 驱动程序没有 dmesg</a> 中说：</p>
<blockquote>
<p dir="auto"><a class="plugin-mentions-user plugin-mentions-a" href="https://bbs.aw-ol.com/uid/4059">@kanken6174</a> camerademo抓图正常吗？如果camerademo抓图正常，那就是Tiger ISP的配置问题了。先确保camerademo能抓到正确的图</p>
</blockquote>
<p dir="auto">我的平台camerademo能抓图了<br />
Tiger ISP怎么调呢</p>
]]></description><link>https://bbs.aw-ol.com/post/20561</link><guid isPermaLink="true">https://bbs.aw-ol.com/post/20561</guid><dc:creator><![CDATA[mysteryli]]></dc:creator><pubDate>Mon, 25 Dec 2023 11:36:14 GMT</pubDate></item><item><title><![CDATA[Reply to V851S tina linux ov5647 驱动程序没有 dmesg on Mon, 25 Dec 2023 08:44:22 GMT]]></title><description><![CDATA[<p dir="auto"><a class="plugin-mentions-user plugin-mentions-a" href="https://bbs.aw-ol.com/uid/4059">@kanken6174</a> camerademo抓图正常吗？如果camerademo抓图正常，那就是Tiger ISP的配置问题了。先确保camerademo能抓到正确的图</p>
]]></description><link>https://bbs.aw-ol.com/post/20556</link><guid isPermaLink="true">https://bbs.aw-ol.com/post/20556</guid><dc:creator><![CDATA[zheng1]]></dc:creator><pubDate>Mon, 25 Dec 2023 08:44:22 GMT</pubDate></item><item><title><![CDATA[Reply to V851S tina linux ov5647 驱动程序没有 dmesg on Mon, 18 Dec 2023 17:02:09 GMT]]></title><description><![CDATA[<p dir="auto"><a class="plugin-mentions-user plugin-mentions-a" href="https://bbs.aw-ol.com/uid/2606">@zheng1</a> 我确实没有正确的设置来调试芯片内的 Tiger ISP，但如果需要，我可以设置一个。 但现在校准颜色并不是我的主要问题，因为相机似乎仍然无法正常运行，看看这张捕获的“图像”：<br />
<img src="/assets/uploads/files/1702918922114-2caedd95-16c3-4b8c-a680-f630fc99d768-image.png" alt="2caedd95-16c3-4b8c-a680-f630fc99d768-image.png" class=" img-responsive img-markdown" width="810" height="608" /><br />
我的大部分颜色是黑色，顶部有一点数据，该图像是使用 TigerISP 应用程序从 RAW 格式提取的。 我真的不确定这里可能出了什么问题，这不可能是曝光，因为我直接在相机上闪光，而没有对图像进行任何更改，并且由于数据是在单个 MIPI 通道上发送的，所以应该 不可能是时间问题吧？</p>
<p dir="auto">我将等待我的主板版本 2 修复 mipi 通道，看看这是否对官方驱动程序有帮助。 开发文档的常见问题解答并未涵盖这种特定情况，因此我现在只能尝试更改相机内的配置......</p>
]]></description><link>https://bbs.aw-ol.com/post/20461</link><guid isPermaLink="true">https://bbs.aw-ol.com/post/20461</guid><dc:creator><![CDATA[kanken6174]]></dc:creator><pubDate>Mon, 18 Dec 2023 17:02:09 GMT</pubDate></item><item><title><![CDATA[Reply to V851S tina linux ov5647 驱动程序没有 dmesg on Mon, 18 Dec 2023 06:38:51 GMT]]></title><description><![CDATA[<p dir="auto">我这里还有imx219的<a href="/assets/uploads/files/1702881508191-imx219.c">imx219.c</a> <a href="/assets/uploads/files/1702881508189-ov5647_mipi.c">ov5647_mipi.c</a> ，你有ISP调试环境吗？灯箱色卡之类的</p>
]]></description><link>https://bbs.aw-ol.com/post/20458</link><guid isPermaLink="true">https://bbs.aw-ol.com/post/20458</guid><dc:creator><![CDATA[zheng1]]></dc:creator><pubDate>Mon, 18 Dec 2023 06:38:51 GMT</pubDate></item><item><title><![CDATA[Reply to V851S tina linux ov5647 驱动程序没有 dmesg on Fri, 15 Dec 2023 17:45:30 GMT]]></title><description><![CDATA[<p dir="auto">修复了翻转的通道并纠正了一些混乱的寄存器后，它起作用了！ 最后！ 感谢大家的帮助！ 现在我必须正确设置 ISP 才能查看生成的 RAW 文件，但这已经是向前迈出的一大步了 ^^</p>
<p dir="auto"><img src="/assets/uploads/files/1702662327601-2ad3bd6e-d4a5-4929-86c2-7d97a1e4b18d-image.png" alt="2ad3bd6e-d4a5-4929-86c2-7d97a1e4b18d-image.png" class=" img-responsive img-markdown" width="763" height="1583" /></p>
]]></description><link>https://bbs.aw-ol.com/post/20436</link><guid isPermaLink="true">https://bbs.aw-ol.com/post/20436</guid><dc:creator><![CDATA[kanken6174]]></dc:creator><pubDate>Fri, 15 Dec 2023 17:45:30 GMT</pubDate></item><item><title><![CDATA[Reply to V851S tina linux ov5647 驱动程序没有 dmesg on Thu, 14 Dec 2023 17:02:54 GMT]]></title><description><![CDATA[<p dir="auto">我发现了我的问题，我非常讨厌它......普遍的愚蠢 <img src="https://bbs.aw-ol.com/plugins/nodebb-plugin-emoji/emoji/android/1f622.png?v=9vrjmbh7mr2" class="not-responsive emoji emoji-android emoji--cry" title=":cry:" alt="😢" /><br />
<img src="/assets/uploads/files/1702573351024-a901fac5-3a42-4d9d-a9f6-30ef5ae5b87a-image.png" alt="a901fac5-3a42-4d9d-a9f6-30ef5ae5b87a-image.png" class=" img-responsive img-markdown" width="694" height="160" /></p>
]]></description><link>https://bbs.aw-ol.com/post/20413</link><guid isPermaLink="true">https://bbs.aw-ol.com/post/20413</guid><dc:creator><![CDATA[kanken6174]]></dc:creator><pubDate>Thu, 14 Dec 2023 17:02:54 GMT</pubDate></item><item><title><![CDATA[Reply to V851S tina linux ov5647 驱动程序没有 dmesg on Thu, 14 Dec 2023 16:28:20 GMT]]></title><description><![CDATA[<p dir="auto"><a class="plugin-mentions-user plugin-mentions-a" href="https://bbs.aw-ol.com/uid/3792">@spr2023</a> 谢谢，我将阅读这篇文章，尝试看看他们做了什么不同的事情。 请注意，分辨率不是camerademo的问题，就好像640x480不可用一样，它将使用它可以使用的第一个分辨率，在我的例子中是1296x972，这是树莓派3运行这些相机的标准分辨率。 我使用的寄存器正是树莓派针对该特定分辨率发送的寄存器。 我尝试了许多不同的分辨率和寄存器配置，但总是出现相同的超时错误，我什至尝试使用主线 OV5647 驱动程序 (<a href="https://github.com/torvalds/linux/blob/master/drivers/media/i2c/ov5647.c" target="_blank" rel="noopener noreferrer nofollow ugc">https://github.com/torvalds/linux/blob/master/drivers/media/i2c/ov5647.c</a>) 中的寄存器和配置。<br />
我的驱动程序的基础已经是 ov5648 驱动程序，只是修改了开机顺序（我的相机所需）和寄存器/配置。</p>
]]></description><link>https://bbs.aw-ol.com/post/20412</link><guid isPermaLink="true">https://bbs.aw-ol.com/post/20412</guid><dc:creator><![CDATA[kanken6174]]></dc:creator><pubDate>Thu, 14 Dec 2023 16:28:20 GMT</pubDate></item><item><title><![CDATA[Reply to V851S tina linux ov5647 驱动程序没有 dmesg on Thu, 14 Dec 2023 16:22:20 GMT]]></title><description><![CDATA[<p dir="auto"><a class="plugin-mentions-user plugin-mentions-a" href="https://bbs.aw-ol.com/uid/2123">@whycanservice</a> 谢谢，这对调试很有用</p>
]]></description><link>https://bbs.aw-ol.com/post/20411</link><guid isPermaLink="true">https://bbs.aw-ol.com/post/20411</guid><dc:creator><![CDATA[kanken6174]]></dc:creator><pubDate>Thu, 14 Dec 2023 16:22:20 GMT</pubDate></item><item><title><![CDATA[Reply to V851S tina linux ov5647 驱动程序没有 dmesg on Thu, 14 Dec 2023 11:35:53 GMT]]></title><description><![CDATA[<p dir="auto"><a class="plugin-mentions-user plugin-mentions-a" href="https://bbs.aw-ol.com/uid/4059">@kanken6174</a> R853的偏移量可以用到V851上</p>
]]></description><link>https://bbs.aw-ol.com/post/20407</link><guid isPermaLink="true">https://bbs.aw-ol.com/post/20407</guid><dc:creator><![CDATA[WhycanService]]></dc:creator><pubDate>Thu, 14 Dec 2023 11:35:53 GMT</pubDate></item><item><title><![CDATA[Reply to V851S tina linux ov5647 驱动程序没有 dmesg on Thu, 14 Dec 2023 01:53:58 GMT]]></title><description><![CDATA[<p dir="auto"><a class="plugin-mentions-user plugin-mentions-a" href="https://bbs.aw-ol.com/uid/4059">@kanken6174</a> 在 <a href="/post/19999">V851S tina linux ov5647 驱动程序没有 dmesg</a> 中说：</p>
<blockquote>
<p dir="auto">相机加电，所以它永远找不到它</p>
</blockquote>
<p dir="auto">你好，我看了下你移植的 ov5647 sensor驱动过程。首先你是想基于ov5648 sensor驱动自己修改出来5647的驱动来尝试移植，如果按照已有的5648驱动框架来修改适配的话，应该是难度不大的。我看你上面已经i2c识别到了sensor，但是你用camera demo没有出图，log上面有提示是你camerademo出图的640*480？但你驱动里面只有720p和另一个分辨率，如果需要支持这个分辨率，需要用到你后面说的那一堆初始化寄存器，这个寄存器不建议自己一个个尝试得出来，最好找一份你买sensor的支持，要一份初始化参数过来，替换ov5648的初始化参数，然后你驱动里面配置的line什么的应该也没错，能成功识别到sensor上电时序和pwdn也都对，猜测没点亮重点在初始化参数的配置。我看你参考的文档，移植的应该是linux平台的驱动不是快起的，你可以参考这篇博客的流程，然后根据ov5648的驱动框架移植，希望对你有帮助</p>
<p dir="auto"><a href="https://blog.csdn.net/weixin_45349811/article/details/132707827" target="_blank" rel="noopener noreferrer nofollow ugc">https://blog.csdn.net/weixin_45349811/article/details/132707827</a></p>
]]></description><link>https://bbs.aw-ol.com/post/20381</link><guid isPermaLink="true">https://bbs.aw-ol.com/post/20381</guid><dc:creator><![CDATA[spr2023]]></dc:creator><pubDate>Thu, 14 Dec 2023 01:53:58 GMT</pubDate></item><item><title><![CDATA[Reply to V851S tina linux ov5647 驱动程序没有 dmesg on Wed, 13 Dec 2023 23:14:53 GMT]]></title><description><![CDATA[<p dir="auto">我发现 allwinner 提供的文档之一在常见问题解答中提供了有关我所面临的确切问题的信息。 所以我现在会尝试按照其中的说明进行操作。 我似乎需要 mipi 寄存器偏移量才能正确调试，但他们不为 V851S 提供这些偏移量，只为其他芯片提供这些偏移量，而且我在芯片的数据表中没有找到它们，知道我可以从哪里获得它们吗？<br />
<img src="/assets/uploads/files/1702509285940-f744245b-0586-491b-863f-6cdc427887ed-image.png" alt="f744245b-0586-491b-863f-6cdc427887ed-image.png" class=" img-responsive img-markdown" width="844" height="656" /></p>
]]></description><link>https://bbs.aw-ol.com/post/20380</link><guid isPermaLink="true">https://bbs.aw-ol.com/post/20380</guid><dc:creator><![CDATA[kanken6174]]></dc:creator><pubDate>Wed, 13 Dec 2023 23:14:53 GMT</pubDate></item><item><title><![CDATA[Reply to V851S tina linux ov5647 驱动程序没有 dmesg on Wed, 13 Dec 2023 22:45:54 GMT]]></title><description><![CDATA[<p dir="auto">这是执行camerademo后调试FS的输出，您可以在这里清楚地看到驱动程序处于MIPI模式但尚未接收到任何数据。:</p>
<pre><code class="language-bash">root@TinaLinux:/# cat /sys/kernel/debug/mpp/vi
*****************************************************
VIN hardware feature list:
mcsi 2, ncsi 1, parser 3, isp 1, vipp 4, dma 4
CSI_VERSION: CSI300_200, ISP_VERSION: ISP600_100
CSI_CLK: 200000000, ISP_CLK: 24000000
*****************************************************
vi0:
ov5647_mipi =&gt; mipi0 =&gt; csi0 =&gt; tdm_rx0 =&gt; isp0 =&gt; vipp0
input =&gt; hoff: 0, voff: 0, w: 1296, h: 972, fmt: GBRG10
output =&gt; width: 1296, height: 972, fmt: NV21
interface: MIPI, isp_mode: NORMAL, hflip: 0, vflip: 0
prs_in =&gt; x: 0, y: 0, hb: 0, hs: 0
bkbuf =&gt; cnt: 3 size: 1900544 rest: 3, work_mode: online
tdmbuf =&gt; cnt: 0 size: 0, cmp_ratio: 0
ispbuf =&gt; cnt: 4 size: 1991680/15552/15552/15552, cmp_ratio: 1024
frame =&gt; cnt: 0, lost_cnt: 0, error_cnt: 0
internal =&gt; avg: 0(ms), max: 0(ms), min: 0(ms)
*****************************************************
vi4:
(null) =&gt; mipi0 =&gt; csi0 =&gt; tdm_rx0 =&gt; isp0 =&gt; vipp4
input =&gt; hoff: 0, voff: 0, w: 0, h: 0, fmt: NULL
output =&gt; width: 0, height: 0, fmt: NULL
interface: PARALLEL, isp_mode: NORMAL, hflip: 0, vflip: 0
prs_in =&gt; x: 0, y: 0, hb: 0, hs: 0
bkbuf =&gt; cnt: 0 size: 0 rest: 0, work_mode: online
tdmbuf =&gt; cnt: 0 size: 0, cmp_ratio: 0
ispbuf =&gt; cnt: 4 size: 1991680/15552/15552/15552, cmp_ratio: 1024
frame =&gt; cnt: 0, lost_cnt: 0, error_cnt: 0
internal =&gt; avg: 0(ms), max: 0(ms), min: 0(ms)
*****************************************************
vi8:
(null) =&gt; mipi0 =&gt; csi0 =&gt; tdm_rx0 =&gt; isp0 =&gt; vipp8
input =&gt; hoff: 0, voff: 0, w: 0, h: 0, fmt: NULL
output =&gt; width: 0, height: 0, fmt: NULL
interface: PARALLEL, isp_mode: NORMAL, hflip: 0, vflip: 0
prs_in =&gt; x: 0, y: 0, hb: 0, hs: 0
bkbuf =&gt; cnt: 0 size: 0 rest: 0, work_mode: online
tdmbuf =&gt; cnt: 0 size: 0, cmp_ratio: 0
ispbuf =&gt; cnt: 4 size: 1991680/15552/15552/15552, cmp_ratio: 1024
frame =&gt; cnt: 0, lost_cnt: 0, error_cnt: 0
internal =&gt; avg: 0(ms), max: 0(ms), min: 0(ms)
*****************************************************
vi12:
(null) =&gt; mipi0 =&gt; csi0 =&gt; tdm_rx0 =&gt; isp0 =&gt; vipp12
input =&gt; hoff: 0, voff: 0, w: 0, h: 0, fmt: NULL
output =&gt; width: 0, height: 0, fmt: NULL
interface: PARALLEL, isp_mode: NORMAL, hflip: 0, vflip: 0
prs_in =&gt; x: 0, y: 0, hb: 0, hs: 0
bkbuf =&gt; cnt: 0 size: 0 rest: 0, work_mode: online
tdmbuf =&gt; cnt: 0 size: 0, cmp_ratio: 0
ispbuf =&gt; cnt: 4 size: 1991680/15552/15552/15552, cmp_ratio: 1024
frame =&gt; cnt: 0, lost_cnt: 0, error_cnt: 0
internal =&gt; avg: 0(ms), max: 0(ms), min: 0(ms)
*****************************************************
</code></pre>
<p dir="auto">并行节点未使用，仅 VI0 重要</p>
]]></description><link>https://bbs.aw-ol.com/post/20379</link><guid isPermaLink="true">https://bbs.aw-ol.com/post/20379</guid><dc:creator><![CDATA[kanken6174]]></dc:creator><pubDate>Wed, 13 Dec 2023 22:45:54 GMT</pubDate></item><item><title><![CDATA[Reply to V851S tina linux ov5647 驱动程序没有 dmesg on Wed, 13 Dec 2023 22:23:10 GMT]]></title><description><![CDATA[<p dir="auto"><a class="plugin-mentions-user plugin-mentions-a" href="https://bbs.aw-ol.com/uid/1915">@awwwwa</a> 我还尝试修改 IMX219 官方驱动程序以使用 2 通道模式，IMX219 <em>确实</em>支持该模式（因为它用于树莓派相机 V2，它使用两个通道）。</p>
<pre><code class="language-cpp">/*
 * A V4L2 driver for IMX219 Raw cameras.
 *
 * Copyright (c) 2017 by Allwinnertech Co., Ltd.  http://www.allwinnertech.com
 *
 * Authors:  Zhao Wei &lt;zhaowei@allwinnertech.com&gt;
 *    Yang Feng &lt;yangfeng@allwinnertech.com&gt;
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation.
 */
//camerademo BGGR8 1280 720 30 bmp /tmp 5
#include &lt;linux/init.h&gt;
#include &lt;linux/module.h&gt;
#include &lt;linux/slab.h&gt;
#include &lt;linux/i2c.h&gt;
#include &lt;linux/delay.h&gt;
#include &lt;linux/videodev2.h&gt;
#include &lt;linux/clk.h&gt;
#include &lt;media/v4l2-device.h&gt;
#include &lt;media/v4l2-mediabus.h&gt;
#include &lt;linux/io.h&gt;
#include "camera.h"
#include "sensor_helper.h"

MODULE_AUTHOR("Chomoly");
MODULE_DESCRIPTION("A low-level driver for IMX219 sensors");
MODULE_LICENSE("GPL");

#define MCLK              (24*1000*1000)
#define V4L2_IDENT_SENSOR 0x0219//0x0219
#define DEBUG_FS 1

/*
 * Our nominal (default) frame rate.
 */
#ifdef FPGA
#define SENSOR_FRAME_RATE 15
#else
#define SENSOR_FRAME_RATE 30
#endif

/*
 * The IMX219 sits on i2c with ID 0x6c
 */
#define I2C_ADDR 0x20
#define SENSOR_NAME "imx219"
int imx219_sensor_vts;
#define ES_GAIN(a, b, c) ((unsigned short)(a * 160) &lt; (c * 10) &amp;&amp; (c*10) &lt;= (unsigned short)(b * 160))

struct cfg_array {		/* coming later */
	struct regval_list *regs;
	int size;
};



/*
 * The default register settings
 *
 */

static struct regval_list sensor_default_regs[] = {	/*3280 x 2464_20fps 4lanes 720Mbps/lane */
	{0x30EB, 0x05},	//manufacturer specific reg access sequence
	{0x30EB, 0x0C},	//manufacturer specific reg access sequence
	{0x300A, 0xFF},	//manufacturer specific reg access sequence
	{0x300B, 0xFF},	//manufacturer specific reg access sequence
	{0x30EB, 0x05},	//manufacturer specific reg access sequence
	{0x30EB, 0x09},	//manufacturer specific reg access sequence
	{0x0114, 0x01},	//two lane mode	//03 quad
	{0x0128, 0x00},	//auto mipi timing
	{0x012A, 0x18},	//INCK frequency [MHz] default 0C
	{0x012B, 0x00},	//INCK frequency [MHz] 
	{0x0160, 0x02},	//frame length lines	(2*1lines)
	{0x0161, 0x00},	//frame length lines	(0*3lines)
	{0x0162, 0x0D},	//line_length_plck in pixels (13)
	{0x0163, 0xE8},	//line_length_plck in pixels (232) 3560
	{0x0164, 0x03},	//X-address of the top left corner of the visible pixel data Units: Pixels
	{0x0165, 0xE8}, //X-address of the top left corner of the visible pixel data Units: Pixels	// 0x03E8 = 1000
	{0x0166, 0x08},	//X-address of the bottom right corner of the visible pixel data Units: Pixels
	{0x0167, 0xE7}, //X-address of the bottom right corner of the visible pixel data Units: Pixels //0x08E7 = 2279 -1000 = 1279
	{0x0168, 0x03},	//Y-address of the top left corner of the visible pixel data Units: Lines
	{0x0169, 0x68}, //Y-address of the top left corner of the visible pixel data Units: Lines //0x0368 = 872
	{0x016A, 0x06},	//Y-address of the bottom right corner of the visible pixel data Units: Pixels
	{0x016B, 0x37}, //Y-address of the bottom right corner of the visible pixel data Units: Pixels : 0x0637 = 1591 - 872 = 719	// 1280*720
	{0x016C, 0x05},	//output size x
	{0x016D, 0x00},	//output size x pixels
	{0x016E, 0x02},	//output size y 
	{0x016F, 0xD0},	//output size y lines
	{0x0170, 0x01},	//x_odd_inc Increment for odd pixels 1, 3; turns 1279 into 1280
	{0x0171, 0x01}, //y_odd_inc Increment for odd pixels 1, 3; turns 719 into 720
	{0x0174, 0x00},	//no binning
	{0x0175, 0x00},	//no binning
	{0x018C, 0x0A},	//CSI-2 data format (0x0A default)
	{0x018D, 0x0A},	//CSI-2 data format (0x0A default)
	{0x0301, 0x05},	//Video Timing Pixel Clock Divider Value 
	{0x0303, 0x01},	//Video Timing System Clock Divider Value 
	{0x0304, 0x03},	//Pre PLL clock Video Timing System Divider value //camerademo RGGB8 1280 720 30 bmp /tmp 5 |vin is not support this pixelformat
	{0x0305, 0x03},	//Pre PLL clock Output System Divider Value
	{0x0306, 0x00},	//PLL Video Timing System multiplier Value 
	{0x0307, 0x57},	//PLL Video Timing System multiplier Value 
	{0x0309, 0x05 /*0A */ },	//Output Pixel Clock Divider Value (0A default)
	{0x030B, 0x01},	//Output System Clock Divider Value 
	{0x030C, 0x00},	//PLL Output System multiplier Value
	{0x030D, 0x5A},	//PLL Output System multiplier Value
	//{0x4767, 0x0F},
	//{0x4750, 0x14},
	//{0x47B4, 0x14},	//unk
	{0x0100, 0x01},	//streaming mode on
};


static struct regval_list sensor_hxga_regs[] = {

	{0x30EB, 0x05},
	{0x30EB, 0x0C},
	{0x300A, 0xFF},
	{0x300B, 0xFF},
	{0x30EB, 0x05},
	{0x30EB, 0x09},
	{0x0114, 0x01},
	{0x0128, 0x00},
	{0x012A, 0x18},
	{0x012B, 0x00},

	{0x0160, 0x0F},
	{0x0161, 0xC5},
	{0x0162, 0x0D},
	{0x0163, 0x78},

	{0x0164, 0x00},
	{0x0165, 0x00},
	{0x0166, 0x0C},
	{0x0167, 0xCF},
	{0x0168, 0x00},
	{0x0169, 0x00},
	{0x016A, 0x09},
	{0x016B, 0x9F},
	{0x016C, 0x0C},
	{0x016D, 0xD0},
	{0x016E, 0x09},
	{0x016F, 0xA0},
	{0x0170, 0x01},
	{0x0171, 0x01},
	{0x0174, 0x00},
	{0x0175, 0x00},
	{0x018C, 0x0A},
	{0x018D, 0x0A},
	{0x0301, 0x05},
	{0x0303, 0x01},
	{0x0304, 0x03},
	{0x0305, 0x03},
	{0x0306, 0x00},
	{0x0307, 0x57},
	{0x0309, 0x0A},
	{0x030B, 0x01},
	{0x030C, 0x00},
	{0x030D, 0x5A},
	{0x4767, 0x0F},
	{0x4750, 0x14},
	{0x47B4, 0x14},

	{0x0100, 0x01},

};

static struct regval_list sensor_sxga_regs[] = {

	{0x30EB, 0x05},
	{0x30EB, 0x0C},
	{0x300A, 0xFF},
	{0x300B, 0xFF},
	{0x30EB, 0x05},
	{0x30EB, 0x09},
	{0x0114, 0x01},
	{0x0128, 0x00},
	{0x012A, 0x18},
	{0x012B, 0x00},
	{0x0160, 0x0a},
	{0x0161, 0x2f},
	{0x0162, 0x0d},
	{0x0163, 0xe8},
	{0x0164, 0x03},
	{0x0165, 0xe8},
	{0x0166, 0x08},
	{0x0167, 0xe7},
	{0x0168, 0x02},
	{0x0169, 0xf0},
	{0x016A, 0x06},
	{0x016B, 0xaF},
	{0x016C, 0x05},
	{0x016D, 0x00},
	{0x016E, 0x03},
	{0x016F, 0xc0},





	{0x0170, 0x01},
	{0x0171, 0x01},
	{0x0174, 0x00},
	{0x0175, 0x00},
	{0x018C, 0x0A},
	{0x018D, 0x0A},
	{0x0301, 0x05},
	{0x0303, 0x01},
	{0x0304, 0x03},
	{0x0305, 0x03},
	{0x0306, 0x00},
	{0x0307, 0x57},
	{0x0309, 0x0A},
	{0x030B, 0x01},
	{0x030C, 0x00},
	{0x030D, 0x5A},
	{0x4767, 0x0F},
	{0x4750, 0x14},
	{0x47B4, 0x14},
	{0x0100, 0x01},
};


static struct regval_list sensor_1080p_regs[] = {


	{0x30EB, 0x05},
	{0x30EB, 0x0C},
	{0x300A, 0xFF},
	{0x300B, 0xFF},
	{0x30EB, 0x05},
	{0x30EB, 0x09},

	{0x0114, 0x01},
	{0x0128, 0x00},
	{0x012A, 0x18},
	{0x012B, 0x00},



	{0x0160, 0x0A},
	{0x0161, 0x2F},
	{0x0162, 0x0D},
	{0x0163, 0xE8},
	{0x0164, 0x02},
	{0x0165, 0xA8},
	{0x0166, 0x0A},
	{0x0167, 0x27},
	{0x0168, 0x02},
	{0x0169, 0xB4},
	{0x016A, 0x06},
	{0x016B, 0xEB},
	{0x016C, 0x07},
	{0x016D, 0x80},
	{0x016E, 0x04},
	{0x016F, 0x38},
	{0x0170, 0x01},
	{0x0171, 0x01},
	{0x0174, 0x00},
	{0x0175, 0x00},
	{0x018C, 0x0A},
	{0x018D, 0x0A},
	{0x0301, 0x05},
	{0x0303, 0x01},
	{0x0304, 0x03},
	{0x0305, 0x03},
	{0x0306, 0x00},
	{0x0307, 0x57},
	{0x0309, 0x0A},
	{0x030B, 0x01},
	{0x030C, 0x00},
	{0x030D, 0x5A},
	{0x4767, 0x0F},
	{0x4750, 0x14},
	{0x47B4, 0x14},
	{0x0100, 0x01},
};

#define sensor_720p_regs sensor_default_regs

//static struct regval_list* sensor_720p_regs = sensor_default_regs;


/*
 * Here we'll try to encapsulate the changes for just the output
 * video format.
 *
 */

static struct regval_list sensor_fmt_raw[] = {

};

static int sensor_s_exp_gain(struct v4l2_subdev *sd,
			     struct sensor_exp_gain *exp_gain)
{
	int exp_val, gain_val, frame_length, shutter;
	unsigned char explow = 0, exphigh = 0;
	struct sensor_info *info = to_state(sd);

	exp_val = exp_gain-&gt;exp_val;
	gain_val = exp_gain-&gt;gain_val;

	if (gain_val &lt; 1 * 16)
		gain_val = 16;
	if (gain_val &gt; 10 * 16 - 1)
		gain_val = 10 * 16 - 1;

	if (exp_val &gt; 0xfffff)
		exp_val = 0xfffff;

	exp_val &gt;&gt;= 4;
	exphigh = (unsigned char)((0x00ff00 &amp; exp_val) &gt;&gt; 8);
	explow = (unsigned char)((0x0000ff &amp; exp_val));

	sensor_write(sd, 0x015b, explow);
	sensor_write(sd, 0x015a, exphigh);

	shutter = exp_val;

	if (shutter &gt; imx219_sensor_vts - 4)
		frame_length = shutter + 4;
	else
		frame_length = imx219_sensor_vts;
	sensor_write(sd, 0x0161, frame_length &amp; 0xff);

	sensor_write(sd, 0x0160, frame_length &gt;&gt; 8);
	if (gain_val == 16)
		sensor_write(sd, 0x0157, 0x01);
	if (ES_GAIN(1.0, 1.1, gain_val))
		sensor_write(sd, 0x0157, 24);
	else if (ES_GAIN(1.1, 1.2, gain_val))
		sensor_write(sd, 0x0157, 42);
	else if (ES_GAIN(1.2, 1.3, gain_val))
		sensor_write(sd, 0x0157, 60);
	else if (ES_GAIN(1.3, 1.4, gain_val))
		sensor_write(sd, 0x0157, 73);
	else if (ES_GAIN(1.4, 1.5, gain_val))
		sensor_write(sd, 0x0157, 85);
	else if (ES_GAIN(1.5, 1.6, gain_val))
		sensor_write(sd, 0x0157, 96);
	else if (ES_GAIN(1.6, 1.7, gain_val))
		sensor_write(sd, 0x0157, 105);
	else if (ES_GAIN(1.7, 1.8, gain_val))
		sensor_write(sd, 0x0157, 114);
	else if (ES_GAIN(1.8, 1.9, gain_val))
		sensor_write(sd, 0x0157, 122);
	else if (ES_GAIN(1.9, 2.0, gain_val))
		sensor_write(sd, 0x0157, 0x80);
	else if (ES_GAIN(2.0, 2.1, gain_val))
		sensor_write(sd, 0x0157, 134);
	else if (ES_GAIN(2.1, 2.2, gain_val))
		sensor_write(sd, 0x0157, 140);
	else if (ES_GAIN(2.2, 2.3, gain_val))
		sensor_write(sd, 0x0157, 145);
	else if (ES_GAIN(2.3, 2.4, gain_val))
		sensor_write(sd, 0x0157, 150);
	else if (ES_GAIN(2.4, 2.5, gain_val))
		sensor_write(sd, 0x0157, 154);
	else if (ES_GAIN(2.5, 2.6, gain_val))
		sensor_write(sd, 0x0157, 158);
	else if (ES_GAIN(2.6, 2.7, gain_val))
		sensor_write(sd, 0x0157, 162);
	else if (ES_GAIN(2.7, 2.8, gain_val))
		sensor_write(sd, 0x0157, 165);

	else if (ES_GAIN(2.8, 2.9, gain_val))
		sensor_write(sd, 0x0157, 168);
	else if (ES_GAIN(2.9, 3.0, gain_val))
		sensor_write(sd, 0x0157, 0xab);
	else if (ES_GAIN(3.0, 3.1, gain_val))
		sensor_write(sd, 0x0157, 174);
	else if (ES_GAIN(3.1, 3.2, gain_val))
		sensor_write(sd, 0x0157, 176);
	else if (ES_GAIN(3.2, 3.3, gain_val))
		sensor_write(sd, 0x0157, 179);
	else if (ES_GAIN(3.3, 3.4, gain_val))
		sensor_write(sd, 0x0157, 181);
	else if (ES_GAIN(3.4, 3.5, gain_val))
		sensor_write(sd, 0x0157, 183);
	else if (ES_GAIN(3.5, 3.6, gain_val))
		sensor_write(sd, 0x0157, 185);
	else if (ES_GAIN(3.6, 3.7, gain_val))
		sensor_write(sd, 0x0157, 187);
	else if (ES_GAIN(3.7, 3.8, gain_val))
		sensor_write(sd, 0x0157, 189);
	else if (ES_GAIN(3.8, 3.9, gain_val))
		sensor_write(sd, 0x0157, 191);
	else if (ES_GAIN(3.9, 4.0, gain_val))
		sensor_write(sd, 0x0157, 192);
	else if (ES_GAIN(4.0, 4.1, gain_val))
		sensor_write(sd, 0x0157, 194);
	else if (ES_GAIN(4.1, 4.2, gain_val))
		sensor_write(sd, 0x0157, 195);
	else if (ES_GAIN(4.2, 4.3, gain_val))
		sensor_write(sd, 0x0157, 197);
	else if (ES_GAIN(4.3, 4.4, gain_val))
		sensor_write(sd, 0x0157, 198);
	else if (ES_GAIN(4.4, 4.5, gain_val))
		sensor_write(sd, 0x0157, 200);
	else if (ES_GAIN(4.5, 4.6, gain_val))
		sensor_write(sd, 0x0157, 201);
	else if (ES_GAIN(4.6, 4.7, gain_val))
		sensor_write(sd, 0x0157, 202);
	else if (ES_GAIN(4.7, 4.8, gain_val))
		sensor_write(sd, 0x0157, 203);
	else if (ES_GAIN(4.8, 4.9, gain_val))
		sensor_write(sd, 0x0157, 204);
	else if (ES_GAIN(4.9, 5.0, gain_val))
		sensor_write(sd, 0x0157, 205);
	else if (ES_GAIN(5.0, 5.1, gain_val))
		sensor_write(sd, 0x0157, 206);
	else if (ES_GAIN(5.1, 5.2, gain_val))
		sensor_write(sd, 0x0157, 207);

	else if (ES_GAIN(5.2, 5.3, gain_val))
		sensor_write(sd, 0x0157, 208);
	else if (ES_GAIN(5.3, 5.4, gain_val))
		sensor_write(sd, 0x0157, 209);
	else if (ES_GAIN(5.4, 5.5, gain_val))
		sensor_write(sd, 0x0157, 210);
	else if (ES_GAIN(5.5, 5.7, gain_val))
		sensor_write(sd, 0x0157, 211);
	else if (ES_GAIN(5.7, 5.8, gain_val))
		sensor_write(sd, 0x0157, 212);
	else if (ES_GAIN(5.8, 5.9, gain_val))
		sensor_write(sd, 0x0157, 213);
	else if (ES_GAIN(5.9, 6.2, gain_val))
		sensor_write(sd, 0x0157, 215);
	else if (ES_GAIN(6.2, 6.4, gain_val))
		sensor_write(sd, 0x0157, 216);
	else if (ES_GAIN(6.4, 6.5, gain_val))
		sensor_write(sd, 0x0157, 217);
	else if (ES_GAIN(6.5, 6.7, gain_val))
		sensor_write(sd, 0x0157, 218);
	else if (ES_GAIN(6.7, 6.9, gain_val))
		sensor_write(sd, 0x0157, 219);
	else if (ES_GAIN(6.9, 7.1, gain_val))
		sensor_write(sd, 0x0157, 220);
	else if (ES_GAIN(7.1, 7.3, gain_val))
		sensor_write(sd, 0x0157, 221);
	else if (ES_GAIN(7.3, 7.5, gain_val))
		sensor_write(sd, 0x0157, 222);
	else if (ES_GAIN(7.5, 7.7, gain_val))
		sensor_write(sd, 0x0157, 223);
	else if (ES_GAIN(7.7, 8.0, gain_val))
		sensor_write(sd, 0x0157, 224);
	else if (ES_GAIN(8.0, 8.3, gain_val))
		sensor_write(sd, 0x0157, 225);
	else if (ES_GAIN(8.3, 8.5, gain_val))
		sensor_write(sd, 0x0157, 226);
	else if (ES_GAIN(8.5, 8.8, gain_val))
		sensor_write(sd, 0x0157, 227);
	else if (ES_GAIN(8.8, 9.1, gain_val))
		sensor_write(sd, 0x0157, 228);

	else if (ES_GAIN(9.1, 9.4, gain_val))
		sensor_write(sd, 0x0157, 228);
	else if (ES_GAIN(9.4, 9.8, gain_val))
		sensor_write(sd, 0x0157, 230);
	else if (ES_GAIN(9.8, 10.2, gain_val))
		sensor_write(sd, 0x0157, 231);
	else if (ES_GAIN(10.0, 10.6, gain_val))
		sensor_write(sd, 0x0157, 232);

	info-&gt;exp = exp_val;
	info-&gt;gain = gain_val;
	return 0;
}

static int sensor_g_exp(struct v4l2_subdev *sd, __s32 *value)
{
	struct sensor_info *info = to_state(sd);

	*value = info-&gt;exp;
	sensor_dbg("sensor_get_exposure = %d\n", info-&gt;exp);
	return 0;
}

static int sensor_s_exp(struct v4l2_subdev *sd, unsigned int exp_val)
{
	unsigned char explow, exphigh;
	struct sensor_info *info = to_state(sd);

	if (exp_val &gt; 0xfffff)
		exp_val = 0xfffff;
	exp_val &gt;&gt;= 4;
	exphigh = (unsigned char)((0x00ff00 &amp; exp_val) &gt;&gt; 8);
	explow = (unsigned char)((0x0000ff &amp; exp_val));
	sensor_write(sd, 0x015b, explow);
	sensor_write(sd, 0x015a, exphigh);

	info-&gt;exp = exp_val;
	return 0;
}

static int sensor_g_gain(struct v4l2_subdev *sd, __s32 *value)
{
	struct sensor_info *info = to_state(sd);

	*value = info-&gt;gain;
	sensor_dbg("sensor_get_gain = %d\n", info-&gt;gain);
	return 0;
}

static int sensor_s_gain(struct v4l2_subdev *sd, int gain_val)
{
	struct sensor_info *info = to_state(sd);

	if (gain_val &lt; 1 * 16)
		gain_val = 16;
	if (gain_val &gt; 0x1ff)
		gain_val = 0x1ff;
	if (gain_val == 16)
		sensor_write(sd, 0x0157, 0x01);
	if (ES_GAIN(1.0, 1.1, gain_val))
		sensor_write(sd, 0x0157, 24);
	else if (ES_GAIN(1.1, 1.2, gain_val))
		sensor_write(sd, 0x0157, 42);
	else if (ES_GAIN(1.2, 1.3, gain_val))
		sensor_write(sd, 0x0157, 60);
	else if (ES_GAIN(1.3, 1.4, gain_val))
		sensor_write(sd, 0x0157, 73);
	else if (ES_GAIN(1.4, 1.5, gain_val))
		sensor_write(sd, 0x0157, 85);
	else if (ES_GAIN(1.5, 1.6, gain_val))
		sensor_write(sd, 0x0157, 96);
	else if (ES_GAIN(1.6, 1.7, gain_val))
		sensor_write(sd, 0x0157, 105);
	else if (ES_GAIN(1.7, 1.8, gain_val))
		sensor_write(sd, 0x0157, 114);
	else if (ES_GAIN(1.8, 1.9, gain_val))
		sensor_write(sd, 0x0157, 122);
	else if (ES_GAIN(1.9, 2.0, gain_val))
		sensor_write(sd, 0x0157, 0x80);
	else if (ES_GAIN(2.0, 2.1, gain_val))
		sensor_write(sd, 0x0157, 134);
	else if (ES_GAIN(2.1, 2.2, gain_val))
		sensor_write(sd, 0x0157, 140);
	else if (ES_GAIN(2.2, 2.3, gain_val))
		sensor_write(sd, 0x0157, 145);
	else if (ES_GAIN(2.3, 2.4, gain_val))
		sensor_write(sd, 0x0157, 150);
	else if (ES_GAIN(2.4, 2.5, gain_val))
		sensor_write(sd, 0x0157, 154);
	else if (ES_GAIN(2.5, 2.6, gain_val))
		sensor_write(sd, 0x0157, 158);
	else if (ES_GAIN(2.6, 2.7, gain_val))
		sensor_write(sd, 0x0157, 162);
	else if (ES_GAIN(2.7, 2.8, gain_val))
		sensor_write(sd, 0x0157, 165);

	else if (ES_GAIN(2.8, 2.9, gain_val))
		sensor_write(sd, 0x0157, 168);
	else if (ES_GAIN(2.9, 3.0, gain_val))
		sensor_write(sd, 0x0157, 0xab);
	else if (ES_GAIN(3.0, 3.1, gain_val))
		sensor_write(sd, 0x0157, 174);
	else if (ES_GAIN(3.1, 3.2, gain_val))
		sensor_write(sd, 0x0157, 176);
	else if (ES_GAIN(3.2, 3.3, gain_val))
		sensor_write(sd, 0x0157, 179);
	else if (ES_GAIN(3.3, 3.4, gain_val))
		sensor_write(sd, 0x0157, 181);
	else if (ES_GAIN(3.4, 3.5, gain_val))
		sensor_write(sd, 0x0157, 183);
	else if (ES_GAIN(3.5, 3.6, gain_val))
		sensor_write(sd, 0x0157, 185);
	else if (ES_GAIN(3.6, 3.7, gain_val))
		sensor_write(sd, 0x0157, 187);
	else if (ES_GAIN(3.7, 3.8, gain_val))
		sensor_write(sd, 0x0157, 189);
	else if (ES_GAIN(3.8, 3.9, gain_val))
		sensor_write(sd, 0x0157, 191);
	else if (ES_GAIN(3.9, 4.0, gain_val))
		sensor_write(sd, 0x0157, 192);
	else if (ES_GAIN(4.0, 4.1, gain_val))
		sensor_write(sd, 0x0157, 194);
	else if (ES_GAIN(4.1, 4.2, gain_val))
		sensor_write(sd, 0x0157, 195);
	else if (ES_GAIN(4.2, 4.3, gain_val))
		sensor_write(sd, 0x0157, 197);
	else if (ES_GAIN(4.3, 4.4, gain_val))
		sensor_write(sd, 0x0157, 198);
	else if (ES_GAIN(4.4, 4.5, gain_val))
		sensor_write(sd, 0x0157, 200);
	else if (ES_GAIN(4.5, 4.6, gain_val))
		sensor_write(sd, 0x0157, 201);
	else if (ES_GAIN(4.6, 4.7, gain_val))
		sensor_write(sd, 0x0157, 202);
	else if (ES_GAIN(4.7, 4.8, gain_val))
		sensor_write(sd, 0x0157, 203);
	else if (ES_GAIN(4.8, 4.9, gain_val))
		sensor_write(sd, 0x0157, 204);
	else if (ES_GAIN(4.9, 5.0, gain_val))
		sensor_write(sd, 0x0157, 205);
	else if (ES_GAIN(5.0, 5.1, gain_val))
		sensor_write(sd, 0x0157, 206);
	else if (ES_GAIN(5.1, 5.2, gain_val))
		sensor_write(sd, 0x0157, 207);

	else if (ES_GAIN(5.2, 5.3, gain_val))
		sensor_write(sd, 0x0157, 208);
	else if (ES_GAIN(5.3, 5.4, gain_val))
		sensor_write(sd, 0x0157, 209);
	else if (ES_GAIN(5.4, 5.5, gain_val))
		sensor_write(sd, 0x0157, 210);
	else if (ES_GAIN(5.5, 5.7, gain_val))
		sensor_write(sd, 0x0157, 211);
	else if (ES_GAIN(5.7, 5.8, gain_val))
		sensor_write(sd, 0x0157, 212);
	else if (ES_GAIN(5.8, 5.9, gain_val))
		sensor_write(sd, 0x0157, 213);
	else if (ES_GAIN(5.9, 6.2, gain_val))
		sensor_write(sd, 0x0157, 215);
	else if (ES_GAIN(6.2, 6.4, gain_val))
		sensor_write(sd, 0x0157, 216);
	else if (ES_GAIN(6.4, 6.5, gain_val))
		sensor_write(sd, 0x0157, 217);
	else if (ES_GAIN(6.5, 6.7, gain_val))
		sensor_write(sd, 0x0157, 218);
	else if (ES_GAIN(6.7, 6.9, gain_val))
		sensor_write(sd, 0x0157, 219);
	else if (ES_GAIN(6.9, 7.1, gain_val))
		sensor_write(sd, 0x0157, 220);
	else if (ES_GAIN(7.1, 7.3, gain_val))
		sensor_write(sd, 0x0157, 221);
	else if (ES_GAIN(7.3, 7.5, gain_val))
		sensor_write(sd, 0x0157, 222);
	else if (ES_GAIN(7.5, 7.7, gain_val))
		sensor_write(sd, 0x0157, 223);
	else if (ES_GAIN(7.7, 8.0, gain_val))
		sensor_write(sd, 0x0157, 224);
	else if (ES_GAIN(8.0, 8.3, gain_val))
		sensor_write(sd, 0x0157, 225);
	else if (ES_GAIN(8.3, 8.5, gain_val))
		sensor_write(sd, 0x0157, 226);
	else if (ES_GAIN(8.5, 8.8, gain_val))
		sensor_write(sd, 0x0157, 227);
	else if (ES_GAIN(8.8, 9.1, gain_val))
		sensor_write(sd, 0x0157, 228);

	else if (ES_GAIN(9.1, 9.4, gain_val))
		sensor_write(sd, 0x0157, 228);
	else if (ES_GAIN(9.4, 9.8, gain_val))
		sensor_write(sd, 0x0157, 230);
	else if (ES_GAIN(9.8, 10.2, gain_val))
		sensor_write(sd, 0x0157, 231);
	else if (ES_GAIN(10.0, 10.6, gain_val))
		sensor_write(sd, 0x0157, 232);
	info-&gt;gain = gain_val;

	return 0;
}
#if 0
static int sensor_s_sw_stby(struct v4l2_subdev *sd, int on_off)
{
	int ret;
	data_type rdval;

	ret = sensor_read(sd, 0x0100, &amp;rdval);
	if (ret != 0)
		return ret;

	if (on_off == CSI_GPIO_LOW)
		ret = sensor_write(sd, 0x0100, rdval &amp; 0xfe);
	else
		ret = sensor_write(sd, 0x0100, rdval | 0x01);
	return ret;
}
#endif
/*
 * Stuff that knows about the sensor.
 */

static int sensor_power(struct v4l2_subdev *sd, int on)
{
sensor_print("entering sensor_power\n");
	sensor_dbg("zzz5648 sensor_power\n");

	switch (on) {
	case STBY_ON:
		/*sensor_print("entering sensor_power STBY_ON\n");
		sensor_print("STBY_ON!\n");
		cci_lock(sd);
		sensor_s_sw_stby(sd, STBY_ON);
		usleep_range(1000, 1200);
		cci_unlock(sd);*/
		break;
	case STBY_OFF:
		sensor_print("entering sensor_power STBY_OFF\n");
		sensor_print("STBY_OFF!\n");
		/*cci_lock(sd);
		usleep_range(1000, 1200);
		sensor_s_sw_stby(sd, STBY_OFF);
		cci_unlock(sd);*/
		break;
	case PWR_ON:
		sensor_print("entering sensor_power PWR_ON, pins: %d %d\n",PWDN ,POWER_EN);
		gpio_direction_output(GPIOA(8), 0);	//led enable
		gpio_direction_output(GPIOA(9), 0);	//power enable
		sensor_print("PWR_ON!100\n");
		cci_lock(sd);
		vin_gpio_set_status(sd, PWDN, 1);
		//vin_gpio_write(sd, RESET, CSI_GPIO_HIGH);	//not needed for the rpi ov5647 modules
		vin_gpio_set_status(sd, POWER_EN, 1);
		vin_gpio_write(sd, PWDN, CSI_GPIO_HIGH);	//special case, since PWDN is the led we power it ON
		//vin_gpio_write(sd, RESET, CSI_GPIO_LOW);	//ignore reset
		vin_gpio_write(sd, POWER_EN, CSI_GPIO_HIGH);
		usleep_range(7000, 8000);
		vin_set_pmu_channel(sd, IOVDD, ON);
		usleep_range(7000, 8000);
		vin_set_pmu_channel(sd, AVDD, ON);
		vin_set_pmu_channel(sd, AFVDD, ON);
		usleep_range(7000, 8000);
		vin_set_pmu_channel(sd, DVDD, ON);
		usleep_range(7000, 8000);
		vin_set_mclk_freq(sd, MCLK);
		vin_set_mclk(sd, ON);
		usleep_range(10000, 12000);
		//vin_gpio_write(sd, RESET, CSI_GPIO_HIGH);	//these calls are useless as well
		//vin_gpio_write(sd, PWDN, CSI_GPIO_HIGH);
		vin_set_pmu_channel(sd, CAMERAVDD, ON);/*AFVCC ON*/
		usleep_range(10000, 12000);
		cci_unlock(sd);
		break;
	case PWR_OFF:
		/*sensor_print("PWR_OFF!\n");
		cci_lock(sd);
		vin_gpio_write(sd, PWDN, CSI_GPIO_LOW);	//LED off
		//vin_gpio_write(sd, RESET, CSI_GPIO_HIGH);
		vin_set_mclk(sd, OFF);
		usleep_range(7000, 8000);
		vin_set_pmu_channel(sd, DVDD, OFF);
		//vin_gpio_write(sd, PWDN, CSI_GPIO_LOW);
		//vin_gpio_write(sd, RESET, CSI_GPIO_LOW);
		vin_gpio_write(sd, POWER_EN, CSI_GPIO_LOW);	//turn off power to the camera
		vin_set_pmu_channel(sd, AVDD, OFF);
		vin_set_pmu_channel(sd, IOVDD, OFF);
		vin_set_pmu_channel(sd, AFVDD, OFF);
		vin_set_pmu_channel(sd, CAMERAVDD, OFF);/*AFVCC ON*/
		//cci_unlock(sd);
		break;
	default:
		return -EINVAL;
	}

	return 0;
}

static int sensor_reset(struct v4l2_subdev *sd, u32 val)
{
	switch (val) {
	case 0:
		vin_gpio_write(sd, RESET, CSI_GPIO_HIGH);
		usleep_range(10000, 12000);
		break;
	case 1:
		vin_gpio_write(sd, RESET, CSI_GPIO_LOW);
		usleep_range(10000, 12000);
		break;
	default:
		return -EINVAL;
	}

	return 0;
}

static int sensor_detect(struct v4l2_subdev *sd)
{
	data_type rdval, rdval2;
	unsigned int SENSOR_ID = 0;
	printk(KERN_WARNING "entering sensor_detect\n");
	sensor_read(sd, 0x0000, &amp;rdval);
	sensor_read(sd, 0x0001, &amp;rdval2);

	SENSOR_ID = (rdval &lt;&lt; 8) | rdval2;
	sensor_print("V4L2_IDENT_SENSOR = 0x%x\n", SENSOR_ID);
	if (SENSOR_ID != V4L2_IDENT_SENSOR) {
		sensor_print("imx219 %s error, chip found is not an target chip", __func__);
		printk(KERN_WARNING "exiting sensor_detect, not found\n");
		//return -ENODEV;
	}
	printk(KERN_WARNING "exiting sensor_detect, found\n");
	return 0;
}

static int sensor_init(struct v4l2_subdev *sd, u32 val)
{
	int ret;
	sensor_power(sd, PWR_ON);	//added
	struct sensor_info *info = to_state(sd);

	sensor_dbg("sensor_init\n");
	sensor_power(sd, PWR_ON);	//added
	/*Make sure it is a target sensor */
	ret = sensor_detect(sd);
	if (ret) {
		sensor_err("chip found is not an target chip.\n");
		return ret;
	}

	info-&gt;focus_status = 0;
	info-&gt;low_speed = 0;
	info-&gt;width = HXGA_WIDTH;
	info-&gt;height = HXGA_HEIGHT;
	info-&gt;hflip = 0;
	info-&gt;vflip = 0;
	info-&gt;gain = 0;

	info-&gt;tpf.numerator = 1;
	info-&gt;tpf.denominator = 10;	/* 30fps */

	info-&gt;preview_first_flag = 1;

	return 0;
}

static long sensor_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg)
{
	int ret = 0;
	struct sensor_info *info = to_state(sd);

	switch (cmd) {
	case GET_CURRENT_WIN_CFG:
		if (info-&gt;current_wins != NULL) {
			memcpy(arg,
			       info-&gt;current_wins,
			       sizeof(struct sensor_win_size));
			ret = 0;
		} else {
			sensor_err("empty wins!\n");
			ret = -1;
		}
		break;
	case SET_FPS:
		break;
	case VIDIOC_VIN_SENSOR_EXP_GAIN:
		sensor_s_exp_gain(sd, (struct sensor_exp_gain *)arg);
		break;
	case VIDIOC_VIN_SENSOR_CFG_REQ:
		sensor_cfg_req(sd, (struct sensor_config *)arg);
		break;
	default:
		return -EINVAL;
	}
	return ret;
}

/*
 * Store information about the video data format.
 */
static struct sensor_format_struct sensor_formats[] = {
	{
		.desc = "Raw RGB Bayer",
		.mbus_code = MEDIA_BUS_FMT_SBGGR8_1X8,//MEDIA_BUS_FMT_SRGGB10_1X10,
		.regs = sensor_fmt_raw,
		.regs_size = ARRAY_SIZE(sensor_fmt_raw),
		.bpp = 1
	}
};
#define N_FMTS ARRAY_SIZE(sensor_formats)

/*
 * Then there is the issue of window sizes.  Try to capture the info here.
 */

static struct sensor_win_size sensor_win_sizes[] = {
	/* 3280*2464 */
	/*{
	 .width = 3264,
	 .height = 2448,
	 .hoffset = (3280 - 3264) / 2,
	 .voffset = (2464 - 2448) / 2,
	 .hts = 3448,
	 .vts = 4037,
	 .pclk = (278 * 1000 * 1000),
	 .mipi_bps = 720 * 1000 * 1000,
	 .fps_fixed = 1,
	 .bin_factor = 1,
	 .intg_min = 1 &lt;&lt; 4,
	 .intg_max = (4037 - 4) &lt;&lt; 4,
	 .gain_min = 1 &lt;&lt; 4,
	 .gain_max = 10 &lt;&lt; 4,
	 .regs = sensor_hxga_regs,
	 .regs_size = ARRAY_SIZE(sensor_hxga_regs),
	 .set_size = NULL,
	 },*/

	/* 1080P */
	/*{
	 .width = HD1080_WIDTH,
	 .height = HD1080_HEIGHT,
	 .hoffset = 0,
	 .voffset = 0,
	 .hts = 3560,
	 .vts = 2607,
	 .pclk = (278 * 1000 * 1000),
	 .mipi_bps = 720 * 1000 * 1000,
	 .fps_fixed = 1,
	 .bin_factor = 2,
	 .intg_min = 1 &lt;&lt; 4,
	 .intg_max = (2607 - 4) &lt;&lt; 4,
	 .gain_min = 1 &lt;&lt; 4,
	 .gain_max = 10 &lt;&lt; 4,
	 .regs = sensor_1080p_regs,
	 .regs_size = ARRAY_SIZE(sensor_1080p_regs),
	 .set_size = NULL,
	 },*/
	/* SXGA */
	/*{
	 .width = SXGA_WIDTH,
	 .height = SXGA_HEIGHT,
	 .hoffset = 0,
	 .voffset = 0,
	 .hts = 3560,
	 .vts = 2607,
	 .pclk = (278 * 1000 * 1000),
	 .mipi_bps = 720 * 1000 * 1000,
	 .fps_fixed = 1,
	 .bin_factor = 2,
	 .intg_min = 1 &lt;&lt; 4,
	 .intg_max = 2607 &lt;&lt; 4,
	 .gain_min = 1 &lt;&lt; 4,
	 .gain_max = 10 &lt;&lt; 4,
	 .regs = sensor_sxga_regs,
	 .regs_size = ARRAY_SIZE(sensor_sxga_regs),
	 .set_size = NULL,
	 },*/
	/* 720p */
	{
	 .width = HD720_WIDTH,
	 .height = HD720_HEIGHT,
	 .hoffset = 0,
	 .voffset = 0,
	 .hts = 2560,
	 .vts = 1303,
	 .pclk = (200 * 1000 * 1000),
	 .mipi_bps = 720 * 1000 * 1000,
	 .fps_fixed = 1,
	 .bin_factor = 2,
	 .intg_min = 1 &lt;&lt; 4,
	 .intg_max = (1303 - 4) &lt;&lt; 4,
	 .gain_min = 1 &lt;&lt; 4,
	 .gain_max = 10 &lt;&lt; 4,
	 .regs = sensor_720p_regs,
	 .regs_size = ARRAY_SIZE(sensor_720p_regs),
	 .set_size = NULL,
	 },

};

#define N_WIN_SIZES (ARRAY_SIZE(sensor_win_sizes))

static int sensor_reg_init(struct sensor_info *info)
{

	int ret = 0;
	struct v4l2_subdev *sd = &amp;info-&gt;sd;
	struct sensor_format_struct *sensor_fmt = info-&gt;fmt;
	struct sensor_win_size *wsize = info-&gt;current_wins;

	ret = sensor_write_array(sd, sensor_default_regs,
			       ARRAY_SIZE(sensor_default_regs));
	if (ret &lt; 0) {
		sensor_err("write sensor_default_regs error\n");
		return ret;
	}

	ret = sensor_read_array(sd, sensor_default_regs, ARRAY_SIZE(sensor_default_regs));

	if (ret &lt; 0) {
		sensor_err("read-back ov5647_640x480_10bpp error\n");
		return ret;
	}

	sensor_write_array(sd, sensor_fmt-&gt;regs, sensor_fmt-&gt;regs_size);

	if (wsize-&gt;regs)
		sensor_write_array(sd, wsize-&gt;regs, wsize-&gt;regs_size);

	if (wsize-&gt;set_size)
		wsize-&gt;set_size(sd);

	info-&gt;width = wsize-&gt;width;
	info-&gt;height = wsize-&gt;height;
	imx219_sensor_vts = wsize-&gt;vts;

	sensor_print("s_fmt set width = %d, height = %d\n", wsize-&gt;width,
		      wsize-&gt;height);

	return 0;
}

static int sensor_s_stream(struct v4l2_subdev *sd, int enable)
{
	struct sensor_info *info = to_state(sd);

	sensor_print("%s on = %d, %d*%d %x\n", __func__, enable,
		  info-&gt;current_wins-&gt;width,
		  info-&gt;current_wins-&gt;height, info-&gt;fmt-&gt;mbus_code);

	if (!enable)
		return 0;
	return sensor_reg_init(info);
}

static int sensor_g_mbus_config(struct v4l2_subdev *sd,
				struct v4l2_mbus_config *cfg)
{
	cfg-&gt;type = V4L2_MBUS_CSI2;
	cfg-&gt;flags = 0 | V4L2_MBUS_CSI2_2_LANE | V4L2_MBUS_CSI2_CHANNEL_0;

	return 0;
}

static int sensor_g_ctrl(struct v4l2_ctrl *ctrl)
{
	struct sensor_info *info =
			container_of(ctrl-&gt;handler, struct sensor_info, handler);
	struct v4l2_subdev *sd = &amp;info-&gt;sd;

	switch (ctrl-&gt;id) {
	case V4L2_CID_GAIN:
		return sensor_g_gain(sd, &amp;ctrl-&gt;val);
	case V4L2_CID_EXPOSURE:
		return sensor_g_exp(sd, &amp;ctrl-&gt;val);
	}
	return -EINVAL;
}

static int sensor_s_ctrl(struct v4l2_ctrl *ctrl)
{
	struct sensor_info *info =
			container_of(ctrl-&gt;handler, struct sensor_info, handler);
	struct v4l2_subdev *sd = &amp;info-&gt;sd;

	switch (ctrl-&gt;id) {
	case V4L2_CID_GAIN:
		return sensor_s_gain(sd, ctrl-&gt;val);
	case V4L2_CID_EXPOSURE:
		return sensor_s_exp(sd, ctrl-&gt;val);
	}
	return -EINVAL;
}

/* ----------------------------------------------------------------------- */

static const struct v4l2_ctrl_ops sensor_ctrl_ops = {
	.g_volatile_ctrl = sensor_g_ctrl,
	.s_ctrl = sensor_s_ctrl,
};

static const struct v4l2_subdev_core_ops sensor_core_ops = {
	.reset = sensor_reset,
	.init = sensor_init,
	.s_power = sensor_power,
	.ioctl = sensor_ioctl,
#ifdef CONFIG_COMPAT
	.compat_ioctl32 = sensor_compat_ioctl32,
#endif
};

static const struct v4l2_subdev_video_ops sensor_video_ops = {
	.s_parm = sensor_s_parm,
	.g_parm = sensor_g_parm,
	.s_stream = sensor_s_stream,
	.g_mbus_config = sensor_g_mbus_config,
};

static const struct v4l2_subdev_pad_ops sensor_pad_ops = {
	.enum_mbus_code = sensor_enum_mbus_code,
	.enum_frame_size = sensor_enum_frame_size,
	.get_fmt = sensor_get_fmt,
	.set_fmt = sensor_set_fmt,
};

static const struct v4l2_subdev_ops sensor_ops = {
	.core = &amp;sensor_core_ops,
	.video = &amp;sensor_video_ops,
	.pad = &amp;sensor_pad_ops,
};

/* ----------------------------------------------------------------------- */
static struct cci_driver cci_drv = {
	.name = SENSOR_NAME,
	.addr_width = CCI_BITS_16,
	.data_width = CCI_BITS_8,
};

static const struct v4l2_ctrl_config sensor_custom_ctrls[] = {
	{
		.ops = &amp;sensor_ctrl_ops,
		.id = V4L2_CID_FRAME_RATE,
		.name = "frame rate",
		.type = V4L2_CTRL_TYPE_INTEGER,
		.min = 15,
		.max = 120,
		.step = 1,
		.def = 120,
	},
};

static int sensor_init_controls(struct v4l2_subdev *sd, const struct v4l2_ctrl_ops *ops)
{
	struct sensor_info *info = to_state(sd);
	struct v4l2_ctrl_handler *handler = &amp;info-&gt;handler;
	struct v4l2_ctrl *ctrl;
	int i;
	int ret = 0;

	v4l2_ctrl_handler_init(handler, 2 + ARRAY_SIZE(sensor_custom_ctrls));

	ctrl = v4l2_ctrl_new_std(handler, ops, V4L2_CID_EXPOSURE, 0,
			      65536 * 16, 1, 0);
	if (ctrl != NULL)
		ctrl-&gt;flags |= V4L2_CTRL_FLAG_VOLATILE;
	v4l2_ctrl_new_std(handler, ops, V4L2_CID_GAIN, 1 * 1600,
			      256 * 1600, 1, 1 * 1600);
	for (i = 0; i &lt; ARRAY_SIZE(sensor_custom_ctrls); i++)
		v4l2_ctrl_new_custom(handler, &amp;sensor_custom_ctrls[i], NULL);

	if (handler-&gt;error) {
		ret = handler-&gt;error;
		v4l2_ctrl_handler_free(handler);
	}

	sd-&gt;ctrl_handler = handler;

	return ret;
}

static int sensor_probe(struct i2c_client *client,
			const struct i2c_device_id *id)
{
	struct v4l2_subdev *sd;
	struct sensor_info *info;

	info = kzalloc(sizeof(struct sensor_info), GFP_KERNEL);
	if (info == NULL)
		return -ENOMEM;
	sd = &amp;info-&gt;sd;
	cci_dev_probe_helper(sd, client, &amp;sensor_ops, &amp;cci_drv);
	sensor_init_controls(sd, &amp;sensor_ctrl_ops);
	mutex_init(&amp;info-&gt;lock);

	info-&gt;fmt = &amp;sensor_formats[0];
	info-&gt;fmt_pt = &amp;sensor_formats[0];
	info-&gt;win_pt = &amp;sensor_win_sizes[0];
	info-&gt;fmt_num = N_FMTS;
	info-&gt;win_size_num = N_WIN_SIZES;
	info-&gt;sensor_field = V4L2_FIELD_NONE;
	info-&gt;af_first_flag = 1;

	return 0;
}
static int sensor_remove(struct i2c_client *client)
{
	struct v4l2_subdev *sd;

	sd = cci_dev_remove_helper(client, &amp;cci_drv);
	kfree(to_state(sd));
	return 0;
}

static const struct i2c_device_id sensor_id[] = {
	{SENSOR_NAME, 0},
	{}
};

MODULE_DEVICE_TABLE(i2c, sensor_id);

static struct i2c_driver sensor_driver = {
	.driver = {
		   .owner = THIS_MODULE,
		   .name = SENSOR_NAME,
		   },
	.probe = sensor_probe,
	.remove = sensor_remove,
	.id_table = sensor_id,
};
static __init int init_sensor(void)
{
	return cci_dev_init_helper(&amp;sensor_driver);
}

static __exit void exit_sensor(void)
{
	cci_dev_exit_helper(&amp;sensor_driver);
}

module_init(init_sensor);
module_exit(exit_sensor);
</code></pre>
<p dir="auto">修改后的驱动程序的工作原理与我尝试过的其他所有操作相同，捕获帧超时。</p>
<pre><code class="language-bash">root@TinaLinux:/# camerademo BGGR8 1280 720 30 bmp /tmp 5
[CAMERA]************************[  193.743051] [imx219]entering sensor_power
********************************[  193.749768] [imx219]entering sensor_power PWR_ON, pins: 1 0
**
[CAMERA]*                   [  193.758780] [imx219]PWR_ON!100
                                     *
[CAMERA]*              this is camera test.                      *
[CAMERA]*           [  193.773171] [VIN_ERR]imx219 cannot find the match sensor_helper
                                             *
[CAMERA]****************************************[  193.790703] [VIN_ERR]imx219 cannot find the match sensor_helper
******************
[CAMERA]****[  193.797641] [VIN_ERR]imx219 cannot find the match sensor_helper
******************************************************
[CAMERA] open /dev/video0!
[CAMERA]****[  193.814747] [VIN_ERR]imx219 cannot find the match sensor_helper
******************************************************
[CAMERA]**********************************************************
[CAMERA] The path to data saving is /tmp.
[CAMERA] The number of captured photos is 5.
[CAMERA] save bmp format
[  193.842052] [VIN_ERR]imx219 cannot find the match sensor_helper
[  193.861353] [imx219]entering sensor_power
[  193.865910] [imx219]entering sensor_power PWR_ON, pins: 1 0
[  193.872154] [imx219]PWR_ON!100
[  193.883647] [VIN_ERR]imx219 cannot find the match sensor_helper
[  193.898305] [VIN_ERR]imx219 cannot find the match sensor_helper
[  193.904951] [VIN_ERR]imx219 cannot find the match sensor_helper
[  193.919592] [VIN_ERR]imx219 cannot find the match sensor_helper
[  193.946278] [VIN_ERR]imx219 cannot find the match sensor_helper
[  193.964736] entering sensor_detect
[  193.969158] [imx219]V4L2_IDENT_SENSOR = 0x219
[  193.974040] exiting sensor_detect, found
[  193.979674] [VIN_ERR]vin is not support this pixelformat
[  193.985673] [VIN_ERR]sensor pixelformat is 3001
[  193.990940] [VIN_ERR]vin is not support this pixelformat
[  193.996918] [VIN_ERR]sensor pixelformat is 3001
[  194.002195] [VIN_ERR]vin is not support this pixelformat
[  194.008161] [VIN_ERR]sensor pixelformat is 3001
[  194.013424] [VIN_ERR]vin is not support this pixelformat
[  194.019478] [VIN_ERR]sensor pixelformat is 3001
[  194.024792] [VIN_ERR]vin is not support this pixelformat
[  194.030743] [VIN_ERR]sensor pixelformat is 3001
[  194.036038] [VIN_ERR]vin is not support this pixelformat
[  194.041987] [VIN_ERR]sensor pixelformat is 3001
[  194.047283] [VIN_ERR]vin is not support this pixelformat
[  194.053234] [VIN_ERR]sensor pixelformat is 3001
[  194.058514] [VIN_ERR]vin is not support this pixelformat
[  194.064461] [VIN_ERR]sensor pixelformat is 3001
[  194.069812] [VIN_ERR]vin is not support this pixelformat
[  194.075786] [VIN_ERR]sensor pixelformat is 3001
[  194.081055] [VIN_ERR]vin is not support this pixelformat
[  194.087025] [VIN_ERR]sensor pixelformat is 3001
[  194.092299] [VIN_ERR]vin is not support this pixelformat
[  194.098266] [VIN_ERR]sensor pixelformat is 3001
[  194.103530] [VIN_ERR]vin is not support this pixelformat
[  194.109497] [VIN_ERR]sensor pixelformat is 3001
[CAMERA]********************************************************[  194.118170] [imx219]sensor_s_stream on = 1, 1280*720 3001
**
[CAMERA] Using format parameters BGGR8.
[CAMERA] camera pix[  194.131226] [VIN_DEV_I2C_ERR]read from imx219 addr is 0x30eb, data is 0x0, but should be 0x5
elformat: BGGR8
[CAMERA] Resolu[  194.141789] [VIN_DEV_I2C_ERR]read from imx219 addr is 0x30eb, data is 0x0, but should be 0xc
tion size : 1280 * 720
[CAMERA][  194.154018] [VIN_DEV_I2C]read from imx219 addr is 0x300a, data is 0xff
 The photo save path is /tmp.
&lsqb;&lsqb;  194.164104] [VIN_DEV_I2C]read from imx219 addr is 0x300b, data is 0xff
CAMERA] The number of photos tak[  194.174288] [VIN_DEV_I2C_ERR]read from imx219 addr is 0x30eb, data is 0x0, but should be 0x5
en is 5.
[  194.186439] [VIN_DEV_I2C_ERR]read from imx219 addr is 0x30eb, data is 0x0, but should be 0x9

pid: 883, g_alloc_context = 0xb[  194.198671] [VIN_DEV_I2C]read from imx219 addr is 0x114, data is 0x1
6db3360
[CAMERA] Camera captur[  194.208567] [VIN_DEV_I2C]read from imx219 addr is 0x128, data is 0x0
e framerate is 1/1
[CAMERA] VID[  194.218526] [VIN_DEV_I2C]read from imx219 addr is 0x12a, data is 0x18
IOC_S_FMT succeed
[CAMERA] fmt.[  194.228466] [VIN_DEV_I2C]read from imx219 addr is 0x12b, data is 0x0
type = 9
[CAMERA] fmt.fmt.pix_m[  194.238365] [VIN_DEV_I2C]read from imx219 addr is 0x160, data is 0x2
p.width = 1280
[CAMERA] fmt.fmt[  194.248258] [VIN_DEV_I2C]read from imx219 addr is 0x161, data is 0x0
.pix_mp.height = 720
[CAMERA] f[  194.258149] [VIN_DEV_I2C]read from imx219 addr is 0x162, data is 0xd
mt.fmt.pix_mp.pixelformat = BGGR[  194.268092] [VIN_DEV_I2C]read from imx219 addr is 0x163, data is 0xe8
8
[CAMERA] fmt.fmt.pix_mp.field[  194.278044] [VIN_DEV_I2C]read from imx219 addr is 0x164, data is 0x3
 = 1
[  194.287929] [VIN_DEV_I2C]read from imx219 addr is 0x165, data is 0xe8
[  194.295659] [VIN_DEV_I2C]read from imx219 addr is 0x166, data is 0x8
[  194.303039] [VIN_DEV_I2C]read from imx219 addr is 0x167, data is 0xe7
[  194.310529] [VIN_DEV_I2C]read from imx219 addr is 0x168, data is 0x3
[  194.317967] [VIN_DEV_I2C]read from imx219 addr is 0x169, data is 0x68
[  194.325461] [VIN_DEV_I2C]read from imx219 addr is 0x16a, data is 0x6
[  194.332841] [VIN_DEV_I2C]read from imx219 addr is 0x16b, data is 0x37
[  194.340333] [VIN_DEV_I2C]read from imx219 addr is 0x16c, data is 0x5
[  194.347726] [VIN_DEV_I2C]read from imx219 addr is 0x16d, data is 0x0
[  194.355113] [VIN_DEV_I2C]read from imx219 addr is 0x16e, data is 0x2
[  194.362489] [VIN_DEV_I2C]read from imx219 addr is 0x16f, data is 0xd0
[  194.370021] [VIN_DEV_I2C]read from imx219 addr is 0x170, data is 0x1
[  194.377423] [VIN_DEV_I2C]read from imx219 addr is 0x171, data is 0x1
[  194.384804] [VIN_DEV_I2C]read from imx219 addr is 0x174, data is 0x0
[  194.392184] [VIN_DEV_I2C]read from imx219 addr is 0x175, data is 0x0
[  194.399578] [VIN_DEV_I2C]read from imx219 addr is 0x18c, data is 0xa
[  194.406965] [VIN_DEV_I2C]read from imx219 addr is 0x18d, data is 0xa
[  194.414343] [VIN_DEV_I2C]read from imx219 addr is 0x301, data is 0x5
[  194.421774] [VIN_DEV_I2C]read from imx219 addr is 0x303, data is 0x1
[  194.429173] [VIN_DEV_I2C]read from imx219 addr is 0x304, data is 0x3
[  194.436568] [VIN_DEV_I2C]read from imx219 addr is 0x305, data is 0x3
[  194.443947] [VIN_DEV_I2C]read from imx219 addr is 0x306, data is 0x0
[  194.451344] [VIN_DEV_I2C]read from imx219 addr is 0x307, data is 0x57
[  194.458830] [VIN_DEV_I2C]read from imx219 addr is 0x309, data is 0x5
[  194.466260] [VIN_DEV_I2C]read from imx219 addr is 0x30b, data is 0x1
[  194.473640] [VIN_DEV_I2C]read from imx219 addr is 0x30c, data is 0x0
[  194.481032] [VIN_DEV_I2C]read from imx219 addr is 0x30d, data is 0x5a
[  194.488574] [VIN_DEV_I2C]read from imx219 addr is 0x100, data is 0x1
[  194.500109] [imx219]s_fmt set width = 1280, height = 720
[CAMERA] stream on succeed
[CAMERA] camera0 capture num is [0]
[CAMERA_ERR] camera0[  196.509907] [imx219]sensor_s_stream on = 0, 1280*720 3001
 select timeout,end capture thread!
[CAMERA] Capture thread finish
[CAMERA] close /dev/video0
[CAMERA_ERR] capture_photo return error
root@TinaLinux:/#
</code></pre>
]]></description><link>https://bbs.aw-ol.com/post/20378</link><guid isPermaLink="true">https://bbs.aw-ol.com/post/20378</guid><dc:creator><![CDATA[kanken6174]]></dc:creator><pubDate>Wed, 13 Dec 2023 22:23:10 GMT</pubDate></item><item><title><![CDATA[Reply to V851S tina linux ov5647 驱动程序没有 dmesg on Wed, 13 Dec 2023 19:43:52 GMT]]></title><description><![CDATA[<p dir="auto"><a class="plugin-mentions-user plugin-mentions-a" href="https://bbs.aw-ol.com/uid/1915">@awwwwa</a> 我已经研究过 <a class="plugin-mentions-user plugin-mentions-a" href="https://bbs.aw-ol.com/uid/317">@YuzukiTsuru</a>  制作的这个特定驱动程序，它存在一些问题：</p>
<ul>
<li>未正确配置与 OV5647 的接口，V4L2_IDENT_SENSOR 不正确，因为它是 0x5648 而不是 0x5647，如果按原样使用，则永远不会检测到相机，因为在sensor_detect() 中进行了此检查：</li>
</ul>
<pre><code class="language-cpp">#define V4L2_IDENT_SENSOR 0x5648
</code></pre>
<pre><code class="language-cpp">static int sensor_detect(struct v4l2_subdev *sd)
{
	data_type rdval;
	unsigned int SENSOR_ID = 0;
	sensor_read(sd, 0x300A, &amp;rdval);
	SENSOR_ID |= rdval;
	SENSOR_ID |= (rdval &lt;&lt; 8);
	sensor_read(sd, 0x300B, &amp;rdval);
	SENSOR_ID |= (rdval);
	sensor_print("V4L2_IDENT_SENSOR = 0x%x\n", SENSOR_ID);
	if (SENSOR_ID != V4L2_IDENT_SENSOR) {
		sensor_print("ov5648 %s error, chip found is not an target chip", __func__);
		//return -ENODEV;
	}
	return 0;
}
</code></pre>
<ul>
<li>驱动程序将其传感器报告为“ov5648_mipi”，如果您将相同的内容放入 DTS 中，这并不是什么大问题，但它仍然具有误导性。</li>
</ul>
<pre><code class="language-cpp">#define SENSOR_NAME "ov5648_mipi"
</code></pre>
<p dir="auto">一旦这些基本问题得到解决，驱动程序就会加载并创建 /dev/video 节点，就像我的驱动程序一样。 但我们最终在camerademo应用程序上遇到了完全相同的错误：<br />
<img src="/assets/uploads/files/1702496416161-502f5673-a8d3-4eba-a7b0-87186ce6d5f1-screenshot-from-2023-12-13-20-28-16.png" alt="502f5673-a8d3-4eba-a7b0-87186ce6d5f1-Screenshot from 2023-12-13 20-28-16.png" class=" img-responsive img-markdown" width="837" height="1153" /><br />
唯一的区别是由于缺少配置文件而导致 ISP 上出现一些错误行，但由于我们的错误与超时相关，因此它不应受到任何“像素格式”或 ISP 错误的影响。 因此，即使有了这个驱动程序，我们还是回到了原点。</p>
<p dir="auto">我想知道 MLCK 位于相机内部并且未连接到 V851S 是否会导致问题...</p>
]]></description><link>https://bbs.aw-ol.com/post/20377</link><guid isPermaLink="true">https://bbs.aw-ol.com/post/20377</guid><dc:creator><![CDATA[kanken6174]]></dc:creator><pubDate>Wed, 13 Dec 2023 19:43:52 GMT</pubDate></item><item><title><![CDATA[Reply to V851S tina linux ov5647 驱动程序没有 dmesg on Wed, 13 Dec 2023 10:11:55 GMT]]></title><description><![CDATA[<p dir="auto">使用 V3s SDK 提供VFE框架的驱动移植到VIN框架下抓图成功。但是图像非常暗，并且撕裂，抓raw数据查看也是一样，考虑可能mclk不同步导致。</p>
<pre><code>sensor0:sensor@0 {
	device_type = "sensor0";
	sensor0_mname = "ov5648_mipi";
	sensor0_twi_cci_id = &lt;0&gt;;
	sensor0_twi_addr = &lt;0x6c&gt;;
	sensor0_mclk_id = &lt;0&gt;;
	sensor0_pos = "rear";
	sensor0_isp_used = &lt;1&gt;;
	sensor0_fmt = &lt;1&gt;;
	sensor0_stby_mode = &lt;0&gt;;
	sensor0_vflip = &lt;0&gt;;
	sensor0_hflip = &lt;0&gt;;
	sensor0_iovdd-supply = &lt;&gt;;
	sensor0_iovdd_vol = &lt;1800000&gt;;
	sensor0_avdd-supply = &lt;&gt;;
	sensor0_avdd_vol = &lt;2800000&gt;;
	sensor0_dvdd-supply = &lt;&gt;;
	sensor0_dvdd_vol = &lt;1200000&gt;;
	sensor0_power_en = &lt;&gt;;
	sensor0_reset = &lt;&amp;pio PA 18 1 0 1 0&gt;;
	sensor0_pwdn = &lt;&amp;pio PA 19 1 0 1 0&gt;;
	sensor0_sm_hs = &lt;&gt;;
	sensor0_sm_vs = &lt;&gt;;
	flash_handle = &lt;&gt;;
	act_handle = &lt;&gt;;
	status	= "okay";
};
</code></pre>
<pre><code>/*
 * A V4L2 driver for ov5647 Raw cameras.
 *
 * Copyright (c) 2022 by YuzukiTsuru  &lt;gloomyghost@gloomyghost.com&gt;
 * Copyright (c) 2018 by Allwinnertech Co., Ltd.  http://www.allwinnertech.com
 *
 * Authors:  Zheng ZeQun &lt;zequnzheng@allwinnertech.com&gt;
 *    	   Liang WeiJie &lt;liangweijie@allwinnertech.com&gt;
 *          YuzukiTsuru &lt;gloomyghost@gloomyghost.com&gt;
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation.
 */

#include &lt;linux/init.h&gt;
#include &lt;linux/module.h&gt;
#include &lt;linux/slab.h&gt;
#include &lt;linux/i2c.h&gt;
#include &lt;linux/delay.h&gt;
#include &lt;linux/videodev2.h&gt;
#include &lt;linux/clk.h&gt;
#include &lt;media/v4l2-device.h&gt;
#include &lt;media/v4l2-mediabus.h&gt;
#include &lt;linux/io.h&gt;

#include "camera.h"
#include "sensor_helper.h"

MODULE_AUTHOR("YuzukiTsuru");
MODULE_DESCRIPTION("A low-level driver for ov5647 sensors");
MODULE_LICENSE("GPL");

#define MCLK              (24*1000*1000)
#define V4L2_IDENT_SENSOR 0x5648

/*
 * Our nominal (default) frame rate.
 */

#define SENSOR_FRAME_RATE 30

/*
 * The GC0310 i2c address
 */
#define I2C_ADDR 0x6c

#define SENSOR_NAME "ov5648_mipi"


/*
 * The default register settings
 */

static struct regval_list sensor_default_regs[] = {
	//Slave_ID=0x6c;
	{0x0100, 0x00},// ; software standby
	{0x0103, 0x01},// ; software reset
	{REG_DLY, 0x25},
	{0x370c, 0x03},// ; analog control
	{0x5000, 0x06},// ; lens off, bpc on, wpc on
	{0x5003, 0x08},// ; buf_en
	{0x5a00, 0x08},//
	{0x3000, 0xff},// ; D[9:8] output
	{0x3001, 0xff},// ; D[7:0] output
	{0x3002, 0xff},// ; Vsync, Href, PCLK, Frex, Strobe, SDA, GPIO1, GPIO0 output
	{0x301d, 0xf0},//
	{0x3a18, 0x00},// ; gain ceiling = 15.5x
	{0x3a19, 0xf8},// ; gain ceiling
	{0x3c01, 0x80},// ; band detection manual mode
	{0x3b07, 0x0c},// ; strobe frex mode
	//; analog control
	{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},
	//; AG/AE target
	{0x3a0f, 0x58},// ; stable in high
	{0x3a10, 0x50},// ; stable in low
	{0x3a1b, 0x58},// ; stable out high
	{0x3a1e, 0x50},// ; stable out low
	{0x3a11, 0x60},// ; fast zone high
	{0x3a1f, 0x28},// ; fast zone low
	{0x4001, 0x02},// ; BLC start line
	{0x4000, 0x09},// ; BLC enable
	{0x3000, 0x00},// ; D[9:8] input
	{0x3001, 0x00},// ; D[7:0] input
	{0x3002, 0x00},// ; Vsync, Href, PCLK, Frex, Strobe, SDA, GPIO1, GPIO0 input
	{0x3017, 0xe0},// ; MIPI PHY
	{0x301c, 0xfc},//
	{0x3636, 0x06},// ; analog control
	{0x3016, 0x08},// ; MIPI pad enable
	{0x3827, 0xec},//
	{0x3018, 0x44},// ; MIPI 2 lane, MIPI enable
	{0x3035, 0x21},// ; PLL
	{0x3106, 0xf5},// ; PLL 
	{0x3034, 0x1a},// ; PLL
	{0x301c, 0xf8},//
	{0x3503, 0x03},// ; Gain has no latch delay, AGC manual, AEC 
			
	{0x3501, 0x10},// ; exposure[15:8]
	{0x3502, 0x80},// ; exposure[7:0]
	{0x350a, 0x00},// ; gain[9:8]
	{0x350b, 0x7f},// ; gain[7:0]
	{0x5001, 0x01},// ; AWB on
	{0x5180, 0x08},// ; AWB manual gain enable
	
	{0x5186, 0x04},// ; manual red gain high
	{0x5187, 0x00},// ; manual red gain low
	{0x5188, 0x04},// ; manual green gain high
	{0x5189, 0x00},// ; manual green gain low
	{0x518a, 0x04},// ; manual blue gain high
	{0x518b, 0x00},// ; manual blue gain low
	{0x5000, 0x06},// ; lenc off, bpc on, wpc on
};

static struct regval_list sensor_qsxga_regs[] = { //qsxga: 2592*1936@15fps
	{0x0100, 0x00},// ; software standby
	{0x3035, 0x21},// ; PLL
	{0x3036, 0x66},// ; PLL
	{0x303c, 0x11},// ; PLL
	{0x3821, 0x06},// ; ISP mirror on, Sensor mirror on
	{0x3820, 0x00},// ; ISP flip off, Sensor flip off
	{0x3612, 0x5b},// ; analog control
	{0x3618, 0x04},// ; analog control
	{0x380c, 0x0a},// ; HTS = 2752
	{0x380d, 0xc0},// ; HTS
	{0x380e, 0x07},// ; VTS = 1974
	{0x380f, 0xb6},// ; VTS
	{0x3814, 0x11},// ; X INC
	{0x3815, 0x11},// ; X INC
	{0x3708, 0x64},// ; analog control
	{0x3709, 0x12},// ; analog control
	{0x3808, 0x0a},// ; X OUTPUT SIZE = 2592
	{0x3809, 0x20},// ; X OUTPUT SIZE
	{0x380a, 0x07},// ; Y OUTPUT SIZE = 1944
	{0x380b, 0x98},// ; Y OUTPUT SIZE
	{0x3800, 0x00},// ; X Start
	{0x3801, 0x0c},// ; X Start
	{0x3802, 0x00},// ; Y Start
	{0x3803, 0x02},// ; Y Start
	{0x3804, 0x0a},// ; X End
	{0x3805, 0x33},// ; X End
	{0x3806, 0x07},// ; Y End
	{0x3807, 0xa1},// ; Y End
	///////////; Banding filter
	{0x3a08, 0x01},// ; B50
	{0x3a09, 0x28},// ; B50
	{0x3a0a, 0x00},// ; B60
	{0x3a0b, 0xf6},// ; B60
	{0x3a0d, 0x07},// ; B60 max
	{0x3a0e, 0x06},// ; B50 max
	{0x4004, 0x04},// ; black line number
	{0x4837, 0x19},// ; MIPI pclk period
	{0x0100, 0x01},// ; wake up from software standby
};

static struct regval_list sensor_720p_regs[] = { //720: 1280*720@30fps
	{0x0100, 0x00},// ; software standby
	{0x3035, 0x21},// ; PLL
	{0x3036, 0x46},// ; PLL
	{0x303c, 0x11},// ; PLL
	{0x3821, 0x07},// ; ISP mirror on, Sensor mirror on, bin on
	{0x3820, 0x41},// ; ISP flip off, Sensor flip off, bin on
	{0x3612, 0x59},// ; analog control
	{0x3618, 0x00},// ; analog control
	{0x380c, 0x07},// ; HTS = 1896
	{0x380d, 0x68},// ; HTS
	{0x380e, 0x03},// ; VTS = 984
	{0x380f, 0xd8},// ; VTS
	{0x3814, 0x31},// ; X INC
	{0x3815, 0x31},// ; Y INC
	{0x3708, 0x64},// ; analog control
	{0x3709, 0x52},// ; analog control
	{0x3808, 0x05},// ; X OUTPUT SIZE = 1280
	{0x3809, 0x00},// ; X OUTPUT SIZE
	{0x380a, 0x03},// ; Y OUTPUT SIZE = 960
	{0x380b, 0xc0},// ; Y OUTPUT SIZE
	{0x3800, 0x00},// ; X Start
	{0x3801, 0x18},// ; X Start
	{0x3802, 0x00},// ; Y Start
	{0x3803, 0x0e},// ; Y Start
	{0x3804, 0x0a},// ; X End
	{0x3805, 0x27},// ; X End
	{0x3806, 0x07},// ; Y End
	{0x3807, 0x95},// ; Y End
	// banding filter
	{0x3a08, 0x01},// ; B50
	{0x3a09, 0x27},// ; B50
	{0x3a0a, 0x00},// ; B60
	{0x3a0b, 0xf6},// ; B60
	{0x3a0d, 0x04},// ; B50 max
	{0x3a0e, 0x03},// ; B60 max
	{0x4004, 0x02},// ; black line number
	{0x4837, 0x24},// ; MIPI pclk period
	{0x0100, 0x01},// ; wake up from software standby
};

static struct regval_list sensor_fmt_raw[] = {

};

/*
 * Code for dealing with controls.
 * fill with different sensor module
 * different sensor module has different settings here
 * if not support the follow function ,retrun -EINVAL
 */

static int sensor_g_exp(struct v4l2_subdev *sd, __s32 *value)
{
	struct sensor_info *info = to_state(sd);

	*value = info-&gt;exp;
	sensor_print("sensor_get_exposure = %d\n", info-&gt;exp);
	return 0;
}

static int sensor_s_exp(struct v4l2_subdev *sd, unsigned int exp_val)
{
	unsigned char explow, expmid, exphigh;
	struct sensor_info *info = to_state(sd);

	if(exp_val&gt;0xfffff)
		exp_val=0xfffff;
  
	sensor_write(sd, 0x3208, 0x00);//enter group write
	sensor_write(sd, 0x3503, 0x13);
    exphigh = (unsigned char) ( (0x0f0000&amp;exp_val)&gt;&gt;16);
    expmid  = (unsigned char) ( (0x00ff00&amp;exp_val)&gt;&gt;8);
    explow  = (unsigned char) ( (0x0000ff&amp;exp_val)   );
	
	//sensor_write(sd, 0x3208, 0x00);//enter group write
	sensor_write(sd, 0x3502, explow);
	sensor_write(sd, 0x3501, expmid);
	sensor_write(sd, 0x3500, exphigh);	
	sensor_write(sd, 0x3208, 0x10);//end group write
	sensor_write(sd, 0x3208, 0xa0);//init group write
	sensor_print("ov5647_mipi sensor_set_exp = %d, Done!\n", exp_val);
	
	info-&gt;exp = exp_val;
	return 0;
}

static int sensor_g_gain(struct v4l2_subdev *sd, __s32 *value)
{
	struct sensor_info *info = to_state(sd);
	*value = info-&gt;gain;
	sensor_print("sensor_get_gain = %d\n", info-&gt;gain);
	return 0;
}

static int sensor_s_gain(struct v4l2_subdev *sd, unsigned int gain_val)
{
	struct sensor_info *info = to_state(sd);
	unsigned char gainlow=0;
	unsigned char gainhigh=0;
	
	if(gain_val&lt;1*16)
		gain_val=16;
	if(gain_val&gt;64*16-1)
		gain_val=64*16-1;
	
	gainlow=(unsigned char)(gain_val&amp;0xff);
	gainhigh=(unsigned char)((gain_val&gt;&gt;8)&amp;0x3);
	
	sensor_write(sd, 0x3208, 0x00);//enter group write
	
	sensor_write(sd, 0x3503, 0x13);
	sensor_write(sd, 0x350b, gainlow);
	sensor_write(sd, 0x350a, gainhigh);
	sensor_write(sd, 0x3208, 0x10);//end group write
	sensor_write(sd, 0x3208, 0xa0);//init group write
	
	//printk("ov5647_mipi sensor_set_gain = %d, Done!\n", gain_val);
	info-&gt;gain = gain_val;
	
	return 0;
}

static int ov5648_sensor_vts;
static int sensor_s_exp_gain(struct v4l2_subdev *sd,
				struct sensor_exp_gain *exp_gain)
{
	int exp_val, gain_val,frame_length,shutter;
	unsigned char explow=0,expmid=0,exphigh=0;
	unsigned char gainlow=0,gainhigh=0;  
	struct sensor_info *info = to_state(sd);

	exp_val = exp_gain-&gt;exp_val;
	gain_val = exp_gain-&gt;gain_val;

	if(gain_val&lt;1*16)
		gain_val=16;
	if(gain_val&gt;64*16-1)
		gain_val=64*16-1;
	
	if(exp_val&gt;0xfffff)
		exp_val=0xfffff;
	
	gainlow=(unsigned char)(gain_val&amp;0xff);
	gainhigh=(unsigned char)((gain_val&gt;&gt;8)&amp;0x3);
	
	exphigh	= (unsigned char) ( (0x0f0000&amp;exp_val)&gt;&gt;16);
	expmid	= (unsigned char) ( (0x00ff00&amp;exp_val)&gt;&gt;8);
	explow	= (unsigned char) ( (0x0000ff&amp;exp_val)	 );
	shutter = exp_val/16;
	sensor_print("ov5648_sensor_vts = %d\n",ov5648_sensor_vts);
	
	if(shutter  &gt; ov5648_sensor_vts- 4)
			frame_length = shutter + 4;
	else
			frame_length = ov5648_sensor_vts;
	sensor_write(sd, 0x3503, 0x07);
	sensor_write(sd, 0x380f, (frame_length &amp; 0xff));
	sensor_write(sd, 0x380e, (frame_length &gt;&gt; 8));

	sensor_print("exp_val = %d,gain_val = %d\n",exp_val,gain_val);
	sensor_write(sd, 0x3208, 0x00);//enter group write
	
	sensor_write(sd, 0x350b, gainlow);
	sensor_write(sd, 0x350a, gainhigh);
	
	sensor_write(sd, 0x3502, explow);
	sensor_write(sd, 0x3501, expmid);
	sensor_write(sd, 0x3500, exphigh);	
	sensor_write(sd, 0x3208, 0x10);//end group write
	sensor_write(sd, 0x3208, 0xa0);//init group write

	info-&gt;exp = exp_val;
	info-&gt;gain = gain_val;
	return 0;
}

static void sensor_s_sw_stby(struct v4l2_subdev *sd, int on_off)
{
	int ret = 0;
	return ret;
}

/*
 * Stuff that knows about the sensor.
 */
static int sensor_power(struct v4l2_subdev *sd, int on)
{
	int ret = 0;
	sensor_print("ov5648 sensor_power\n");
	switch (on) {
	case STBY_ON:
		sensor_print("STBY_ON!\n");
		cci_lock(sd);
		sensor_s_sw_stby(sd, STBY_ON);
		usleep_range(1000, 1200);
		cci_unlock(sd);
		break;
	case STBY_OFF:
		sensor_print("STBY_OFF!\n");
		cci_lock(sd);
		usleep_range(1000, 1200);
		sensor_s_sw_stby(sd, STBY_OFF);
		cci_unlock(sd);
		break;
	case PWR_ON:
		sensor_print("PWR_ON!100\n");
		cci_lock(sd);
		vin_gpio_set_status(sd, PWDN, 1);
		vin_gpio_write(sd, RESET, CSI_GPIO_HIGH);
		vin_gpio_set_status(sd, POWER_EN, 1);
		vin_gpio_write(sd, PWDN, CSI_GPIO_LOW);
		vin_gpio_write(sd, RESET, CSI_GPIO_LOW);
		vin_gpio_write(sd, POWER_EN, CSI_GPIO_HIGH);
		usleep_range(7000, 8000);
		vin_set_pmu_channel(sd, IOVDD, ON);
		usleep_range(7000, 8000);
		vin_set_pmu_channel(sd, AVDD, ON);
		vin_set_pmu_channel(sd, AFVDD, ON);
		usleep_range(7000, 8000);
		vin_set_pmu_channel(sd, DVDD, ON);
		usleep_range(7000, 8000);
		vin_set_mclk_freq(sd, MCLK);
		vin_set_mclk(sd, ON);
		usleep_range(10000, 12000);
		vin_gpio_write(sd, RESET, CSI_GPIO_HIGH);
		vin_gpio_write(sd, PWDN, CSI_GPIO_HIGH);
		vin_set_pmu_channel(sd, CAMERAVDD, ON);/*AFVCC ON*/
		usleep_range(10000, 12000);
		cci_unlock(sd);
		break;
	case PWR_OFF:
		sensor_print("PWR_OFF!\n");
		cci_lock(sd);
		vin_gpio_write(sd, PWDN, CSI_GPIO_HIGH);
		vin_gpio_write(sd, RESET, CSI_GPIO_HIGH);
		vin_set_mclk(sd, OFF);
		usleep_range(7000, 8000);
		vin_set_pmu_channel(sd, DVDD, OFF);
		vin_gpio_write(sd, PWDN, CSI_GPIO_LOW);
		vin_gpio_write(sd, RESET, CSI_GPIO_LOW);
		vin_gpio_write(sd, POWER_EN, CSI_GPIO_LOW);
		vin_set_pmu_channel(sd, AVDD, OFF);
		vin_set_pmu_channel(sd, IOVDD, OFF);
		vin_set_pmu_channel(sd, AFVDD, OFF);
		vin_set_pmu_channel(sd, CAMERAVDD, OFF);/*AFVCC ON*/
		cci_unlock(sd);
		break;
	default:
		return -EINVAL;
	}

	return 0;
}

static int sensor_reset(struct v4l2_subdev *sd, u32 val)
{
	switch (val) {
	case 0:
		vin_gpio_write(sd, RESET, CSI_GPIO_HIGH);
		usleep_range(10000,12000);
		break;
	case 1:
		vin_gpio_write(sd, RESET, CSI_GPIO_LOW);
		usleep_range(10000,12000);
		break;
	default:
		return -EINVAL;
	}
	return 0;
}

static int sensor_detect(struct v4l2_subdev *sd)
{
	data_type rdval;
	unsigned int SENSOR_ID = 0;
	sensor_read(sd, 0x300A, &amp;rdval);
	SENSOR_ID |= rdval;
	SENSOR_ID |= (rdval &lt;&lt; 8);
	sensor_read(sd, 0x300B, &amp;rdval);
	SENSOR_ID |= (rdval);
	sensor_print("V4L2_IDENT_SENSOR = 0x%x\n", SENSOR_ID);
	if (SENSOR_ID != V4L2_IDENT_SENSOR) {
		sensor_print("ov5648 %s error, chip found is not an target chip", __func__);
		//return -ENODEV;
	}
	return 0;
}

static int sensor_init(struct v4l2_subdev *sd, u32 val)
{
	int ret;
	struct sensor_info *info = to_state(sd);

	sensor_print("sensor_init\n");

	/*Make sure it is a target sensor */
	ret = sensor_detect(sd);
	if (ret) {
		sensor_err("chip found is not an target chip.\n");
		return ret;
	}

	info-&gt;focus_status = 0;
	info-&gt;low_speed = 0;
	info-&gt;width = QSXGA_WIDTH;
	info-&gt;height = QSXGA_HEIGHT;
	info-&gt;hflip = 0;
	info-&gt;vflip = 0;
	info-&gt;gain = 0;

	info-&gt;tpf.numerator = 1;
	info-&gt;tpf.denominator = 30;	/* 30fps */

	info-&gt;preview_first_flag = 1;

	return 0;
}

static long sensor_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg)
{
	int ret = 0;
	struct sensor_info *info = to_state(sd);

	switch (cmd) {
	case GET_CURRENT_WIN_CFG:
		if (info-&gt;current_wins != NULL) {
			memcpy(arg, info-&gt;current_wins,
				sizeof(struct sensor_win_size));
			ret = 0;
		} else {
			sensor_err("empty wins!\n");
			ret = -1;
		}
		break;
	case SET_FPS:
		ret = 0;
		break;
	case VIDIOC_VIN_SENSOR_EXP_GAIN:
		ret = sensor_s_exp_gain(sd, (struct sensor_exp_gain *)arg);
		break;
	case VIDIOC_VIN_SENSOR_CFG_REQ:
		sensor_cfg_req(sd, (struct sensor_config *)arg);
		break;
	case VIDIOC_VIN_ACT_INIT:
		ret = actuator_init(sd, (struct actuator_para *)arg);
		break;
	case VIDIOC_VIN_ACT_SET_CODE:
		ret = actuator_set_code(sd, (struct actuator_ctrl *)arg);
		break;
	default:
		return -EINVAL;
	}
	return ret;
}

/*
 * Store information about the video data format.
 */
static struct sensor_format_struct sensor_formats[] = {
	{
		.desc = "Raw RGB Bayer",
		.mbus_code = MEDIA_BUS_FMT_SBGGR10_1X10,
		.regs = sensor_fmt_raw,
		.regs_size = ARRAY_SIZE(sensor_fmt_raw),
		.bpp = 1
	},
};
#define N_FMTS ARRAY_SIZE(sensor_formats)

/*
 * Then there is the issue of window sizes.  Try to capture the info here.
 */

static struct sensor_win_size sensor_win_sizes[] = {
	{
      .width      = QSXGA_WIDTH,
      .height     = QSXGA_HEIGHT,
      .hoffset    = 0,
      .voffset    = 4,
      .hts        = 2752,
      .vts        = 1974,
      .pclk       = 81486720,
      .mipi_bps	  = 408*1000*1000,
      .fps_fixed  = 2,
      .bin_factor = 1,
      .intg_min   = 1,
      .intg_max   = (1974)&lt;&lt;4,
      .gain_min   = 1&lt;&lt;4,
      .gain_max   = 12&lt;&lt;4,
      .regs       = sensor_qsxga_regs,
      .regs_size  = ARRAY_SIZE(sensor_qsxga_regs),
      .set_size   = NULL,
    },
	{
      .width      = HD720_WIDTH,
      .height     = HD720_HEIGHT,
      .hoffset    = 0,
      .voffset    = 120,
      .hts        = 1896,
      .vts        = 984,
      .pclk       = 56*1000*1000,      
      .mipi_bps	  = 280*1000*1000,
      .fps_fixed  = 1,
      .bin_factor = 1,
      .intg_min   = 1,
      .intg_max   = 984&lt;&lt;4,
      .gain_min   = 1&lt;&lt;4,
      .gain_max   = 12&lt;&lt;4,
      .regs		  = sensor_720p_regs,//
      .regs_size  = ARRAY_SIZE(sensor_720p_regs),//
      .set_size	  = NULL,
    },
};

#define N_WIN_SIZES (ARRAY_SIZE(sensor_win_sizes))

static int sensor_reg_init(struct sensor_info *info)
{
	int ret;
	struct v4l2_subdev *sd = &amp;info-&gt;sd;
	struct sensor_format_struct *sensor_fmt = info-&gt;fmt;
	struct sensor_win_size *wsize = info-&gt;current_wins;

	ret = sensor_write_array(sd, sensor_default_regs,
				ARRAY_SIZE(sensor_default_regs));
	if (ret &lt; 0) {
		sensor_err("write sensor_default_regs error\n");
		return ret;
	}

	sensor_print("sensor_reg_init\n");

	sensor_write_array(sd, sensor_fmt-&gt;regs, sensor_fmt-&gt;regs_size);

	if (wsize-&gt;regs)
		sensor_write_array(sd, wsize-&gt;regs, wsize-&gt;regs_size);

	if (wsize-&gt;set_size)
		wsize-&gt;set_size(sd);

	info-&gt;width = wsize-&gt;width;
	info-&gt;height = wsize-&gt;height;
	info-&gt;exp = 0;
	info-&gt;gain = 0;
	ov5648_sensor_vts = wsize-&gt;vts;
	sensor_print("s_fmt set width = %d, height = %d\n", wsize-&gt;width,
				wsize-&gt;height);

	return 0;
}

static int sensor_s_stream(struct v4l2_subdev *sd, int enable)
{
	struct sensor_info *info = to_state(sd);

	sensor_print("%s on = %d, %d*%d fps: %d code: %x\n", __func__, enable,
			info-&gt;current_wins-&gt;width, info-&gt;current_wins-&gt;height,
			info-&gt;current_wins-&gt;fps_fixed, info-&gt;fmt-&gt;mbus_code);

	if (!enable)
		return 0;

	return sensor_reg_init(info);
}

static int sensor_g_mbus_config(struct v4l2_subdev *sd,
				struct v4l2_mbus_config *cfg)
{
	cfg-&gt;type = V4L2_MBUS_CSI2;
	cfg-&gt;flags = 0 | V4L2_MBUS_CSI2_2_LANE | V4L2_MBUS_CSI2_CHANNEL_0;

	return 0;
}

static int sensor_g_ctrl(struct v4l2_ctrl *ctrl)
{
	struct sensor_info *info = container_of(ctrl-&gt;handler,
			struct sensor_info, handler);
	struct v4l2_subdev *sd = &amp;info-&gt;sd;

	switch (ctrl-&gt;id) {
	case V4L2_CID_GAIN:
		return sensor_g_gain(sd, &amp;ctrl-&gt;val);
	case V4L2_CID_EXPOSURE:
		return sensor_g_exp(sd, &amp;ctrl-&gt;val);
	}
	return -EINVAL;
}

static int sensor_s_ctrl(struct v4l2_ctrl *ctrl)
{
	struct sensor_info *info = container_of(ctrl-&gt;handler,
			struct sensor_info, handler);
	struct v4l2_subdev *sd = &amp;info-&gt;sd;

	switch (ctrl-&gt;id) {
	case V4L2_CID_GAIN:
		return sensor_s_gain(sd, ctrl-&gt;val);
	case V4L2_CID_EXPOSURE:
		return sensor_s_exp(sd, ctrl-&gt;val);
	}
	return -EINVAL;
}

/* ----------------------------------------------------------------------- */

static const struct v4l2_ctrl_ops sensor_ctrl_ops = {
	.g_volatile_ctrl = sensor_g_ctrl,
	.s_ctrl = sensor_s_ctrl,
};

static const struct v4l2_subdev_core_ops sensor_core_ops = {
	.reset = sensor_reset,
	.init = sensor_init,
	.s_power = sensor_power,
	.ioctl = sensor_ioctl,
#ifdef CONFIG_COMPAT
	.compat_ioctl32 = sensor_compat_ioctl32,
#endif
};

static const struct v4l2_subdev_video_ops sensor_video_ops = {
	.s_parm = sensor_s_parm,
	.g_parm = sensor_g_parm,
	.s_stream = sensor_s_stream,
	.g_mbus_config = sensor_g_mbus_config,
};

static const struct v4l2_subdev_pad_ops sensor_pad_ops = {
	.enum_mbus_code = sensor_enum_mbus_code,
	.enum_frame_size = sensor_enum_frame_size,
	.get_fmt = sensor_get_fmt,
	.set_fmt = sensor_set_fmt,
};

static const struct v4l2_subdev_ops sensor_ops = {
	.core = &amp;sensor_core_ops,
	.video = &amp;sensor_video_ops,
	.pad = &amp;sensor_pad_ops,
};

/* ----------------------------------------------------------------------- */
static struct cci_driver cci_drv = {
		.name = SENSOR_NAME,
		.addr_width = CCI_BITS_16,
		.data_width = CCI_BITS_8,
};

static const struct v4l2_ctrl_config sensor_custom_ctrls[] = {
	{
		.ops = &amp;sensor_ctrl_ops,
		.id = V4L2_CID_FRAME_RATE,
		.name = "frame rate",
		.type = V4L2_CTRL_TYPE_INTEGER,
		.min = 15,
		.max = 120,
		.step = 1,
		.def = 120,
	},
};

static int sensor_init_controls(struct v4l2_subdev *sd,
			const struct v4l2_ctrl_ops *ops)
{
	struct sensor_info *info = to_state(sd);
	struct v4l2_ctrl_handler *handler = &amp;info-&gt;handler;
	struct v4l2_ctrl *ctrl;
	int i;
	int ret = 0;

	v4l2_ctrl_handler_init(handler, 2 + ARRAY_SIZE(sensor_custom_ctrls));

	v4l2_ctrl_new_std(handler, ops, V4L2_CID_GAIN, 1 * 1600,
				256 * 1600, 1, 1 * 1600);
	ctrl = v4l2_ctrl_new_std(handler, ops, V4L2_CID_EXPOSURE, 0,
				65536 * 16, 1, 0);
	if (ctrl != NULL)
		ctrl-&gt;flags |= V4L2_CTRL_FLAG_VOLATILE;
	for (i = 0; i &lt; ARRAY_SIZE(sensor_custom_ctrls); i++)
		v4l2_ctrl_new_custom(handler, &amp;sensor_custom_ctrls[i], NULL);

	if (handler-&gt;error) {
		ret = handler-&gt;error;
		v4l2_ctrl_handler_free(handler);
	}

	sd-&gt;ctrl_handler = handler;

	return ret;
}

static int sensor_probe(struct i2c_client *client,
			const struct i2c_device_id *id)
{
	struct v4l2_subdev *sd;
	struct sensor_info *info;

	info = kzalloc(sizeof(struct sensor_info), GFP_KERNEL);
	if (info == NULL)
		return -ENOMEM;
	sd = &amp;info-&gt;sd;

	cci_dev_probe_helper(sd, client, &amp;sensor_ops, &amp;cci_drv);
	sensor_init_controls(sd, &amp;sensor_ctrl_ops);

	mutex_init(&amp;info-&gt;lock);
#ifdef CONFIG_SAME_I2C
	info-&gt;sensor_i2c_addr = I2C_ADDR &gt;&gt; 1;
#endif
	info-&gt;fmt = &amp;sensor_formats[0];
	info-&gt;fmt_pt = &amp;sensor_formats[0];
	info-&gt;win_pt = &amp;sensor_win_sizes[0];
	info-&gt;fmt_num = N_FMTS;
	info-&gt;win_size_num = N_WIN_SIZES;
	info-&gt;sensor_field = V4L2_FIELD_NONE;
	info-&gt;stream_seq = MIPI_BEFORE_SENSOR;
	info-&gt;af_first_flag = 1;
	info-&gt;exp = 0;
	info-&gt;gain = 0;

	return 0;
}

static int sensor_remove(struct i2c_client *client)
{
	struct v4l2_subdev *sd;

	sd = cci_dev_remove_helper(client, &amp;cci_drv);

	kfree(to_state(sd));
	return 0;
}

static const struct i2c_device_id sensor_id[] = {
	{SENSOR_NAME, 0},
	{}
};

MODULE_DEVICE_TABLE(i2c, sensor_id);

static struct i2c_driver sensor_driver = {
		.driver = {
				.owner = THIS_MODULE,
				.name = SENSOR_NAME,
				},
		.probe = sensor_probe,
		.remove = sensor_remove,
		.id_table = sensor_id,
};
static __init int init_sensor(void)
{
	return cci_dev_init_helper(&amp;sensor_driver);
}

static __exit void exit_sensor(void)
{
	cci_dev_exit_helper(&amp;sensor_driver);
}

module_init(init_sensor);
module_exit(exit_sensor);
</code></pre>
<p dir="auto">另外建议使用支持列表中的摄像头，例如gc2053，gc2063，这些摄像头已经适配量产完成并且调整ISP后画质更佳，也支持aiisp实现低照度全彩画质，树莓派的摄像头不推荐使用，因为他是外挂mclk的会引起芯片处于错误的模式，另外原厂也没有相应的支持（2017年前的芯片才有这个支持）</p>
<p dir="auto">IMX219 同样可以使用，但是请注意4lane的摄像头不可适配2lane的数据</p>
]]></description><link>https://bbs.aw-ol.com/post/20374</link><guid isPermaLink="true">https://bbs.aw-ol.com/post/20374</guid><dc:creator><![CDATA[awwwwa]]></dc:creator><pubDate>Wed, 13 Dec 2023 10:11:55 GMT</pubDate></item><item><title><![CDATA[Reply to V851S tina linux ov5647 驱动程序没有 dmesg on Tue, 12 Dec 2023 23:27:30 GMT]]></title><description><![CDATA[<p dir="auto">请注意，对于上一篇带有图片的文章，有 4 层，因此 mipi 信号通过完整的接地层路由，具有正确的阻抗</p>
]]></description><link>https://bbs.aw-ol.com/post/20359</link><guid isPermaLink="true">https://bbs.aw-ol.com/post/20359</guid><dc:creator><![CDATA[kanken6174]]></dc:creator><pubDate>Tue, 12 Dec 2023 23:27:30 GMT</pubDate></item><item><title><![CDATA[Reply to V851S tina linux ov5647 驱动程序没有 dmesg on Tue, 12 Dec 2023 23:17:51 GMT]]></title><description><![CDATA[<p dir="auto"><a class="plugin-mentions-user plugin-mentions-a" href="https://bbs.aw-ol.com/uid/2123">@whycanservice</a> 我完全遵循了 allwinner 提供的文档，我查看了您指出的指南以及专门关于 mipi-csi 的指南，我遵循了所需的所有步骤，甚至将逻辑分析仪连接到单独的树莓派 3 以通过 I2C 发送来收集它 数据来复制它，这至少应该在启用流的 mipi-csi 模式下生成一个配置，然后相应地配置驱动程序（分辨率、VTS/HTS...），但仍然超时并且主板未检测到任何内容。</p>
<pre><code class="language-cpp">static int sensor_g_mbus_config(struct v4l2_subdev *sd,
				struct v4l2_mbus_config *cfg)
{
	cfg-&gt;type = V4L2_MBUS_CSI2;
	cfg-&gt;flags = 0 | V4L2_MBUS_CSI2_2_LANE | V4L2_MBUS_CSI2_CHANNEL_0

	return 0;
}
</code></pre>
<pre><code class="language-cpp">static struct sensor_win_size sensor_win_sizes[] = {
	{
	.width	  	= 1296,	//camerademo GBRG10 1296 972 15 bmp /tmp 5
	.height	  	= 972,
	.hoffset	= 0,
	.voffset	= 0,
	.hts		= 1128,	//Horizontal total size   1852 (unit pclk)
	.vts		= 1200,	//Vertical total size 0x1f8 (unit line)
	.pclk		= 46.5*MHZ,
	.mipi_bps   = 1296*972*10*30,
	.fps_fixed  = 30,	//fps = camera_clk /(hts * vts)
	.bin_factor = 1,
	.intg_min   = 16,
	.intg_max   = (1984-4)&lt;&lt;4,
	.gain_min   = 1&lt;&lt;4,
	.gain_max   = 64&lt;&lt;4,
	.regs		= ov5647_rpi3,
	.regs_size  = ARRAY_SIZE(ov5647_rpi3),
	.set_size   = NULL,
	},
};
</code></pre>
<pre><code class="language-cpp">static struct regval_list ov5647_rpi3[] = {
	{0x3000, 0x0F},
	{0x3001, 0xFF},
	{0x3002, 0xE4},
	{0x4800, 0x25},
	{0x4202, 0x0F},
	{0x300D, 0x01},
	{0x0100, 0x00},
	{0x0103, 0x01},
	{0x3034, 0x1A},
	{0x3035, 0x32},
	{0x3036, 0x62},
	{0x303C, 0x11},
	{0x3106, 0xF5},
	{0x3827, 0xEC},
	{0x370C, 0x03},	
	{0x3612, 0x59},
	{0x3618, 0x00},
	{0x5000, 0x06},
	//???? //0b01101100 001010000 000000100 010000010 
	// 6C 50 04 82
	{0x5004, 0x82},
	{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, 0x07},
	{0x3809, 0xA3},
	{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},
	{0x3621, 0xE0},
	{0x3600, 0x37},
	{0x3704, 0xA0},
	{0x3703, 0x5A},
	{0x3715, 0x78},
	{0x3717, 0x01},
	{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},
	{REG_DLY,70},	//wait 70ms
	{0x3500, 0x00},	//exposure
	{0x3501, 0x59},
	{0x3502, 0x70},
	{0x350A, 0x00},	//AGC
	{0x350B, 0x80},
	{REG_DLY, 500},
	{0x4800, 0x25},
	{0x4202, 0x0F},
	{0x300D, 0x01},
	{0x3000, 0x00},
	{0x3001, 0x00},
	{0x3002, 0x00},
	{0x0100, 0x00},
};
</code></pre>
<p dir="auto">所有数据均正确读回<br />
<img src="/assets/uploads/files/1702422823081-ef1f2035-95ce-4ee3-9f3b-f8f1ae34306e-image.png" alt="ef1f2035-95ce-4ee3-9f3b-f8f1ae34306e-image.png" class=" img-responsive img-markdown" width="659" height="1105" /></p>
<p dir="auto">在 rpi 3 上，相机工作正常，因此相机没有任何问题。</p>
<p dir="auto">我对 mipi 通道进行了连续性测试，所有通道都正确连接到处理器焊盘，因此没有焊接错误。 走线的阻抗应该足够好，能够像在 rpi 3 上一样工作，即使将飞线测试引线焊接到通道上也是如此。</p>
<p dir="auto">我尝试了许多不同的配置、DTS、.fex、驱动程序的更改，无论我更改什么，我总是得到相同的结果。 对我来说，没有比这更好的调试方法了。 我已经订购了 yuzukilizard 板来尝试比较该板上的 mipi 信号并使用相机适配器测试我的代码，但这需要一些时间才能到达。</p>
<p dir="auto">目前，我真的没有任何想法来使这个工作......如果我找不到这个驱动程序有什么问题，我可能会完全改变平台，因为对 V851S 的支持似乎非常有限。</p>
<p dir="auto"><img src="/assets/uploads/files/1702422942156-9eded2d5-9f94-491a-af2b-0fed1b7bbf21-image.png" alt="9eded2d5-9f94-491a-af2b-0fed1b7bbf21-image.png" class=" img-responsive img-markdown" width="722" height="1097" /><br />
<img src="/assets/uploads/files/1702422977662-7467f3e7-c976-4488-a451-a8a3db63337a-image.png" alt="7467f3e7-c976-4488-a451-a8a3db63337a-image.png" class=" img-responsive img-markdown" width="401" height="421" /><br />
<img src="/assets/uploads/files/1702422996341-924ec271-88cf-4ef1-b1f6-4ed46c55a6fa-image.png" alt="924ec271-88cf-4ef1-b1f6-4ed46c55a6fa-image.png" class=" img-responsive img-markdown" width="715" height="297" /><br />
MLCK 没有连接，因为 rpi 相机板上有一个内部时钟振荡器，并且它们的 MLCK 没有断开。<br />
相机已正确开机并正确响应所有 i2c 命令。</p>
]]></description><link>https://bbs.aw-ol.com/post/20358</link><guid isPermaLink="true">https://bbs.aw-ol.com/post/20358</guid><dc:creator><![CDATA[kanken6174]]></dc:creator><pubDate>Tue, 12 Dec 2023 23:17:51 GMT</pubDate></item></channel></rss>