Embeded linux之soc camera

soc camera 子系统为分为soc camera device 和 soc camera host,并且定义了标准的接口或者回调函数.
流程:
1.获取传来信息,填充soc_camera_link
2.初始化soc_camera_device(iface、device、设备号、总线类型)、加入链表
3.
一、/linux-3.0.35/drivers/media/video/soc_camera.c主要是用来管理接口或者回调函数.
module_init(soc_camera_init);
static 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获取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_width= default_width;
icd->user_height= default_height;
}
structsoc_camera_link{
int bus_id;//匹配soccamerahost的序号
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_param)(struct soc_camera_link *, unsigned long flags);
unsigned long (*query_bus_param)(struct soc_camera_link *);
void (*free_bus)(struct soc_camera_link *);
};
structsoc_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;//于cameralink中的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 intsoc_camera_device_register(struct soc_camera_device *icd)
{
struct soc_camera_device *ix;
int num = -1, i;
for (i = 0; i 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 voidsoc_camera_device_init(struct device *dev, void *pdata)
{
dev->platform_data= pdata;
dev->bus= &soc_camera_bus_type;//设置总线类型
dev->release= dummy_release;
}
struct bus_typesoc_camera_bus_type= {
.name= soc-camera,
.probe=soc_camera_probe,
.remove= soc_camera_remove,
.suspend= soc_camera_suspend,
.resume= soc_camera_resume,
};
static intsoc_camera_probe(struct device *dev)
{
...
ret =video_dev_create(icd);
...
}
static intvideo_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_operationssoc_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 intsoc_camera_open(struct file *file)
{
struct video_device *vdev = video_devdata(file);//获取video_driver信息
...

/linux-3.0.35/drivers/media/video/v4l2-ioctl.c
longvideo_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;
}
...
}

近三十年来的通信运营商发展的历程
【RTT大赛作品连载】linkboy面向WCH移植(4)
奇瑞新能源车型众多,相比同级车企有着明显的竞争优势
恩智浦经典LPC系列MCU内部Flash IAP驱动介绍
阿里推出AR汽车导航技术,AliOS体验升级
Embeded linux之soc camera
回收废旧电池 一老人一年收579节
手机音频功放IC的作用及特性要求
如何制作Arduino控制的水火箭
Type-C集线器给您带来不同的功能,不通过的选择
可折叠智能手机测试中应用大电流弹片微针模组的优势
LeCun新作:全面综述下一代「增强语言模型」
三星:12寸厂到2015年将不符经济效益
屏蔽箱的材质结构和使用事项介绍
HTU U Ultra深度评测:又一台骁龙821是糟点的旗舰机型
盘点半导体技术对未来汽车安全作用
自动变光太阳能航空障碍灯
iOS11被果粉吐槽史上Bug最多
单片机对蜂鸣器的设计
全球SiC晶圆市场预计2030年达21亿美元!市场+技术趋势深度分析