1. 驱动初始化
在drivers/media/video/sp0a19.c中
device_initcall_sync(sp0a_mod_init);
-
static struct i2c_driver sp0a_i2c_driver = {
-
.driver = {
-
.name = SP0A_NAME_STRING(),
-
},
-
.probe = sp0a_probe,
-
.remove = sp0a_remove,
-
.id_table = sp0a_id,
-
};
-
-
static int __init sp0a_mod_init(void)
-
{
-
return i2c_add_driver(&sp0a_i2c_driver);
-
}
在probe函数中
-
static int sp0a_probe(struct i2c_client *client, const struct i2c_device_id *did)
-
{
-
struct sp0a *sp0a;
-
struct soc_camera_device *icd = client->dev.platform_data;
-
struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent);
-
struct soc_camera_link *icl;
-
-
icl = to_soc_camera_link(icd);
-
sp0a = kzalloc(sizeof(struct sp0a), GFP_KERNEL);
-
v4l2_i2c_subdev_init(&sp0a->subdev, client, &sp0a_subdev_ops);
-
icd->ops = &sp0a_ops;
-
sp0a->info_priv.fmt = sp0a_colour_fmts[0];
-
sp0a_video_probe(icd, client);
-
return ret;
-
}
函数指针的注册过程
v4l2_i2c_subdev_init
(&sp0a
->subdev
, client
, &sp0a_subdev_ops
);
-
static struct v4l2_subdev_core_ops sp0a_subdev_core_ops = {
-
.init = sp0a_init,
-
.g_ctrl = sp0a_g_control,
-
.s_ctrl = sp0a_s_control,
-
.g_ext_ctrls = sp0a_g_ext_controls,
-
.s_ext_ctrls = sp0a_s_ext_controls,
-
.g_chip_ident = sp0a_g_chip_ident,
-
.ioctl = sp0a_ioctl,
-
};
-
-
static struct v4l2_subdev_video_ops sp0a_subdev_video_ops = {
-
.s_mbus_fmt = sp0a_s_fmt,
-
.g_mbus_fmt = sp0a_g_fmt,
-
.try_mbus_fmt = sp0a_try_fmt,
-
.enum_mbus_fmt = sp0a_enum_fmt,
-
};
-
-
static struct v4l2_subdev_ops sp0a_subdev_ops = {
-
.core = &sp0a_subdev_core_ops,
-
.video = &sp0a_subdev_video_ops,
-
};
icd
->ops
= &sp0a_ops
;
-
static struct soc_camera_ops sp0a_ops =
-
{
-
.suspend = sp0a_suspend,
-
.resume = sp0a_resume,
-
.set_bus_param = sp0a_set_bus_param,
-
.query_bus_param = sp0a_query_bus_param,
-
.controls = sp0a_controls,
-
.menus = sp0a_menus,
-
.num_controls = ARRAY_SIZE(sp0a_controls),
-
.num_menus = ARRAY_SIZE(sp0a_menus),
-
};
-
static int sp0a_video_probe(struct soc_camera_device *icd, struct i2c_client *client)
-
{
-
char pid = 0;
-
int ret;
-
struct sp0a *sp0a = to_sp0a(client);
-
if ( g_bIsAtvStart )
-
{
-
return 0;
-
}
-
//.add power.sheng 2012.09.04
-
-
/* We must have a parent by now. And it cannot be a wrong one.
-
* So this entire test is completely redundant. */
-
if (!icd->dev.parent ||
-
to_soc_camera_host(icd->dev.parent)->nr != icd->iface)
-
return -ENODEV;
-
-
if (sp0a_ioctrl(icd, Sensor_PowerDown, 0) < 0) {
-
ret = -ENODEV;
-
goto sp0a_video_probe_err;
-
}
-
-
/* soft reset */
-
/* ret = sp0a_write(client, 0x12, 0x80);
-
if (ret != 0)
-
{
-
SP0A_TR("soft reset %s failed\n",SP0A_NAME_STRING());
-
return -ENODEV;
-
}
-
mdelay(50); *///delay 5 microseconds
-
-
/* check if it is an sp0a sp0a */
-
ret = sp0a_read(client, 0x02, &pid);
-
if (ret != 0) {
-
SP0A_TR("%s read chip id high byte failed\n",SP0A_NAME_STRING());
-
ret = -ENODEV;
-
goto sp0a_video_probe_err;
-
}
-
-
SP0A_DG("\n %s pid = 0x%x\n", SP0A_NAME_STRING(), pid);
-
if (pid == SP0A_ID) {
-
sp0a->model = SP0A_V4L2_IDENT;
-
} else {
-
SP0A_TR("error: %s mismatched pid = 0x%x\n", SP0A_NAME_STRING(), pid);
-
ret = -ENODEV;
-
goto sp0a_video_probe_err;
-
}
-
-
return 0;
-
-
sp0a_video_probe_err:
-
-
return ret;
-
}
阅读(2500) | 评论(0) | 转发(1) |