blob: e975abebc9a5fbd832a38980999e3d21d3bf44f5 [file] [log] [blame]
Lukasz Majewski9273f4f2012-08-06 14:41:09 +02001/*
2 * cmd_dfu.c -- dfu command
3 *
4 * Copyright (C) 2012 Samsung Electronics
5 * authors: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
6 * Lukasz Majewski <l.majewski@samsung.com>
7 *
Wolfgang Denkd79de1d2013-07-08 09:37:19 +02008 * SPDX-License-Identifier: GPL-2.0+
Lukasz Majewski9273f4f2012-08-06 14:41:09 +02009 */
10
11#include <common.h>
Lukasz Majewski9273f4f2012-08-06 14:41:09 +020012#include <dfu.h>
Lukasz Majewski9273f4f2012-08-06 14:41:09 +020013#include <g_dnl.h>
Mateusz Zalegad862f892013-10-04 19:22:26 +020014#include <usb.h>
Lukasz Majewski9273f4f2012-08-06 14:41:09 +020015
16static int do_dfu(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
17{
Lukasz Majewskid9eae702014-08-25 11:07:28 +020018 bool dfu_reset = false;
19
Mateusz Zalegad862f892013-10-04 19:22:26 +020020 if (argc < 4)
21 return CMD_RET_USAGE;
22
23 char *usb_controller = argv[1];
24 char *interface = argv[2];
25 char *devstring = argv[3];
26
Lukasz Majewski2968aa22013-07-18 13:19:14 +020027 int ret, i = 0;
Lukasz Majewski9273f4f2012-08-06 14:41:09 +020028
Stephen Warren4afe50f2014-06-11 16:03:33 -060029 ret = dfu_init_env_entities(interface, devstring);
Lukasz Majewski9273f4f2012-08-06 14:41:09 +020030 if (ret)
Stephen Warrenf9d47dd2014-06-10 10:06:41 -060031 goto done;
Lukasz Majewski9273f4f2012-08-06 14:41:09 +020032
Stephen Warrenf9d47dd2014-06-10 10:06:41 -060033 ret = CMD_RET_SUCCESS;
Mateusz Zalegad862f892013-10-04 19:22:26 +020034 if (argc > 4 && strcmp(argv[4], "list") == 0) {
Lukasz Majewski9273f4f2012-08-06 14:41:09 +020035 dfu_show_entities();
36 goto done;
37 }
38
Mateusz Zalegad862f892013-10-04 19:22:26 +020039 int controller_index = simple_strtoul(usb_controller, NULL, 0);
40 board_usb_init(controller_index, USB_INIT_DEVICE);
Rob Herringd38f24e2014-12-10 14:43:03 -060041 g_dnl_clear_detach();
Mateusz Zalega69cb0bb2014-04-28 21:13:28 +020042 g_dnl_register("usb_dnl_dfu");
Lukasz Majewski9273f4f2012-08-06 14:41:09 +020043 while (1) {
Rob Herringd38f24e2014-12-10 14:43:03 -060044 if (g_dnl_detach()) {
Lukasz Majewskid9eae702014-08-25 11:07:28 +020045 /*
46 * Check if USB bus reset is performed after detach,
47 * which indicates that -R switch has been passed to
48 * dfu-util. In this case reboot the device
49 */
50 if (dfu_usb_get_reset()) {
51 dfu_reset = true;
52 goto exit;
53 }
54
Lukasz Majewski2968aa22013-07-18 13:19:14 +020055 /*
56 * This extra number of usb_gadget_handle_interrupts()
57 * calls is necessary to assure correct transmission
58 * completion with dfu-util
59 */
Lukasz Majewskid9eae702014-08-25 11:07:28 +020060 if (++i == 10000)
Lukasz Majewski2968aa22013-07-18 13:19:14 +020061 goto exit;
Lukasz Majewskid9eae702014-08-25 11:07:28 +020062 }
Lukasz Majewski2968aa22013-07-18 13:19:14 +020063
Lukasz Majewski9273f4f2012-08-06 14:41:09 +020064 if (ctrlc())
65 goto exit;
66
67 usb_gadget_handle_interrupts();
68 }
69exit:
70 g_dnl_unregister();
71done:
72 dfu_free_entities();
Lukasz Majewski9273f4f2012-08-06 14:41:09 +020073
Lukasz Majewskid9eae702014-08-25 11:07:28 +020074 if (dfu_reset)
Lukasz Majewski2968aa22013-07-18 13:19:14 +020075 run_command("reset", 0);
76
Rob Herringd38f24e2014-12-10 14:43:03 -060077 g_dnl_clear_detach();
Lukasz Majewskid9eae702014-08-25 11:07:28 +020078
Stephen Warrenf9d47dd2014-06-10 10:06:41 -060079 return ret;
Lukasz Majewski9273f4f2012-08-06 14:41:09 +020080}
81
82U_BOOT_CMD(dfu, CONFIG_SYS_MAXARGS, 1, do_dfu,
83 "Device Firmware Upgrade",
Mateusz Zalegad862f892013-10-04 19:22:26 +020084 "<USB_controller> <interface> <dev> [list]\n"
85 " - device firmware upgrade via <USB_controller>\n"
86 " on device <dev>, attached to interface\n"
87 " <interface>\n"
88 " [list] - list available alt settings\n"
Lukasz Majewski9273f4f2012-08-06 14:41:09 +020089);