Commit 46919a23 authored by Andrzej Pietrasiewicz's avatar Andrzej Pietrasiewicz Committed by Felipe Balbi

usb: gadget: uvc: configfs support in uvc function

Add support for using the uvc function as a component of USB gadgets composed
with configfs.
Acked-by: default avatarLaurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: default avatarAndrzej Pietrasiewicz <andrzej.p@samsung.com>
Signed-off-by: default avatarFelipe Balbi <balbi@ti.com>
parent 6c25955e
What: /config/usb-gadget/gadget/functions/uvc.name
Date: Dec 2014
KernelVersion: 3.20
Description: UVC function directory
streaming_maxburst - 0..15 (ss only)
streaming_maxpacket - 1..1023 (fs), 1..3072 (hs/ss)
streaming_interval - 1..16
What: /config/usb-gadget/gadget/functions/uvc.name/control
Date: Dec 2014
KernelVersion: 3.20
Description: Control descriptors
What: /config/usb-gadget/gadget/functions/uvc.name/control/class
Date: Dec 2014
KernelVersion: 3.20
Description: Class descriptors
What: /config/usb-gadget/gadget/functions/uvc.name/control/class/ss
Date: Dec 2014
KernelVersion: 3.20
Description: Super speed control class descriptors
What: /config/usb-gadget/gadget/functions/uvc.name/control/class/fs
Date: Dec 2014
KernelVersion: 3.20
Description: Full speed control class descriptors
What: /config/usb-gadget/gadget/functions/uvc.name/control/terminal
Date: Dec 2014
KernelVersion: 3.20
Description: Terminal descriptors
What: /config/usb-gadget/gadget/functions/uvc.name/control/terminal/output
Date: Dec 2014
KernelVersion: 3.20
Description: Output terminal descriptors
What: /config/usb-gadget/gadget/functions/uvc.name/control/terminal/output/default
Date: Dec 2014
KernelVersion: 3.20
Description: Default output terminal descriptors
All attributes read only:
iTerminal - index of string descriptor
bSourceID - id of the terminal to which this terminal
is connected
bAssocTerminal - id of the input terminal to which this output
terminal is associated
wTerminalType - terminal type
bTerminalID - a non-zero id of this terminal
What: /config/usb-gadget/gadget/functions/uvc.name/control/terminal/camera
Date: Dec 2014
KernelVersion: 3.20
Description: Camera terminal descriptors
What: /config/usb-gadget/gadget/functions/uvc.name/control/terminal/camera/default
Date: Dec 2014
KernelVersion: 3.20
Description: Default camera terminal descriptors
All attributes read only:
bmControls - bitmap specifying which controls are
supported for the video stream
wOcularFocalLength - the value of Locular
wObjectiveFocalLengthMax- the value of Lmin
wObjectiveFocalLengthMin- the value of Lmax
iTerminal - index of string descriptor
bAssocTerminal - id of the output terminal to which
this terminal is connected
wTerminalType - terminal type
bTerminalID - a non-zero id of this terminal
What: /config/usb-gadget/gadget/functions/uvc.name/control/processing
Date: Dec 2014
KernelVersion: 3.20
Description: Processing unit descriptors
What: /config/usb-gadget/gadget/functions/uvc.name/control/processing/default
Date: Dec 2014
KernelVersion: 3.20
Description: Default processing unit descriptors
All attributes read only:
iProcessing - index of string descriptor
bmControls - bitmap specifying which controls are
supported for the video stream
wMaxMultiplier - maximum digital magnification x100
bSourceID - id of the terminal to which this unit is
connected
bUnitID - a non-zero id of this unit
What: /config/usb-gadget/gadget/functions/uvc.name/control/header
Date: Dec 2014
KernelVersion: 3.20
Description: Control header descriptors
What: /config/usb-gadget/gadget/functions/uvc.name/control/header/name
Date: Dec 2014
KernelVersion: 3.20
Description: Specific control header descriptors
dwClockFrequency
bcdUVC
What: /config/usb-gadget/gadget/functions/uvc.name/streaming
Date: Dec 2014
KernelVersion: 3.20
Description: Streaming descriptors
What: /config/usb-gadget/gadget/functions/uvc.name/streaming/class
Date: Dec 2014
KernelVersion: 3.20
Description: Streaming class descriptors
What: /config/usb-gadget/gadget/functions/uvc.name/streaming/class/ss
Date: Dec 2014
KernelVersion: 3.20
Description: Super speed streaming class descriptors
What: /config/usb-gadget/gadget/functions/uvc.name/streaming/class/hs
Date: Dec 2014
KernelVersion: 3.20
Description: High speed streaming class descriptors
What: /config/usb-gadget/gadget/functions/uvc.name/streaming/class/fs
Date: Dec 2014
KernelVersion: 3.20
Description: Full speed streaming class descriptors
What: /config/usb-gadget/gadget/functions/uvc.name/streaming/color_matching
Date: Dec 2014
KernelVersion: 3.20
Description: Color matching descriptors
What: /config/usb-gadget/gadget/functions/uvc.name/streaming/color_matching/default
Date: Dec 2014
KernelVersion: 3.20
Description: Default color matching descriptors
All attributes read only:
bMatrixCoefficients - matrix used to compute luma and
chroma values from the color primaries
bTransferCharacteristics- optoelectronic transfer
characteristic of the source picutre,
also called the gamma function
bColorPrimaries - color primaries and the reference
white
What: /config/usb-gadget/gadget/functions/uvc.name/streaming/mjpeg
Date: Dec 2014
KernelVersion: 3.20
Description: MJPEG format descriptors
What: /config/usb-gadget/gadget/functions/uvc.name/streaming/mjpeg/name
Date: Dec 2014
KernelVersion: 3.20
Description: Specific MJPEG format descriptors
All attributes read only,
except bmaControls and bDefaultFrameIndex:
bmaControls - this format's data for bmaControls in
the streaming header
bmInterfaceFlags - specifies interlace information,
read-only
bAspectRatioY - the X dimension of the picture aspect
ratio, read-only
bAspectRatioX - the Y dimension of the picture aspect
ratio, read-only
bmFlags - characteristics of this format,
read-only
bDefaultFrameIndex - optimum frame index for this stream
What: /config/usb-gadget/gadget/functions/uvc.name/streaming/mjpeg/name/name
Date: Dec 2014
KernelVersion: 3.20
Description: Specific MJPEG frame descriptors
dwFrameInterval - indicates how frame interval can be
programmed; a number of values
separated by newline can be specified
dwDefaultFrameInterval - the frame interval the device would
like to use as default
dwMaxVideoFrameBufferSize- the maximum number of bytes the
compressor will produce for a video
frame or still image
dwMaxBitRate - the maximum bit rate at the shortest
frame interval in bps
dwMinBitRate - the minimum bit rate at the longest
frame interval in bps
wHeight - height of decoded bitmap frame in px
wWidth - width of decoded bitmam frame in px
bmCapabilities - still image support, fixed frame-rate
support
What: /config/usb-gadget/gadget/functions/uvc.name/streaming/uncompressed
Date: Dec 2014
KernelVersion: 3.20
Description: Uncompressed format descriptors
What: /config/usb-gadget/gadget/functions/uvc.name/streaming/uncompressed/name
Date: Dec 2014
KernelVersion: 3.20
Description: Specific uncompressed format descriptors
bmaControls - this format's data for bmaControls in
the streaming header
bmInterfaceFlags - specifies interlace information,
read-only
bAspectRatioY - the X dimension of the picture aspect
ratio, read-only
bAspectRatioX - the Y dimension of the picture aspect
ratio, read-only
bDefaultFrameIndex - optimum frame index for this stream
bBitsPerPixel - number of bits per pixel used to
specify color in the decoded video
frame
guidFormat - globally unique id used to identify
stream-encoding format
What: /config/usb-gadget/gadget/functions/uvc.name/streaming/uncompressed/name/name
Date: Dec 2014
KernelVersion: 3.20
Description: Specific uncompressed frame descriptors
dwFrameInterval - indicates how frame interval can be
programmed; a number of values
separated by newline can be specified
dwDefaultFrameInterval - the frame interval the device would
like to use as default
dwMaxVideoFrameBufferSize- the maximum number of bytes the
compressor will produce for a video
frame or still image
dwMaxBitRate - the maximum bit rate at the shortest
frame interval in bps
dwMinBitRate - the minimum bit rate at the longest
frame interval in bps
wHeight - height of decoded bitmap frame in px
wWidth - width of decoded bitmam frame in px
bmCapabilities - still image support, fixed frame-rate
support
What: /config/usb-gadget/gadget/functions/uvc.name/streaming/header
Date: Dec 2014
KernelVersion: 3.20
Description: Streaming header descriptors
What: /config/usb-gadget/gadget/functions/uvc.name/streaming/header/name
Date: Dec 2014
KernelVersion: 3.20
Description: Specific streaming header descriptors
All attributes read only:
bTriggerUsage - how the host software will respond to
a hardware trigger interrupt event
bTriggerSupport - flag specifying if hardware
triggering is supported
bStillCaptureMethod - method of still image caputre
supported
bTerminalLink - id of the output terminal to which
the video endpoint of this interface
is connected
bmInfo - capabilities of this video streaming
interface
...@@ -423,6 +423,17 @@ config USB_CONFIGFS_F_HID ...@@ -423,6 +423,17 @@ config USB_CONFIGFS_F_HID
For more information, see Documentation/usb/gadget_hid.txt. For more information, see Documentation/usb/gadget_hid.txt.
config USB_CONFIGFS_F_UVC
boolean "USB Webcam function"
depends on USB_CONFIGFS
depends on VIDEO_DEV
select VIDEOBUF2_VMALLOC
select USB_F_UVC
help
The Webcam function acts as a composite USB Audio and Video Class
device. It provides a userspace API to process UVC control requests
and stream video data to the host.
source "drivers/usb/gadget/legacy/Kconfig" source "drivers/usb/gadget/legacy/Kconfig"
endchoice endchoice
......
...@@ -36,7 +36,7 @@ usb_f_uac1-y := f_uac1.o u_uac1.o ...@@ -36,7 +36,7 @@ usb_f_uac1-y := f_uac1.o u_uac1.o
obj-$(CONFIG_USB_F_UAC1) += usb_f_uac1.o obj-$(CONFIG_USB_F_UAC1) += usb_f_uac1.o
usb_f_uac2-y := f_uac2.o usb_f_uac2-y := f_uac2.o
obj-$(CONFIG_USB_F_UAC2) += usb_f_uac2.o obj-$(CONFIG_USB_F_UAC2) += usb_f_uac2.o
usb_f_uvc-y := f_uvc.o uvc_queue.o uvc_v4l2.o uvc_video.o usb_f_uvc-y := f_uvc.o uvc_queue.o uvc_v4l2.o uvc_video.o uvc_configfs.o
obj-$(CONFIG_USB_F_UVC) += usb_f_uvc.o obj-$(CONFIG_USB_F_UVC) += usb_f_uvc.o
usb_f_midi-y := f_midi.o usb_f_midi-y := f_midi.o
obj-$(CONFIG_USB_F_MIDI) += usb_f_midi.o obj-$(CONFIG_USB_F_MIDI) += usb_f_midi.o
......
...@@ -27,10 +27,11 @@ ...@@ -27,10 +27,11 @@
#include <media/v4l2-dev.h> #include <media/v4l2-dev.h>
#include <media/v4l2-event.h> #include <media/v4l2-event.h>
#include "u_uvc.h"
#include "uvc.h" #include "uvc.h"
#include "uvc_configfs.h"
#include "uvc_v4l2.h" #include "uvc_v4l2.h"
#include "uvc_video.h" #include "uvc_video.h"
#include "u_uvc.h"
unsigned int uvc_gadget_trace_param; unsigned int uvc_gadget_trace_param;
...@@ -788,25 +789,104 @@ static void uvc_free_inst(struct usb_function_instance *f) ...@@ -788,25 +789,104 @@ static void uvc_free_inst(struct usb_function_instance *f)
{ {
struct f_uvc_opts *opts = fi_to_f_uvc_opts(f); struct f_uvc_opts *opts = fi_to_f_uvc_opts(f);
mutex_destroy(&opts->lock);
kfree(opts); kfree(opts);
} }
static struct usb_function_instance *uvc_alloc_inst(void) static struct usb_function_instance *uvc_alloc_inst(void)
{ {
struct f_uvc_opts *opts; struct f_uvc_opts *opts;
struct uvc_camera_terminal_descriptor *cd;
struct uvc_processing_unit_descriptor *pd;
struct uvc_output_terminal_descriptor *od;
struct uvc_color_matching_descriptor *md;
struct uvc_descriptor_header **ctl_cls;
opts = kzalloc(sizeof(*opts), GFP_KERNEL); opts = kzalloc(sizeof(*opts), GFP_KERNEL);
if (!opts) if (!opts)
return ERR_PTR(-ENOMEM); return ERR_PTR(-ENOMEM);
opts->func_inst.free_func_inst = uvc_free_inst; opts->func_inst.free_func_inst = uvc_free_inst;
mutex_init(&opts->lock);
cd = &opts->uvc_camera_terminal;
cd->bLength = UVC_DT_CAMERA_TERMINAL_SIZE(3);
cd->bDescriptorType = USB_DT_CS_INTERFACE;
cd->bDescriptorSubType = UVC_VC_INPUT_TERMINAL;
cd->bTerminalID = 1;
cd->wTerminalType = cpu_to_le16(0x0201);
cd->bAssocTerminal = 0;
cd->iTerminal = 0;
cd->wObjectiveFocalLengthMin = cpu_to_le16(0);
cd->wObjectiveFocalLengthMax = cpu_to_le16(0);
cd->wOcularFocalLength = cpu_to_le16(0);
cd->bControlSize = 3;
cd->bmControls[0] = 2;
cd->bmControls[1] = 0;
cd->bmControls[2] = 0;
pd = &opts->uvc_processing;
pd->bLength = UVC_DT_PROCESSING_UNIT_SIZE(2);
pd->bDescriptorType = USB_DT_CS_INTERFACE;
pd->bDescriptorSubType = UVC_VC_PROCESSING_UNIT;
pd->bUnitID = 2;
pd->bSourceID = 1;
pd->wMaxMultiplier = cpu_to_le16(16*1024);
pd->bControlSize = 2;
pd->bmControls[0] = 1;
pd->bmControls[1] = 0;
pd->iProcessing = 0;
od = &opts->uvc_output_terminal;
od->bLength = UVC_DT_OUTPUT_TERMINAL_SIZE;
od->bDescriptorType = USB_DT_CS_INTERFACE;
od->bDescriptorSubType = UVC_VC_OUTPUT_TERMINAL;
od->bTerminalID = 3;
od->wTerminalType = cpu_to_le16(0x0101);
od->bAssocTerminal = 0;
od->bSourceID = 2;
od->iTerminal = 0;
md = &opts->uvc_color_matching;
md->bLength = UVC_DT_COLOR_MATCHING_SIZE;
md->bDescriptorType = USB_DT_CS_INTERFACE;
md->bDescriptorSubType = UVC_VS_COLORFORMAT;
md->bColorPrimaries = 1;
md->bTransferCharacteristics = 1;
md->bMatrixCoefficients = 4;
/* Prepare fs control class descriptors for configfs-based gadgets */
ctl_cls = opts->uvc_fs_control_cls;
ctl_cls[0] = NULL; /* assigned elsewhere by configfs */
ctl_cls[1] = (struct uvc_descriptor_header *)cd;
ctl_cls[2] = (struct uvc_descriptor_header *)pd;
ctl_cls[3] = (struct uvc_descriptor_header *)od;
ctl_cls[4] = NULL; /* NULL-terminate */
opts->fs_control =
(const struct uvc_descriptor_header * const *)ctl_cls;
/* Prepare hs control class descriptors for configfs-based gadgets */
ctl_cls = opts->uvc_ss_control_cls;
ctl_cls[0] = NULL; /* assigned elsewhere by configfs */
ctl_cls[1] = (struct uvc_descriptor_header *)cd;
ctl_cls[2] = (struct uvc_descriptor_header *)pd;
ctl_cls[3] = (struct uvc_descriptor_header *)od;
ctl_cls[4] = NULL; /* NULL-terminate */
opts->ss_control =
(const struct uvc_descriptor_header * const *)ctl_cls;
opts->streaming_interval = 1;
opts->streaming_maxpacket = 1024;
uvcg_attach_configfs(opts);
return &opts->func_inst; return &opts->func_inst;
} }
static void uvc_free(struct usb_function *f) static void uvc_free(struct usb_function *f)
{ {
struct uvc_device *uvc = to_uvc(f); struct uvc_device *uvc = to_uvc(f);
struct f_uvc_opts *opts = container_of(f->fi, struct f_uvc_opts,
func_inst);
--opts->refcnt;
kfree(uvc); kfree(uvc);
} }
...@@ -832,6 +912,7 @@ static struct usb_function *uvc_alloc(struct usb_function_instance *fi) ...@@ -832,6 +912,7 @@ static struct usb_function *uvc_alloc(struct usb_function_instance *fi)
{ {
struct uvc_device *uvc; struct uvc_device *uvc;
struct f_uvc_opts *opts; struct f_uvc_opts *opts;
struct uvc_descriptor_header **strm_cls;
uvc = kzalloc(sizeof(*uvc), GFP_KERNEL); uvc = kzalloc(sizeof(*uvc), GFP_KERNEL);
if (uvc == NULL) if (uvc == NULL)
...@@ -840,11 +921,30 @@ static struct usb_function *uvc_alloc(struct usb_function_instance *fi) ...@@ -840,11 +921,30 @@ static struct usb_function *uvc_alloc(struct usb_function_instance *fi)
uvc->state = UVC_STATE_DISCONNECTED; uvc->state = UVC_STATE_DISCONNECTED;
opts = fi_to_f_uvc_opts(fi); opts = fi_to_f_uvc_opts(fi);
mutex_lock(&opts->lock);
if (opts->uvc_fs_streaming_cls) {
strm_cls = opts->uvc_fs_streaming_cls;
opts->fs_streaming =
(const struct uvc_descriptor_header * const *)strm_cls;
}
if (opts->uvc_hs_streaming_cls) {
strm_cls = opts->uvc_hs_streaming_cls;
opts->hs_streaming =
(const struct uvc_descriptor_header * const *)strm_cls;
}
if (opts->uvc_ss_streaming_cls) {
strm_cls = opts->uvc_ss_streaming_cls;
opts->ss_streaming =
(const struct uvc_descriptor_header * const *)strm_cls;
}
uvc->desc.fs_control = opts->fs_control; uvc->desc.fs_control = opts->fs_control;
uvc->desc.ss_control = opts->ss_control; uvc->desc.ss_control = opts->ss_control;
uvc->desc.fs_streaming = opts->fs_streaming; uvc->desc.fs_streaming = opts->fs_streaming;
uvc->desc.hs_streaming = opts->hs_streaming; uvc->desc.hs_streaming = opts->hs_streaming;
uvc->desc.ss_streaming = opts->ss_streaming; uvc->desc.ss_streaming = opts->ss_streaming;
++opts->refcnt;
mutex_unlock(&opts->lock);
/* Register the function. */ /* Register the function. */
uvc->func.name = "uvc"; uvc->func.name = "uvc";
......
...@@ -17,6 +17,7 @@ ...@@ -17,6 +17,7 @@
#define U_UVC_H #define U_UVC_H
#include <linux/usb/composite.h> #include <linux/usb/composite.h>
#include <linux/usb/video.h>
#define fi_to_f_uvc_opts(f) container_of(f, struct f_uvc_opts, func_inst) #define fi_to_f_uvc_opts(f) container_of(f, struct f_uvc_opts, func_inst)
...@@ -26,11 +27,60 @@ struct f_uvc_opts { ...@@ -26,11 +27,60 @@ struct f_uvc_opts {
unsigned int streaming_interval; unsigned int streaming_interval;
unsigned int streaming_maxpacket; unsigned int streaming_maxpacket;
unsigned int streaming_maxburst; unsigned int streaming_maxburst;
/*
* Control descriptors array pointers for full-/high-speed and
* super-speed. They point by default to the uvc_fs_control_cls and
* uvc_ss_control_cls arrays respectively. Legacy gadgets must
* override them in their gadget bind callback.
*/
const struct uvc_descriptor_header * const *fs_control; const struct uvc_descriptor_header * const *fs_control;
const struct uvc_descriptor_header * const *ss_control; const struct uvc_descriptor_header * const *ss_control;
/*
* Streaming descriptors array pointers for full-speed, high-speed and
* super-speed. They will point to the uvc_[fhs]s_streaming_cls arrays
* for configfs-based gadgets. Legacy gadgets must initialize them in
* their gadget bind callback.
*/
const struct uvc_descriptor_header * const *fs_streaming; const struct uvc_descriptor_header * const *fs_streaming;
const struct uvc_descriptor_header * const *hs_streaming; const struct uvc_descriptor_header * const *hs_streaming;
const struct uvc_descriptor_header * const *ss_streaming; const struct uvc_descriptor_header * const *ss_streaming;
/* Default control descriptors for configfs-based gadgets. */
struct uvc_camera_terminal_descriptor uvc_camera_terminal;
struct uvc_processing_unit_descriptor uvc_processing;
struct uvc_output_terminal_descriptor uvc_output_terminal;
struct uvc_color_matching_descriptor uvc_color_matching;
/*
* Control descriptors pointers arrays for full-/high-speed and
* super-speed. The first element is a configurable control header
* descriptor, the other elements point to the fixed default control
* descriptors. Used by configfs only, must not be touched by legacy
* gadgets.
*/
struct uvc_descriptor_header *uvc_fs_control_cls[5];
struct uvc_descriptor_header *uvc_ss_control_cls[5];
/*
* Streaming descriptors for full-speed, high-speed and super-speed.
* Used by configfs only, must not be touched by legacy gadgets. The
* arrays are allocated at runtime as the number of descriptors isn't
* known in advance.
*/
struct uvc_descriptor_header **uvc_fs_streaming_cls;
struct uvc_descriptor_header **uvc_hs_streaming_cls;
struct uvc_descriptor_header **uvc_ss_streaming_cls;
/*
* Read/write access to configfs attributes is handled by configfs.
*
* This lock protects the descriptors from concurrent access by
* read/write and symlink creation/removal.
*/
struct mutex lock;
int refcnt;
}; };
void uvc_set_trace_param(unsigned int trace); void uvc_set_trace_param(unsigned int trace);
......
This diff is collapsed.
/*
* uvc_configfs.h
*
* Configfs support for the uvc function.
*
* Copyright (c) 2014 Samsung Electronics Co., Ltd.
* http://www.samsung.com
*
* Author: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#ifndef UVC_CONFIGFS_H
#define UVC_CONFIGFS_H
struct f_uvc_opts;
int uvcg_attach_configfs(struct f_uvc_opts *opts);
#endif /* UVC_CONFIGFS_H */
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment