linux V4L2子系统——v4l2的结构体(3)之v4l2_subdev
子设备,负责实现具体的功能。可将其抽象为具体的某一摄像头传感器,如OV7740、OV7251、OV5640等。
·
linux V4L2子系统——v4l2的结构体(3)之v4l2_subdev
备注:
1. Kernel版本:5.4
2. 使用工具:Source Insight 4.0
文章目录
简介
子设备,负责实现具体的功能。可将其抽象为具体的某一摄像头传感器,如OV7740、OV7251、OV5640等。
每一个子设备驱动都必须有一个 v4l2_subdev
结构体,这个结构体可以作为独立的简单子设备存在,也可以嵌入到更大的结构体(自定义的子设备结构体)里面。通常会有一个由内核设置的低层次结构体(i2c_client
,也就是上面说的 i2c 设备),它包含了一些设备数据,要调用 v4l2_set_subdevdata
来设置子设备私有数据指针指向它,这样的话就可以很方便的从 subdev 找到相关的 I2C 设备数据(这个要编程实现的时候才能够了解它的用意)。另外也需要设置低级别结构的私有数据指针指向 v4l2_subdev
结构体,方便从低级别的结构体访问 v4l2_subdev
结构体,达到双向访问的目的,对于 i2c_client
来说,可以用 i2c_set_clientdata
函数来设置,其它的需使用与之相应的函数来完成设置。
定义
struct v4l2_subdev
//源码:include/media/v4l2-subdev.h
/* Set this flag if this subdev is a i2c device. */
#define V4L2_SUBDEV_FL_IS_I2C (1U << 0) // 从设备是I2C设备
/* Set this flag if this subdev is a spi device. */
#define V4L2_SUBDEV_FL_IS_SPI (1U << 1) // 从设备是SPI设备
/* Set this flag if this subdev needs a device node. */
#define V4L2_SUBDEV_FL_HAS_DEVNODE (1U << 2) // 从设备需要设备节点
/*
* Set this flag if this subdev generates events.
* Note controls can send events, thus drivers exposing controls
* should set this flag.
*/
#define V4L2_SUBDEV_FL_HAS_EVENTS (1U << 3) // 从设备会产生事件
/**
* struct v4l2_subdev - describes a V4L2 sub-device
*
* @entity: pointer to &struct media_entity
* @list: List of sub-devices
* @owner: The owner is the same as the driver's &struct device owner.
* @owner_v4l2_dev: true if the &sd->owner matches the owner of @v4l2_dev->dev
* owner. Initialized by v4l2_device_register_subdev().
* @flags: subdev flags. Can be:
* %V4L2_SUBDEV_FL_IS_I2C - Set this flag if this subdev is a i2c device;
* %V4L2_SUBDEV_FL_IS_SPI - Set this flag if this subdev is a spi device;
* %V4L2_SUBDEV_FL_HAS_DEVNODE - Set this flag if this subdev needs a
* device node;
* %V4L2_SUBDEV_FL_HAS_EVENTS - Set this flag if this subdev generates
* events.
*
* @v4l2_dev: pointer to struct &v4l2_device
* @ops: pointer to struct &v4l2_subdev_ops
* @internal_ops: pointer to struct &v4l2_subdev_internal_ops.
* Never call these internal ops from within a driver!
* @ctrl_handler: The control handler of this subdev. May be NULL.
* @name: Name of the sub-device. Please notice that the name must be unique.
* @grp_id: can be used to group similar subdevs. Value is driver-specific
* @dev_priv: pointer to private data
* @host_priv: pointer to private data used by the device where the subdev
* is attached.
* @devnode: subdev device node
* @dev: pointer to the physical device, if any
* @fwnode: The fwnode_handle of the subdev, usually the same as
* either dev->of_node->fwnode or dev->fwnode (whichever is non-NULL).
* @async_list: Links this subdev to a global subdev_list or @notifier->done
* list.
* @asd: Pointer to respective &struct v4l2_async_subdev.
* @notifier: Pointer to the managing notifier.
* @subdev_notifier: A sub-device notifier implicitly registered for the sub-
* device using v4l2_device_register_sensor_subdev().
* @pdata: common part of subdevice platform data
*
* Each instance of a subdev driver should create this struct, either
* stand-alone or embedded in a larger struct.
*
* This structure should be initialized by v4l2_subdev_init() or one of
* its variants: v4l2_spi_subdev_init(), v4l2_i2c_subdev_init().
*/
struct v4l2_subdev {
#if defined(CONFIG_MEDIA_CONTROLLER)
struct media_entity entity;
#endif
struct list_head list; // 子设备串联链表
struct module *owner; // 属于那个模块,一般指向i2c_lient驱动模块
bool owner_v4l2_dev;
u32 flags; // 标志位,确定该设备属于那种设备,由V4L2_SUBDEV_FL_IS_XX宏确定
// 指向父设备
struct v4l2_device *v4l2_dev;
// v4l2子设备的操作函数集合
const struct v4l2_subdev_ops *ops;
// 提供给v4l2框架的操作函数,只有v4l2框架会调用,驱动不使用
const struct v4l2_subdev_internal_ops *internal_ops;
// subdev控制接口
struct v4l2_ctrl_handler *ctrl_handler;
// name must be unique
// 从设备的名称,必须独一无二
char name[V4L2_SUBDEV_NAME_SIZE];
// 从设备组的ID,由驱动定义,相似的从设备可以编为一组
u32 grp_id;
// 从设备私有数据指针,一般指向i2c_client的设备结构体dev
void *dev_priv;
// 主设备私有数据指针,一般指向v4l2_device嵌入的结构体
void *host_priv;
// 指向video设备结构体
struct video_device *devnode;
// 指向物理设备
struct device *dev;
struct fwnode_handle *fwnode;
// 将所有从设备连接到全局subdev_list链表或notifier->done链表
struct list_head async_list;
// 指向struct v4l2_async_subdev,用于异步事件
struct v4l2_async_subdev *asd;
// 指向管理的notifier,用于主设备和从设备的异步关联
struct v4l2_async_notifier *notifier;
struct v4l2_async_notifier *subdev_notifier;
/* common part of subdevice platform data */
struct v4l2_subdev_platform_data *pdata;
};
struct v4l2_subdev_ops
//源码:include/media/v4l2-subdev.h
/**
* struct v4l2_subdev_ops - Subdev operations
*
* @core: pointer to &struct v4l2_subdev_core_ops. Can be %NULL
* @tuner: pointer to &struct v4l2_subdev_tuner_ops. Can be %NULL
* @audio: pointer to &struct v4l2_subdev_audio_ops. Can be %NULL
* @video: pointer to &struct v4l2_subdev_video_ops. Can be %NULL
* @vbi: pointer to &struct v4l2_subdev_vbi_ops. Can be %NULL
* @ir: pointer to &struct v4l2_subdev_ir_ops. Can be %NULL
* @sensor: pointer to &struct v4l2_subdev_sensor_ops. Can be %NULL
* @pad: pointer to &struct v4l2_subdev_pad_ops. Can be %NULL
*/
struct v4l2_subdev_ops {
//视频设备通用的操作:初始化、加载FW、上电和RESET等
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;
};
struct v4l2_subdev_core_ops
//源码:include/media/v4l2-subdev.h
/**
* struct v4l2_subdev_core_ops - Define core ops callbacks for subdevs
*
* @log_status: callback for VIDIOC_LOG_STATUS() ioctl handler code.
*
* @s_io_pin_config: configure one or more chip I/O pins for chips that
* multiplex different internal signal pads out to IO pins. This function
* takes a pointer to an array of 'n' pin configuration entries, one for
* each pin being configured. This function could be called at times
* other than just subdevice initialization.
*
* @init: initialize the sensor registers to some sort of reasonable default
* values. Do not use for new drivers and should be removed in existing
* drivers.
*
* @load_fw: load firmware.
*
* @reset: generic reset command. The argument selects which subsystems to
* reset. Passing 0 will always reset the whole chip. Do not use for new
* drivers without discussing this first on the linux-media mailinglist.
* There should be no reason normally to reset a device.
*
* @s_gpio: set GPIO pins. Very simple right now, might need to be extended with
* a direction argument if needed.
*
* @ioctl: called at the end of ioctl() syscall handler at the V4L2 core.
* used to provide support for private ioctls used on the driver.
*
* @compat_ioctl32: called when a 32 bits application uses a 64 bits Kernel,
* in order to fix data passed from/to userspace.
*
* @g_register: callback for VIDIOC_DBG_G_REGISTER() ioctl handler code.
*
* @s_register: callback for VIDIOC_DBG_S_REGISTER() ioctl handler code.
*
* @s_power: puts subdevice in power saving mode (on == 0) or normal operation
* mode (on == 1).
*
* @interrupt_service_routine: Called by the bridge chip's interrupt service
* handler, when an interrupt status has be raised due to this subdev,
* so that this subdev can handle the details. It may schedule work to be
* performed later. It must not sleep. **Called from an IRQ context**.
*
* @subscribe_event: used by the drivers to request the control framework that
* for it to be warned when the value of a control changes.
*
* @unsubscribe_event: remove event subscription from the control framework.
*/
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); /* 加载firmware */
int (*reset)(struct v4l2_subdev *sd, u32 val); /* 重置设备 */
int (*s_gpio)(struct v4l2_subdev *sd, u32 val); /* 设置gpio */
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);
};
struct v4l2_subdev_tuner_ops
//源码:include/media/v4l2-subdev.h
/**
* struct v4l2_subdev_tuner_ops - Callbacks used when v4l device was opened
* in radio mode.
*
* @standby: puts the tuner in standby mode. It will be woken up
* automatically the next time it is used.
*
* @s_radio: callback that switches the tuner to radio mode.
* drivers should explicitly call it when a tuner ops should
* operate on radio mode, before being able to handle it.
* Used on devices that have both AM/FM radio receiver and TV.
*
* @s_frequency: callback for VIDIOC_S_FREQUENCY() ioctl handler code.
*
* @g_frequency: callback for VIDIOC_G_FREQUENCY() ioctl handler code.
* freq->type must be filled in. Normally done by video_ioctl2()
* or the bridge driver.
*
* @enum_freq_bands: callback for VIDIOC_ENUM_FREQ_BANDS() ioctl handler code.
*
* @g_tuner: callback for VIDIOC_G_TUNER() ioctl handler code.
*
* @s_tuner: callback for VIDIOC_S_TUNER() ioctl handler code. @vt->type must be
* filled in. Normally done by video_ioctl2 or the
* bridge driver.
*
* @g_modulator: callback for VIDIOC_G_MODULATOR() ioctl handler code.
*
* @s_modulator: callback for VIDIOC_S_MODULATOR() ioctl handler code.
*
* @s_type_addr: sets tuner type and its I2C addr.
*
* @s_config: sets tda9887 specific stuff, like port1, port2 and qss
*
* .. note::
*
* On devices that have both AM/FM and TV, it is up to the driver
* to explicitly call s_radio when the tuner should be switched to
* radio mode, before handling other &struct v4l2_subdev_tuner_ops
* that would require it. An example of such usage is::
*
* 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);
* }
*/
struct v4l2_subdev_tuner_ops {
int (*standby)(struct v4l2_subdev *sd); /* 控制standby模式 */
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); /* 设置配置信息 */
};
struct v4l2_subdev_audio_ops
//源码:include/media/v4l2-subdev.h
/**
* struct v4l2_subdev_audio_ops - Callbacks used for audio-related settings
*
* @s_clock_freq: set the frequency (in Hz) of the audio clock output.
* Used to slave an audio processor to the video decoder, ensuring that
* audio and video remain synchronized. Usual values for the frequency
* are 48000, 44100 or 32000 Hz. If the frequency is not supported, then
* -EINVAL is returned.
*
* @s_i2s_clock_freq: sets I2S speed in bps. This is used to provide a standard
* way to select I2S clock used by driving digital audio streams at some
* board designs. Usual values for the frequency are 1024000 and 2048000.
* If the frequency is not supported, then %-EINVAL is returned.
*
* @s_routing: used to define the input and/or output pins of an audio chip,
* and any additional configuration data.
* Never attempt to use user-level input IDs (e.g. Composite, S-Video,
* Tuner) at this level. An i2c device shouldn't know about whether an
* input pin is connected to a Composite connector, become on another
* board or platform it might be connected to something else entirely.
* The calling driver is responsible for mapping a user-level input to
* the right pins on the i2c device.
*
* @s_stream: used to notify the audio code that stream will start or has
* stopped.
*/
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); /* 设置i2s总线频率 */
int (*s_routing)(struct v4l2_subdev *sd, u32 input, u32 output, u32 config); /* 设置音频路由 */
int (*s_stream)(struct v4l2_subdev *sd, int enable); /* 控制音频流 */
};
struct v4l2_subdev_video_ops
//源码:include/media/v4l2-subdev.h
/**
* struct v4l2_subdev_video_ops - Callbacks used when v4l device was opened
* in video mode.
*
* @s_routing: see s_routing in audio_ops, except this version is for video
* devices.
*
* @s_crystal_freq: sets the frequency of the crystal used to generate the
* clocks in Hz. An extra flags field allows device specific configuration
* regarding clock frequency dividers, etc. If not used, then set flags
* to 0. If the frequency is not supported, then -EINVAL is returned.
*
* @g_std: callback for VIDIOC_G_STD() ioctl handler code.
*
* @s_std: callback for VIDIOC_S_STD() ioctl handler code.
*
* @s_std_output: set v4l2_std_id for video OUTPUT devices. This is ignored by
* video input devices.
*
* @g_std_output: get current standard for video OUTPUT devices. This is ignored
* by video input devices.
*
* @querystd: callback for VIDIOC_QUERYSTD() ioctl handler code.
*
* @g_tvnorms: get &v4l2_std_id with all standards supported by the video
* CAPTURE device. This is ignored by video output devices.
*
* @g_tvnorms_output: get v4l2_std_id with all standards supported by the video
* OUTPUT device. This is ignored by video capture devices.
*
* @g_input_status: get input status. Same as the status field in the
* &struct &v4l2_input
*
* @s_stream: used to notify the driver that a video stream will start or has
* stopped.
*
* @g_pixelaspect: callback to return the pixelaspect ratio.
*
* @g_frame_interval: callback for VIDIOC_SUBDEV_G_FRAME_INTERVAL()
* ioctl handler code.
*
* @s_frame_interval: callback for VIDIOC_SUBDEV_S_FRAME_INTERVAL()
* ioctl handler code.
*
* @s_dv_timings: Set custom dv timings in the sub device. This is used
* when sub device is capable of setting detailed timing information
* in the hardware to generate/detect the video signal.
*
* @g_dv_timings: Get custom dv timings in the sub device.
*
* @query_dv_timings: callback for VIDIOC_QUERY_DV_TIMINGS() ioctl handler code.
*
* @g_mbus_config: get supported mediabus configurations
*
* @s_mbus_config: set a certain mediabus configuration. This operation is added
* for compatibility with soc-camera drivers and should not be used by new
* software.
*
* @s_rx_buffer: set a host allocated memory buffer for the subdev. The subdev
* can adjust @size to a lower value and must not write more data to the
* buffer starting at @data than the original value of @size.
*/
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);
// 获取总线配置,对于 MIPI接口,
// sensor驱动内若支持不同 lane数配置或者支持 HDR,
// 通过这个接口返回当前 sensor 工作模式下的MIPI配置
int (*g_mbus_config)(struct v4l2_subdev *sd,
struct v4l2_mbus_config *cfg);
int (*s_mbus_config)(struct v4l2_subdev *sd,
const struct v4l2_mbus_config *cfg);
int (*s_rx_buffer)(struct v4l2_subdev *sd, void *buf,
unsigned int *size);
};
struct v4l2_subdev_pad_ops
//源码:include/media/v4l2-subdev.h
/**
* struct v4l2_subdev_pad_ops - v4l2-subdev pad level operations
*
* @init_cfg: initialize the pad config to default values
* @enum_mbus_code: callback for VIDIOC_SUBDEV_ENUM_MBUS_CODE() ioctl handler
* code.
* @enum_frame_size: callback for VIDIOC_SUBDEV_ENUM_FRAME_SIZE() ioctl handler
* code.
*
* @enum_frame_interval: callback for VIDIOC_SUBDEV_ENUM_FRAME_INTERVAL() ioctl
* handler code.
*
* @get_fmt: callback for VIDIOC_SUBDEV_G_FMT() ioctl handler code.
*
* @set_fmt: callback for VIDIOC_SUBDEV_S_FMT() ioctl handler code.
*
* @get_selection: callback for VIDIOC_SUBDEV_G_SELECTION() ioctl handler code.
*
* @set_selection: callback for VIDIOC_SUBDEV_S_SELECTION() ioctl handler code.
*
* @get_edid: callback for VIDIOC_SUBDEV_G_EDID() ioctl handler code.
*
* @set_edid: callback for VIDIOC_SUBDEV_S_EDID() ioctl handler code.
*
* @dv_timings_cap: callback for VIDIOC_SUBDEV_DV_TIMINGS_CAP() ioctl handler
* code.
*
* @enum_dv_timings: callback for VIDIOC_SUBDEV_ENUM_DV_TIMINGS() ioctl handler
* code.
*
* @link_validate: used by the media controller code to check if the links
* that belongs to a pipeline can be used for stream.
*
* @get_frame_desc: get the current low level media bus frame parameters.
*
* @set_frame_desc: set the low level media bus frame parameters, @fd array
* may be adjusted by the subdev driver to device capabilities.
*/
struct v4l2_subdev_pad_ops {
int (*init_cfg)(struct v4l2_subdev *sd,
struct v4l2_subdev_pad_config *cfg);
// 枚举当前CIS 驱动支持数据格式
int (*enum_mbus_code)(struct v4l2_subdev *sd,
struct v4l2_subdev_pad_config *cfg,
struct v4l2_subdev_mbus_code_enum *code);
// 枚举当前CIS 驱动支持分辨率
int (*enum_frame_size)(struct v4l2_subdev *sd,
struct v4l2_subdev_pad_config *cfg,
struct v4l2_subdev_frame_size_enum *fse);
// 枚举sensor支持的帧间隔,包含分辨率
int (*enum_frame_interval)(struct v4l2_subdev *sd,
struct v4l2_subdev_pad_config *cfg,
struct v4l2_subdev_frame_interval_enum *fie);
// 枚举当前CIS 驱动支持分辨率
int (*get_fmt)(struct v4l2_subdev *sd,
struct v4l2_subdev_pad_config *cfg,
struct v4l2_subdev_format *format);
//设置CIS 驱动输出数据格式以及分辨率,务必实现
int (*set_fmt)(struct v4l2_subdev *sd,
struct v4l2_subdev_pad_config *cfg,
struct v4l2_subdev_format *format);
// 配置裁剪参数,isp输入的宽度要求16对齐,高度 8 对齐
int (*get_selection)(struct v4l2_subdev *sd,
struct v4l2_subdev_pad_config *cfg,
struct v4l2_subdev_selection *sel);
int (*set_selection)(struct v4l2_subdev *sd,
struct v4l2_subdev_pad_config *cfg,
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 /* CONFIG_MEDIA_CONTROLLER */
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);
};
更多推荐
已为社区贡献7条内容
所有评论(0)