先贴代码:
#define OV965X_I2C_ADDR 0x60//0x5a
const static u16 ignore[] = { I2C_CLIENT_END };
const static u16 normal_addr[] = { (OV965X_I2C_ADDR >> 1), I2C_CLIENT_END };
const static u16 *forces[] = { NULL };
static struct i2c_driver ov965x_i2c_driver;
static struct s3c_fimc_camera ov965x_data = {
.id = CONFIG_VIDEO_FIMC_CAM_CH,
.type = CAM_TYPE_ITU,
.mode = ITU_601_YCBCR422_8BIT,
.order422 = CAM_ORDER422_8BIT_YCBYCR,//YCRYCB,
.clockrate = 24000000,
.width = 640,//800,
.height = 480,//600,
.offset = {
.h1 = 0,
.h2 = 0,
.v1 = 0,
.v2 = 0,
},
.polarity = {
.pclk = 0,
.vsync = 1,
.href = 0,
.hsync = 0,
},
.initialized = 0,
};
static struct i2c_client_address_data addr_data = {
.normal_i2c = normal_addr,
.probe = ignore,
.ignore = ignore,
.forces = forces,
};
static void ov965x_start(struct i2c_client *client)
{
int i;
//printk("[CAM] OV965X init reg start...\n");
for (i = 0; i < OV965X_INIT_REGS; i++) {
s3c_fimc_i2c_write(client, OV965X_init_reg.subaddr, \
OV965X_init_reg.value);
}
//printk("[CAM] OV965X init reg end.\n");
} static int ov965x_attach(struct i2c_adapter *adap, int addr, int kind)
{
struct i2c_client *c;
c = kmalloc(sizeof(*c), GFP_KERNEL);
if (!c)
return -ENOMEM;
memset(c, 0, sizeof(struct i2c_client));
strcpy(c->name, "ov965x");
c->addr = addr;
c->adapter = adap;
c->driver = &ov965x_i2c_driver;
ov965x_data.client = c;
info("OV965X attached successfully\n");
return i2c_attach_client(c);
}
static int ov965x_attach_adapter(struct i2c_adapter *adap)
{
int ret = 0;
//printk("[OV965X]ov965x_attach_adapter.\n");
s3c_fimc_register_camera(&ov965x_data);
ret = i2c_probe(adap, &addr_data, ov965x_attach);
if (ret) {
err("failed to attach ov965x driver\n");
ret = -ENODEV;
}
return ret;
}
static int ov965x_detach(struct i2c_client *client)
{
i2c_detach_client(client);
return 0;
}
static int ov965x_change_resolution(struct i2c_client *client, int res)
{
switch (res) {
case CAM_RES_DEFAULT: /* fall through */
case CAM_RES_MAX: /* fall through */
break;
default:
err("unexpect value\n");
}
return 0;
}
static int ov965x_change_whitebalance(struct i2c_client *client, enum s3c_fimc_wb_t type)
{
//s3c_fimc_i2c_write(client, 0xfc, 0x0);
//s3c_fimc_i2c_write(client, 0x30, type);
return 0;
}
static int ov965x_command(struct i2c_client *client, u32 cmd, void *arg)
{
switch (cmd) {
case I2C_CAM_INIT:
///s3c_fimc_reset_camera();
ov965x_start(client);
info("external camera initialized\n");
break;
case I2C_CAM_RESOLUTION:
ov965x_change_resolution(client, (int) arg);
break;
case I2C_CAM_WB:
ov965x_change_whitebalance(client, (enum s3c_fimc_wb_t) arg);
break;
default:
err("unexpect command\n");
break;
}
return 0;
}
static struct i2c_driver ov965x_i2c_driver = {
.driver = {
.name = "ov965x",
},
.id = I2C_DRIVERID_OV965X,
.attach_adapter = ov965x_attach_adapter,
.detach_client = ov965x_detach,
.command = ov965x_command,
};
static __init int ov965x_init(void)
{
return i2c_add_driver(&ov965x_i2c_driver);
}
static __init void ov965x_exit(void)
{
i2c_del_driver(&ov965x_i2c_driver);
}
module_init(ov965x_init)
module_exit(ov965x_exit)
小弟初学驱动,看了CMOS摄像头驱动,有许多不明白的地方,望各位前辈不吝啬指点一下。
1.红色代码部分实现了对OV9650寄存器的初始化,但是从头到尾没有看到哪里调用过这个函数,那么请问是如何实现对寄存器的复制的??
2.注册的
ov965x_command函数在哪里可以使用呢??3.为什么执行insmod ov9650.ko 后会生成/dev/video0节点呢,没有看到有video0相关的注册啊??谢谢大家了 熬夜发帖求助不容易啊,拜托大家了