大家好,我是本期栏目编辑小友,现在为大家讲解Embeded linux之soc camera问题。
社会学摄像机子系统为分为社会学摄像机设备和社会学摄像机主机,并且定义了标准的接口或者回调函数。
流程:
1.获取传来信息,填充soc_camera_link
2.初始化soc_camera_device(iface、device),设备号、总线类型)、加入链表
3.
一、/Linux-3。0 .35/驱动程序/媒体/视频/soc_camera.c主要是用来管理接口或者回调函数。
module _ init(SOC _ camera _ init);
静态int __initsoc_camera_init(void)
{
int ret=bus _ register(SOC _ camera _ bus _ type);//注册单没有关联
.
ret=driver _ register(IC _ drv);
.
ret=platform _ driver _ probe(SOC _ camera _ pdrv,SOC _ camera _ pdrv _ probe);
.
}
staTIc int _ _ devinitsoc _ camera _ pdrv _ probe(struct platform _ device * pdev)
{
//通过传入的参数pdev获取平台_数据,即结构soc_camera_link
结构SOC _ camera _ link * ICL=pdev-dev。platform _ data
结构soc _ camera _ device * icd
/*
* 分配设备结构及初始化
*/
icd=kzalloc(sizeof(*icd),GFP _ KERNEL);
ICD-iface=ICL-巴士_ id//iface被初始化为总线编号
ICD-pdev=pdev-dev;
platform _ set _ drv data(ICD pdev);
ret=SOC _ camera _ device _ register(ICD);//SOC _摄像机_设备加到全局照相机设备链表@设备上,并且为它分配设备号,做一些必要的初始化
soc_camera_device_init(icd-dev,ICL);//设置soc _ came _ device对应设备的公共汽车为soc_camera_bus_type,这样当我们注册设备时,就会调用soc _摄像机_探头
ICD-用户_宽度=默认_宽度;
ICD-用户_高度=默认_高度;
}
structsoc_camera_link{
int bus _ id//匹配soccamerahost的序号
无符号长标志;
int i2c _ adapter _ id//I2C适配器号
结构I2C板信息*板信息;
const char *模块名
无效* priv
结构体调节器_批量_数据*调节器;//用于电源的管理
int num _ regulators
/*
*针
对那些非I2C的平台的函数,用于管理sensor设备的添加或者删除*/ int (*add_device)(struct soc_camera_link *, struct device *); void (*del_device)(struct soc_camera_link *); int (*power)(struct device *, int); int (*reset)(struct device *); int (*set_bus_param)(struct soc_camera_link *, unsigned long flags); unsigned long (*query_bus_param)(struct soc_camera_link *); void (*free_bus)(struct soc_camera_link *); };
struct soc_camera_device { struct list_head list; struct device dev; struct device *pdev; s32 user_width; //图像的宽度,以像素为单位 s32 user_height;//图像的高度,以像素为单位 u32 bytesperline; u32 sizeimage; //一画图像的大小,也是存储图像缓冲区的大小 enum v4l2_colorspace colorspace;//色域,指描述色彩时所使用的坐标系 unsigned char iface; //于camera link中的bus_id相对应 unsigned char devnum; struct soc_camera_sense *sense; struct soc_camera_ops *ops; struct video_device *vdev; const struct soc_camera_format_xlate *current_fmt;//驱动中当前使用的视频格式 struct soc_camera_format_xlate *user_formats; //全部支持的视频格式 int num_user_formats; enum v4l2_field field; //决定图像源数据交错的方式 void *host_priv; int use_count; struct mutex video_lock; struct file *streamer;
/*
* 管理帧缓冲区
*/ union { struct videobuf_queue vb_vidq; struct vb2_queue vb2_vidq; }; };
staTIc int soc_camera_device_register(struct soc_camera_device *icd) { struct soc_camera_device *ix; int num = -1, i;
for (i = 0; i < 256 && num iface == icd->iface && ix->devnum == i) { num = -1; break; } } }
icd->devnum = num;//找到空闲的设备号 icd->use_count = 0; icd->host_priv = NULL; mutex_init(&icd->video_lock);
list_add_tail(&icd->list, &devices);//将空闲的设备结构放入链表
}
staTIc void soc_camera_device_init(struct device *dev, void *pdata) { dev->platform_data = pdata; dev->bus = &soc_camera_bus_type;//设置总线类型 dev->release = dummy_release; }
struct bus_type soc_camera_bus_type = { .name = "soc-camera", .probe = soc_camera_probe, .remove = soc_camera_remove, .suspend = soc_camera_suspend, .resume = soc_camera_resume, };
staTIc int soc_camera_probe(struct device *dev) {
... ret = video_dev_create(icd);
...
}
static int video_dev_create(struct soc_camera_device *icd) { struct video_device *vdev = video_device_alloc();
strlcpy(vdev->name, ici->drv_name, sizeof(vdev->name));
vdev->parent = &icd->dev; vdev->current_norm = V4L2_STD_UNKNOWN; vdev->fops = &soc_camera_fops; vdev->ioctl_ops = &soc_camera_ioctl_ops; vdev->release = video_device_release; vdev->tvnorms = V4L2_STD_UNKNOWN;
icd->vdev = vdev;
return 0; }
static struct v4l2_file_operations soc_camera_fops = { .owner = THIS_MODULE, .open = soc_camera_open, .release = soc_camera_close, .unlocked_ioctl = video_ioctl2, .read = soc_camera_read, .mmap = soc_camera_mmap, .poll = soc_camera_poll, };
static int soc_camera_open(struct file *file) { struct video_device *vdev = video_devdata(file);//获取video_driver信息
...
}
/linux-3.0.35/drivers/media/video/v4l2-ioctl.c
long video_ioctl2(struct file *file, unsigned int cmd, unsigned long arg) { return video_usercopy(file, cmd, arg, __video_do_ioctl); }
static long __video_do_ioctl(struct file *file, unsigned int cmd, void *arg) { struct video_device *vfd = video_devdata(file); const struct v4l2_ioctl_ops *ops = vfd->ioctl_ops; void *fh = file->private_data;
...
case VIDIOC_S_CROP: { struct v4l2_crop *p = arg;
ret = ops->vidioc_s_crop(file, fh, p); break; }
...
}
标签:
版权声明:转载此文是出于传递更多信息之目的。若有来源标注错误或侵犯了您的合法权益,请作者持权属证明与本网联系,我们将及时更正、删除,谢谢您的支持与理解。