webcam.c和f_uvc.c驱动分析(一)

static int __init webcam_init(void)
{
	return usb_composite_probe(&webcam_driver, webcam_bind);
}

static void __exit
webcam_cleanup(void)
{
	usb_composite_unregister(&webcam_driver);
}

通过usb_composite_probe()函数将usb_composite_driver结构体和webcam_bind绑定在一起。

进入usb_composite_probe看一看,将驱动功能和参数传递下去

struct usb_gadget_driver {
	char			*function;
	enum usb_device_speed	max_speed;
	void			(*unbind)(struct usb_gadget *);
	int			(*setup)(struct usb_gadget *,
					const struct usb_ctrlrequest *);
	void			(*disconnect)(struct usb_gadget *);
	void			(*suspend)(struct usb_gadget *);
	void			(*resume)(struct usb_gadget *);

	/* FIXME support safe rmmod */
	struct device_driver	driver;
};

int usb_composite_probe(struct usb_composite_driver *driver,
			       int (*bind)(struct usb_composite_dev *cdev))
{
	if (!driver || !driver->dev || !bind || composite)    //判断
		return -EINVAL;

	if (!driver->name)
		driver->name = "composite";
	if (!driver->iProduct)
		driver->iProduct = driver->name;
	composite_driver.function =  (char *) driver->name;    //接口功能名字
	composite_driver.driver.name = driver->name;        //驱动名字
	composite_driver.max_speed =
		min_t(u8, composite_driver.max_speed, driver->max_speed);
	composite = driver;    //绑定复合驱动结构体
	composite_gadget_bind = bind;    //

	return usb_gadget_probe_driver(&composite_driver, composite_bind);
}

return usb_gadget_probe_driver(&composite_driver, composite_bind)。 调用composite.c中的函数,该代码一般不用修改。

        回到usb_composite_probe(&webcam_driver, webcam_bind);webcam_driver必须被填充

static struct usb_composite_driver webcam_driver = {
	.name		= "drive_name",
	.dev		= &webcam_device_descriptor,
	.strings	= webcam_device_strings,
	.max_speed	= USB_SPEED_HIGH,
	.unbind		= webcam_unbind,
};

struct usb_composite_driver {
	const char				*name;    //驱动名字
	const char				*iProduct;    //厂商自定义
	const char				*iManufacturer;    //厂商自定义
	const struct usb_device_descriptor	*dev;    //最重要的设备描述符
	struct usb_gadget_strings		**strings;    //绑定语言和camera的名字
	enum usb_device_speed			max_speed;
	unsigned		needs_serial:1;

	int			(*unbind)(struct usb_composite_dev *);

	void			(*disconnect)(struct usb_composite_dev *);

	/* global suspend hooks */
	void			(*suspend)(struct usb_composite_dev *);
	void			(*resume)(struct usb_composite_dev *);
};

看向webcam_bind()函数,usb_add_config()由composite.c提供,我们负责填充里面的参数。usb_composite_dev *cdev先不理会。

	if ((ret = usb_add_config(cdev, &webcam_config_driver,
					webcam_config_bind)) < 0)

看向usb_configuration webcam_config_driver配置,

struct usb_configuration {
	const char			*label;    //usb版本:USB2.0 USB3.0
	struct usb_gadget_strings	**strings;
	const struct usb_descriptor_header **descriptors;

	/* REVISIT:  bind() functions can be marked __init, which
	 * makes trouble for section mismatch analysis.  See if
	 * we can't restructure things to avoid mismatching...
	 */

	/* configuration management: unbind/setup */
	void			(*unbind)(struct usb_configuration *);
	int			(*setup)(struct usb_configuration *,
					const struct usb_ctrlrequest *);

	/* fields in the config descriptor */
	u8			bConfigurationValue;
	u8			iConfiguration;
	u8			bmAttributes;
	u8			bMaxPower;

	struct usb_composite_dev	*cdev;

	/* private: */
	/* internals */
	struct list_head	list;
	struct list_head	functions;
	u8			next_interface_id;
	unsigned		superspeed:1;
	unsigned		highspeed:1;
	unsigned		fullspeed:1;
	struct usb_function	*interface[MAX_CONFIG_INTERFACES];
};


/* from config descriptor bmAttributes */
#define USB_CONFIG_ATT_ONE		(1 << 7)	/* must be set */
#define USB_CONFIG_ATT_SELFPOWER	(1 << 6)	/* self powered */
#define USB_CONFIG_ATT_WAKEUP		(1 << 5)	/* can wakeup */
#define USB_CONFIG_ATT_BATTERY		(1 << 4)	/* battery powered */

看向webcam_config_bind中的uvc_bind_config(c, uvc_control_cls, uvc_fs_streaming_cls,

uvc_hs_streaming_cls); 调用到f_uvc.c中进行UVC控制类和UVC视频类的绑定。

UVC控制类

static const struct uvc_descriptor_header * const uvc_control_cls[] = {
	(const struct uvc_descriptor_header *) &uvc_control_header,
	(const struct uvc_descriptor_header *) &uvc_camera_terminal,
	(const struct uvc_descriptor_header *) &uvc_processing,
	(const struct uvc_descriptor_header *) &uvc_xu_extdesc,
	(const struct uvc_descriptor_header *) &uvc_output_terminal,
	NULL,
};

uvc_control_header  控制接口?不确定


uvc_control_header = {
	.bLength			= UVC_DT_HEADER_SIZE(1),
	.bDescriptorType	= USB_DT_CS_INTERFACE,
	.bDescriptorSubType	= UVC_VC_HEADER,    //video control header
	.bcdUVC				= cpu_to_le16(0x0150),    //UVC的版本
	.wTotalLength		= cpu_to_le16(0x0050), /* 描述符长度*/
	.dwClockFrequency	= cpu_to_le32(48000000),  //时钟
	.bInCollection		= 1, /* dynamic */
	.baInterfaceNr[0]	= 1, /* dynamic */
};

uvc_camera_terminal,CT描述符。相机需要支持什命令就需要在这里添加对应的功能。

static const struct uvc_camera_terminal_descriptor uvc_camera_terminal = {
	.bLength			= UVC_DT_CAMERA_TERMINAL_SIZE(3),
	.bDescriptorType	= USB_DT_CS_INTERFACE,
	.bDescriptorSubType	= UVC_VC_INPUT_TERMINAL,//视频类特定的VC接口描述子类型  
	.bTerminalID		= UVC_ENTITY_ID_INPUT_TERMINAL,
	.wTerminalType		= cpu_to_le16(UVC_ITT_CAMERA),
	.bAssocTerminal		= 0,
	.iTerminal			= 0,
	.wObjectiveFocalLengthMin	= cpu_to_le16(0),
	.wObjectiveFocalLengthMax	= cpu_to_le16(0),
	.wOcularFocalLength		    = cpu_to_le16(0),
	.bControlSize				= 3,//对照UVC协议的CT控制
    .bmControls[0]		= 0x00,
	.bmControls[1]		= 0x00,
	.bmControls[2]		= 0x00,
	.wObjectiveFocalLengthMin	= cpu_to_le16(0),
	.wObjectiveFocalLengthMax	= cpu_to_le16(0),
	.wOcularFocalLength		    = cpu_to_le16(0),
	.bControlSize		= 3,
	.bmControls[0]		= 0x00,	
	.bmControls[1]		= 0x00,	
	.bmControls[2]		= 0x00,

};
static  struct uvc_processing_unit_descriptor uvc_processing = {
	.bLength			= UVC_DT_PROCESSING_UNIT_SIZE(2),
	.bDescriptorType	= USB_DT_CS_INTERFACE,
	.bDescriptorSubType	= UVC_VC_PROCESSING_UNIT,
	.bUnitID			= UVC_ENTITY_ID_PROCESSING_UNIT,
	.bSourceID			= UVC_ENTITY_ID_INPUT_TERMINAL,
	.wMaxMultiplier		= cpu_to_le16(0x4000),
	.bControlSize		= 2,
	.bmControls[0]		= 0xff, 	// PU的控制选项
	.bmControls[1]		= 0xff,		// 
	.bmVideoStandards   = 0 //UVC 1.0 no support

};

uvc_processing。PU描述符,亮度与对比度之类功能添加,具体看UVC协议。

uvc_output_terminal_descriptor uvc_output_terminal端点描述符。bSourceID意为与其他单元的连接,如CT单元、PU单元。

static const struct uvc_output_terminal_descriptor uvc_output_terminal = {
	.bLength			= UVC_DT_OUTPUT_TERMINAL_SIZE,
	.bDescriptorType	= USB_DT_CS_INTERFACE,
	.bDescriptorSubType	= UVC_VC_OUTPUT_TERMINAL,
	.bTerminalID		= UVC_ENTITY_ID_OUTPUT_TERMINAL,
	.wTerminalType		= cpu_to_le16(0x0101),
	.bAssocTerminal		= 0,
	.bSourceID			= UVC_ENTITY_ID_XU_H264,//UVC_ENTITY_ID_PROCESSING_UNIT,
	.iTerminal			= 0,
};

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值