structv4l2_decode_vbi_line是用于解码VBI行的结构体。定义:
struct v4l2_decode_vbi_line {
u32 is_second_field;
u8 *p;
u32 line;
u32 type;
};
它有以下成员:is_second_field:在第一个场景况下设置为0;在第二个场景况下设置为p:指向从解码器取出的分片VBI数据的指针。退出时,该指针指向有效载荷的起始位置。line:分片VBI数据的行号。type:VBI服务类型。如果没有发现服务,则为0。enumv4l2_subdev_io_pin_bits是用于子设备外部IO引脚配置的位常量。常量如下所示:V4L2_SUBDEV_IO_PIN_DISABLE:禁用引脚配置。假定为启用状态。V4L2_SUBDEV_IO_PIN_OUTPUT:如果引脚为输出,则设置此位。V4L2_SUBDEV_IO_PIN_INPUT:如果引脚为输入,则设置此位。V4L2_SUBDEV_IO_PIN_SET_VALUE:通过structv4l2_subdev_io_pin_config->value设置输出值。V4L2_SUBDEV_IO_PIN_ACTIVE_LOW:如果引脚为低电平有效,则将此位置否则,假定为高电平有效。structv4l2_subdev_io_pin_config是用于子设备外部IO引脚配置的结构体。定义:
struct v4l2_subdev_io_pin_config {
u32 flags;
u8 pin;
u8 function;
u8 value;
u8 strength;
};
它有以下成员:flags:表示此引脚配置的标志位掩码,其位由v4l2_subdev_io_pin_bits枚举定义。pin:要配置的芯片外部IO引脚。function:要路由到IO引脚的内部信号pad/功能。value:引脚的初始值-例如GPIO输出值。strength:引脚驱动强度。structv4l2_subdev_core_ops是用于子设备核心操作回调的结构体。定义:
struct v4l2_subdev_core_ops {
int (*log_status)(struct v4l2_subdev *sd);
int (*s_io_pin_config)(struct v4l2_subdev *sd, size_t n, struct v4l2_subdev_io_pin_config *pincfg);
int (*init)(struct v4l2_subdev *sd, u32 val);
int (*load_fw)(struct v4l2_subdev *sd);
int (*reset)(struct v4l2_subdev *sd, u32 val);
int (*s_gpio)(struct v4l2_subdev *sd, u32 val);
long (*command)(struct v4l2_subdev *sd, unsigned int cmd, void *arg);
long (*ioctl)(struct v4l2_subdev *sd, unsigned int cmd, void *arg);
#ifdef CONFIG_COMPAT;
long (*compat_ioctl32)(struct v4l2_subdev *sd, unsigned int cmd, unsigned long arg);
#endif;
#ifdef CONFIG_VIDEO_ADV_DEBUG;
int (*g_register)(struct v4l2_subdev *sd, struct v4l2_dbg_register *reg);
int (*s_register)(struct v4l2_subdev *sd, const struct v4l2_dbg_register *reg);
#endif;
int (*s_power)(struct v4l2_subdev *sd, int on);
int (*interrupt_service_routine)(struct v4l2_subdev *sd, u32 status, bool *handled);
int (*subscribe_event)(struct v4l2_subdev *sd, struct v4l2_fh *fh, struct v4l2_event_subscription *sub);
int (*unsubscribe_event)(struct v4l2_subdev *sd, struct v4l2_fh *fh, struct v4l2_event_subscription *sub);
};
它包含了多个函数指针,用于处理特定的操作:log_status:处理VIDIOC_LOG_STATUSioctl的日志状态回调代码。s_io_pin_config:配置一个或多个芯片的IO引脚。此函数需要一个指向‘n’个引脚配置条目的数组指针,每个引脚都需要一个配置条目。此函数可以在子设备初始化期间以外的时间被调用。init:将传感器寄存器初始化为某种合理的默认值。不应该在新驱动程序中使用,并且应该在现有驱动程序中删除。load_fw:加载固件。reset:通用重置命令。参数选择要重置的子系统。传递0将始终重置整个芯片。不应在没有先在linux-media邮件列表上讨论的情况下在新驱动程序中使用。通常不需要重置设备。s_gpio:设置GPIO引脚。目前非常简单,如果需要,可能需要扩展一个方向参数。command:由内核驱动程序调用,以调用具有单独回调的subdev驱动程序内部功能。ioctl:在V4L2core的ioctl系统调用处理程序结束时调用。用于支持驱动程序使用的私有IOCTL。compat_ioctl3当32位应用程序使用64位内核时,调用以修复从/向用户空间传递的数据。g_register:处理VIDIOC_DBG_G_REGISTERioctl的回调代码。s_register:处理VIDIOC_DBG_S_REGISTERioctl的回调代码。s_power:将子设备置于省电模式或正常操作模式。interrupt_service_routine:由桥接芯片的中断服务处理程序调用,当由于此subdev而引发中断状态时,以便此subdev可以处理详细信息。它可能安排稍后执行的工作。必须不休眠。从IRQ上下文调用。subscribe_event:由驱动程序用于请求控制框架,在控制更改时给它发出警告。unsubscribe_event:从控制框架中删除事件订阅。structv4l2_subdev_tuner_ops是用于处理当V4L设备在收音机模式下打开时的回调函数集合。定义:
struct v4l2_subdev_tuner_ops {
int (*standby)(struct v4l2_subdev *sd);
int (*s_radio)(struct v4l2_subdev *sd);
int (*s_frequency)(struct v4l2_subdev *sd, const struct v4l2_frequency *freq);
int (*g_frequency)(struct v4l2_subdev *sd, struct v4l2_frequency *freq);
int (*enum_freq_bands)(struct v4l2_subdev *sd, struct v4l2_frequency_band *band);
int (*g_tuner)(struct v4l2_subdev *sd, struct v4l2_tuner *vt);
int (*s_tuner)(struct v4l2_subdev *sd, const struct v4l2_tuner *vt);
int (*g_modulator)(struct v4l2_subdev *sd, struct v4l2_modulator *vm);
int (*s_modulator)(struct v4l2_subdev *sd, const struct v4l2_modulator *vm);
int (*s_type_addr)(struct v4l2_subdev *sd, struct tuner_setup *type);
int (*s_config)(struct v4l2_subdev *sd, const struct v4l2_priv_tun_config *config);
};
它包括以下函数指针:standby:将调谐器置于待机状态。它将在下一次使用时自动唤醒。s_radio:切换调谐器到收音机模式。当一个调谐器操作需要在收音机模式下进行处理时,驱动程序应明确调用此函数。这通常在同时具有AM/FM收音机接收器和电视的设备上使用。s_frequency:用于处理VIDIOC_S_FREQUENCYioctl处理程序代码的回调函数。g_frequency:用于处理VIDIOC_G_FREQUENCYioctl处理程序代码的回调函数。freq->type必须填充。通常由video_ioctl2或桥接驱动程序完成。enum_freq_bands:用于处理VIDIOC_ENUM_FREQ_BANDSioctl处理程序代码的回调函数。g_tuner:用于处理VIDIOC_G_TUNERioctl处理程序代码的回调函数。s_tuner:用于处理VIDIOC_S_TUNERioctl处理程序代码的回调函数。vt->type必须填充。通常由video_ioctl2或桥接驱动程序完成。g_modulator:用于处理VIDIOC_G_MODULATORioctl处理程序代码的回调函数。s_modulator:用于处理VIDIOC_S_MODULATORioctl处理程序代码的回调函数。s_type_addr:设置调谐器类型及其I2C地址的回调函数。s_config:设置tda9887特定内容的回调函数,如portport2和qss。注意:对于同时具有AM/FM和电视功能的设备,驱动程序必须明确调用s_radio将调谐器切换到收音机模式,然后处理其他需要在该模式下进行处理的v4l2_subdev_tuner_ops函数。例如:
static void s_frequency(void *priv, const struct v4l2_frequency *f) {
...
if (f.type == V4L2_TUNER_RADIO)
v4l2_device_call_all(v4l2_dev, 0, tuner, s_radio);
...
v4l2_device_call_all(v4l2_dev, 0, tuner, s_frequency);
}
structv4l2_subdev_audio_ops是一组用于处理与音频相关的设置的回调函数。定义:
struct v4l2_subdev_audio_ops {
int (*s_clock_freq)(struct v4l2_subdev *sd, u32 freq);
int (*s_i2s_clock_freq)(struct v4l2_subdev *sd, u32 freq);
int (*s_routing)(struct v4l2_subdev *sd, u32 input, u32 output, u32 config);
int (*s_stream)(struct v4l2_subdev *sd, int enable);
};
它包括以下函数指针:s_clock_freq:设置音频时钟输出的频率。用于将音频处理器从视频解码器上同步,确保音频和视频保持同步。常见的频率值是48000、44100或32000Hz。如果不支持该频率,则返回-EINVAL。s_i2s_clock_freq:设置I2S速度。这用于提供一种选择I2S时钟的标准方法,以驱动数字音频流。常见的频率值是1024000和2048000。如果不支持该频率,则返回-EINVAL。s_routing:定义音频芯片的输入和/或输出引脚以及任何其他配置数据。永远不要在此级别使用用户级输入ID。一个i2c设备不应该知道一个输入引脚是否连接到复合连接器上,因为在另一个板子或平台上它可能连接到完全不同的东西。调用驱动程序负责将用户级输入映射到i2c设备上的正确引脚。s_stream:用于通知音频代码流开始或停止。enumv4l2_mbus_frame_desc_flags是用于描述媒体总线帧属性的位掩码。常见的位域包括:V4L2_MBUS_FRAME_DESC_FL_LEN_MAX:指示structv4l2_mbus_frame_desc_entry->length字段指定最大数据长度。V4L2_MBUS_FRAME_DESC_FL_BLOB:指示格式没有行偏移,即接收器应使用1DDMA。structv4l2_mbus_frame_desc_entry是用于描述媒体总线帧的结构体。定义:
struct v4l2_mbus_frame_desc_entry {
enum v4l2_mbus_frame_desc_flags flags;
u32 pixelcode;
u32 length;
};
它包括以下成员:flags:位掩码标志,在enumv4l2_mbus_frame_desc_flags中定义。pixelcode:当未设置FRAME_DESC_FL_BLOB标志时,表示媒体总线像素代码的有效值。length:当设置了V4L2_MBUS_FRAME_DESC_FL_LEN_MAX标志时,表示每帧的字节数。structv4l2_mbus_frame_desc是用于描述媒体总线数据帧的结构体。定义:
struct v4l2_mbus_frame_desc {
struct v4l2_mbus_frame_desc_entry entry[V4L2_FRAME_DESC_ENTRY_MAX];
unsigned short num_entries;
};
它包括以下成员:entry:帧描述符数组。num_entries:entry数组中的条目数。enumv4l2_subdev_pre_streamon_flags是用于pre_streamon子设备核心操作的标志位。常见的标志位如下:V4L2_SUBDEV_PRE_STREAMON_FL_MANUAL_LP:在调用s_stream之前将发射器设置为LP-11或LP-111模式。structv4l2_subdev_video_ops是在v4l设备以视频模式打开时使用的回调函数集合。定义:
struct v4l2_subdev_video_ops {
int (*s_routing)(struct v4l2_subdev *sd, u32 input, u32 output, u32 config);
int (*s_crystal_freq)(struct v4l2_subdev *sd, u32 freq, u32 flags);
int (*g_std)(struct v4l2_subdev *sd, v4l2_std_id *norm);
int (*s_std)(struct v4l2_subdev *sd, v4l2_std_id norm);
int (*s_std_output)(struct v4l2_subdev *sd, v4l2_std_id std);
int (*g_std_output)(struct v4l2_subdev *sd, v4l2_std_id *std);
int (*querystd)(struct v4l2_subdev *sd, v4l2_std_id *std);
int (*g_tvnorms)(struct v4l2_subdev *sd, v4l2_std_id *std);
int (*g_tvnorms_output)(struct v4l2_subdev *sd, v4l2_std_id *std);
int (*g_input_status)(struct v4l2_subdev *sd, u32 *status);
int (*s_stream)(struct v4l2_subdev *sd, int enable);
int (*g_pixelaspect)(struct v4l2_subdev *sd, struct v4l2_fract *aspect);
int (*g_frame_interval)(struct v4l2_subdev *sd, struct v4l2_subdev_frame_interval *interval);
int (*s_frame_interval)(struct v4l2_subdev *sd, struct v4l2_subdev_frame_interval *interval);
int (*s_dv_timings)(struct v4l2_subdev *sd, struct v4l2_dv_timings *timings);
int (*g_dv_timings)(struct v4l2_subdev *sd, struct v4l2_dv_timings *timings);
int (*query_dv_timings)(struct v4l2_subdev *sd, struct v4l2_dv_timings *timings);
int (*s_rx_buffer)(struct v4l2_subdev *sd, void *buf, unsigned int *size);
int (*pre_streamon)(struct v4l2_subdev *sd, u32 flags);
int (*post_streamoff)(struct v4l2_subdev *sd);
};
struct v4l2_subdev_vbi_ops {
int (*decode_vbi_line)(struct v4l2_subdev *sd, struct v4l2_decode_vbi_line *vbi_line);
int (*s_vbi_data)(struct v4l2_subdev *sd, const struct v4l2_sliced_vbi_data *vbi_data);
int (*g_vbi_data)(struct v4l2_subdev *sd, struct v4l2_sliced_vbi_data *vbi_data);
int (*g_sliced_vbi_cap)(struct v4l2_subdev *sd, struct v4l2_sliced_vbi_cap *cap);
int (*s_raw_fmt)(struct v4l2_subdev *sd, struct v4l2_vbi_format *fmt);
int (*g_sliced_fmt)(struct v4l2_subdev *sd, struct v4l2_sliced_vbi_format *fmt);
int (*s_sliced_fmt)(struct v4l2_subdev *sd, struct v4l2_sliced_vbi_format *fmt);
};
它包括以下成员:decode_vbi_line:视频解码器需要支持slicedVBI并实现此ioctl。structv4l2_decode_vbi_line中的p字段设置为解码器生成的VBI数据的起始位置。然后驱动程序会解析slicedVBI数据并相应地设置struct中的其他字段。指针p更新为指向可以逐字复制到structv4l2_sliced_vbi_data的data字段中的payload的开始位置。如果未找到有效的VBI数据,则返回时type字段设置为0。s_vbi_data:用于在视频信号上生成VBI信号。使用structv4l2_sliced_vbi_data填充数据包。请注意,如果将line字段设置为0,则禁用该VBI信号。如果未找到有效的VBI数据,则返回时type字段设置为0。g_vbi_data:用于从读回寄存器中获取slicedVBI分组。并非所有视频解码器都支持此功能。如果没有可用数据,因为读回寄存器包含无效或错误的数据,则返回-EIO。请注意,您必须填写"id"成员和"field"成员。g_sliced_vbi_cap:用于VIDIOC_G_SLICED_VBI_CAPioctl处理器代码的回调函数。s_raw_fmt:设置视频编码器/解码器以使用原始VBI。g_sliced_fmt:检索当前的slicedVBI设置。s_sliced_fmt:设置slicedVBI设置。structv4l2_subdev_sensor_ops是v4l2子设备中的传感器操作集合。定义:
struct v4l2_subdev_sensor_ops {
int (*g_skip_top_lines)(struct v4l2_subdev *sd, u32 *lines);
int (*g_skip_frames)(struct v4l2_subdev *sd, u32 *frames);
};
它包括以下成员:g_skip_top_lines:需要跳过像顶部几行的行数。这对于某些传感器是必需的,因为它们总是会破坏输出像的若干顶部行,或是在这些行中发送元数据。g_skip_frames:需要跳过的流开始处的帧数。这对于有缺陷的传感器是必需的,因为当它们被打开时会生成错误的帧。enumv4l2_subdev_ir_mode描述了支持的红外类型。常量V4L2_SUBDEV_IR_MODE_PULSE_WIDTH表示红外使用structir_raw_event记录。structv4l2_subdev_ir_parameters是用于IR传输或接收的参数集合。定义:
struct v4l2_subdev_ir_parameters {
unsigned int bytes_per_data_element;
enum v4l2_subdev_ir_mode mode;
bool enable;
bool interrupt_enable;
bool shutdown;
bool modulation;
u32 max_pulse_width;
unsigned int carrier_freq;
unsigned int duty_cycle;
bool invert_level;
bool invert_carrier_sense;
u32 noise_filter_min_width;
unsigned int carrier_range_lower;
unsigned int carrier_range_upper;
u32 resolution;
};
它包括以下成员:bytes_per_data_element:每个数据元素中的字节数,在读取或写入调用中使用。mode:由枚举类型v4l2_subdev_ir_mode定义的IR模式。enable:如果为true,则设备处于活动状态。interrupt_enable:如果为true,则启用IR中断。shutdown:如果为true,则将硬件设置为低功率或无功率状态,如果为false,则为正常模式。modulation:如果为true,则使用载波;如果为false,则使用基带信号。max_pulse_width:基带信号的最大脉冲宽度,仅对基带信号有效。carrier_freq:调制信号的载波频率,仅对调制信号有效。duty_cycle:占空比百分比,仅对调制信号有效。invert_level:反转信号电平。invert_carrier_sense:仅在TX中使用,将0或空格作为载波突发发送。noise_filter_min_width:有效脉冲的最小时间,以纳秒为单位。仅用于RX。carrier_range_lower:下限载波范围,以Hz为单位,仅对调制信号有效。仅用于RX。carrier_range_upper:上限载波范围,以Hz为单位,仅对调制信号有效。仅用于RX。resolution:以ns为单位的接收分辨率。仅用于RX。structv4l2_subdev_ir_ops该结构体定义了IR子备操作。包括接收端和发送端的操作。定义:
struct v4l2_subdev_ir_ops {
int (*rx_read)(struct v4l2_subdev *sd, u8 *buf, size_t count, ssize_t *num);
int (*rx_g_parameters)(struct v4l2_subdev *sd, struct v4l2_subdev_ir_parameters *params);
int (*rx_s_parameters)(struct v4l2_subdev *sd, struct v4l2_subdev_ir_parameters *params);
int (*tx_write)(struct v4l2_subdev *sd, u8 *buf, size_t count, ssize_t *num);
int (*tx_g_parameters)(struct v4l2_subdev *sd, struct v4l2_subdev_ir_parameters *params);
int (*tx_s_parameters)(struct v4l2_subdev *sd, struct v4l2_subdev_ir_parameters *params);
};
具体包括以下成员:rx_read函数,用于读取接收到的红外代码或脉冲宽度数据,类似于非阻塞的read函数。rx_g_parameters函数,用于获取IR接收器的当前工作参数和状态。rx_s_parameters函数,用于设置IR接收器的当前工作参数和状态。建议先调用rx_g_parameters函数以填充当前状态,然后仅更改需要更改的字段。返回时,实际设备工作参数和状态将被返回。请注意,由于硬件限制,实际设置可能与请求设置不匹配,例如当请求36,000Hz时,实际载波设置为35,904Hz。当shutdown参数为true时,情况有所不同。将返回上次使用的操作参数,但实际硬件状态可能有所不同,以最小化功耗和处理。tx_write函数,用于写入要传输的代码或脉冲宽度数据,类似于非阻塞的write函数。tx_g_parameters函数,用于获取IR发送器的当前工作参数和状态。tx_s_parameters函数,用于设置IR发送器的当前工作参数和状态。建议先调用tx_g_parameters函数以填充当前状态,然后仅更改需要更改的字段。返回时,实际设备工作参数和状态将被返回。请注意,由于硬件限制,实际设置可能与请求设置不匹配,例如当请求36,000Hz时,实际载波设置为35,904Hz。当shutdown参数为true时,情况有所不同。将返回上次使用的操作参数,但实际硬件状态可能有所不同,以最小化功耗和处理。structv4l2_subdev_pad_config该结构体用于存储子设备的pad信息,包含以下成员:定义:
struct v4l2_subdev_pad_config {
struct v4l2_mbus_framefmt try_fmt;
struct v4l2_rect try_crop;
struct v4l2_rect try_compose;
};
try_fmt,结构体类型为structv4l2_mbus_framefmt,表示尝试使用的格式try_crop,结构体类型为structv4l2_rect,表示要用于剪裁的矩形区域try_compose,结构体类型为structv4l2_rect,表示要用于合成的矩形区域如果主参数的"which"字段设置为V4L2_SUBDEV_FORMAT_TRY,则只需将此结构体传递给pad操作。对于V4L2_SUBDEV_FORMAT_ACTIVE,可以安全地传递NULL。structv4l2_subdev_state该结构体用于存储子设备的状态信息定义:
struct v4l2_subdev_state {
struct v4l2_subdev_pad_config *pads;
};
包含以下成员:pads,指向v4l2_subdev_pad_config类型数组的指针。如果主参数的"which"字段设置为V4L2_SUBDEV_FORMAT_TRY,则只需将此结构体传递给pad操作。对于V4L2_SUBDEV_FORMAT_ACTIVE,可以安全地传递NULL。structv4l2_subdev_pad_ops为v4l2子设备的pad级别操作定义了一组回调函数定义:
struct v4l2_subdev_pad_ops {
int (*init_cfg)(struct v4l2_subdev *sd, struct v4l2_subdev_state *state);
int (*enum_mbus_code)(struct v4l2_subdev *sd,struct v4l2_subdev_state *state, struct v4l2_subdev_mbus_code_enum *code);
int (*enum_frame_size)(struct v4l2_subdev *sd,struct v4l2_subdev_state *state, struct v4l2_subdev_frame_size_enum *fse);
int (*enum_frame_interval)(struct v4l2_subdev *sd,struct v4l2_subdev_state *state, struct v4l2_subdev_frame_interval_enum *fie);
int (*get_fmt)(struct v4l2_subdev *sd,struct v4l2_subdev_state *state, struct v4l2_subdev_format *format);
int (*set_fmt)(struct v4l2_subdev *sd,struct v4l2_subdev_state *state, struct v4l2_subdev_format *format);
int (*get_selection)(struct v4l2_subdev *sd,struct v4l2_subdev_state *state, struct v4l2_subdev_selection *sel);
int (*set_selection)(struct v4l2_subdev *sd,struct v4l2_subdev_state *state, struct v4l2_subdev_selection *sel);
int (*get_edid)(struct v4l2_subdev *sd, struct v4l2_edid *edid);
int (*set_edid)(struct v4l2_subdev *sd, struct v4l2_edid *edid);
int (*dv_timings_cap)(struct v4l2_subdev *sd, struct v4l2_dv_timings_cap *cap);
int (*enum_dv_timings)(struct v4l2_subdev *sd, struct v4l2_enum_dv_timings *timings);
#ifdef CONFIG_MEDIA_CONTROLLER;
int (*link_validate)(struct v4l2_subdev *sd, struct media_link *link,struct v4l2 subdev_format *source_fmt, struct v4l2_subdev_format *sink_fmt);
#endif ;
int (*get_frame_desc)(struct v4l2_subdev *sd, unsigned int pad, struct v4l2_mbus_frame_desc *fd);
int (*set_frame_desc)(struct v4l2_subdev *sd, unsigned int pad, struct v4l2_mbus_frame_desc *fd);
int (*get_mbus_config)(struct v4l2_subdev *sd, unsigned int pad, struct v4l2_mbus_config *config);
int (*set_mbus_config)(struct v4l2_subdev *sd, unsigned int pad, struct v4l2_mbus_config *config);
};
包括:init_cfg函数,用于将pad配置初始化为默认值;enum_mbus_code函数,作为VIDIOC_SUBDEV_ENUM_MBUS_CODEioctlhandlercode的回调函数;enum_frame_size函数,作为VIDIOC_SUBDEV_ENUM_FRAME_SIZEioctlhandlercode的回调函数;enum_frame_interval函数,作为VIDIOC_SUBDEV_ENUM_FRAME_INTERVALioctlhandlercode的回调函数;get_fmt函数,作为VIDIOC_SUBDEV_G_FMTioctlhandlercode的回调函数;set_fmt函数,作为VIDIOC_SUBDEV_S_FMTioctlhandlercode的回调函数;get_selection函数,作为VIDIOC_SUBDEV_G_SELECTIONioctlhandlercode的回调函数;set_selection函数,作为VIDIOC_SUBDEV_S_SELECTIONioctlhandlercode的回调函数;get_edid函数,作为VIDIOC_SUBDEV_G_EDIDioctlhandlercode的回调函数;set_edid函数,作为VIDIOC_SUBDEV_S_EDIDioctlhandlercode的回调函数;1dv_timings_cap函数,作为VIDIOC_SUBDEV_DV_TIMINGS_CAPioctlhandlercode的回调函数;1enum_dv_timings函数,作为VIDIOC_SUBDEV_ENUM_DV_TIMINGSioctlhandlercode的回调函数;1link_validate函数,由媒体控制器代码使用,以检查属于管道的链接是否可用于流;1get_frame_desc函数,用于获取当前的低级媒体总线帧参数;1set_frame_desc函数,用于设置低级媒体总线帧参数,子设备驱动程序可以调整fd数组以适应设备能力;1get_mbus_config函数,用于获取远程子设备的媒体总线配置。媒体总线配置通常在子设备探测时从固件接口中检索,立即应用于硬件,并最终由驱动程序调整。远程子设备应使用此操作查询传输端总线配置,以相应地调整其自己的总线配置。调用者应确保他们从远程端获取了尽可能最新的配置,可能尽可能接近流媒体时间调用此操作。如果已调用的pad索引无效或发生不可恢复的故障,则操作将失败。1set_mbus_config函数,用于设置远程子设备的媒体总线配置。该操作旨在允许通过get_mbus_config操作协商媒体总线配置参数。如果所请求的配置不受支持,则操作不会失败,但驱动程序将更新config参数的内容以反映已实际应用于硬件的内容。如果已调用的pad索引无效或发生不可恢复的故障,则操作将失败。structv4l2_subdev_ops定义了v4l2子设备驱动程序需要实现的一组操作。定义:
struct v4l2_subdev_ops {
const struct v4l2_subdev_core_ops *core;
const struct v4l2_subdev_tuner_ops *tuner;
const struct v4l2_subdev_audio_ops *audio;
const struct v4l2_subdev_video_ops *video;
const struct v4l2_subdev_vbi_ops *vbi;
const struct v4l2_subdev_ir_ops *ir;
const struct v4l2_subdev_sensor_ops *sensor;
const struct v4l2_subdev_pad_ops *pad;
};
这些操作可分为以下几个部分:core:包含一组核心的回调函数,用于v4l2子设备的基本操作,例如在打开/关闭设备、查询设备信息、模块插入/拔出时调用。tuner:包含一组回调函数,用于操作Tuner模块,例如调整频道、改变调谐器的频率范围等操作。audio:包含一组回调函数,用于操作音频模块,例如设置音量、选择输入源等操作。video:包含一组回调函数,用于操作视频模块,例如捕获视频帧、设置像素格式、调整曝光、白平衡等操作。vbi:包含一组回调函数,用于操作VBI数据,例如捕获VBI数据、设置数据格式等操作。ir:包含一组回调函数,用于操作红外模块,例如发送/接收红外信号等操作。sensor:包含一组回调函数,用于与像传感器交互,例如配置传感器参数、启动/停止采集等操作。pad:包含一组回调函数,用于处理不同pad之间的数据流转,例如获取/设置帧格式、获取/设置数据选择等操作。这些操作函数的实现由子设备驱动程序负责,以完成对应的功能。在初始化v4l2子设备时,可以选择仅实现部分操作,从而适应不同的应用场景。structv4l2_subdev_internal_ops定义了v4l2子设备驱动程序内部使用的一组操作,这些操作函数只能由v4l2框架调用,驱动程序不能直接调用。定义:
struct v4l2_subdev_internal_ops {
int (*registered)(struct v4l2_subdev *sd);
void (*unregistered)(struct v4l2_subdev *sd);
int (*open)(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh);
int (*close)(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh);
void (*release)(struct v4l2_subdev *sd);
};
registered:当子设备被注册到V4L2系统中时,会调用这个函数。在这里完成对子设备结构体的初始化工作,例如申请内存等。unregistered:在子设备从V4L2系统中注销时,会调用这个函数。在这里进行清理工作,例如释放资源、回收内存等。open:当用户打开设备文件时,会调用这个函数。在这里进行相关的初始化工作,例如设置寄存器、启动数据流等。close:当用户关闭设备文件时,会调用这个函数。在这里进行相关的清理工作,例如停止数据流、关闭中断等。release:当最后一个用户关闭设备文件后,会调用这个函数。在这里进行相关的清理工作,并释放子设备的资源,例如回收内存、关闭相关外设等。需要注意的是,驱动程序不能直接调用这些操作函数,它们仅供v4l2框架使用,并且需要在子设备的ops结构体中进行注册。驱动程序可以根据需要选择实现这些操作中的部分或全部,以满足不同的应用场景。structv4l2_subdev_platform_data定义了子设备与平台通信时使用的一些数据和配置信息。定义:
struct v4l2_subdev_platform_data {
struct regulator_bulk_data *regulators;
int num_regulators;
void *host_priv;
};
regulators:用于控制子设备电源的电压、电流,从而实现开关子设备的操作。这是一个可选参数,通常由平台设备提供支持。num_regulators:regulators数组中元素的个数,即需要控制的电源数量。host_priv:用于保存与子设备相关的平台特定数据,例如平台设备的配置寄存器地址等。这些数据和配置信息通常由平台驱动程序提供给子设备驱动程序。子设备驱动程序可以在初始化过程中读取这些信息,并据此对子设备进行初始化、配置等操作。其中,regulators是一个非常重要的参数,主要用于控制子设备的电源,以确保能够正常工作。structv4l2_subdev定义了V4L2子设备的通用结构体,包含了子设备的各种属性和信息。定义:
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[V4L2_SUBDEV_NAME_SIZE];
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 v4l2_async_subdev *asd;
struct v4l2_async_notifier *notifier;
struct v4l2_async_notifier *subdev_notifier;
struct v4l2_subdev_platform_data *pdata;
};
entity:指向structmedia_entity结构体的指针,描述了该子设备在媒体设备拓扑中的位置和连接方式。owner:指向structdevice_driver结构体中的owner成员,表示该子设备的驱动程序所属的模块。flags:子设备的标志位,用于指示该子设备的类型、特性等信息。例如,是否为I2C或SPI设备,是否需要创建设备节点等。v4l2_dev:指向structv4l2_device结构体的指针,表示该子设备所属的v4l2设备。ops:指向structv4l2_subdev_ops结构体的指针,表示该子设备支持的操作函数集合。internal_ops:指向structv4l2_subdev_internal_ops结构体的指针,包含了驱动程序内部使用的一组操作函数。ctrl_handler:指向structv4l2_ctrl_handler结构体的指针,用于控制子设备的各种参数和属性。name:子设备的名字,必须是唯一的。grp_id:可以用于将多个类似的子设备进行分组,具体值由驱动程序决定。dev_priv:指向私有数据的指针,用于存储子设备的相关属性和状态。1host_priv:指向私有数据的指针,与平台相关,用于描述该子设备在平台中的位置和连接方式。1devnode:指向子设备节点的指针,用于创建和访问设备节点文件。1dev:指向物理设备的指针,如果该子设备是直接连接到物理设备上的,则指向该物理设备。1fwnode:指向fwnode_handle结构体的指针,表示该子设备在平台设备树中的节点。1async_list:链接到全局子设备列表或notifier->done列表的子设备列表。1asd:指向structv4l2_async_subdev结构体的指针,用于表示该子设备在异步子设备链表中的位置。1notifier:指向structv4l2_async_notifier结构体的指针,用于管理和通知异步事件的处理。1subdev_notifier:指向structv4l2_subdev_notifier结构体的指针,表示为该子设备隐式注册的子设备notifier。一般情况下,子设备驱动程序应该使用v4l2_subdev_init函数或其变种进行初始化。media_entity_to_v4l2_subdev函数返回包含在structmedia_entity结构体中的structv4l2_subdev结构体。参数ent是指向structmedia_entity结构体的指针。该函数的作用是通过指向media_entity结构体的指针,获取到media_entity所嵌套的v4l2_subdev结构体的指针。这个函数在底层框架中被广泛使用,用于将媒体实体和V4L2子设备关联起来。vdev_to_v4l2_subdev函数返回包含在structvideo_device结构体中的structv4l2_subdev结构体。参数vdev是指向structvideo_device结构体的指针。该函数的作用是通过指向video_device结构体的指针,获取到video_device所嵌套的v4l2_subdev结构体的指针。这个函数在Video4Linux框架中被广泛使用,用于将视频设备节点和V4L2子设备关联起来。structv4l2_subdev_fh结构体用于存储每个文件句柄所对应的V4L2子设备信息。定义:
struct v4l2_subdev_fh {
struct v4l2_fh vfh;
struct module *owner;
#if defined(CONFIG_VIDEO_V4L2_SUBDEV_API);
struct v4l2_subdev_state *state;
#endif;
};
文章为作者独立观点,不代表 股票程序化软件自动交易接口观点