V851S tina linux ov5647 驱动程序没有 dmesg
-
大家好,
在修复了我的 i2c 并使用 i2cDetect 和手动 GPIO 选择手动检测到我的相机后,我正在尝试为相机制作一个驱动程序。
我将它基于已经存在的 OV5468 mipi 驱动程序。 我更改了所有必需的标识符和寄存器/值,以使其符合 ov5647 的要求,我编辑了必要的 makefile 来构建它,并为新传感器配置了板的 DTS。
我的问题是这样的:
当我使用 insmod 加载 ov5647_mipi.ko 内核模块时,没有任何反应。 即使我将日志级别设置为 8,并且我在驱动程序中放置了各种 printk() 调用,但 dmesg 中根本没有出现任何消息,但这些调用实际上都没有显示在日志中。 你们知道我可能错过了什么吗? 也许是某个特定的配置使日志静音? DTS 错误?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#
我的DTS:
soc@03000000 { /*wlan: wlan@0 { compatible = "allwinner,sunxi-wlan"; pinctrl-names = "default"; clock-names = "32k-fanout0"; clocks = <&clk_fanout0>; wlan_busnum = <0x1>; wlan_regon = <&pio PE 6 1 0x1 0x2 0>; wlan_hostwake = <&pio PE 7 14 0x1 0x2 0>; chip_en; power_en; status = "io_disabled"; wakeup-source; };*/ vind0:vind@0 { vind0_clk = <200000000>; status = "okay"; csi2:csi@2 { pinctrl-names = "default","sleep"; pinctrl-0 = <&ncsi_pins_a>; pinctrl-1 = <&ncsi_pins_b>; status = "okay"; }; tdm0:tdm@0 { work_mode = <0>; }; isp00:isp@0 { work_mode = <0>; }; scaler00:scaler@0 { work_mode = <0>; }; scaler10:scaler@4 { work_mode = <0>; }; scaler20:scaler@8 { work_mode = <0>; }; scaler30:scaler@12 { work_mode = <0>; }; actuator0:actuator@0 { device_type = "actuator0"; actuator0_name = "ad5820_act"; actuator0_slave = <0x18>; actuator0_af_pwdn = <>; actuator0_afvdd = "afvcc-csi"; actuator0_afvdd_vol = <2800000>; status = "disabled"; }; flash0:flash@0 { device_type = "flash0"; flash0_type = <2>; flash0_en = <>; flash0_mode = <>; flash0_flvdd = ""; flash0_flvdd_vol = <>; status = "disabled"; }; sensor0:sensor@0 { device_type = "sensor0"; sensor0_mname = "ov5647_mipi"; sensor0_twi_cci_id = <1>; sensor0_twi_addr = <0x6c>; sensor0_mclk_id = <0>; sensor0_pos = "rear"; sensor0_isp_used = <1>; sensor0_fmt = <1>; sensor0_stby_mode = <0>; sensor0_vflip = <0>; sensor0_hflip = <0>; sensor0_iovdd-supply = <1800000>; sensor0_iovdd_vol = <>; sensor0_avdd-supply = <2800000>; sensor0_avdd_vol = <>; sensor0_dvdd-supply = <1200000>; sensor0_dvdd_vol = <>; sensor0_reset = <>; //sensor0_power_en = <>; //sensor0_pwdn = <>; sensor0_power_en = <&pio PA 9 1 0 1 0>; sensor0_pwdn = <&pio PA 8 1 0 1 0>; /*sensor0_sm_hs = <&pio PE 2 1 0 1 0>;*/ /*sensor0_sm_vs = <&pio PE 3 1 0 1 0>;*/ flash_handle = <&flash0>; //&flash0 act_handle = <&actuator0>; //&actuator0 status = "okay"; }; sensor1:sensor@1 { device_type = "sensor1"; sensor1_mname = "ov5640"; sensor1_twi_cci_id = <2>; sensor1_twi_addr = <0x30>; sensor1_mclk_id = <1>; sensor1_pos = "front"; sensor1_isp_used = <1>; sensor1_fmt = <1>; sensor1_stby_mode = <0>; sensor1_vflip = <0>; sensor1_hflip = <0>; sensor1_iovdd-supply = <>; sensor1_iovdd_vol = <1800000>; sensor1_avdd-supply = <>; sensor1_avdd_vol = <2800000>; sensor1_dvdd-supply = <>; sensor1_dvdd_vol = <1200000>; sensor1_power_en = <>; sensor1_reset = <>; sensor1_pwdn = <>; sensor1_sm_hs = <&pio PE 2 1 0 1 0>; sensor1_sm_vs = <&pio PE 3 1 0 1 0>; flash_handle = <>; act_handle = <>; status = "disabled"; }; vinc00:vinc@0 { vinc0_csi_sel = <0>; vinc0_mipi_sel = <0>; vinc0_isp_sel = <0>; vinc0_isp_tx_ch_ = <0>; vinc0_tdm_rx_sel = <0>; vinc0_rear_sensor_sel = <0>; vinc0_front_sensor_sel = <0>; vinc0_sensor_list = <0>; work_mode = <0x0>; status = "okay"; }; vinc01:vinc@1 { vinc1_csi_sel = <2>; vinc1_mipi_sel = <0xff>; vinc1_isp_sel = <1>; vinc1_isp_tx_ch = <1>; vinc1_tdm_rx_sel = <1>; vinc1_rear_sensor_sel = <0>; vinc1_front_sensor_sel = <0>; vinc1_sensor_list = <0>; status = "disabled"; }; vinc02:vinc@2 { vinc2_csi_sel = <2>; vinc2_mipi_sel = <0xff>; vinc2_isp_sel = <2>; vinc2_isp_tx_ch_ = <2>; vinc2_tdm_rx_sel = <2>; vinc2_rear_sensor_sel = <0>; vinc2_front_sensor_sel = <0>; vinc2_sensor_list = <0>; status = "disabled"; }; vinc03:vinc@3 { vinc3_csi_sel = <0>; vinc3_mipi_sel = <0xff>; vinc3_isp_sel = <0>; vinc3_isp_tx_ch_ = <0>; vinc3_tdm_rx_sel = <0>; vinc3_rear_sensor_sel = <1>; vinc3_front_sensor_sel = <1>; vinc3_sensor_list = <0>; status = "disabled"; }; vinc10:vinc@4 { vinc4_csi_sel = <0>; vinc4_mipi_sel = <0>; vinc4_isp_sel = <0>; vinc4_isp_tx_ch = <0>; vinc4_tdm_rx_sel = <0>; vinc4_rear_sensor_sel = <0>; vinc4_front_sensor_sel = <0>; vinc4_sensor_list = <0>; work_mode = <0x0>; status = "okay"; }; vinc11:vinc@5 { vinc5_csi_sel = <2>; vinc5_mipi_sel = <0xff>; vinc5_isp_sel = <1>; vinc5_isp_tx_ch = <1>; vinc5_tdm_rx_sel = <1>; vinc5_rear_sensor_sel = <0>; vinc5_front_sensor_sel = <0>; vinc5_sensor_list = <0>; status = "disabled"; }; vinc12:vinc@6 { vinc6_csi_sel = <2>; vinc6_mipi_sel = <0xff>; vinc6_isp_sel = <0>; vinc6_isp_tx_ch = <0>; vinc6_tdm_rx_sel = <0>; vinc6_rear_sensor_sel = <0>; vinc6_front_sensor_sel = <0>; vinc6_sensor_list = <0>; status = "disabled"; }; vinc13:vinc@7 { vinc7_csi_sel = <2>; vinc7_mipi_sel = <0xff>; vinc7_isp_sel = <0>; vinc7_isp_tx_ch = <0>; vinc7_tdm_rx_sel = <0>; vinc7_rear_sensor_sel = <0>; vinc7_front_sensor_sel = <0>; vinc7_sensor_list = <0>; status = "disabled"; }; vinc20:vinc@8 { vinc8_csi_sel = <0>; vinc8_mipi_sel = <0>; vinc8_isp_sel = <0>; vinc8_isp_tx_ch = <0>; vinc8_tdm_rx_sel = <0>; vinc8_rear_sensor_sel = <0>; vinc8_front_sensor_sel = <0>; vinc8_sensor_list = <0>; work_mode = <0x0>; status = "okay"; }; vinc21:vinc@9 { vinc9_csi_sel = <2>; vinc9_mipi_sel = <0xff>; vinc9_isp_sel = <0>; vinc9_isp_tx_ch = <0>; vinc9_tdm_rx_sel = <0>; vinc9_rear_sensor_sel = <0>; vinc9_front_sensor_sel = <0>; vinc9_sensor_list = <0>; status = "disabled"; }; vinc22:vinc@10 { vinc10_csi_sel = <2>; vinc10_mipi_sel = <0xff>; vinc10_isp_sel = <0>; vinc10_isp_tx_ch = <0>; vinc10_tdm_rx_sel = <0>; vinc10_rear_sensor_sel = <0>; vinc10_front_sensor_sel = <0>; vinc10_sensor_list = <0>; status = "disabled"; }; vinc23:vinc@11 { vinc11_csi_sel = <2>; vinc11_mipi_sel = <0xff>; vinc11_isp_sel = <0>; vinc11_isp_tx_ch = <0>; vinc11_tdm_rx_sel = <0>; vinc11_rear_sensor_sel = <0>; vinc11_front_sensor_sel = <0>; vinc11_sensor_list = <0>; status = "disabled"; }; vinc30:vinc@12 { vinc12_csi_sel = <0>; vinc12_mipi_sel = <0>; vinc12_isp_sel = <0>; vinc12_isp_tx_ch = <0>; vinc12_tdm_rx_sel = <0>; vinc12_rear_sensor_sel = <0>; vinc12_front_sensor_sel = <0>; vinc12_sensor_list = <0>; work_mode = <0x0>; status = "okay"; }; vinc31:vinc@13 { vinc13_csi_sel = <2>; vinc13_mipi_sel = <0xff>; vinc13_isp_sel = <0>; vinc13_isp_tx_ch = <0>; vinc13_tdm_rx_sel = <0>; vinc13_rear_sensor_sel = <0>; vinc13_front_sensor_sel = <0>; vinc13_sensor_list = <0>; status = "disabled"; }; vinc32:vinc@14 { vinc14_csi_sel = <2>; vinc14_mipi_sel = <0xff>; vinc14_isp_sel = <0>; vinc14_isp_tx_ch = <0>; vinc14_tdm_rx_sel = <0>; vinc14_rear_sensor_sel = <0>; vinc14_front_sensor_sel = <0>; vinc14_sensor_list = <0>; status = "disabled"; }; vinc33:vinc@15 { vinc15_csi_sel = <2>; vinc15_mipi_sel = <0xff>; vinc15_isp_sel = <0>; vinc15_isp_tx_ch = <0>; vinc15_tdm_rx_sel = <0>; vinc15_rear_sensor_sel = <0>; vinc15_front_sensor_sel = <0>; vinc15_sensor_list = <0>; status = "disabled"; }; }; };
最后是我的驱动程序,如您所见,它实现了各种日志:
#include <linux/init.h> #include <linux/module.h> #include <linux/slab.h> #include <linux/i2c.h> #include <linux/delay.h> #include <linux/videodev2.h> #include <linux/clk.h> #include <media/v4l2-device.h> #include <media/v4l2-mediabus.h> #include <linux/io.h> #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->exp; sensor_dbg("sensor_get_exposure = %d\n", info->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 > 0xfffff) exp_val = 0xfffff; if (exp_val < 7) exp_val = 7; exphigh = (unsigned char)((0x0f0000 & exp_val) >> 16); expmid = (unsigned char)((0x00ff00 & exp_val) >> 8); explow = (unsigned char)(0x0000ff & exp_val); sensor_write(sd, 0x3502, explow); sensor_write(sd, 0x3501, expmid); sensor_write(sd, 0x3500, exphigh); info->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->gain; sensor_dbg("sensor_get_gain = %d\n", info->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 < 1 * 16) gain_val = 16; if (gain_val > 64 * 16 - 1) gain_val = 64 * 16 - 1; gainlow = (unsigned char)(gain_val & 0xff); gainhigh = (unsigned char)((gain_val >> 8) & 0x3); sensor_write(sd, 0x350b, gainlow); sensor_write(sd, 0x350a, gainhigh); info->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->exp_val; gain_val = exp_gain->gain_val; if (gain_val < 1*16) gain_val = 16; if (gain_val > 64*16-1) gain_val = 64*16-1; if (exp_val > 0xfffff) exp_val = 0xfffff; gainlow = (unsigned char)(gain_val & 0xff); gainhigh = (unsigned char)((gain_val >> 8)&0x3); exphigh = (unsigned char)((0x0f0000&exp_val) >> 16); expmid = (unsigned char)((0x00ff00&exp_val) >> 8); explow = (unsigned char)((0x0000ff&exp_val)); shutter = exp_val/16; if (shutter > 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 & 0xff)); sensor_write(sd, 0x380e, (frame_length >> 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->exp = exp_val; info->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, &rdval); SENSOR_ID |= rdval; SENSOR_ID |= (rdval << 8); sensor_read(sd, 0x300B, &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->focus_status = 0; info->low_speed = 0; info->width = 1280; info->height = 720; info->hflip = 0; info->vflip = 0; info->gain = 0; info->tpf.numerator = 1; info->tpf.denominator = 30; /* 30fps */ info->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->current_wins != NULL) { memcpy(arg, info->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)<<4, .gain_min = 1<<4, .gain_max = 64<<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)<<4, .gain_min = 1<<4, .gain_max = 64<<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 = &info->sd; struct sensor_format_struct *sensor_fmt = info->fmt; struct sensor_win_size *wsize = info->current_wins; ret = sensor_write_array(sd, sensor_default_regs, ARRAY_SIZE(sensor_default_regs)); if (ret < 0) { sensor_err("write sensor_default_regs error\n"); return ret; } sensor_print("sensor_reg_init\n"); sensor_write_array(sd, sensor_fmt->regs, sensor_fmt->regs_size); if (wsize->regs) sensor_write_array(sd, wsize->regs, wsize->regs_size); if (wsize->set_size) wsize->set_size(sd); info->width = wsize->width; info->height = wsize->height; info->exp = 0; info->gain = 0; ov5647_sensor_vts = wsize->vts; sensor_print("s_fmt set width = %d, height = %d\n", wsize->width, wsize->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->current_wins->width, info->current_wins->height, info->current_wins->fps_fixed, info->fmt->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->type = V4L2_MBUS_CSI2; cfg->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->handler, struct sensor_info, handler); struct v4l2_subdev *sd = &info->sd; switch (ctrl->id) { case V4L2_CID_GAIN: return sensor_g_gain(sd, &ctrl->val); case V4L2_CID_EXPOSURE: return sensor_g_exp(sd, &ctrl->val); } return -EINVAL; } static int sensor_s_ctrl(struct v4l2_ctrl *ctrl) { struct sensor_info *info = container_of(ctrl->handler, struct sensor_info, handler); struct v4l2_subdev *sd = &info->sd; switch (ctrl->id) { case V4L2_CID_GAIN: return sensor_s_gain(sd, ctrl->val); case V4L2_CID_EXPOSURE: return sensor_s_exp(sd, ctrl->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 = &sensor_core_ops, .video = &sensor_video_ops, .pad = &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 = &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 = &info->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->flags |= V4L2_CTRL_FLAG_VOLATILE; for (i = 0; i < ARRAY_SIZE(sensor_custom_ctrls); i++) v4l2_ctrl_new_custom(handler, &sensor_custom_ctrls[i], NULL); if (handler->error) { ret = handler->error; v4l2_ctrl_handler_free(handler); } sd->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 = &info->sd; cci_dev_probe_helper(sd, client, &sensor_ops, &cci_drv); sensor_init_controls(sd, &sensor_ctrl_ops); mutex_init(&info->lock); #ifdef CONFIG_SAME_I2C info->sensor_i2c_addr = I2C_ADDR >> 1; #endif info->fmt = &sensor_formats[0]; info->fmt_pt = &sensor_formats[0]; info->win_pt = &sensor_win_sizes[0]; info->fmt_num = N_FMTS; info->win_size_num = N_WIN_SIZES; info->sensor_field = V4L2_FIELD_NONE; info->stream_seq = MIPI_BEFORE_SENSOR; info->af_first_flag = 1; info->exp = 0; info->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, &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(&sensor_driver); } static __exit void exit_sensor(void) { cci_dev_exit_helper(&sensor_driver); } module_init(init_sensor); module_exit(exit_sensor);
-
我让它工作了,似乎驱动程序需要在启动时正确加载,否则 DTS 将传感器设置为“禁用”。
另一方面,我基于 ov5647 的 ov5648 官方 allwinner 驱动程序的寄存器似乎完全错误! 它是一个 mipi 驱动程序,它修改相机中与并行 csi 相关的寄存器,完全是废话......我正在从头开始重写它。
//these register maps are completely wrong, even for the ov5648 for which this driver was originally written static struct regval_list sensor_qsxga_regs[] = { /*2592x1944 15fps 2 lane MIPI 420Mbps/lane */ {0x0100, 0x00}, //start software sleep {0x3501, 0x7b}, //exposure {0x2502, 0x00}, //unknown? {0x3708, 0x63}, //unknown? {0x3709, 0x12}, //unknown? {0x370c, 0xc0}, //unknown? {0x3800, 0x00}, //TIMING_X_ADDR_START {0x3801, 0x00}, //TIMING_X_ADDR_START {0x3802, 0x00}, //TIMING_Y_ADDR_START {0x3803, 0x00}, //TIMING_Y_ADDR_START {0x3804, 0x0a}, //TIMING_X_ADDR_END {0x3805, 0x3f}, //TIMING_X_ADDR_END {0x3806, 0x07}, //TIMING_Y_ADDR_END {0x3807, 0xa3}, //TIMING_Y_ADDR_END {0x3808, 0x0a}, //TIMING_X_OUTPUT_SIZE {0x3809, 0x20}, //TIMING_X_OUTPUT_SIZE {0x380a, 0x07}, //TIMING_Y_OUTPUT_SIZE {0x380b, 0x98}, //TIMING_Y_OUTPUT_SIZE {0x380c, 0x0b}, //TIMING_HTS {0x380d, 0x00}, //TIMING_HTS {0x380e, 0x07}, //TIMING_VTS {0x380f, 0xc0}, //TIMING_VTS {0x3810, 0x00}, //TIMING_ISP_X_WIN {0x3811, 0x10}, //TIMING_ISP_X_WIN {0x3812, 0x00}, //TIMING_ISP_Y_WIN {0x3813, 0x06}, //TIMING_ISP_Y_WIN {0x3814, 0x11}, //TIMING_X_INC {0x3815, 0x11}, //TIMING_Y_INC //TIMING_HSYNCST is missing?? {0x3817, 0x00}, //TIMING_HSYNCST {0x3820, 0x40}, //TIMING_TC_REG20 {0x3821, 0x06}, //TIMING_TC_REG21 {0x4004, 0x04}, //BLC CTRL04 {0x4005, 0x1a}, //BLC CTRL05 {0x350b, 0x40}, //AGC (gain) {0x4837, 0x17}, //PCLK_PERIOD {0x0100, 0x01}, //end software sleep };
-
@kanken6174 在 V851S tina linux ov5647 驱动程序没有 dmesg 中说:
我正在从头开始重写它。
你好
当我在 linux 中开发传感器驱动程序时,我使用特殊代码将 ioctl 添加到 V4l2 驱动程序、VIN 驱动程序和传感器驱动程序中。
此 ioctl 用于直接从用户空间写入和读取传感器寄存器。 这种方法大大加快了开发速度, 因为从用户程序测试传感器寄存器编程的各种选项比从驱动程序测试要容易得多。 -
@alb702 这是个好建议,我可能会这样做,因为传感器由于某种原因仍然没有发送其 mipi 帧......它至少会让调试更容易
-
ov5647 这个型号的摄像头并没有适配,SDK也没有支持。
请参考V85x的摄像头支持手册选择适配的摄像头。这里推荐已经量产的产品使用的GC2063,GC2083,GC4663这三款摄像头,已经经过严格的测试与调试,可以达到最佳画质和分辨率
-
@awwwwa 我知道 OV5647 不支持开箱即用,我想通过修改内核中已有的 OV5648 驱动程序来为其制作一个驱动程序。 我在驱动程序中仔细设置了 I2C 上每个必需的寄存器,其方式类似于 linux 内核 6.1 驱动程序处理它的方式(因为 linux 6.1 内置了 0V5647 驱动程序)。
我按照 allwinner 提供的在 tina-linux 下移植相机的指南进行操作,我的驱动程序成功加载、发送相机配置并正确报告。 mipi-csi 时钟和数据通道上也有活动(但它们太快了,我无法正确调试),这表明相机确实对其新配置做出了反应。
现在我当然可以选择支持更好的 GC 相机,但这不是目标,我正在尝试在这个平台上支持 rapsberry pi 1.3 相机。 我这样做是因为许多廉价模块都采用这种 15 针外形尺寸,但 GC 系列相机很难找到这种格式。
接下来我可能会尝试 IMX219(树莓派相机 V2),因为当前的 4.9 内核中已经有它的驱动程序,但目前 OV5647 仍然超时与camerademo,并且没有太多关于应该采取的行动过程的信息 在这种情况下,请参见 PDF 的常见问题解答。
您认为有什么东西可能会破坏我的 allwinner Eyesee 框架方面的驱动程序吗? 我还必须考虑硬件不兼容的可能性,并验证我猜的所有 mipi 逻辑级别...
-
@kanken6174 我之前尝试移植过,可以使用这个帖子中的驱动测试
Porject Yosemite - 基于全志V853的开发板
https://bbs.aw-ol.com/topic/1389/share/41 -
@yuzukitsuru 感谢该驱动程序,但我之前已经尝试过但没有成功,它有很多问题(如果您在本文中引用 ov5647_mipi.c 驱动程序),例如:
- 设备ID和传感器名称错误:
#define SENSOR_NAME "ov5648_mipi" #define V4L2_IDENT_SENSOR 0x5648
应该
#define SENSOR_NAME "ov5647_mipi" #define V4L2_IDENT_SENSOR 0x5647
- 读取CHIP_ID的方式也是错误的,导致读取的是0x5657而不是0x5647
sensor_read(sd, 0x300A, &rdval); SENSOR_ID |= rdval; SENSOR_ID |= (rdval << 8); sensor_read(sd, 0x300B, &rdval); SENSOR_ID |= (rdval); sensor_print("V4L2_IDENT_SENSOR = 0x%x\n", SENSOR_ID);
应该
data_type rdval, rdval2; unsigned int SENSOR_ID = 0; printk(KERN_WARNING "entering sensor_detect\n"); sensor_read(sd, CHIP_ID_ADDR, &rdval); sensor_read(sd, CHIP_ID_ADDR_L, &rdval2); SENSOR_ID = (rdval << 8) | rdval2; sensor_print("V4L2_IDENT_SENSOR = 0x%x\n", SENSOR_ID);
- 检测时似乎根本没有给相机加电,所以它永远找不到它(我必须在 INIT 函数中添加对传感器电源的调用才能检测到我的)
static int sensor_init(struct v4l2_subdev *sd, u32 val) { int ret = 0; struct sensor_info *info = to_state(sd); printk(KERN_WARNING "entering sensor_init\n"); sensor_print("sensor_init\n"); sensor_power(sd, PWR_ON); //added
总体而言,这个驱动程序似乎是基于 OV5648.c 的,该驱动程序已经存在所有这些问题,您是否真的让它在某个时刻与 OV5647 一起工作,或者它只是一个草案?
-
我已经购买了树莓派相机模块 V2 (IMX219),我尝试使用提供的驱动程序模块,很明显它无法像现在一样工作。 我必须将通道设置更改为 2 通道和相应的寄存器,因为驱动程序默认配置为 4 通道 mipi csi 操作。
经过几次测试后,我遇到了同样的问题,camerademo 超时并且不保存任何帧。 正如您在日志中看到的那样,I2C 配置已完美发送,它与我发送的配置匹配,寄存器有意义,数据格式应为 RGB8 位。
root@TinaLinux:/# camerademo RGGB8 1280 720 30 bmp /tmp 5 [CAMERA]************************[ 106.325471] [imx219]entering sensor_power ********************************[ 106.332158] [imx219]entering sensor_power PWR_ON, pins: 1 0 ** [CAMERA]* [ 106.341204] [imx219]PWR_ON!100 * [CAMERA]* this is camera test. [ 106.355469] [VIN_ERR]imx219 cannot find the match sensor_helper * [CAMERA]* * [CAMERA]********[ 106.370358] [VIN_ERR]imx219 cannot find the match sensor_helper ********************************[ 106.377305] [VIN_ERR]imx219 cannot find the match sensor_helper ****************** [CAMERA]********************************************************** [CAMERA][ 106.394725] [VIN_ERR]imx219 cannot find the match sensor_helper open /dev/video0! [CAMERA]********************************************************** [CAMERA]********************************************************** [CAMERA] The path to data saving is /tmp. [CAMERA] The number of captured photos is 5. [CAMERA] sa[ 106.421709] [VIN_ERR]imx219 cannot find the match sensor_helper ve bmp format [ 106.442489] [imx219]entering sensor_power [ 106.446997] [imx219]entering sensor_power PWR_ON, pins: 1 0 [ 106.453243] [imx219]PWR_ON!100 [ 106.464759] [VIN_ERR]imx219 cannot find the match sensor_helper [ 106.479407] [VIN_ERR]imx219 cannot find the match sensor_helper [ 106.486050] [VIN_ERR]imx219 cannot find the match sensor_helper [ 106.500689] [VIN_ERR]imx219 cannot find the match sensor_helper [ 106.526778] [VIN_ERR]imx219 cannot find the match sensor_helper [ 106.546028] [imx219]IMX219 found: 0x19 [ 106.550783] [VIN_ERR]vin is not support this pixelformat [ 106.556950] [VIN_ERR]vin is not support this pixelformat [ 106.563035] [VIN_ERR]vin is not support this pixelformat [ 106.569236] [VIN_ERR]vin is not support this pixelformat [ 106.575351] [VIN_ERR]vin is not support this pixelformat [ 106.581437] [VIN_ERR]vin is not support this pixelformat [ 106.587540] [VIN_ERR]vin is not support this pixelformat [ 106.593920] [VIN_ERR]vin is not support this pixelformat [ 106.600029] [VIN_ERR]vin is not support this pixelformat [ 106.606125] [VIN_ERR]vin is not support this pixelformat [ 106.612205] [VIN_ERR]vin is not support this pixelformat [ 106.618370] [VIN_ERR]vin is not support this pixelformat [ 106.624458] [VIN_ERR]vin is not support this pixelformat [ 106.630563] [VIN_ERR]vin is not support this pixelformat [ 106.636660] [VIN_ERR]vin is not support this pixelformat [ 106.642741] [VIN_ERR]vin is not support this pixelformat [ 106.648841] [VIN_ERR]vin is not support this pixelformat [ 106.654949] [VIN_ERR]vin is not support this pixelformat [ 106.661031] [VIN_ERR]vin is not support this pixelformat [CAMERA]********************************************************[ 106.670585] [imx219]sensor_s_stream on = 1, 1280*720 31384142 ** [CAMERA] Using format parameters RGGB8. [CAMERA] camera pix[ 106.684056] [VIN_DEV_I2C]read from imx219 addr is 0x30eb, data is 0x0 elformat: RGGB8 [CAMERA] Resolu[ 106.692344] [VIN_DEV_I2C]read from imx219 addr is 0x30eb, data is 0x0 tion size : 1280 * 720 [CAMERA][ 106.702334] [VIN_DEV_I2C]read from imx219 addr is 0x300a, data is 0xff The photo save path is /tmp. [[ 106.712417] [VIN_DEV_I2C]read from imx219 addr is 0x300b, data is 0xff CAMERA] The number of photos tak[ 106.722584] [VIN_DEV_I2C]read from imx219 addr is 0x30eb, data is 0x0 en is 5. [ 106.732510] [VIN_DEV_I2C]read from imx219 addr is 0x30eb, data is 0x0 pid: 863, g_alloc_context = 0x2[ 106.742495] [VIN_DEV_I2C]read from imx219 addr is 0x114, data is 0x1 ecd0 [CAMERA] Camera capture f[ 106.752394] [VIN_DEV_I2C]read from imx219 addr is 0x128, data is 0x0 ramerate is 1/1 [CAMERA] VIDIOC[ 106.762271] [VIN_DEV_I2C]read from imx219 addr is 0x12a, data is 0x18 _S_FMT succeed [CAMERA] fmt.typ[ 106.772314] [VIN_DEV_I2C]read from imx219 addr is 0x12b, data is 0x0 e = 9 [CAMERA] fmt.fmt.pix_mp.w[ 106.782168] [VIN_DEV_I2C]read from imx219 addr is 0x160, data is 0x2 idth = 1280 [CAMERA] fmt.fmt.pi[ 106.792056] [VIN_DEV_I2C]read from imx219 addr is 0x161, data is 0x0 x_mp.height = 720 [CAMERA] fmt.[ 106.801948] [VIN_DEV_I2C]read from imx219 addr is 0x162, data is 0xd fmt.pix_mp.pixelformat = RGGB8 [ 106.811838] [VIN_DEV_I2C]read from imx219 addr is 0x163, data is 0xe8 [CAMERA] fmt.fmt.pix_mp.field = [ 106.821877] [VIN_DEV_I2C]read from imx219 addr is 0x164, data is 0x3 1 [ 106.831726] [VIN_DEV_I2C]read from imx219 addr is 0x165, data is 0xe8 [ 106.839218] [VIN_DEV_I2C]read from imx219 addr is 0x166, data is 0x8 [ 106.846610] [VIN_DEV_I2C]read from imx219 addr is 0x167, data is 0xe7 [ 106.854086] [VIN_DEV_I2C]read from imx219 addr is 0x168, data is 0x3 [ 106.861477] [VIN_DEV_I2C]read from imx219 addr is 0x169, data is 0x68 [ 106.869015] [VIN_DEV_I2C]read from imx219 addr is 0x16a, data is 0x6 [ 106.876410] [VIN_DEV_I2C]read from imx219 addr is 0x16b, data is 0x37 [ 106.883888] [VIN_DEV_I2C]read from imx219 addr is 0x16c, data is 0x5 [ 106.891284] [VIN_DEV_I2C]read from imx219 addr is 0x16d, data is 0x0 [ 106.898679] [VIN_DEV_I2C]read from imx219 addr is 0x16e, data is 0x2 [ 106.906067] [VIN_DEV_I2C]read from imx219 addr is 0x16f, data is 0xd0 [ 106.913540] [VIN_DEV_I2C]read from imx219 addr is 0x170, data is 0x1 [ 106.920972] [VIN_DEV_I2C]read from imx219 addr is 0x171, data is 0x1 [ 106.928369] [VIN_DEV_I2C]read from imx219 addr is 0x174, data is 0x0 [ 106.935760] [VIN_DEV_I2C]read from imx219 addr is 0x175, data is 0x0 [ 106.943138] [VIN_DEV_I2C]read from imx219 addr is 0x18c, data is 0xa [ 106.950531] [VIN_DEV_I2C]read from imx219 addr is 0x18d, data is 0xa [ 106.957922] [VIN_DEV_I2C]read from imx219 addr is 0x301, data is 0x5 [ 106.965353] [VIN_DEV_I2C]read from imx219 addr is 0x303, data is 0x1 [ 106.972733] [VIN_DEV_I2C]read from imx219 addr is 0x304, data is 0x3 [ 106.980134] [VIN_DEV_I2C]read from imx219 addr is 0x305, data is 0x3 [ 106.987531] [VIN_DEV_I2C]read from imx219 addr is 0x306, data is 0x0 [ 106.994916] [VIN_DEV_I2C]read from imx219 addr is 0x307, data is 0x57 [ 107.002397] [VIN_DEV_I2C]read from imx219 addr is 0x309, data is 0x5 [ 107.009786] [VIN_DEV_I2C]read from imx219 addr is 0x30b, data is 0x1 [ 107.017220] [VIN_DEV_I2C]read from imx219 addr is 0x30c, data is 0x0 [ 107.024601] [VIN_DEV_I2C]read from imx219 addr is 0x30d, data is 0x5a [ 107.032102] [VIN_DEV_I2C]read from imx219 addr is 0x100, data is 0x1 [ 107.043636] [imx219]s_fmt set width = 1280, height = 720 [CAMERA] stream on succeed [CAMERA] camera0 capture num is [0] [CAMERA_ERR] camera0[ 109.053436] [imx219]sensor_s_stream on = 0, 1280*720 31384142 select timeout,end capture thread! [CAMERA] Capture thread finish [CAMERA] close /dev/video0 [CAMERA_ERR] capture_photo return error root@TinaLinux:/#
目前,要么是我的内核配置有问题,要么是我的 mipi 线路上的主板出现硬件问题……但这两者似乎都不明显,对于如此低的数据速率,我的路由应该“足够好”。
这些“VIN 格式不支持”错误也很奇怪,因为我似乎使用了正确的格式。
我附上了我的IMX219.C驱动程序的修改版本,如果有人想看一下,我现在唯一尝试支持的设置是720P。
imx219.c
ov5647_mipi.c我还附上了主板的完整启动日志,有很多启动错误,但我怀疑它们实际上与当前问题有关,因为所有必需的模块都已加载。
也许有人能够发现我错过的明显的东西......
-
这是启动日志:
boot.log -
@kanken6174 在 V851S tina linux ov5647 驱动程序没有 dmesg 中说:
VIN_ERR
错误
[ 106.661031] [VIN_ERR]vin is not support this pixelformat
表示 VIN 驱动程序不支持为此传感器模式设置的像素格式
确保具有此名称的格式已在 VIN 驱动程序源中列出
-
@alb702 我在驱动程序源代码和camerademo命令中尝试了许多不同的像素格式,但它总是最终无法实际工作并给出某种形式的错误。 除了 RGGB8 之外,相机不支持其他格式,当我使用 RGGB8 时,camerademo 会查询传感器的图像,这意味着它至少可以工作到那时。
然后等待帧返回超时,我仍在尝试理解原因,但显然存在相机配置方式或 allwinner 驱动程序期望如何接收帧的问题。如果这是图像格式的问题,我不会收到这种特定类型的错误:
-
@kanken6174 你好,请问这个问题解决了吗?我在添加调试OV9734的摄像头驱动也遇到了这个问题?请问有什么调试的思路吗?
-
@j_biao 目前我还无法让它发挥作用,我仍然停留在与以前相同的位置。 我购买了一台高速逻辑分析仪来尝试看看 mipi 总线上发生了什么。
看起来 mipi 通道的行为根本不像 mipi 通道,这看起来像并行 csi 数据(如果有的话)(时钟通道应该是不同的,但它们不是?)...这很奇怪,因为我仔细检查了两次和三次 我的 i2c/CCI 配置和所有正确的配置应发送到 OV5647 以进入 mipi 模式,而不是并行 csi 模式。
我将尝试获取树莓派 3 来调试它如何设置相机并查看 I2C 和 MIPI 方面的任何差异。
Copyright © 2023 深圳全志在线有限公司 粤ICP备2021084185号 粤公网安备44030502007680号