这绝对是一种奇怪的锁定官方图像的方式......尤其是对于那些不流利中文的人 X')
感谢这篇文章,它有帮助。
大家好,
我是一名嵌入式系统的学生(来自法国),我正在围绕 V851S 制作这个小板。 它应该用于连接树莓派相机或 esp32-cam 相机,并使用 usb-uvc 将它们用作 USB 网络摄像头。
该项目仍处于早期阶段,我是这个论坛的新手,所以我想我只是将其作为介绍发布。
以下是该板的一些图片:
大家好,
我已经使用 yukilizard 项目的 BSP 以及 tina-V853 存储库成功为 V851S 构建了映像。 但现在我想为 V851S 构建 GCC。 当我在 Developpement->GCC 中启用该选项(它自己启用其他选项)并且我“make”时,它编译得很好,直到到达 GCC,此时我遇到了此错误:
make menuconfig options
error
有谁知道我如何/是否可以解决这个问题?
大家好,
我的 V851S (tina-linux) 上的 i2c/twi 总线似乎有问题,每次我尝试使用 i2cdump 或 i2cDetect 等 shell i2C 实用程序时,我都会收到以下错误 (i2cget 和 i2cwrite 也会发生这种情况):
root@TinaLinux:/sys/devices/platform/soc/pio/gpiochip0/gpio/gpio8# i2cdetect 1
[ 786.358195] i2c i2c-1: ioctl, cmd=0x705, arg=0xbea72c6c
i2cdetect: WARNING! This program can confuse your I2C bus
Continue? [y/N] y
0 1 2 3 4 5 6 7 8 [ 789.513384] i2c i2c-1: ioctl, cmd=0x703, arg=0x03
9 a b c d e f
00: [ 789.521510] i2c i2c-1: ioctl, cmd=0x720, arg=0xbea72c4c
[ 789.530134] i2c i2c-1: master_xfer[0] W, addr=0x03, len=0
[ 789.536525] twi_start()508 - [i2c1] START can't sendout!
[ 789.542553] sunxi_i2c_do_xfer()1951 - [i2c1] twi_regulator:
[ 789.549191] twi_start()508 - [i2c1] START can't sendout!
[ 789.555137] sunxi_i2c_do_xfer()1951 - [i2c1] twi_regulator:
[ 789.561763] twi_start()508 - [i2c1] START can't sendout!
[ 789.567722] sunxi_i2c_do_xfer()1951 - [i2c1] twi_regulator:
-- [ 789.574219] i2c i2c-1: ioctl, cmd=0x703, arg=0x04
[ 789.579759] i2c i2c-1: ioctl, cmd=0x720, arg=0xbea72c4c
[ 789.585615] i2c i2c-1: master_xfer[0] W, addr=0x04, len=0
[ 789.591919] twi_start()508 - [i2c1] START can't sendout!
[ 789.597882] sunxi_i2c_do_xfer()1951 - [i2c1] twi_regulator:
[ 789.604494] twi_start()508 - [i2c1] START can't sendout!
[ 789.610452] sunxi_i2c_do_xfer()1951 - [i2c1] twi_regulator:
[ 789.617068] twi_start()508 - [i2c1] START can't sendout!
[ 789.623016] sunxi_i2c_do_xfer()1951 - [i2c1] twi_regulator:
-- [ 789.629512] i2c i2c-1: ioctl, cmd=0x703, arg=0x05
[ 789.635030] i2c i2c-1: ioctl, cmd=0x720, arg=0xbea72c4c
[ 789.640964] i2c i2c-1: master_xfer[0] W, addr=0x05, len=0
[ 789.647206] twi_start()508 - [i2c1] START can't sendout!
[ 789.653155] sunxi_i2c_do_xfer()1951 - [i2c1] twi_regulator:
[ 789.659783] twi_start()508 - [i2c1] START can't sendout!
[ 789.665728] sunxi_i2c_do_xfer()1951 - [i2c1] twi_regulator:
[ 789.672352] twi_start()508 - [i2c1] START can't sendout!
[ 789.678309] sunxi_i2c_do_xfer()1951 - [i2c1] twi_regulator:
这是我的 I2C 内核配置:
和我的 i2c“menuconfig”:
我知道至少已经有一篇关于此问题的帖子,但这只是一条警告消息,在我的情况下,它无法正常工作,因为我在 I2C 1 的地址 0x36 上有一个未检测到的设备。
我怎样才能摆脱这些错误?
我的 twi DTS 配置如下:
twi0_pins_a: twi0@0 {
allwinner,pins = "PA16", "PA17";
allwinner,pname = "twi0_scl", "twi0_sda";
allwinner,function = "twi0";
allwinner,muxsel = <4>;
allwinner,drive = <0>;
allwinner,pull = <1>;
};
twi0_pins_b: twi0@1 {
allwinner,pins = "PA16", "PA17";
allwinner,function = "io_disabled";
allwinner,muxsel = <0xf>;
allwinner,drive = <0>;
allwinner,pull = <0>;
};
twi1_pins_a: twi1@0 {
allwinner,pins = "PA6", "PA7";
allwinner,pname = "twi1_scl", "twi1_sda";
allwinner,function = "twi1";
allwinner,muxsel = <4>;
allwinner,drive = <0>;
allwinner,pull = <1>;
};
twi1_pins_b: twi1@1 {
allwinner,pins = "PA6", "PA7";
allwinner,function = "io_disabled";
allwinner,muxsel = <0xf>;
allwinner,drive = <0>;
allwinner,pull = <0>;
};
twi2_pins_a: twi2@0 {
allwinner,pins = "PH11", "PH12";
allwinner,pname = "twi2_scl", "twi2_sda";
allwinner,function = "twi2";
allwinner,muxsel = <5>;
allwinner,drive = <0>;
allwinner,pull = <1>;
};
twi2_pins_b: twi2@1 {
allwinner,pins = "PH11", "PH12";
allwinner,function = "io_disabled";
allwinner,muxsel = <0xf>;
allwinner,drive = <0>;
allwinner,pull = <0>;
};
twi3_pins_a: twi3@0 {
allwinner,pins = "PI3", "PI4";
allwinner,pname = "twi3_scl", "twi3_sda";
allwinner,function = "twi6";
allwinner,muxsel = <6>;
allwinner,drive = <0>;
allwinner,pull = <1>;
};
twi3_pins_b: twi3@1 {
allwinner,pins = "PI3", "PI4";
allwinner,function = "io_disabled";//io_disabled
allwinner,muxsel = <0xf>;
allwinner,drive = <0>;
allwinner,pull = <0>;
};
twi4_pins_a: twi4@0 {
allwinner,pins = "PI1", "PI2";
allwinner,pname = "twi4_scl", "twi4_sda";
allwinner,function = "twi4";
allwinner,muxsel = <5>;
allwinner,drive = <0>;
allwinner,pull = <1>;
};
twi4_pins_b: twi4@1 {
allwinner,pins = "PI1", "PI2";
allwinner,function = "io_disabled";
allwinner,muxsel = <0xf>;
allwinner,drive = <0>;
allwinner,pull = <0>;
};
大家好,我目前正在为 V851S 构建映像,并且我总是在“make”期间看到弹出这些警告:
Check Vendor Package...
CreateSoftLink /home/kanken/code/tina-v853-open/openwrt/openwrt/package/subpackage link to /home/kanken/code/tina-v853-open/openwrt/package
end
WARNING: Makefile 'package/subpackage/thirdparty/multimedia/gstreamer/gst1-libav/Makefile' has a build dependency on 'libgstreamer1', which does not exist
WARNING: Makefile 'package/subpackage/thirdparty/multimedia/gstreamer/gst1-libav/Makefile' has a build dependency on 'gstreamer1-plugins-base', which does not exist
WARNING: Makefile 'package/subpackage/thirdparty/multimedia/gstreamer/gst1-omx/Makefile' has a dependency on 'libgst1gl', which does not exist
WARNING: Makefile 'package/subpackage/thirdparty/multimedia/gstreamer/gst1-plugins-aw/Makefile' has a build dependency on 'libgstreamer1', which does not exist
WARNING: Makefile 'package/subpackage/thirdparty/multimedia/gstreamer/gst1-plugins-aw/Makefile' has a build dependency on 'gstreamer1-plugins-base', which does not exist
WARNING: Makefile 'package/subpackage/thirdparty/multimedia/gstreamer/gst1-plugins-aw/Makefile' has a build dependency on 'gstreamer1-plugins-good', which does not exist
WARNING: Makefile 'package/subpackage/thirdparty/multimedia/gstreamer/gst1-plugins-bad/Makefile' has a dependency on 'wayland', which does not exist
WARNING: Makefile 'package/subpackage/thirdparty/multimedia/gstreamer/gst1-plugins-bad/Makefile' has a dependency on 'wayland-protocols', which does not exist
WARNING: Makefile 'package/subpackage/thirdparty/multimedia/gstreamer/gst1-plugins-bad/Makefile' has a dependency on 'libgst1badvideo', which does not exist
WARNING: Makefile 'package/subpackage/thirdparty/multimedia/gstreamer/gst1-plugins-bad/Makefile' has a dependency on 'libgst1gl', which does not exist
WARNING: Makefile 'package/subpackage/thirdparty/multimedia/gstreamer/gst1-plugins-bad/Makefile' has a build dependency on 'libgstreamer1', which does not exist
WARNING: Makefile 'package/subpackage/thirdparty/multimedia/gstreamer/gst1-plugins-bad/Makefile' has a build dependency on 'gstreamer1-plugins-base', which does not exist
WARNING: Makefile 'package/subpackage/thirdparty/multimedia/gstreamer/gst1-plugins-base/Makefile' has a build dependency on 'libgstreamer1', which does not exist
WARNING: Makefile 'package/subpackage/thirdparty/multimedia/gstreamer/gst1-plugins-good/Makefile' has a build dependency on 'libgstreamer1', which does not exist
WARNING: Makefile 'package/subpackage/thirdparty/multimedia/gstreamer/gst1-plugins-good/Makefile' has a build dependency on 'gstreamer1-plugins-base', which does not exist
WARNING: Makefile 'package/subpackage/thirdparty/multimedia/gstreamer/gst1-plugins-ugly/Makefile' has a build dependency on 'libgstreamer1', which does not exist
WARNING: Makefile 'package/subpackage/thirdparty/multimedia/gstreamer/gst1-plugins-ugly/Makefile' has a build dependency on 'gstreamer1-plugins-base', which does not exist
WARNING: Makefile 'package/kernel/linux/Makefile' has a dependency on 'kmod-sunxi-rf-wlan', which does not exist
WARNING: Makefile 'package/subpackage/allwinner/eyesee-mpp/middleware/Makefile' has a dependency on 'awsystrace', which does not exist
WARNING: Makefile 'package/subpackage/thirdparty/gui/qt/qt5/Makefile' has a dependency on 'weston', which does not exist
WARNING: Makefile 'package/subpackage/thirdparty/gui/qt/qt5/Makefile' has a dependency on 'wayland', which does not exist
WARNING: Makefile 'package/subpackage/thirdparty/gui/qt/qt5/Makefile' has a dependency on 'qt5-multimediawidgets', which does not exist
WARNING: Makefile 'package/subpackage/thirdparty/gui/qt/qt5/Makefile' has a build dependency on 'libstdcpp', which does not exist
copy from /home/kanken/code/tina-v853-open/openwrt/target/v851s/v851s-lizard/defconfig
它们引用了我已经安装在我的电脑上的软件包,但它们不会消失,这是正常的还是我错过了这里的一个步骤?我应该忽略这些警告吗?
事实证明 .ko 文件确实是由“make”命令构建的,但它们只是没有被发送到图像:
为了能够将它们包含在图像中,我必须编辑 openwrt/target/v851S/<board_name> 中的文件:
添加我需要的各种 ov 驱动程序并注释掉我不需要的 gc2053 驱动程序
这仍然有点奇怪,这不是自动配置的,需要您手动编辑这些 makefile...感觉很笨重
大家好,
在修复了我的 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
};
@bardi4567 repo init -u https://sdk.aw-ol.com/git_repo/V853Tina_Open/manifest.git -b master -m tina-v853-open.xml
然后
repo sync
非常适合我,要么您的存储库配置不正确,要么您有一些文件权限问题,无论哪种方式,您都应该为您的问题创建一个单独的主题,因为它与本主题(tinyvision 开发板)无关!
大家好,
当我在 kernel_menuconfig 中将 OV5640 和 OV5658 驱动程序设置为编译为模块 (M) 时(并且禁用 gc_2053):
我编辑 DTS 以反映更改:
并编译/运行,似乎没有考虑到更改。 menuconfig 中的其他更改确实适用于图像,但 kernel_menuconfig 中完成的某些更改则不然。 看这里,gc_2053 驱动程序仍然处于活动状态,而 OV 驱动程序却不见踪影:
知道为什么会出现这种情况吗?
大家好,
我一直在尝试实现自己的基于 H616 的模块,并且一直想知道 SOC 工作是否确实需要 APX313A PMIC,我可以使用多个“哑”DC-DC 来代替吗? 这个 PMIC 很难从中国以外的地方采购,所以如果我可以不用它,那将会有所帮助。
@allspace123 不,我没有,我得到的只是黑屏和几条绿线,我放弃了并使用了 GC2053。 我也几乎放弃了 V851S 作为 mipi-csi 转 USB 平台,因为我无法让视频编码器工作,尽管社区已经以某种方式使其能够在 V851SE 上工作。 没有办法获得V851SE芯片,所以我的项目目前陷入困境。
您可以在此 github 页面上找到我对驱动程序的失败尝试。
https://github.com/Kanken6174/V851S-OV5647
@YuzukiTsuru 我无法让它在 V851S 上工作,你所说的 “替换 rootfs” 到底是什么意思?(我不小心错误地将这条消息发送到您的另一篇帖子,对此表示抱歉)
@YuzukiTsuru 我无法让它在 V851S 上工作,你所说的 “替换 rootfs” 到底是什么意思?
@bardi4567 repo init -u https://sdk.aw-ol.com/git_repo/V853Tina_Open/manifest.git -b master -m tina-v853-open.xml
然后
repo sync
非常适合我,要么您的存储库配置不正确,要么您有一些文件权限问题,无论哪种方式,您都应该为您的问题创建一个单独的主题,因为它与本主题(tinyvision 开发板)无关!
@yuzukitsuru 您是说,如果我只是覆盖适用于 V851S 的 .img 文件的 squashfs 分区,它将与您提供的 V851SE 特定 iamge 文件一起使用? 因为我尝试过,它导致了内核恐慌...
[ 3.507007] sunxi-mmc sdc1: sdc set ios:clk 0Hz bm PP pm OFF vdd 0 width 1 timing LEGACY(SDR12) dt B
[ 3.618963] remoteproc0: Direct firmware load for melis-elf failed with error -2
[ 3.629611] get det_vbus is fail, 84
[ 3.634517] get id is fail, 84
[ 3.639115] sunxi-rtc rtc: setting system clock to 1970-01-01 00:01:42 UTC (102)
[ 3.648833] clk: Not disabling unused clocks
[ 3.653760] ALSA device list:
[ 3.657088] #0: audiocodec
[ 3.660466] #1: snddaudio0
[ 3.670653] VFS: Mounted root (squashfs filesystem) readonly on device 179:4.
[ 3.682504] devtmpfs: mounted
[ 3.687970] Freeing unused kernel memory: 1024K
[ 3.693329] will run init ...
[ 3.696755] Kernel panic - not syncing: Requested init /init failed (error -2).
[ 3.704937] CPU: 0 PID: 1 Comm: swapper Not tainted 4.9.191 #1
[ 3.711457] Hardware name: sun8iw21
[ 3.715390] [<c010d5a0>] (unwind_backtrace) from [<c010a694>] (show_stack+0x10/0x14)
[ 3.724060] [<c010a694>] (show_stack) from [<c017050c>] (panic+0xac/0x2b8)
[ 3.731758] [<c017050c>] (panic) from [<c0680854>] (kernel_init+0x98/0x118)
[ 3.739553] [<c0680854>] (kernel_init) from [<c0106e08>] (ret_from_fork+0x14/0x2c)
[ 3.748027] ---[ end Kernel panic - not syncing: Requested init /init failed (error -2).
[ 3.757074] sunxi dump enabled
[ 3.760484] dump regs done
[ 3.763544] flush cache done
[ 3.766782] crashdump enter
该映像是使用默认设置 (squashfs) 的 yuzukilizard BSP/openwrt 从默认的 V853 sdk 编译的(按原样使用时有效),我使用该命令来替换 rootfs squashfs:
sudo dd if=/dev/sdf4 of=/dev/sdi4 bs=4M conv=fsync
或者这不是您所说的“替换rootfs”的意思?
@yuzukitsuru 这是一块非常好的板,您认为这个版本的 SDK 可以适应在 V851S(非 SE)上以同样的方式工作吗?
@YuzukiTsuru 非常好的项目,这正是我一直在努力实现的目标,您使用的是 NDA 下的专有 sdk,而不是开源 tina linux sdk,不是吗? 否则你如何让视频编码器工作?
@awwwwa 感谢您的链接,这是一个有趣的解决方案,非常接近我想要实现的目标,我相信这使用了专有的闭源 tina-os,对吧? 但由于这只是一个磁盘映像而不是开源的,我无法真正使用它,特别是因为它是用于 V851SE 而不是 V851S...我想在芯片上实现我自己的驱动程序和图像处理方法,从什么 我知道这需要 NDA 下的专有 sdk...