summaryrefslogtreecommitdiffstats
path: root/common/usbgadget.c
diff options
context:
space:
mode:
authorLadislav Michl <ladis@linux-mips.org>2018-10-26 17:39:10 +0200
committerSascha Hauer <s.hauer@pengutronix.de>2018-10-29 11:26:35 +0100
commit44add42d43300a330647704141c5a285358361db (patch)
treee5ae0bd91e190ae2d1ef55a5dc2c32b86401a13d /common/usbgadget.c
parent3e24dfe93d85e699c1510b795810382099167521 (diff)
downloadbarebox-44add42d43300a330647704141c5a285358361db.tar.gz
usbgadget: autostart: add DFU support
Use global variable dfu_function to autostart DFU. As similar code is used to start multifunction gadget using command, move common code to common/usbgadget.c and consolidate it. It turned out that '-s' option of usbgadget command does nothing, so remove its help text and make it function as '-a'. Signed-off-by: Ladislav Michl <ladis@linux-mips.org> Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
Diffstat (limited to 'common/usbgadget.c')
-rw-r--r--common/usbgadget.c144
1 files changed, 144 insertions, 0 deletions
diff --git a/common/usbgadget.c b/common/usbgadget.c
new file mode 100644
index 0000000..a8f104c
--- /dev/null
+++ b/common/usbgadget.c
@@ -0,0 +1,144 @@
+/*
+ * Copyright (c) 2017 Oleksij Rempel <o.rempel@pengutronix.de>, Pengutronix
+ *
+ * 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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+#define pr_fmt(fmt) "usbgadget: " fmt
+
+#include <common.h>
+#include <command.h>
+#include <errno.h>
+#include <environment.h>
+#include <malloc.h>
+#include <getopt.h>
+#include <fs.h>
+#include <xfuncs.h>
+#include <usb/usbserial.h>
+#include <usb/dfu.h>
+#include <usb/gadget-multi.h>
+#include <globalvar.h>
+#include <magicvar.h>
+
+static int autostart;
+static int acm;
+static char *dfu_function;
+static char *fastboot_function;
+static int fastboot_bbu;
+
+static struct file_list *parse(const char *files)
+{
+ struct file_list *list = file_list_parse(files);
+ if (IS_ERR(list)) {
+ pr_err("Parsing file list \"%s\" failed: %s\n", files,
+ strerrorp(list));
+ return NULL;
+ }
+ return list;
+}
+
+int usbgadget_register(bool dfu, const char *dfu_opts,
+ bool fastboot, const char *fastboot_opts,
+ bool acm, bool export_bbu)
+{
+ int ret;
+ struct device_d *dev;
+ struct f_multi_opts *opts;
+
+ if (dfu && !dfu_opts && dfu_function && *dfu_function)
+ dfu_opts = dfu_function;
+
+ if (fastboot && !fastboot_opts &&
+ fastboot_function && *fastboot_function)
+ fastboot_opts = fastboot_function;
+
+ if (!dfu_opts && !fastboot_opts && !acm)
+ return COMMAND_ERROR_USAGE;
+
+ /*
+ * Creating a gadget with both DFU and Fastboot doesn't work.
+ * Both client tools seem to assume that the device only has
+ * a single configuration
+ */
+ if (fastboot_opts && dfu_opts) {
+ pr_err("Only one of Fastboot and DFU allowed\n");
+ return -EINVAL;
+ }
+
+ opts = xzalloc(sizeof(*opts));
+ opts->release = usb_multi_opts_release;
+
+ if (fastboot_opts) {
+ opts->fastboot_opts.files = parse(fastboot_opts);
+ opts->fastboot_opts.export_bbu = export_bbu;
+ }
+
+ if (dfu_opts)
+ opts->dfu_opts.files = parse(dfu_opts);
+
+ if (!opts->dfu_opts.files && !opts->fastboot_opts.files && !acm) {
+ pr_warn("No functions to register\n");
+ free(opts);
+ return 0;
+ }
+
+ opts->create_acm = acm;
+
+ dev = get_device_by_name("otg");
+ if (dev)
+ dev_set_param(dev, "mode", "peripheral");
+
+ ret = usb_multi_register(opts);
+ if (ret)
+ usb_multi_opts_release(opts);
+
+ return ret;
+}
+
+static int usbgadget_autostart(void)
+{
+ if (!IS_ENABLED(CONFIG_USB_GADGET_AUTOSTART) || !autostart)
+ return 0;
+
+ return usbgadget_register(true, NULL, true, NULL, acm, fastboot_bbu);
+}
+postenvironment_initcall(usbgadget_autostart);
+
+static int usbgadget_globalvars_init(void)
+{
+ if (IS_ENABLED(CONFIG_USB_GADGET_AUTOSTART)) {
+ globalvar_add_simple_bool("usbgadget.autostart", &autostart);
+ globalvar_add_simple_bool("usbgadget.acm", &acm);
+ globalvar_add_simple_bool("usbgadget.fastboot_bbu",
+ &fastboot_bbu);
+ }
+ globalvar_add_simple_string("usbgadget.dfu_function", &dfu_function);
+ globalvar_add_simple_string("usbgadget.fastboot_function",
+ &fastboot_function);
+
+ return 0;
+}
+device_initcall(usbgadget_globalvars_init);
+
+BAREBOX_MAGICVAR_NAMED(global_usbgadget_autostart,
+ global.usbgadget.autostart,
+ "usbgadget: Automatically start usbgadget on boot");
+BAREBOX_MAGICVAR_NAMED(global_usbgadget_acm,
+ global.usbgadget.acm,
+ "usbgadget: Create CDC ACM function");
+BAREBOX_MAGICVAR_NAMED(global_usbgadget_dfu_function,
+ global.usbgadget.dfu_function,
+ "usbgadget: Create DFU function");
+BAREBOX_MAGICVAR_NAMED(global_usbgadget_fastboot_function,
+ global.usbgadget.fastboot_function,
+ "usbgadget: Create Android Fastboot function");
+BAREBOX_MAGICVAR_NAMED(global_usbgadget_fastboot_bbu,
+ global.usbgadget.fastboot_bbu,
+ "usbgadget: export barebox update handlers via fastboot");