一、攝像頭平臺(tái)層? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ??
drivers\media\video\mxc\capture\mxc_v4l2_capture.c
module_init(camera_init);
隨后,進(jìn)行加載下一個(gè)驅(qū)動(dòng),如果遇到攝像頭設(shè)備層對(duì)應(yīng)驅(qū)動(dòng),舉例adv7180解碼芯片
drivers\media\video\mxc\capture\adv7180.c
module_init(adv7180_init);
static __init int?adv7180_init(void)
{
? u8 err = i2c_add_driver(&adv7180_i2c_driver);
return err;
}
static struct i2c_driver?adv7180_i2c_driver?= {
? .driver = {
???? .owner = THIS_MODULE,
???? .name = "adv7180",
???? },
? .probe = adv7180_probe,
? .remove = adv7180_detach,
? .id_table =?adv7180_id,
};
static __init int?camera_init(void)
{
u8 err = platform_driver_register(&mxc_v4l2_driver);//將mxc_v4l2_driver這個(gè)驅(qū)動(dòng)注冊(cè)到platform平臺(tái)上面,如果有匹配的設(shè)備的話,就會(huì)調(diào)用到mxc_v4l2_driver里面的probe函數(shù)
return err;
}
static struct platform_driver?mxc_v4l2_driver?= {
? .driver = {
???? .name = "mxc_v4l2_capture",
???? },
? .probe =?mxc_v4l2_probe,
? .remove = mxc_v4l2_remove,
? .suspend = mxc_v4l2_suspend,
? .resume = mxc_v4l2_resume,
? .shutdown = NULL,
};
/*
*struct?platform_device?{
?*??const char?* name;
?*??int??id;
?*??struct device?dev;
?*??u32??num_resources;
?*??struct resource?* resource;
?*??const struct platform_device_id?*id_entry;
?*??struct mfd_cell *mfd_cell;
?*??struct pdev_archdata?archdata;
?*};
*/
static int?mxc_v4l2_probe(struct?platform_device?*pdev)
{
...
cam_data *cam = kmalloc(sizeof(cam_data), GFP_KERNEL);
init_camera_struct(cam, pdev);//初始化cam_data結(jié)構(gòu)體
v4l2_int_device_register(cam->self);
...
}
/*私有數(shù)據(jù)的結(jié)構(gòu)體關(guān)系
*struct cam_data??????? drivers\media\video\mxc\capture\mxc_v4l2_capture.h
?*->struct video_device????? include\media\v4l2-dev.h?
?*?? ->struct device include\linux\device.h
?*???? ->struct device_private???drivers\base\base.h
?*?????? ->void *driver_data;
*/
static void?init_camera_struct(cam_data *cam, struct platform_device *pdev)
{
...
cam->video_dev = video_device_alloc();//分配一個(gè)video_device結(jié)構(gòu)體
*(cam->video_dev) = mxc_v4l_template;//設(shè)置ops操作->v4l2_file_operations->mxc_v4l_ioctl->mxc_v4l_do_ioctl->VIDIOC_*_IOCTL:{...}
video_set_drvdata(cam->video_dev, cam);//將cam設(shè)置為cam->video_dev的私有數(shù)據(jù)->dev_set_drvdata ->?dev->p->driver_data = data;
cam->crop_bounds.left = 0;????? //這里只是初始化crop參數(shù)默認(rèn)值
cam->crop_bounds.width = 640;
cam->crop_bounds.top = 0;
cam->crop_bounds.height = 480;
cam->crop_current = cam->crop_defrect = cam->crop_bounds;
cam->enc_callback = camera_callback;
cam->self = kmalloc(sizeof(struct v4l2_int_device), GFP_KERNEL);
cam->self->module = THIS_MODULE;
cam->self->type = v4l2_int_type_master;
cam->self->u.master = &mxc_v4l2_master;//后面會(huì)調(diào)用
...
}
int?v4l2_int_device_register(struct v4l2_int_device *d)
{
? ...
v4l2_int_device_try_attach_all();
...
}
void?v4l2_int_device_try_attach_all(void)
{
struct v4l2_int_device *m, *s;
list_for_each_entry(m, &int_list, head)?
{
if (m->type != v4l2_int_type_master) continue;//從int_list鏈表中取出type類(lèi)型為v4l2_int_type_master的結(jié)構(gòu)體保存在m中
list_for_each_entry(s, &int_list, head)?
{
if (s->type != v4l2_int_type_slave)continue;//從int_list鏈表中取出type類(lèi)型為v4l2_int_type_slave的結(jié)構(gòu)體保存在s中
if (s->u.slave->master)continue;//如果存在s->u.slave->master則跳過(guò)繼續(xù)尋找
s->u.slave->master = m;//找到master設(shè)備和第一個(gè)沒(méi)有設(shè)置master的slave設(shè)備,并將從設(shè)備的master設(shè)置為找到的master
if (m->u.master->attach(s))//調(diào)用m的u.master->atach(s)函數(shù),即cam->self->u.master = &mxc_v4l2_master;設(shè)置的函數(shù)
{
...
}
}
}
}
static struct v4l2_int_master?mxc_v4l2_master?= {
.attach =?mxc_v4l2_master_attach,
.detach = mxc_v4l2_master_detach,
};
static int?mxc_v4l2_master_attach(struct v4l2_int_device *slave)
{
...
cam->crop_bounds.top = cam->crop_bounds.left = 0;//crop參數(shù)都是根據(jù)slave結(jié)構(gòu)體來(lái)設(shè)置的,這里是根據(jù)真正slave設(shè)備中獲取到的參數(shù)來(lái)填充crop參數(shù)
? cam->crop_bounds.width = cam_fmt.fmt.pix.width;
? cam->crop_bounds.height = cam_fmt.fmt.pix.height;
cam->crop_defrect.top = cam->crop_defrect.left = 0;
?cam->crop_defrect.width = cam_fmt.fmt.pix.width;
? cam->crop_defrect.height = cam_fmt.fmt.pix.height;
cam->crop_current.top = cam->crop_current.left = 0;
? cam->crop_current.width = cam_fmt.fmt.pix.width;
? cam->crop_current.height = cam_fmt.fmt.pix.height;
...
}
?
評(píng)論
查看更多