diff options
author | Laurent Pinchart <laurent.pinchart@ideasonboard.com> | 2018-05-26 20:58:19 +0300 |
---|---|---|
committer | Laurent Pinchart <laurent.pinchart@ideasonboard.com> | 2018-06-01 09:47:11 +0300 |
commit | 571e148aaec20c26c308d6611cdb1f34ec81ff1e (patch) | |
tree | 2d829def0ed54aaf55dddd4743c0e9bbb6dec112 /configfs.c | |
parent | 203acba635874681e3e744fbce4151d569afa572 (diff) |
configfs: Refactor ConfigFS parsing code
Move all attribute parsing to a top-level configfs_parse_uvc() function,
and split control and streaming interface attributes to two separate
helper functions. In addition to making the code more structured, it
will also allow supporting multiple streaming interfaces in a single UVC
function in the future.
The uvc_function_config structure is similarly reorganized in a
hierarchical representation of the configuration.
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Diffstat (limited to 'configfs.c')
-rw-r--r-- | configfs.c | 108 |
1 files changed, 84 insertions, 24 deletions
@@ -199,12 +199,21 @@ 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, + .control = { + .intf = { + .bInterfaceNumber = 0, + }, + }, + .streaming = { + .intf = { + .bInterfaceNumber = 1, + }, + .ep = { + .bInterval = 1, + .bMaxBurst = 0, + .wMaxPacketSize = 1024, + }, + }, }; static int parse_legacy_g_webcam(const char *udc, @@ -269,16 +278,74 @@ 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) +#define configfs_parse_child(parent, child, cfg, parse) \ +({ \ + char *__path; \ + int __ret; \ + \ + __path = path_join((parent), (child)); \ + if (__path) { \ + __ret = parse(__path, (cfg)); \ + free(__path); \ + } else { \ + __ret = -ENOMEM; \ + } \ + \ + __ret; \ +}) + +static int configfs_parse_interface(const char *path, + struct uvc_function_config_interface *cfg) { int ret; - ret = attribute_read_uint(fpath, "control/bInterfaceNumber", - &fc->control_interface); + ret = attribute_read_uint(path, "bInterfaceNumber", + &cfg->bInterfaceNumber); + + return ret; +} + +static int configfs_parse_control(const char *path, + struct uvc_function_config_control *cfg) +{ + int ret; + + ret = configfs_parse_interface(path, &cfg->intf); + + return ret; +} + +static int configfs_parse_streaming(const char *path, + struct uvc_function_config_streaming *cfg) +{ + int ret; + + ret = configfs_parse_interface(path, &cfg->intf); + + return ret; +} + +static int configfs_parse_uvc(const char *fpath, + struct uvc_function_config *fc) +{ + int ret = 0; - ret = ret ? : attribute_read_uint(fpath, "streaming/bInterfaceNumber", - &fc->streaming_interface); + ret = ret ? : configfs_parse_child(fpath, "control", &fc->control, + configfs_parse_control); + ret = ret ? : configfs_parse_child(fpath, "streaming", &fc->streaming, + configfs_parse_streaming); + + /* + * These parameters should be part of the streaming interface in + * ConfigFS, but for legacy reasons they are located directly in the + * function directory. + */ + ret = ret ? : attribute_read_uint(fpath, "streaming_interval", + &fc->streaming.ep.bInterval); + ret = ret ? : attribute_read_uint(fpath, "streaming_maxburst", + &fc->streaming.ep.bMaxBurst); + ret = ret ? : attribute_read_uint(fpath, "streaming_maxpacket", + &fc->streaming.ep.wMaxPacketSize); return ret; } @@ -337,21 +404,14 @@ struct uvc_function_config *configfs_parse_uvc_function(const char *function) fc->udc = attribute_read_str(fpath, "../../UDC"); fc->video = udc_find_video_device(fc->udc, function); - if (!fc->video) + if (!fc->video) { ret = -ENODEV; + goto done; + } - /* Identify interface numbers. */ - ret = ret ? : configfs_parse_interfaces(fpath, fc); - - ret = ret ? : attribute_read_uint(fpath, "streaming_interval", - &fc->streaming_interval); - - ret = ret ? : attribute_read_uint(fpath, "streaming_maxburst", - &fc->streaming_maxburst); - - ret = ret ? : attribute_read_uint(fpath, "streaming_maxpacket", - &fc->streaming_maxpacket); + ret = configfs_parse_uvc(fpath, fc); +done: if (ret) { configfs_free_uvc_function(fc); fc = NULL; |