关键结构体、宏定义、枚举
enum v4l2_int_ioctl_num {
/*
*
* "Proper" V4L ioctls, as in struct video_device.
*
*/
vidioc_int_enum_fmt_cap_num = 1,
vidioc_int_g_fmt_cap_num,
vidioc_int_s_fmt_cap_num,
省略
}
#define V4L2_INT_WRAPPER_0(name)
static inline int vidioc_int_##name(struct v4l2_int_device *d)
{
return v4l2_int_ioctl_0(d, vidioc_int_##name##_num);
}
static inline struct v4l2_int_ioctl_desc
vidioc_int_##name##_cb(int (*func)
(struct v4l2_int_device *))
{
struct v4l2_int_ioctl_desc desc;
desc.num = vidioc_int_##name##_num;
desc.func = (v4l2_int_ioctl_func *)func;
return desc;
}
struct v4l2_int_ioctl_desc {
int num;
v4l2_int_ioctl_func *func;
};
struct v4l2_int_master {
int (*attach)(struct v4l2_int_device *slave);
void (*detach)(struct v4l2_int_device *slave);
};
struct v4l2_int_slave {
/* Don't touch master. */
struct v4l2_int_device *master;
char attach_to[V4L2NAMESIZE];
int num_ioctls;
struct v4l2_int_ioctl_desc *ioctls;
};
struct v4l2_int_device {
/* Don't touch head. */
struct list_head head;
struct module *module;
char name[V4L2NAMESIZE];
enum v4l2_int_type type;
union {
struct v4l2_int_master *master;
struct v4l2_int_slave *slave;
} u;
void *priv;
};
struct v4l2_file_operations {
省略
};
struct v4l2_ioctl_ops {
省略
}
struct video_device
{
#if defined(CONFIG_MEDIA_CONTROLLER)
struct media_entity entity;
#endif
/* device ops */
const struct v4l2_file_operations *fops;
/* ioctl callbacks */
const struct v4l2_ioctl_ops *ioctl_ops;
省略一部分
};
关键函数
int v4l2_int_ioctl_0(struct v4l2_int_device *d, int cmd);
void v4l2_int_device_try_attach_all(void);
int v4l2_int_device_register(struct v4l2_int_device *d);
void v4l2_int_device_unregister(struct v4l2_int_device *d);
int v4l2_int_ioctl_0(struct v4l2_int_device *d, int cmd);
int v4l2_int_ioctl_1(struct v4l2_int_device *d, int cmd, void *arg);
static inline int __must_check video_register_device(struct video_device *vdev, int type, int nr);
各个结构体以及函数之间的关系
v4l2_int_device设备是分主从的,通过struct v4l2_int_device结构体里面的struct v4l2_int_master *master和struct v4l2_int_slave *slave来指定,slave里面需要实现v4l2_int_ioctl_desc结构体,结构体里的int num对应enum v4l2_int_ioctl_num里面指定的值,通过num与slave里面具体的ioctl函数进行绑定,v4l2_int_device结构体填充完之后通过v4l2_int_device_register函数加到list链表里,v4l2_int_device_register同时会调用函数v4l2_int_device_try_attach_all(),函数来做master与salve进行匹配,如果匹配成功会调用master里面的attach函数将slave传给cam->sensor,至此master与slave匹配完成,master里调用ioctl时会把cam->sensor,传入到v4l2_int_ioctl_0里面,在v4l2_int_ioctl_0函数里会查找到slave里面对应的ioctl。
v4l2_int_device_register函数使用来添加salve与master,并把slave与master做匹配,不涉及到sys系统的内容,最终sys系统与设备节点是通过video_register_device函数向系统添加的,video_register_device函数是在master端调用的。
enum v4l2_int_ioctl_num {
/*
*
* "Proper" V4L ioctls, as in struct video_device.
*
*/
vidioc_int_enum_fmt_cap_num = 1,
vidioc_int_g_fmt_cap_num,
vidioc_int_s_fmt_cap_num,
省略
}
#define V4L2_INT_WRAPPER_0(name)
static inline int vidioc_int_##name(struct v4l2_int_device *d)
{
return v4l2_int_ioctl_0(d, vidioc_int_##name##_num);
}
static inline struct v4l2_int_ioctl_desc
vidioc_int_##name##_cb(int (*func)
(struct v4l2_int_device *))
{
struct v4l2_int_ioctl_desc desc;
desc.num = vidioc_int_##name##_num;
desc.func = (v4l2_int_ioctl_func *)func;
return desc;
}
struct v4l2_int_ioctl_desc {
int num;
v4l2_int_ioctl_func *func;
};
struct v4l2_int_master {
int (*attach)(struct v4l2_int_device *slave);
void (*detach)(struct v4l2_int_device *slave);
};
struct v4l2_int_slave {
/* Don't touch master. */
struct v4l2_int_device *master;
char attach_to[V4L2NAMESIZE];
int num_ioctls;
struct v4l2_int_ioctl_desc *ioctls;
};
struct v4l2_int_device {
/* Don't touch head. */
struct list_head head;
struct module *module;
char name[V4L2NAMESIZE];
enum v4l2_int_type type;
union {
struct v4l2_int_master *master;
struct v4l2_int_slave *slave;
} u;
void *priv;
};
struct v4l2_file_operations {
省略
};
struct v4l2_ioctl_ops {
省略
}
struct video_device
{
#if defined(CONFIG_MEDIA_CONTROLLER)
struct media_entity entity;
#endif
/* device ops */
const struct v4l2_file_operations *fops;
/* ioctl callbacks */
const struct v4l2_ioctl_ops *ioctl_ops;
省略一部分
};
关键函数
int v4l2_int_ioctl_0(struct v4l2_int_device *d, int cmd);
void v4l2_int_device_try_attach_all(void);
int v4l2_int_device_register(struct v4l2_int_device *d);
void v4l2_int_device_unregister(struct v4l2_int_device *d);
int v4l2_int_ioctl_0(struct v4l2_int_device *d, int cmd);
int v4l2_int_ioctl_1(struct v4l2_int_device *d, int cmd, void *arg);
static inline int __must_check video_register_device(struct video_device *vdev, int type, int nr);
各个结构体以及函数之间的关系
v4l2_int_device设备是分主从的,通过struct v4l2_int_device结构体里面的struct v4l2_int_master *master和struct v4l2_int_slave *slave来指定,slave里面需要实现v4l2_int_ioctl_desc结构体,结构体里的int num对应enum v4l2_int_ioctl_num里面指定的值,通过num与slave里面具体的ioctl函数进行绑定,v4l2_int_device结构体填充完之后通过v4l2_int_device_register函数加到list链表里,v4l2_int_device_register同时会调用函数v4l2_int_device_try_attach_all(),函数来做master与salve进行匹配,如果匹配成功会调用master里面的attach函数将slave传给cam->sensor,至此master与slave匹配完成,master里调用ioctl时会把cam->sensor,传入到v4l2_int_ioctl_0里面,在v4l2_int_ioctl_0函数里会查找到slave里面对应的ioctl。
v4l2_int_device_register函数使用来添加salve与master,并把slave与master做匹配,不涉及到sys系统的内容,最终sys系统与设备节点是通过video_register_device函数向系统添加的,video_register_device函数是在master端调用的。