Embededlinux之soccamera

 soc camera 子系统为分为soc camera device 和 soc camera host,并且定义了标准的接口或者回调函数.

流程:

1.获取传来信息,填充soc_camera_link

2.初始化soc_camera_device(iface、device、设备号、总线类型)、加入链表

3.

一、/     linux   -3.0.35/drive     rs   /media/video/soc_camera.c主要是用来管理接口或者回调函数.

module_init(soc_camera_init);

sta     ti   c int __init soc_camera_init(void)
{
int ret = bus_regis     te   r(&soc_camera_bus_type);//注册单没有关联
...
ret = driver_register(&ic_drv);

...

ret = platform_driver_probe(&soc_camera_pdrv, soc_camera_pdrv_probe);

...
}

sta  TI c int __devinit soc_camera_pdrv_probe(struct platform_device *pdev)
{

//通过传入的参数pdev获取platform_data,即struct soc_camera_link
struct soc_camera_link *icl = pdev->dev.platform_data;

struct soc_camera_device *icd;

/*

* 分配设备结构及初始化

*/

icd = kzalloc(sizeof(*icd), GFP_KERNEL);

icd->iface = icl->bus_id;//iface被初始化为bus_id
icd->pdev = &pdev->dev;
platform_set_drvdata(pdev, icd);

ret = soc_camera_device_register(icd);//soc_camera_device加到全局camera device链表@devices上,并且为它分配设备号,做一些必要的初始化

soc_camera_device_init(&icd->dev, icl);//设置soc_came_device对应device的bus为soc_camera_bus_type,这样当我们注册设备时,就会调用soc_camera_probe

icd->user_w     idt   h  = DEFAULT_WIDTH;
icd->user_height = DEFAULT_HEIGHT;
}

struct soc_camera_link {
int bus_id;//匹配soc camera host的序号
unsigned long flags;
int     i2c   _adapter_id;//I2C 适配器号
struct i2c_board_info *board_info;
const char *module_name;
void *priv;
struct regulator_bulk_data *regulators;//用于电源的管理
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_pa     ram   )(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 v     4l   2_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;
};
};

sta  TI c 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 < 0; i++) {//判断挂接的设备是否256个设备号都占用
num = i;
list_for_each_entry(ix, &devices, list) {
if (ix->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_t     ai   l(&icd->list, &devices);//将空闲的设备结构放入链表

}

sta  TI c 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,
};

sta  TI c 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;
}

...

}



Embededlinux之soccamera_设计制作_嵌入式技术
84
44
0
74

相关资讯

  1. 1、中层管理的生存之道:有效沟通,练就职场高情商2740
  2. 2、案例拆解|百万点赞量的英语教育个人IP视频号如何引流?990
  3. 3、运营工作中的点线面993
  4. 4、社会化营销:从草根派到技术流3619
  5. 5、校园社交乱斗,阿里、头条、京东想对少男少女做什么?3550
  6. 6、下沉市场家用监控的软件服务增长实践1817
  7. 7、转型怪圈:传统企业在焦虑,互联网企业要落地304
  8. 8、APP上线新功能时,运营人员应该做些什么?2881
  9. 9、月薪不到3万,我是怎么做新媒体运营的?3917
  10. 10、6招如何提高Google+的品牌页面内容互动性419
全部评论(0)
我也有话说
0
收藏
点赞
顶部