diff options
| author | Kieran Bingham <kieran.bingham@ideasonboard.com> | 2018-05-25 16:31:33 +0100 | 
|---|---|---|
| committer | Laurent Pinchart <laurent.pinchart@ideasonboard.com> | 2018-05-26 18:33:26 +0300 | 
| commit | 7f04878e79b173dbaca546a283850f44188d8840 (patch) | |
| tree | 59fa5c5e5dea60b4d7e9a0dbd64907c735b33708 | |
| parent | 83fa2cb53742f43c3a254d0453bd96048ee29a82 (diff) | |
configfs: Handle interface numbers
Store the function configuration pointer in the uvc_device, and use it
to identify and store the interface numbers from configfs.
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
| -rw-r--r-- | configfs.c | 26 | ||||
| -rw-r--r-- | configfs.h | 3 | ||||
| -rw-r--r-- | uvc-gadget.c | 25 | 
3 files changed, 39 insertions, 15 deletions
| @@ -199,6 +199,9 @@ static char *udc_find_video_device(const char *udc, const char *function)   */  static const struct uvc_function_config g_webcam_config = { +	.control_interface = 0, +	.streaming_interface = 1, +  	.streaming_interval = 1,  	.streaming_maxburst = 0,  	.streaming_maxpacket = 1024, @@ -266,6 +269,26 @@ void configfs_free_uvc_function(struct uvc_function_config *fc)  	free(fc);  } +static int configfs_parse_interfaces(const char *fpath, +				     struct uvc_function_config *fc) +{ +	int ret; + +	ret = attribute_read_uint(fpath, "control/bInterfaceNumber", +				  &fc->control_interface); + +	ret = ret ? : attribute_read_uint(fpath, "streaming/bInterfaceNumber", +					  &fc->streaming_interface); + +	if (ret) { +		printf("Failed to obtain interface numbers, using defaults\n"); +		fc->control_interface = 0; +		fc->streaming_interface = 1; +	} + +	return 0; +} +  /*   * configfs_parse_uvc_function - Parse a UVC function configuration in ConfigFS   * @function: The function name @@ -323,6 +346,9 @@ struct uvc_function_config *configfs_parse_uvc_function(const char *function)  	if (!fc->video)  		ret = -ENODEV; +	/* Identify interface numbers, or fall back to defaults. */ +	configfs_parse_interfaces(fpath, fc); +  	ret = ret ? : attribute_read_uint(fpath, "streaming_interval",  					  &fc->streaming_interval); @@ -14,6 +14,9 @@ struct uvc_function_config {  	char *video;  	char *udc; +	unsigned int control_interface; +	unsigned int streaming_interface; +  	unsigned int streaming_interval;  	unsigned int streaming_maxburst;  	unsigned int streaming_maxpacket; diff --git a/uvc-gadget.c b/uvc-gadget.c index dbf1e10..96f9996 100644 --- a/uvc-gadget.c +++ b/uvc-gadget.c @@ -43,13 +43,12 @@  #include "tools.h"  #include "v4l2.h" -#define UVC_INTF_CONTROL	0 -#define UVC_INTF_STREAMING	1 -  struct uvc_device  {  	struct v4l2_device *vdev; +	struct uvc_function_config *fc; +  	struct uvc_streaming_control probe;  	struct uvc_streaming_control commit; @@ -410,21 +409,15 @@ uvc_events_process_class(struct uvc_device *dev,  			 const struct usb_ctrlrequest *ctrl,  			 struct uvc_request_data *resp)  { +	unsigned int interface = ctrl->wIndex & 0xff; +  	if ((ctrl->bRequestType & USB_RECIP_MASK) != USB_RECIP_INTERFACE)  		return; -	switch (ctrl->wIndex & 0xff) { -	case UVC_INTF_CONTROL: +	if (interface == dev->fc->control_interface)  		uvc_events_process_control(dev, ctrl->bRequest, ctrl->wValue >> 8, resp); -		break; - -	case UVC_INTF_STREAMING: +	else if (interface == dev->fc->streaming_interface)  		uvc_events_process_streaming(dev, ctrl->bRequest, ctrl->wValue >> 8, resp); -		break; - -	default: -		break; -	}  }  static void @@ -611,12 +604,14 @@ static void uvc_stream_delete(struct uvc_stream *stream)  	free(stream);  } -static void uvc_stream_init_uvc(struct uvc_stream *stream) +static void uvc_stream_init_uvc(struct uvc_stream *stream, +				struct uvc_function_config *fc)  {  	/*  	 * FIXME: The maximum size should be specified per format and frame.  	 */  	stream->uvc->maxsize = 0; +	stream->uvc->fc = fc;  	uvc_events_init(stream->uvc);  	uvc_video_init(stream->uvc); @@ -725,7 +720,7 @@ int main(int argc, char *argv[])  		goto done;  	} -	uvc_stream_init_uvc(stream); +	uvc_stream_init_uvc(stream, fc);  	uvc_stream_set_event_handler(stream, &events);  	/* Main capture loop */ | 
