Data Structure struct software_node { const char *name; const struct software_node *parent; const struct property_entry *properties; }; struct swnode { struct kobject kobj; struct fwnode_handle fwnode; const struct software_node *node; int id; /* hierarchy */ struct ida child_ids; struct list_head entry; struct list_head children; struct swnode *parent; unsigned int allocated:1; unsigned int managed:1; }; Provider software_node_register()注册单个 software node, software_node_register_node_group()注册一组 software nodes. 都是将 software nodes 挂入一个全局链表. // 定义属性 static const struct property_entry my_device_properties[] = { PROPERTY_ENTRY_U32("reg", 0), PROPERTY_ENTRY_U32("my_property", 1234), { } }; // 定义 software node static const struct software_node my_device_node = { ....
Posts
2.2 Structure of a V4L driver device instances | +-sub-device instances | \-V4L2 device nodes | \-filehandle instances 2.4 Video device video device 用于抽象系统注册的 v4l2 /dev 设备节点,以便用户空间可以进行交互. v4l2-dev.h: struct video_device { #if defined(CONFIG_MEDIA_CONTROLLER) struct media_entity entity; struct media_intf_devnode *intf_devnode; struct media_pipeline pipe; #endif const struct v4l2_file_operations *fops; u32 device_caps; /* sysfs */ struct device dev; struct cdev *cdev; struct v4l2_device *v4l2_dev; struct device *dev_parent; struct v4l2_ctrl_handler *ctrl_handler; struct vb2_queue *queue; struct v4l2_prio_state *prio; /* device info */ char name[64]; enum vfl_devnode_type vfl_type; enum vfl_devnode_direction vfl_dir; int minor; u16 num; unsigned long flags; int index; /* V4L2 file handles */ spinlock_t fh_lock; struct list_head fh_list; int dev_debug; v4l2_std_id tvnorms; /* callbacks */ void (*release)(struct video_device *vdev); const struct v4l2_ioctl_ops *ioctl_ops; DECLARE_BITMAP(valid_ioctls, BASE_VIDIOC_PRIVATE); struct mutex *lock; }; entity:...
2.6 V4L2 File handlers struct v4l2_fh 提供了一种方式,使得 file 方便地处理 V4L2 中的一些 specific data. 初始化:v4l2_fh_init(), 必须在 driver 的 v4l2_file_operations->open() 回调中调用, 会置起 video_device 的 V4L2_FL_USES_V4L2_FH flag. 在 userspace open device node 后,调用到 v4l2_fh_open, 会把 file->private_data 设置为 fh. 许多情况下 v4l2_fh 都会嵌入在更大的结构体中,这时需要调用 v4l2_fh_init() 和 v4l2_fh_add 在.open() 回调 v4l2_fh_del() 和 v4l2_fh_exit() 在.release() 回调 struct v4l2_fh { struct list_head list; struct video_device *vdev; struct v4l2_ctrl_handler *ctrl_handler; enum v4l2_priority prio; wait_queue_head_t wait; struct mutex subscribe_lock; struct list_head subscribed; struct list_head available; unsigned int navailable; u32 sequence; struct v4l2_m2m_ctx *m2m_ctx; }; list: 链接到 video_device 的 fh_list....
2.7 V4L2 sub-devices 许多 drivers 需要和 sub-devices 交流,这些子设备可以处理 audio, video muxing, encoding, decoding 等等。 对于 webcams, 常见的 sub-devices 有 sensors, camera controllers. 通过 v4l2_subdev_init(sd, &ops) 来初始化 v4l2_subdev. 接着需要设置 sd->name. 如果需要和 media framework 聚合,那么需要初始化 media_entity 成员,如果 entity 有 pads 还需要调用media_entity_pads_init. struct v4l2_subdev { #if defined(CONFIG_MEDIA_CONTROLLER) struct media_entity entity; #endif struct list_head list; struct module *owner; bool owner_v4l2_dev; u32 flags; struct v4l2_device *v4l2_dev; const struct v4l2_subdev_ops *ops; const struct v4l2_subdev_internal_ops *internal_ops; struct v4l2_ctrl_handler *ctrl_handler; char name[52]; u32 grp_id; void *dev_priv; void *host_priv; struct video_device *devnode; struct device *dev; struct fwnode_handle *fwnode; struct list_head async_list; struct list_head async_subdev_endpoint_list; struct v4l2_async_notifier *subdev_notifier; struct list_head asc_list; struct v4l2_subdev_platform_data *pdata; struct mutex *state_lock; struct led_classdev *privacy_led; struct v4l2_subdev_state *active_state; u64 enabled_streams; }; owner_v4l2_dev: 如果和 v4l2_dev->dev 的 owner 一致,则为 true....
2.14 V4L2 events V4L2 events 提供了一种方法给 userspace 传递 events. struct v4l2_subscribed_event { struct list_head list; u32 type; u32 id; u32 flags; struct v4l2_fh *fh; struct list_head node; const struct v4l2_subscribed_event_ops *ops; unsigned int elems; unsigned int first; unsigned int in_use; struct v4l2_kevent events[] __counted_by(elems); }; list: 加入到 v4l2_fh->subscribed list 的链表节点。 type: event type, 在 videodev2.h 中定义。 id: event 的 control id, 根据 event 的 (type, id) 二元组就能找到对应的 event. flags: 从 userspace 传入的 v4l2_event_subscription->flags 中拷贝过来。...
2.15 V4L2 controls V4L2 controls 用于控制和调整视频设备的各种参数. 2.15.2 Objects in the framework struct v4l2_ctrl 描述了 control properties 和对应的 value. struct v4l2_ctrl_handler 用来跟踪 v4l2_ctrl objects. 2.15.3 Basic usage for V4L2 and sub-device drivers prepare the driver 通常把 v4l2_ctrl_handler 放在 top-level struct: // v4l2 drvier: struct foo_dev { ... struct v4l2_device v4l2_dev; ... struct v4l2_ctrl_handler ctrl_handler; ... }; // sub-dev driver: struct foo_dev { ... struct v4l2_subdev sd; ... struct v4l2_ctrl_handler ctrl_handler; ... }; 通过 v4l2_ctrl_handler_init(&foo->ctrl_handler, nr_of_controls) 初始化 v4l2_ctrl_handler....
struct vb2_queue { unsigned int type; unsigned int io_modes; struct device *dev; unsigned long dma_attrs; unsigned int bidirectional:1; unsigned int fileio_read_once:1; unsigned int fileio_write_immediately:1; unsigned int allow_zero_bytesused:1; unsigned int quirk_poll_must_check_waiting_for_buffers:1; unsigned int supports_requests:1; unsigned int requires_requests:1; unsigned int uses_qbuf:1; unsigned int uses_requests:1; unsigned int allow_cache_hints:1; unsigned int non_coherent_mem:1; struct mutex *lock; void *owner; const struct vb2_ops *ops; const struct vb2_mem_ops *mem_ops; const struct vb2_buf_ops *buf_ops; void *drv_priv; u32 subsystem_flags; unsigned int buf_struct_size; u32 timestamp_flags; gfp_t gfp_flags; u32 min_queued_buffers; u32 min_reqbufs_allocation; struct device *alloc_devs[VB2_MAX_PLANES]; /* private: internal use only */ struct mutex mmap_lock; unsigned int memory; enum dma_data_direction dma_dir; struct vb2_buffer **bufs; unsigned long *bufs_bitmap; unsigned int max_num_buffers; struct list_head queued_list; unsigned int queued_count; atomic_t owned_by_drv_count; struct list_head done_list; spinlock_t done_lock; wait_queue_head_t done_wq; unsigned int streaming:1; unsigned int start_streaming_called:1; unsigned int error:1; unsigned int waiting_for_buffers:1; unsigned int waiting_in_dqbuf:1; unsigned int is_multiplanar:1; unsigned int is_output:1; unsigned int is_busy:1; unsigned int copy_timestamp:1; unsigned int last_buffer_dequeued:1; struct vb2_fileio_data *fileio; struct vb2_threadio_data *threadio; char name[32]; }; type: buffer的类型, enum v4l2_buf_type, vendor driver初始化时设置....
Media Controller devices 5.1.1 Abstract media device model entity 用来抽象一个 media hardware block, 可以表示一个物理硬件设备(CMOS sensor), 也可以表示一个逻辑硬件设备(isp pipeline)等. pad 用来在 entity 之间传输数据, 数据从 source pad 流向 sink pad. link 是两个 pad 之间 point-to-point 的连接. 5.1.2 Media device struct media_device 注册 media_device 需要调用: media_device_init(), media_device_register(). 注销: media_device_unregister(), media_device_cleanup(). struct media_device { struct device *dev; struct media_devnode *devnode; char model[32]; char driver_name[32]; char serial[40]; char bus_info[32]; u32 hw_revision; u64 topology_version; u32 id; struct ida entity_internal_idx; int entity_internal_idx_max; struct list_head entities; struct list_head interfaces; struct list_head pads; struct list_head links; struct list_head entity_notify; struct mutex graph_mutex; struct media_graph pm_count_walk; void *source_priv; int (*enable_source)(struct media_entity *entity, struct media_pipeline *pipe); void (*disable_source)(struct media_entity *entity); const struct media_device_ops *ops; struct mutex req_queue_mutex; atomic_t request_id; }; dev: 底层的 device parent....
IPCam 3917 isp 模块图: 信号处理路径模块: Crop:裁剪模块,用于裁剪图像的特定区域 BLC:黑电平补偿(Black level Correction) DPC: 坏点校正(Defect Pixel Correction) 2DNR: 2D降噪(2D Noise Reduction) GE: 边缘增强(Gain Enhancement) 3DNR & GE:3D降噪和增益增强 AE Short/Long Gain:自动曝光短/长时间增益控制 HDR Fusion:高动态范围图像融合,合并不同曝光的图像 镜头校正模块: Circle Lens Shading:圆形镜头阴影校正 Grid Lens Shading:网格镜头阴影校正 色彩处理模块: YUV to RGB:YUV色彩空间转换为RGB INTP:demosaic颜色插值, 从raw格式转换到rgb格式 CCM:色彩校正矩阵(Color Correction Matrix) RGB Gamma:RGB伽马校正 WDR:宽动态范围(Wide Dynamic Range)处理 YUV处理模块: YUV420 To YUV422:YUV色彩格式转换 YUV422 To YUV444:YUV色彩格式转换 RGB2YUV444:RGB转YUV444格式 Global Curve:全局曲线调整 UV Tune & UVS:UV通道调整和UV抑制 统计和分析模块: AF Statistics:自动对焦统计数据 AE Short/Long Statistics:自动曝光短/长时间统计数据 Raw Statistics:原始图像统计数据...
//TODO: isp 架构图 libisp api: global api: rts_av_isp_init/cleanup rts_av_isp_start/stop rts_av_isp_get_status rts_av_isp_register/unregister/get_algo rts_av_isp_bind/unbind_algo rts_av_isp_register/unregister/get/check_sensor rts_av_isp_bind/unbind_sensor rts_av_isp_register_iq mipi out api: rts_av_isp_set_mipiout rts_av_isp_get_mipiout v4l2 control: rts_isp_v4l2_query_ctrl rts_isp_v4l2_query_menu rts_isp_v4l2_g_ctrl rts_isp_v4l2_s_ctrl rts_isp_v4l2_query_ext_ctrl rts_isp_v4l2_g_ext_ctrls rts_isp_v4l2_s_ext_ctrls rts_isp_v4l2_try_ext_ctrls sensor: private mask: 3A Setting: 3A Statis: IQ tuning: other: struct isp_core { struct isp_mod_hash_table hash; struct isp_notify notify; struct v4l2_ctrl_handler ctrl_handler; struct isp_statis statis; struct isp_iq iq; int initialized:1; int running:1; }; hash: hash table, 用来保存modules. notify: ctrl_hander: statis: iq: initialized: isp_core_init() 之后置 1....