static int __devinit cmos_ov7740_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
printk("%s %s %d\n", __FILE__, __FUNCTION__, __LINE__);
/* 2.3 硬件相关 */
/* 2.3.1 映射相应的寄存器 */
GPJCON = ioremap(0x560000d0, 4);
GPJDAT = ioremap(0x560000d4, 4);
GPJUP = ioremap(0x560000d8, 4);
CISRCFMT = ioremap(0x4F000000, 4);
CIWDOFST = ioremap(0x4F000004, 4);
CIGCTRL = ioremap(0x4F000008, 4);
CIPRCLRSA1 = ioremap(0x4F00006C, 4);
CIPRCLRSA2 = ioremap(0x4F000070, 4);
CIPRCLRSA3 = ioremap(0x4F000074, 4);
CIPRCLRSA4 = ioremap(0x4F000078, 4);
CIPRTRGFMT = ioremap(0x4F00007C, 4);
CIPRCTRL = ioremap(0x4F000080, 4);
CIPRSCPRERATIO = ioremap(0x4F000084, 4);
CIPRSCPREDST = ioremap(0x4F000088, 4);
CIPRSCCTRL = ioremap(0x4F00008C, 4);
CIPRTAREA = ioremap(0x4F000090, 4);
CIIMGCPT = ioremap(0x4F0000A0, 4);
SRCPND = ioremap(0X4A000000, 4);
INTPND = ioremap(0X4A000010, 4);
SUBSRCPND = ioremap(0X4A000018, 4);
/* 2.3.2 设置相应的GPIO用于CAMIF */
cmos_ov7740_gpio_cfg();
/* 2.3.3 复位一下CAMIF控制器 */
cmos_ov7740_camif_reset();
/* 2.3.4 设置、使能时钟(使能HCLK、使能并设置CAMCLK = 24MHz) */
cmos_ov7740_clk_cfg();
/* 2.3.5 复位一下摄像头模块 */
cmos_ov7740_reset();
/* 2.3.6 通过IIC总线,初始化摄像头模块 */
cmos_ov7740_client = client;
cmos_ov7740_init();
/* 2.3.7 注册中断 */
if (request_irq(IRQ_S3C2440_CAM_C, cmos_ov7740_camif_irq_c, IRQF_DISABLED , "CAM_C", NULL))
printk("%s:request_irq failed\n", __func__);
if (request_irq(IRQ_S3C2440_CAM_P, cmos_ov7740_camif_irq_p, IRQF_DISABLED , "CAM_P", NULL))
printk("%s:request_irq failed\n", __func__);
/* 2.2.注册 */
if(video_register_device(&cmos_ov7740_vdev, VFL_TYPE_GRABBER, -1))
{
printk("unable to register video device\n");
}
return 0;
}
static int __devexit cmos_ov7740_remove(struct i2c_client *client)
{
printk("%s %s %d\n", __FILE__, __FUNCTION__, __LINE__);
iounmap(GPJCON);
iounmap(GPJDAT);
iounmap(GPJUP);
iounmap(CISRCFMT);
iounmap(CIWDOFST);
iounmap(CIGCTRL);
iounmap(CIPRCLRSA1);
iounmap(CIPRCLRSA2);
iounmap(CIPRCLRSA3);
iounmap(CIPRCLRSA4);
iounmap(CIPRTRGFMT);
iounmap(CIPRCTRL);
iounmap(CIPRSCPRERATIO);
iounmap(CIPRSCPREDST);
iounmap(CIPRSCCTRL);
iounmap(CIPRTAREA);
iounmap(CIIMGCPT);
iounmap(SRCPND);
iounmap(INTPND);
iounmap(SUBSRCPND);
free_irq(IRQ_S3C2440_CAM_C, NULL);
free_irq(IRQ_S3C2440_CAM_P, NULL);
video_unregister_device(&cmos_ov7740_vdev);
return 0;
}
static const struct i2c_device_id cmos_ov7740_id_table[] = {
{ "cmos_ov7740", 0 },
{}
};
/* 1.1. 分配、设置一个i2c_driver */
static struct i2c_driver cmos_ov7740_driver = {
.driver = {
.name = "cmos_ov7740",
.owner = THIS_MODULE,
},
.probe = cmos_ov7740_probe,
.remove = __devexit_p(cmos_ov7740_remove),
.id_table = cmos_ov7740_id_table,
};
static int cmos_ov7740_drv_init(void)
{
/* 1.2.注册 */
i2c_add_driver(&cmos_ov7740_driver);
return 0;
}
static void cmos_ov7740_drv_exit(void)
{
i2c_del_driver(&cmos_ov7740_driver);
}
module_init(cmos_ov7740_drv_init);
module_exit(cmos_ov7740_drv_exit);
MODULE_LICENSE("GPL");
再附一段测试程序,对i2c设备的寄存器进行读写测试:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
/* i2c_test r addr
* i2c_test w addr val
*/
void print_usage(char *file)
{
printf("%s r addr\n", file);
printf("%s w addr val\n", file);
}