网络摄像头4 cmos 0v9650,driver
将ov9650的驱动编译进内核 Device Drivers ---> Multimedia support ---> OV9650 on the S3C2440 driver查看这项的help,可知符号Symbol: S3C2440_CAMERA [=y] 在目录/opt/FriendlyArm/mini2440/linux-2.6.32.2/driver
·
将ov9650的驱动编译进内核
Device Drivers ---> <*> Multimedia support ---> <*> OV9650 on the S3C2440 driver
查看这项的help,可知符号
Symbol: S3C2440_CAMERA [=y]
在目录/opt/FriendlyArm/mini2440/linux-2.6.32.2/drivers/media/video的Makefile里面找到以下2行
obj-$(CONFIG_S3C2440_CAMERA) += s3c2440camera.o
s3c2440camera-objs := s3c2440_ov9650.o sccb.o s3c2440camif.o
可见0v9650的驱动由3个c文件构成,如下
s3c2440camif.c
s3c2440_ov9650.c
sccb.c
还有两个h文件
s3c2440camif.h
sccb.h
(并且可如果编译成模块的话,生成s3c2440camera.ko)
其中
s3c2440camif.c用于从cmos接口获取图像数据和 将数据传输到进程空间(在有app读取时)。比如创建misc设备,设备名字是camera。在misc中仅实现3个方法open,read,release。没有ioctl(和mmap),所以在网络摄像头2里所看到的来自app的ioctl会失败。
s3c2440_ov9650.c 读取和配置ov9650寄存器。通过iic接口传输数据。设备地址是60(#define OV9650_SCCB_ADDR 0x60).比如进行初始化和product id获取.
sccb.c 定义了去读ov9650的寄存器的具体方法,是时序模拟的iic。而 s3c2440_ov9650.c里是调用这些具体方法去读写ov9650的寄存器的。
**************************************************************硬件连接******************************************
cmos ov9650的引脚
2440处理器cmos接口
用于传输ov9650的寄存器配置信息即工作参数,ov9650<--->2440
电源控制,ov9650<---2440
用户ov9650传输捕获的图像数据,ov9650--->2440
查看ov9650的spec可知其输出的数据格式
**************************************************************驱动分析****************************************************
Device Drivers ---> <*> Multimedia support ---> <*> OV9650 on the S3C2440 driver
查看这项的help,可知符号
Symbol: S3C2440_CAMERA [=y]
在目录/opt/FriendlyArm/mini2440/linux-2.6.32.2/drivers/media/video的Makefile里面找到以下2行
obj-$(CONFIG_S3C2440_CAMERA) += s3c2440camera.o
s3c2440camera-objs := s3c2440_ov9650.o sccb.o s3c2440camif.o
可见0v9650的驱动由3个c文件构成,如下
s3c2440camif.c
s3c2440_ov9650.c
sccb.c
还有两个h文件
s3c2440camif.h
sccb.h
(并且可如果编译成模块的话,生成s3c2440camera.ko)
其中
s3c2440camif.c用于从cmos接口获取图像数据和 将数据传输到进程空间(在有app读取时)。比如创建misc设备,设备名字是camera。在misc中仅实现3个方法open,read,release。没有ioctl(和mmap),所以在网络摄像头2里所看到的来自app的ioctl会失败。
s3c2440_ov9650.c 读取和配置ov9650寄存器。通过iic接口传输数据。设备地址是60(#define OV9650_SCCB_ADDR 0x60).比如进行初始化和product id获取.
sccb.c 定义了去读ov9650的寄存器的具体方法,是时序模拟的iic。而 s3c2440_ov9650.c里是调用这些具体方法去读写ov9650的寄存器的。
**************************************************************硬件连接******************************************
cmos ov9650的引脚
2440处理器cmos接口
用于传输ov9650的寄存器配置信息即工作参数,ov9650<--->2440
电源控制,ov9650<---2440
用户ov9650传输捕获的图像数据,ov9650--->2440
查看ov9650的spec可知其输出的数据格式
**************************************************************驱动分析****************************************************
/*
* camif_init()
*/
static int __init camif_init(void)
{
int ret;
struct s3c2440camif_dev * pdev;
struct clk * camif_upll_clk;
printk(KERN_ALERT"initializing s3c2440 camera interface......\n");
pdev = &camera;
/* set gpio-j to camera mode. */
s3c2410_gpio_cfgpin(S3C2440_GPJ0, S3C2440_GPJ0_CAMDATA0);
s3c2410_gpio_cfgpin(S3C2440_GPJ1, S3C2440_GPJ1_CAMDATA1);
s3c2410_gpio_cfgpin(S3C2440_GPJ2, S3C2440_GPJ2_CAMDATA2);
s3c2410_gpio_cfgpin(S3C2440_GPJ3, S3C2440_GPJ3_CAMDATA3);
s3c2410_gpio_cfgpin(S3C2440_GPJ4, S3C2440_GPJ4_CAMDATA4);
s3c2410_gpio_cfgpin(S3C2440_GPJ5, S3C2440_GPJ5_CAMDATA5);
s3c2410_gpio_cfgpin(S3C2440_GPJ6, S3C2440_GPJ6_CAMDATA6);
s3c2410_gpio_cfgpin(S3C2440_GPJ7, S3C2440_GPJ7_CAMDATA7);
s3c2410_gpio_cfgpin(S3C2440_GPJ8, S3C2440_GPJ8_CAMPCLK);
s3c2410_gpio_cfgpin(S3C2440_GPJ9, S3C2440_GPJ9_CAMVSYNC);
s3c2410_gpio_cfgpin(S3C2440_GPJ10, S3C2440_GPJ10_CAMHREF);
s3c2410_gpio_cfgpin(S3C2440_GPJ11, S3C2440_GPJ11_CAMCLKOUT);
s3c2410_gpio_cfgpin(S3C2440_GPJ12, S3C2440_GPJ12_CAMRESET);
/* init camera's virtual memory. */
if (!request_mem_region((unsigned long)S3C2440_PA_CAMIF, S3C2440_SZ_CAMIF, CARD_NAME))
{
ret = -EBUSY;
goto error1;
}
/* remap the virtual memory. */
camif_base_addr = (unsigned long)ioremap_nocache((unsigned long)S3C2440_PA_CAMIF, S3C2440_SZ_CAMIF);
if (camif_base_addr == (unsigned long)NULL)
{
ret = -EBUSY;
goto error2;
}
/* init camera clock. */
pdev->clk = clk_get(NULL, "camif");
if (IS_ERR(pdev->clk))
{
ret = -ENOENT;
goto error3;
}
clk_enable(pdev->clk);
camif_upll_clk = clk_get(NULL, "camif-upll");
clk_set_rate(camif_upll_clk, 24000000);
mdelay(100);
/* init reference counter and its mutex. */
mutex_init(&pdev->rcmutex);
pdev->rc = 0;
/* init image input source. */
pdev->input = 0;
/* init camif state and its lock. */
pdev->state = CAMIF_STATE_FREE;
/* init command code, command lock and the command wait queue. */
pdev->cmdcode = CAMIF_CMD_NONE;
init_waitqueue_head(&pdev->cmdqueue);
/* register to videodev layer. */
if (misc_register(&misc) < 0)
{
ret = -EBUSY;
goto error4;
}
printk(KERN_ALERT"s3c2440 camif init done\n");
sccb_init();
hw_reset_camif();
has_ov9650 = s3c2440_ov9650_init() >= 0;
s3c2410_gpio_setpin(S3C2410_GPG(4), 1);
return 0;
error4:
clk_put(pdev->clk);
error3:
iounmap((void *)camif_base_addr);
error2:
release_mem_region((unsigned long)S3C2440_PA_CAMIF, S3C2440_SZ_CAMIF);
error1:
return ret;
}
更多推荐
已为社区贡献3条内容
所有评论(0)