From bcc3c85eaa16bda6436549c82ae24e600fed9d18 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Pawe=C5=82=20Szewczyk?= Date: Wed, 28 Feb 2018 16:08:21 +0100 Subject: [PATCH 01/16] Fix getting ints from sysfs MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Some integers are represented in hex, without leading 0x. Change-Id: If6b950a24496eae52a34623b2fa9735390e26795 Signed-off-by: Paweł Szewczyk --- hw/usb_client/usb_client.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/hw/usb_client/usb_client.c b/hw/usb_client/usb_client.c index f7faa5b..f8bdd3a 100644 --- a/hw/usb_client/usb_client.c +++ b/hw/usb_client/usb_client.c @@ -119,7 +119,7 @@ static int systemd_stop_service(const char *service_name) return systemd_unit_interface("StopUnit", unit); } -static int get_int_from_file(char *path, int *_val) +static int get_int_from_file(char *path, int *_val, int base) { char buf[INT_BUF_SIZE]; char *endptr; @@ -130,7 +130,7 @@ static int get_int_from_file(char *path, int *_val) if (ret) return ret; - val = strtol(buf, &endptr, 0); + val = strtol(buf, &endptr, base); if (val == LONG_MIN || val == LONG_MAX || buf[0] == '\0' || (*endptr != '\0' && *endptr != '\n') || val > INT_MAX) @@ -145,21 +145,21 @@ static int legacy_read_gadget_attrs_strs(struct usb_gadget *gadget) int val; int ret; /* We assume that values received from kernel will be valid */ -#define GET_VALUE_FROM_SYSFS(path, field, type) \ +#define GET_VALUE_FROM_SYSFS(path, field, type, base) \ do { \ - ret = get_int_from_file(path, &val); \ + ret = get_int_from_file(path, &val, base); \ if (ret) \ return ret; \ \ gadget->attrs.field = (type)val; \ } while (0) - GET_VALUE_FROM_SYSFS(LEGACY_CLASS_PATH, bDeviceClass, uint8_t); - GET_VALUE_FROM_SYSFS(LEGACY_SUBCLASS_PATH, bDeviceSubClass, uint8_t); - GET_VALUE_FROM_SYSFS(LEGACY_PROTOCOL_PATH, bDeviceProtocol, uint8_t); - GET_VALUE_FROM_SYSFS(LEGACY_ID_VENDOR_PATH, idVendor, uint16_t); - GET_VALUE_FROM_SYSFS(LEGACY_ID_PRODUCT_PATH, idVendor, uint16_t); - GET_VALUE_FROM_SYSFS(LEGACY_BCD_DEVICE_PATH, bcdDevice, uint16_t); + GET_VALUE_FROM_SYSFS(LEGACY_CLASS_PATH, bDeviceClass, uint8_t, 0); + GET_VALUE_FROM_SYSFS(LEGACY_SUBCLASS_PATH, bDeviceSubClass, uint8_t, 0); + GET_VALUE_FROM_SYSFS(LEGACY_PROTOCOL_PATH, bDeviceProtocol, uint8_t, 0); + GET_VALUE_FROM_SYSFS(LEGACY_ID_VENDOR_PATH, idVendor, uint16_t, 16); + GET_VALUE_FROM_SYSFS(LEGACY_ID_PRODUCT_PATH, idProduct, uint16_t, 16); + GET_VALUE_FROM_SYSFS(LEGACY_BCD_DEVICE_PATH, bcdDevice, uint16_t, 0); #undef GET_VALUE_FROM_SYSFS #define GET_STRING_FROM_SYSFS(path, field) \ -- 2.7.4 From 6c1256d6dd6e1b072453caf9f0a35becc2649261 Mon Sep 17 00:00:00 2001 From: Krzysztof Opasiak Date: Fri, 2 Mar 2018 21:40:56 +0100 Subject: [PATCH 02/16] Add support for FunctionFS-based function Both mtp-responder and sdbd have FunctionFS backend now what allows to use them in ConfigFS implementation of HAL. We use systemd socke activation with special socket type which starts the service when needed. There is an assumption that each of those services provides a suitable .socket file. Change-Id: Ib073ac10f6d12bb75f20e4b9f3961bcdbd21520c Signed-off-by: Krzysztof Opasiak --- hw/usb_client/usb_client_configfs.c | 308 +++++++++++++++++++++++++++++++++--- 1 file changed, 287 insertions(+), 21 deletions(-) diff --git a/hw/usb_client/usb_client_configfs.c b/hw/usb_client/usb_client_configfs.c index c16eae7..d48ae0d 100644 --- a/hw/usb_client/usb_client_configfs.c +++ b/hw/usb_client/usb_client_configfs.c @@ -23,7 +23,13 @@ #include #include #include +#include +#include +#include #include +#include + +#include #define zalloc(amount) calloc(1, amount) @@ -35,6 +41,11 @@ #define CONFIGFS_GADGET_NAME "hal-gadget" #define CONFIGFS_CONFIG_LABEL "hal-config" +#define NAME_INSTANCE_SEP '.' +#define MAX_INSTANCE_LEN 512 + +#define USB_FUNCS_PATH "/dev/usb-funcs/" + struct cfs_client { struct usb_client client; usbg_state *ctx; @@ -154,13 +165,41 @@ out: return ret; } +static bool cfs_match_func(struct usb_function *f, + const char *name, const char *instance) { + if (strcmp(name, usbg_get_function_type_str(USBG_F_FFS))) { + /* Standard functions */ + if (!strcmp(name, f->name) && !strcmp(instance, f->instance)) + return true; + } else { + /* Function with service */ + const char *sep, *fname, *finst; + int len; + + sep = strchr(instance, NAME_INSTANCE_SEP); + if (!sep || strlen(sep + 1) < 1) + return false; + + fname = instance; + len = sep - instance; + finst = sep + 1; + + if (strlen(f->name) == len + && !strncmp(f->name, fname, len) + && !strcmp(f->instance, finst)) + return true; + } + + return false; +} + + static int cfs_find_func(const char *name, const char *instance) { int i; for (i = 0; i < ARRAY_SIZE(_available_funcs); ++i) - if (!strcmp(name, _available_funcs[i]->name) && - !strcmp(instance, _available_funcs[i]->instance)) + if (cfs_match_func(_available_funcs[i], name, instance)) return i; return -ENOENT; @@ -219,9 +258,9 @@ static struct usb_function *cfs_find_func_in_gadget( int i; for (i = 0; gadget->funcs[i]; ++i) - if (!strcmp(name, gadget->funcs[i]->name) - && !strcmp(instance, gadget->funcs[i]->instance)) + if (cfs_match_func(gadget->funcs[i], name, instance)) return gadget->funcs[i]; + return NULL; } @@ -311,7 +350,7 @@ static int cfs_count_bindings(usbg_config *config) static int cfs_read_configs(usbg_gadget *gadget, struct usb_gadget *usb_gadget) { usbg_config *config; - int i; + int i = 0; int n_funcs; int ret; @@ -449,21 +488,23 @@ out: static bool cfs_is_function_supported(struct usb_client *usb, struct usb_function *func) { + bool res; int ret; - /* for now only simple functions without userspace service */ - if (func->function_group != USB_FUNCTION_GROUP_SIMPLE) - return false; - - /* - * TODO - * Instead of only checking whether we know this function - * we should also somehow check that it's realy available - * in our kernel. - */ - ret = usbg_lookup_function_type(func->name); + switch (func->function_group) { + case USB_FUNCTION_GROUP_SIMPLE: + ret = usbg_lookup_function_type(func->name); + res = ret >= 0; + break; + case USB_FUNCTION_GROUP_WITH_SERVICE: + /* TODO: Check if socket is available */ + res = true; + break; + default: + res = false; + } - return ret > 0; + return res; } static bool cfs_is_gadget_supported(struct usb_client *usb, @@ -545,6 +586,195 @@ static int cfs_set_gadget_strs(struct cfs_client *cfs_client, return ret; } +#define SYSTEMD_DBUS_SERVICE "org.freedesktop.systemd1" +#define SYSTEMD_DBUS_PATH "/org/freedesktop/systemd1" +#define SYSTEMD_DBUS_MANAGER_IFACE "org.freedesktop.systemd1.Manager" + +#define SYSTEMD_SOCKET_SUFFIX ".socket" +#define MAX_SOCKET_NAME 1024 + +struct bus_ctx { + const char *unit; + sd_event *loop; +}; + +static int socket_started(sd_bus_message *m, void *userdata, + sd_bus_error *ret_error) +{ + struct bus_ctx *ctx = userdata; + char *signal_unit; + int ret; + + ret = sd_bus_message_read(m, "uoss", NULL, NULL, &signal_unit, NULL); + if (ret < 0) { + sd_event_exit(ctx->loop, ret); + return 0; + } + + if (!strcmp(signal_unit, ctx->unit)) + sd_event_exit(ctx->loop, 0); + + return 0; +} + +static int systemd_unit_interface_sync(const char *method, const char *unit, + bool wait) +{ + sd_bus *bus = NULL; + sd_event *loop = NULL; + struct bus_ctx ctx; + int ret; + + ret = sd_bus_open_system(&bus); + if (ret < 0) + return ret; + + if (wait) { + ret = sd_event_new(&loop); + if (ret < 0) + goto unref_bus; + + ctx.loop = loop; + ctx.unit = unit; + + ret = sd_bus_attach_event(bus, loop, SD_EVENT_PRIORITY_NORMAL); + if (ret < 0) + goto unref_loop; + + ret = sd_bus_add_match(bus, NULL, + "type='signal'," + "sender='" SYSTEMD_DBUS_SERVICE "'," + "interface='" SYSTEMD_DBUS_MANAGER_IFACE "'," + "member='JobRemoved'," + "path_namespace='" SYSTEMD_DBUS_PATH "'", + socket_started, + &ctx); + if (ret < 0) + goto unref_loop; + } + + + ret = sd_bus_call_method(bus, + SYSTEMD_DBUS_SERVICE, + SYSTEMD_DBUS_PATH, + SYSTEMD_DBUS_MANAGER_IFACE, + method, + NULL, + NULL, + "ss", + unit, + "replace"); + if (ret < 0) + goto unref_loop; + + if (wait) + ret = sd_event_loop(loop); + +unref_loop: + if (wait) + sd_event_unref(loop); +unref_bus: + sd_bus_unref(bus); + return ret; +} + +static int systemd_start_socket(const char *socket_name) +{ + char unit[MAX_SOCKET_NAME]; + int ret; + + ret = snprintf(unit, sizeof(unit), "%s" SYSTEMD_SOCKET_SUFFIX, + socket_name); + if (ret < 0 || ret >= sizeof(unit)) + return -ENAMETOOLONG; + + + return systemd_unit_interface_sync("StartUnit", unit, true); +} + +static int systemd_stop_socket(const char *socket_name) +{ + char unit[MAX_SOCKET_NAME]; + int ret; + + ret = snprintf(unit, sizeof(unit), "%s" SYSTEMD_SOCKET_SUFFIX, + socket_name); + if (ret < 0 || ret >= sizeof(unit)) + return -ENAMETOOLONG; + + return systemd_unit_interface_sync("StopUnit", unit, false); +} + +static int cfs_ensure_dir(char *path) +{ + int ret; + + ret = mkdir(path, 0770); + if (ret < 0) + ret = errno == EEXIST ? 0 : errno; + + return ret; +} + +static int cfs_prep_ffs_service(const char *name, const char *instance, + const char *dev_name, const char *socket_name) +{ + char buf[PATH_MAX]; + size_t left; + char *pos; + int ret; + + /* TODO: Add some good error handling */ + + left = sizeof(buf); + pos = buf; + ret = snprintf(pos, left, "%s", USB_FUNCS_PATH); + if (ret < 0 || ret >= left) { + return -ENAMETOOLONG; + } else { + left -= ret; + pos += ret; + } + ret = cfs_ensure_dir(buf); + if (ret < 0) + return ret; + + ret = snprintf(pos, left, "/%s", name); + if (ret < 0 || ret >= left) { + return -ENAMETOOLONG; + } else { + left -= ret; + pos += ret; + } + ret = cfs_ensure_dir(buf); + if (ret < 0) + return ret; + + ret = snprintf(pos, left, "/%s", instance); + if (ret < 0 || ret >= left) { + return -ENAMETOOLONG; + } else { + left -= ret; + pos += ret; + } + ret = cfs_ensure_dir(buf); + if (ret < 0) + return ret; + + ret = mount(dev_name, buf, "functionfs", 0, NULL); + if (ret < 0) + return ret; + + ret = systemd_start_socket(socket_name); + if (ret < 0) + goto umount_ffs; + + return 0; +umount_ffs: + umount(buf); + return ret; +} + static int cfs_set_gadget_config(struct cfs_client *cfs_client, int config_id, struct usb_configuration *usb_config) @@ -581,18 +811,54 @@ static int cfs_set_gadget_config(struct cfs_client *cfs_client, for (i = 0; usb_config->funcs && usb_config->funcs[i]; ++i) { struct usb_function *usb_func = usb_config->funcs[i]; - int type = usbg_lookup_function_type(usb_func->name); + char instance[MAX_INSTANCE_LEN]; + int type; usbg_function *func; - func = usbg_get_function(cfs_client->gadget, - type, usb_func->instance); + switch (usb_func->function_group) { + case USB_FUNCTION_GROUP_SIMPLE: + type = usbg_lookup_function_type(usb_func->name); + if (strlen(usb_func->instance) >= MAX_INSTANCE_LEN) + return -ENAMETOOLONG; + strcpy(instance, usb_func->instance); + break; + case USB_FUNCTION_GROUP_WITH_SERVICE: + type = USBG_F_FFS; + ret = snprintf(instance, sizeof(instance), "%s%c%s", + usb_func->name, NAME_INSTANCE_SEP, + usb_func->instance); + if (ret < 0 || ret >= sizeof(instance)) + return -ENAMETOOLONG; + break; + default: + return -EINVAL; + } + + + func = usbg_get_function(cfs_client->gadget, type, instance); if (!func) { ret = usbg_create_function(cfs_client->gadget, type, - usb_func->instance, + instance, NULL, &func); if (ret) return ret; + + if (usb_func->function_group == + USB_FUNCTION_GROUP_WITH_SERVICE) { + struct usb_function_with_service *fws; + + fws = container_of(usb_func, + struct usb_function_with_service, + func); + ret = cfs_prep_ffs_service(usb_func->name, + usb_func->instance, + instance, + fws->service); + if (ret) + return ret; + } + } ret = usbg_add_config_function(config, NULL, func); -- 2.7.4 From 6ad242f98a744df1ea258a340213ff688aad941e Mon Sep 17 00:00:00 2001 From: INSUN PYO Date: Wed, 14 Mar 2018 13:45:36 +0900 Subject: [PATCH 03/16] usb_client: fix bug MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Signed-off-by: INSUN PYO Change-Id: I70670d18ae5ae128ef0785ac79f220e3aa5c42b0 Signed-off-by: Paweł Szewczyk --- hw/usb_client/usb_client.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/hw/usb_client/usb_client.c b/hw/usb_client/usb_client.c index f8bdd3a..df5229a 100644 --- a/hw/usb_client/usb_client.c +++ b/hw/usb_client/usb_client.c @@ -289,9 +289,12 @@ static int legacy_read_config(struct usb_gadget *gadget, /* count number of functions in this config */ f_cnt = 1; - for (i = 0; buf[i] != '\0'; ++i) + for (i = 0; buf[i] != '\0'; ++i) { if (buf[i] == sep[0]) ++f_cnt; + if (buf[i] == '\n') /* buf ends with it */ + buf[i] = 0; + } ret = legacy_alloc_config(f_cnt, &config); if (ret) @@ -305,7 +308,7 @@ static int legacy_read_config(struct usb_gadget *gadget, if (!func) { /* new function not added yet to gadget */ ret = legacy_alloc_new_func(gadget, fname, &func); - if (!ret) + if (ret) goto free_config; } -- 2.7.4 From 834135cf60aa15ccb76d676f3f7f7bc1a9cf23ca Mon Sep 17 00:00:00 2001 From: =?utf8?q?Pawe=C5=82=20Szewczyk?= Date: Wed, 21 Mar 2018 17:59:01 +0100 Subject: [PATCH 04/16] Fix minor issues MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Change-Id: I78dd77f031b4cda871a758687d4518a5ac22dc43 Signed-off-by: Paweł Szewczyk --- hw/usb_client/usb_client_configfs.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/hw/usb_client/usb_client_configfs.c b/hw/usb_client/usb_client_configfs.c index d48ae0d..deaafcd 100644 --- a/hw/usb_client/usb_client_configfs.c +++ b/hw/usb_client/usb_client_configfs.c @@ -375,7 +375,7 @@ free_current: free(usb_gadget->configs[i]); clean_prev: while (i >= 0) - cfs_free_config(usb_gadget->configs[i]); + cfs_free_config(usb_gadget->configs[i--]); return ret; } @@ -473,9 +473,9 @@ free_funcs: free(usb_funcs); free_strs_with_content: for (i = 0; usb_gadget->strs[i].lang_code; ++i) { - free(usb_gadget->strs[0].manufacturer); - free(usb_gadget->strs[0].product); - free(usb_gadget->strs[0].serial); + free(usb_gadget->strs[i].manufacturer); + free(usb_gadget->strs[i].product); + free(usb_gadget->strs[i].serial); } free_strs: free(usb_gadget->strs); @@ -820,7 +820,8 @@ static int cfs_set_gadget_config(struct cfs_client *cfs_client, type = usbg_lookup_function_type(usb_func->name); if (strlen(usb_func->instance) >= MAX_INSTANCE_LEN) return -ENAMETOOLONG; - strcpy(instance, usb_func->instance); + strncpy(instance, usb_func->instance, MAX_INSTANCE_LEN); + instance[MAX_INSTANCE_LEN - 1] = '\0'; break; case USB_FUNCTION_GROUP_WITH_SERVICE: type = USBG_F_FFS; -- 2.7.4 From 1624d9ddfd5efc5b298b38630a6cb40456158994 Mon Sep 17 00:00:00 2001 From: INSUN PYO Date: Wed, 14 Mar 2018 10:23:57 +0900 Subject: [PATCH 05/16] usb: patches to selectively support both slp and functionfs If /sys/class/usb_mode/usb0/enable exists, it is slp usb_hal. Otherwise it is configfs usb_hal. Signed-off-by: INSUN PYO Change-Id: I8e6b74ffbc6287fe7b5f0a7ab475edff16b2fd88 --- CMakeLists.txt | 1 + hw/usb_cfs_client/CMakeLists.txt | 19 +++++++++++++++++++ .../usb_cfs_client.c} | 7 ++++++- hw/usb_client/usb_client.c | 5 +++++ packaging/device-manager-plugin-artik.spec | 1 + 5 files changed, 32 insertions(+), 1 deletion(-) create mode 100644 hw/usb_cfs_client/CMakeLists.txt rename hw/{usb_client/usb_client_configfs.c => usb_cfs_client/usb_cfs_client.c} (99%) diff --git a/CMakeLists.txt b/CMakeLists.txt index a12e14b..7fab672 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -10,3 +10,4 @@ ADD_SUBDIRECTORY(hw/led) ADD_SUBDIRECTORY(hw/touchscreen) ADD_SUBDIRECTORY(hw/usb_gadget) ADD_SUBDIRECTORY(hw/usb_client) +ADD_SUBDIRECTORY(hw/usb_cfs_client) diff --git a/hw/usb_cfs_client/CMakeLists.txt b/hw/usb_cfs_client/CMakeLists.txt new file mode 100644 index 0000000..15e7cbc --- /dev/null +++ b/hw/usb_cfs_client/CMakeLists.txt @@ -0,0 +1,19 @@ +CMAKE_MINIMUM_REQUIRED(VERSION 2.6) +PROJECT(usb_cfs_client C) + +SET(PREFIX ${CMAKE_INSTALL_PREFIX}) + +INCLUDE(FindPkgConfig) +pkg_check_modules(usb_cfs_client_pkgs REQUIRED hwcommon dlog glib-2.0 libsystemd libusbgx) + +FOREACH(flag ${usb_cfs_client_pkgs_CFLAGS}) + SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}") +ENDFOREACH(flag) + +SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -fvisibility=hidden") +SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS}") + +ADD_LIBRARY(${PROJECT_NAME} MODULE usb_cfs_client.c ../shared.c) +TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${usb_cfs_client_pkgs_LDFLAGS}) +SET_TARGET_PROPERTIES(${PROJECT_NAME} PROPERTIES PREFIX "") +INSTALL(TARGETS ${PROJECT_NAME} DESTINATION ${LIB_INSTALL_DIR}/hw COMPONENT RuntimeLibraries) diff --git a/hw/usb_client/usb_client_configfs.c b/hw/usb_cfs_client/usb_cfs_client.c similarity index 99% rename from hw/usb_client/usb_client_configfs.c rename to hw/usb_cfs_client/usb_cfs_client.c index deaafcd..0e76f3b 100644 --- a/hw/usb_client/usb_client_configfs.c +++ b/hw/usb_cfs_client/usb_cfs_client.c @@ -27,6 +27,7 @@ #include #include #include +#include #include #include @@ -965,6 +966,10 @@ static int cfs_gadget_open(struct hw_info *info, if (!info || !common) return -EINVAL; + /* used exclusively with slp usb_client*/ + if (!access("/sys/class/usb_mode/usb0/enable", F_OK)) + return -ENOENT; + cfs_client = zalloc(sizeof(*cfs_client)); if (!cfs_client) return -ENOMEM; @@ -1031,7 +1036,7 @@ HARDWARE_MODULE_STRUCTURE = { .magic = HARDWARE_INFO_TAG, .hal_version = HARDWARE_INFO_VERSION, .device_version = USB_CLIENT_HARDWARE_DEVICE_VERSION, - .id = USB_CLIENT_HARDWARE_DEVICE_ID, + .id = USB_CFS_CLIENT_HARDWARE_DEVICE_ID, .name = "cfs-gadget", .open = cfs_gadget_open, .close = cfs_gadget_close, diff --git a/hw/usb_client/usb_client.c b/hw/usb_client/usb_client.c index df5229a..824e562 100644 --- a/hw/usb_client/usb_client.c +++ b/hw/usb_client/usb_client.c @@ -23,6 +23,7 @@ #include #include #include +#include #include #define zalloc(amount) calloc(1, amount) @@ -715,6 +716,10 @@ static int legacy_gadget_open(struct hw_info *info, if (!info || !common) return -EINVAL; + /* check if slp usb gadget exists */ + if (access("/sys/class/usb_mode/usb0/enable", F_OK)) + return -ENOENT; + legacy = zalloc(sizeof(*legacy)); if (!legacy) return -ENOMEM; diff --git a/packaging/device-manager-plugin-artik.spec b/packaging/device-manager-plugin-artik.spec index 5feaf0e..7268a6a 100755 --- a/packaging/device-manager-plugin-artik.spec +++ b/packaging/device-manager-plugin-artik.spec @@ -16,6 +16,7 @@ BuildRequires: pkgconfig(libudev) BuildRequires: pkgconfig(capi-system-peripheral-io) BuildRequires: pkgconfig(libusbgx) BuildRequires: pkgconfig(libsystemd) +BuildRequires: pkgconfig(libusbgx) %description Device manager plugin artik -- 2.7.4 From 935068a130dae941bb5abed0249fbe7e033f8d99 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Pawe=C5=82=20Szewczyk?= Date: Thu, 15 Mar 2018 18:51:51 +0100 Subject: [PATCH 06/16] usb: Assign new functions to legacy gadget MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Change-Id: I86df0d0db29813781c8b49dc111f726b24b82041 Signed-off-by: Paweł Szewczyk --- hw/usb_client/usb_client.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/hw/usb_client/usb_client.c b/hw/usb_client/usb_client.c index 824e562..0f1effe 100644 --- a/hw/usb_client/usb_client.c +++ b/hw/usb_client/usb_client.c @@ -278,6 +278,7 @@ static int legacy_read_config(struct usb_gadget *gadget, char *sep = LEGACY_FUNC_SEP; int i, f_cnt; int f_idx; + int g_f_idx; int ret; ret = sys_get_str(cpath, buf, sizeof(buf)); @@ -301,6 +302,8 @@ static int legacy_read_config(struct usb_gadget *gadget, if (ret) return ret; + for (g_f_idx = 0; gadget->funcs[g_f_idx]; ++g_f_idx); + f_idx = 0; for (fname = strsep(&begin, sep); fname; fname = strsep(&begin, sep)) { struct usb_function *func; @@ -311,6 +314,8 @@ static int legacy_read_config(struct usb_gadget *gadget, ret = legacy_alloc_new_func(gadget, fname, &func); if (ret) goto free_config; + + gadget->funcs[g_f_idx++] = func; } config->funcs[f_idx++] = func; -- 2.7.4 From 01a6b2fab7787b61044461111ce877d9748a9200 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Pawe=C5=82=20Szewczyk?= Date: Mon, 9 Apr 2018 11:44:18 +0200 Subject: [PATCH 07/16] Add error logs MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Change-Id: Ibadac25cdec2972a172e8bb893e3a010c4659eb6 Signed-off-by: Paweł Szewczyk --- hw/usb_cfs_client/usb_cfs_client.c | 62 ++++++++++++++++++++++++++++++-------- 1 file changed, 49 insertions(+), 13 deletions(-) diff --git a/hw/usb_cfs_client/usb_cfs_client.c b/hw/usb_cfs_client/usb_cfs_client.c index 0e76f3b..dc09f21 100644 --- a/hw/usb_cfs_client/usb_cfs_client.c +++ b/hw/usb_cfs_client/usb_cfs_client.c @@ -731,44 +731,57 @@ static int cfs_prep_ffs_service(const char *name, const char *instance, pos = buf; ret = snprintf(pos, left, "%s", USB_FUNCS_PATH); if (ret < 0 || ret >= left) { + _E("Function path too long"); return -ENAMETOOLONG; } else { left -= ret; pos += ret; } ret = cfs_ensure_dir(buf); - if (ret < 0) + if (ret < 0) { + _E("Could not create directory %s", buf); return ret; + } ret = snprintf(pos, left, "/%s", name); if (ret < 0 || ret >= left) { + _E("Path too long"); return -ENAMETOOLONG; } else { left -= ret; pos += ret; } ret = cfs_ensure_dir(buf); - if (ret < 0) + if (ret < 0) { + _E("Could not create directory %s", buf); return ret; + } ret = snprintf(pos, left, "/%s", instance); if (ret < 0 || ret >= left) { + _E("Path too long"); return -ENAMETOOLONG; } else { left -= ret; pos += ret; } ret = cfs_ensure_dir(buf); - if (ret < 0) + if (ret < 0) { + _E("Could not create directory %s", buf); return ret; + } ret = mount(dev_name, buf, "functionfs", 0, NULL); - if (ret < 0) + if (ret < 0) { + _E("Could not mount %s: %m", dev_name); return ret; + } ret = systemd_start_socket(socket_name); - if (ret < 0) + if (ret < 0) { + _E("Could not start socket: %d", ret); goto umount_ffs; + } return 0; umount_ffs: @@ -794,20 +807,26 @@ static int cfs_set_gadget_config(struct cfs_client *cfs_client, config = usbg_get_config(cfs_client->gadget, config_id, NULL); if (config) { ret = usbg_rm_config(config, USBG_RM_RECURSE); - if (ret) + if (ret) { + _E("Could not remove config %d", config_id); return ret; + } } ret = usbg_create_config(cfs_client->gadget, config_id, CONFIGFS_CONFIG_LABEL, &cattrs, NULL, &config); - if (ret) + if (ret) { + _E("Could not create config %d", config_id); return ret; + } for (i = 0; usb_config->strs && usb_config->strs[i].lang_code; ++i) { ret = usbg_set_config_string(config, usb_config->strs[i].lang_code, usb_config->strs[i].config_str); - if (ret) + if (ret) { + _E("Could not set config string"); return ret; + } } for (i = 0; usb_config->funcs && usb_config->funcs[i]; ++i) { @@ -818,6 +837,7 @@ static int cfs_set_gadget_config(struct cfs_client *cfs_client, switch (usb_func->function_group) { case USB_FUNCTION_GROUP_SIMPLE: + _I("Adding simple function %s.%s", usb_func->name, usb_func->instance); type = usbg_lookup_function_type(usb_func->name); if (strlen(usb_func->instance) >= MAX_INSTANCE_LEN) return -ENAMETOOLONG; @@ -825,6 +845,7 @@ static int cfs_set_gadget_config(struct cfs_client *cfs_client, instance[MAX_INSTANCE_LEN - 1] = '\0'; break; case USB_FUNCTION_GROUP_WITH_SERVICE: + _I("Adding function %s.%s with service", usb_func->name, usb_func->instance); type = USBG_F_FFS; ret = snprintf(instance, sizeof(instance), "%s%c%s", usb_func->name, NAME_INSTANCE_SEP, @@ -843,8 +864,10 @@ static int cfs_set_gadget_config(struct cfs_client *cfs_client, type, instance, NULL, &func); - if (ret) + if (ret) { + _E("Could not create function %d %s: %d", type, instance, ret); return ret; + } if (usb_func->function_group == USB_FUNCTION_GROUP_WITH_SERVICE) { @@ -857,15 +880,19 @@ static int cfs_set_gadget_config(struct cfs_client *cfs_client, usb_func->instance, instance, fws->service); - if (ret) + if (ret) { + _E("Could not prepare ffs servicef for %s.%s", type, instance); return ret; + } } } ret = usbg_add_config_function(config, NULL, func); - if (ret) + if (ret) { + _E("Could not add function to config"); return ret; + } } return ret; @@ -963,6 +990,8 @@ static int cfs_gadget_open(struct hw_info *info, struct cfs_client *cfs_client; int ret; + _I("Opening configfs gadget"); + if (!info || !common) return -EINVAL; @@ -975,11 +1004,14 @@ static int cfs_gadget_open(struct hw_info *info, return -ENOMEM; ret = usbg_init(CONFIGFS_PATH, &cfs_client->ctx); - if (ret) + if (ret) { + _E("Could not init usbg"); goto err_usbg_init; + } cfs_client->udc = usbg_get_first_udc(cfs_client->ctx); if (!cfs_client->udc) { + _E("No UDC found by usbg"); ret = -ENODEV; goto err_no_udc; } @@ -987,8 +1019,12 @@ static int cfs_gadget_open(struct hw_info *info, ret = usbg_create_gadget(cfs_client->ctx, CONFIGFS_GADGET_NAME, &default_g_attrs, &default_g_strs, &cfs_client->gadget); - if (ret) + if (ret) { + _E("Could not create gadget"); goto err_create_gadget; + } + + _I("Gadget created"); cfs_client->client.common.info = info; cfs_client->client.get_current_gadget = cfs_get_current_gadget; -- 2.7.4 From c6116158ef7ae3dad4b41976aff87c5c73bdbd15 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Pawe=C5=82=20Szewczyk?= Date: Tue, 10 Apr 2018 16:56:20 +0200 Subject: [PATCH 08/16] usb_cfs_client: Enable gadget at reconfiguration MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Extcon support for artik is bound to the gadget, so we need to need to enable it to start monitoring usb connection. This does not do much harm, but can cause some functionfs daemons to run long before they are actually needed. Change-Id: I7a5eaacaa476539a7cf1c237f811163be4d9b7d5 Signed-off-by: Paweł Szewczyk --- hw/usb_cfs_client/usb_cfs_client.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/hw/usb_cfs_client/usb_cfs_client.c b/hw/usb_cfs_client/usb_cfs_client.c index dc09f21..c7875a4 100644 --- a/hw/usb_cfs_client/usb_cfs_client.c +++ b/hw/usb_cfs_client/usb_cfs_client.c @@ -949,6 +949,13 @@ static int cfs_reconfigure_gadget(struct usb_client *usb, goto out; } + /* Workaround for enabling extcon notification on artik */ + ret = usbg_enable_gadget(cfs_client->gadget, cfs_client->udc); + if (ret) { + _E("Could not enable gadget"); + goto out; + } + ret = cfs_cleanup_left_configs(cfs_client, i); /* TODO -- 2.7.4 From 5c7531935aed9b31ba51e29d88192572250fcdfa Mon Sep 17 00:00:00 2001 From: =?utf8?q?Pawe=C5=82=20Szewczyk?= Date: Wed, 18 Apr 2018 13:48:45 +0200 Subject: [PATCH 09/16] Add sdb+acm configuration MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Change-Id: I59e70efcf7c6126dce60efeadbb7b75940332fdb Signed-off-by: Paweł Szewczyk --- hw/usb_gadget/usb_gadget.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/hw/usb_gadget/usb_gadget.c b/hw/usb_gadget/usb_gadget.c index cc965a6..f7d9473 100755 --- a/hw/usb_gadget/usb_gadget.c +++ b/hw/usb_gadget/usb_gadget.c @@ -226,6 +226,13 @@ static int simple_id_to_gadget(struct usb_gadget_id *gadget_id, functions[0][1] = 0; gadget->attrs.idProduct = 0x6863; break; + case USB_FUNCTION_SDB | USB_FUNCTION_ACM: + n_configs = 1; + functions[0][0] = USB_FUNCTION_ACM; + functions[0][1] = USB_FUNCTION_SDB; + functions[0][2] = 0; + gadget->attrs.idProduct = 0x6866; + break; case USB_FUNCTION_MTP | USB_FUNCTION_ACM | USB_FUNCTION_SDB: n_configs = 1; functions[0][0] = USB_FUNCTION_MTP; -- 2.7.4 From 2e1b03c431759d2169a05384cdca43547abfb5be Mon Sep 17 00:00:00 2001 From: Hyotaek Shim Date: Thu, 19 Apr 2018 15:52:20 +0900 Subject: [PATCH 10/16] Add .gitignore Change-Id: Ic21080f08ae17cc5983c3b79708d72067d7ad136 Signed-off-by: Hyotaek Shim --- .gitignore | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 .gitignore diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..9306ae6 --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +cscope.files +cscope.out +tags -- 2.7.4 From 482bb923f664faa69fa784f0cfddd4cfe8e97042 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Pawe=C5=82=20Szewczyk?= Date: Thu, 19 Apr 2018 14:34:09 +0200 Subject: [PATCH 11/16] Change sdb+acm configuration's idProduct MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Change-Id: I8b8381c910da9d7ce4641515389ca2b1c0b8fb3b Signed-off-by: Paweł Szewczyk --- hw/usb_gadget/usb_gadget.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hw/usb_gadget/usb_gadget.c b/hw/usb_gadget/usb_gadget.c index f7d9473..ad4513d 100755 --- a/hw/usb_gadget/usb_gadget.c +++ b/hw/usb_gadget/usb_gadget.c @@ -231,7 +231,7 @@ static int simple_id_to_gadget(struct usb_gadget_id *gadget_id, functions[0][0] = USB_FUNCTION_ACM; functions[0][1] = USB_FUNCTION_SDB; functions[0][2] = 0; - gadget->attrs.idProduct = 0x6866; + gadget->attrs.idProduct = 0x6860; break; case USB_FUNCTION_MTP | USB_FUNCTION_ACM | USB_FUNCTION_SDB: n_configs = 1; -- 2.7.4 From d1bfb925ae2e93fb11c989563a1fd3442bd56844 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Pawe=C5=82=20Szewczyk?= Date: Tue, 15 May 2018 17:10:05 +0200 Subject: [PATCH 12/16] usb_gadget: Retrieve device serial number MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Serial number is retrieved from /sys/firmware/devicetree/base/serial-number file. Change-Id: I3e8251bd1ce916b72d45102017b3533420ef9f54 Signed-off-by: Paweł Szewczyk --- hw/usb_gadget/usb_gadget.c | 30 +++++++++++++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) diff --git a/hw/usb_gadget/usb_gadget.c b/hw/usb_gadget/usb_gadget.c index ad4513d..d1e6704 100755 --- a/hw/usb_gadget/usb_gadget.c +++ b/hw/usb_gadget/usb_gadget.c @@ -20,6 +20,7 @@ #include +#include #include #include #include @@ -122,11 +123,36 @@ out: return -ENOMEM; } +#define SERIAL_FILE_PATH "/sys/firmware/devicetree/base/serial-number" +#define LINE_LEN 64 + +static int get_device_serial(char **out) +{ + FILE *fp; + char *line, *p; + + fp = fopen(SERIAL_FILE_PATH, "r"); + if (!fp) + return -1; + + line = malloc(LINE_LEN); + p = fgets(line, LINE_LEN, fp); + fclose(fp); + if (p == NULL) { + free(line); + return -1; + } + + *out = p; + return 0; +} + static int alloc_default_gadget(struct usb_gadget **_gadget) { struct usb_gadget *gadget; struct usb_gadget_strings *strs; struct usb_configuration **configs; + int ret; gadget = zalloc(sizeof(*gadget)); if (!gadget) @@ -143,7 +169,9 @@ static int alloc_default_gadget(struct usb_gadget **_gadget) strs[0].lang_code = 0x409; strs[0].manufacturer = strdup(DEFAULT_MANUFACTURER); strs[0].product = strdup(DEFAULT_PRODUCT); - strs[0].serial = strdup(DEFAULT_SERIAL); + ret = get_device_serial(&strs[0].serial); + if (ret < 0) + strs[0].serial = strdup(DEFAULT_SERIAL); if (!strs[0].manufacturer || !strs[0].product || !strs[0].serial) goto free_strs; -- 2.7.4 From 95a0642c57ee597753fc2327b94dfbbe362154b8 Mon Sep 17 00:00:00 2001 From: lokilee73 Date: Tue, 19 Jun 2018 17:17:10 +0900 Subject: [PATCH 13/16] Add display_get_state to remove dependency with enlightenment Change-Id: I826e14589707f1a2e58c6105b7658ddbb4d8a108 Signed-off-by: lokilee73 --- hw/display/display.c | 55 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 55 insertions(+) diff --git a/hw/display/display.c b/hw/display/display.c index 0eb19cb..a38ebd0 100755 --- a/hw/display/display.c +++ b/hw/display/display.c @@ -31,6 +31,10 @@ #define BACKLIGHT_PATH "/sys/class/backlight/s6e8fa0" #endif +#ifndef LCD_PATH +#define LCD_PATH "/sys/class/drm/card0" +#endif + #define MAX_BRIGHTNESS_TEMP 100 static int brightness_temp; @@ -100,6 +104,56 @@ static int display_set_brightness(int brightness) return 0; } +static int display_get_state(enum display_state *state) +{ + int r; + char status[64]; + + // PANEL + r = sys_get_str(LCD_PATH"/card0-DSI-1/enabled", status, sizeof(status)); + if (r < 0) { + _E("fail to get panel (errno:%d)", r); + return r; + } + + if (!strncmp(status, "enabled", 7)) { + r = sys_get_str(LCD_PATH"/card0-DSI-1/dpms", status, sizeof(status)); + if (r < 0) { + _E("fail to get state (errno:%d)", r); + return r; + } + goto out; + } + + //HDMI + r = sys_get_str(LCD_PATH"/card0-HDMI-A-1/enabled", status, sizeof(status)); + if (r < 0) { + _E("fail to get hdmi (errno:%d)", r); + return r; + } + + if (!strncmp(status, "enabled", 7)) { + r = sys_get_str(LCD_PATH"/card0-HDMI-A-1/dpms", status, sizeof(status)); + if (r < 0) { + _E("fail to get state (errno:%d)", r); + return r; + } + } + + //Add here for more LCD device + +out: + //remap LCD state + if (!strncmp(status, "On", 2)) { + *state = DISPLAY_ON; + } else if (!strncmp(status, "Off", 3)) { + *state = DISPLAY_OFF; + } else + *state = -EINVAL; + + return 0; +} + static int display_open(struct hw_info *info, const char *id, struct hw_common **common) { @@ -116,6 +170,7 @@ static int display_open(struct hw_info *info, display_dev->get_max_brightness = display_get_max_brightness; display_dev->get_brightness = display_get_brightness; display_dev->set_brightness = display_set_brightness; + display_dev->get_state = display_get_state; *common = (struct hw_common *)display_dev; return 0; -- 2.7.4 From a767db5c43da65675887deaaabcf89a1db338b31 Mon Sep 17 00:00:00 2001 From: lokilee73 Date: Wed, 27 Jun 2018 11:34:22 +0900 Subject: [PATCH 14/16] Modify blinkm_led_stop_script peripherial_i2c_byte_write() was removed, So replaced it with peripherial_i2c_write(). Change-Id: I4fa3388489e23fdedc7e2c95c23272e65c6a949a Signed-off-by: lokilee73 --- hw/led/led.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) mode change 100644 => 100755 hw/led/led.c diff --git a/hw/led/led.c b/hw/led/led.c old mode 100644 new mode 100755 index 547c894..130a8e7 --- a/hw/led/led.c +++ b/hw/led/led.c @@ -73,7 +73,10 @@ static uint8_t off_cmd[4] = { SET_CMD_CODE, 0x00, 0x00, 0x00 }; static void blinkm_led_stop_script(peripheral_i2c_h handle) { - peripheral_i2c_write_byte(handle, STOP_SCRIPT_CMD); + uint8_t data[1] = {STOP_SCRIPT_CMD}; + uint32_t length = 1; + + peripheral_i2c_write(handle, data, length); } /** -- 2.7.4 From d6898ed6ad5006718c119e103a1a0e967fee7231 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Pawe=C5=82=20Szewczyk?= Date: Thu, 28 Jun 2018 12:27:53 +0200 Subject: [PATCH 15/16] usb_gadget: Move common code to hwcommon MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Change-Id: Icc1e965e889d9d73667198120667bd55fbea0df7 Signed-off-by: Paweł Szewczyk --- hw/usb_gadget/usb_gadget.c | 394 --------------------------------------------- 1 file changed, 394 deletions(-) diff --git a/hw/usb_gadget/usb_gadget.c b/hw/usb_gadget/usb_gadget.c index d1e6704..470a984 100755 --- a/hw/usb_gadget/usb_gadget.c +++ b/hw/usb_gadget/usb_gadget.c @@ -20,400 +20,6 @@ #include -#include -#include -#include -#include - -#define ARRAY_SIZE(a) (sizeof(a)/sizeof(a[0])) -#define zalloc(amount) calloc(1, amount) - -/* Based on slp-gadget and initial version of USB HAL by Taeyoung Kim */ -#define DEFAULT_VID 0x04e8 -#define DEFAULT_PID 0x6860 -#define DEFAULT_BCD_DEVICE 0x0100 - -#define DEFAULT_LANG 0x409 /* US_en */ -#define DEFAULT_MANUFACTURER "Samsung" -#define DEFAULT_PRODUCT "TIZEN" -#define DEFAULT_SERIAL "01234TEST" - -#define DEFAULT_BMATTRIBUTES ((1 << 7) | (1 << 6)) -#define DEFAULT_MAX_POWER 500 - -static void simple_cleanup_config(struct usb_configuration *config) -{ - int i; - - if (!config) - return; - - if (config->strs) { - for (i = 0; config->strs[i].lang_code; ++i) - free(config->strs[i].config_str); - - free(config->strs); - } - - /* - * Each function will be free later, - * for now we cleanup only pointers. - */ - if (config->funcs) - free(config->funcs); - - free(config); -} - -static void simple_cleanup_gadget(struct usb_gadget *gadget) -{ - int i; - - if (!gadget) - return; - - if (gadget->strs) { - for (i = 0; gadget->strs[i].lang_code; ++i) { - free(gadget->strs[i].manufacturer); - free(gadget->strs[i].product); - free(gadget->strs[i].serial); - } - free(gadget->strs); - } - - if (gadget->configs) { - for (i = 0; gadget->configs[i]; ++i) - simple_cleanup_config(gadget->configs[i]); - - free(gadget->configs); - } - - if (gadget->funcs) { - for (i = 0; gadget->funcs[i]; ++i) - gadget->funcs[i]->free_func(gadget->funcs[i]); - - free(gadget->funcs); - } - - free(gadget); -} - -static int alloc_default_config(struct usb_configuration **_config) -{ - struct usb_configuration *config; - - config = zalloc(sizeof(*config)); - if (!config) - goto out; - - config->strs = calloc(1, sizeof(*config->strs)); - if (!config->strs) - goto free_config; - - config->attrs.bmAttributs = DEFAULT_BMATTRIBUTES; - config->attrs.MaxPower = DEFAULT_MAX_POWER; - - *_config = config; - - return 0; - -free_config: - free(config); -out: - return -ENOMEM; -} - -#define SERIAL_FILE_PATH "/sys/firmware/devicetree/base/serial-number" -#define LINE_LEN 64 - -static int get_device_serial(char **out) -{ - FILE *fp; - char *line, *p; - - fp = fopen(SERIAL_FILE_PATH, "r"); - if (!fp) - return -1; - - line = malloc(LINE_LEN); - p = fgets(line, LINE_LEN, fp); - fclose(fp); - if (p == NULL) { - free(line); - return -1; - } - - *out = p; - return 0; -} - -static int alloc_default_gadget(struct usb_gadget **_gadget) -{ - struct usb_gadget *gadget; - struct usb_gadget_strings *strs; - struct usb_configuration **configs; - int ret; - - gadget = zalloc(sizeof(*gadget)); - if (!gadget) - goto out; - - gadget->attrs.idVendor = DEFAULT_VID; - gadget->attrs.idProduct = DEFAULT_PID; - gadget->attrs.bcdDevice = DEFAULT_BCD_DEVICE; - - strs = calloc(2, sizeof(*strs)); - if (!strs) - goto free_gadget; - - strs[0].lang_code = 0x409; - strs[0].manufacturer = strdup(DEFAULT_MANUFACTURER); - strs[0].product = strdup(DEFAULT_PRODUCT); - ret = get_device_serial(&strs[0].serial); - if (ret < 0) - strs[0].serial = strdup(DEFAULT_SERIAL); - - if (!strs[0].manufacturer || !strs[0].product || !strs[0].serial) - goto free_strs; - - gadget->strs = strs; - - /* slp-gadget use max 2 confiuration and NULL termination */ - configs = calloc(3, sizeof(*configs)); - if (!configs) - goto free_strs; - - gadget->configs = configs; - *_gadget = gadget; - - return 0; - -free_strs: - free(strs[0].manufacturer); - free(strs[0].product); - free(strs[0].serial); - free(strs); -free_gadget: - free(gadget); -out: - return -ENOMEM; -} - -static inline struct usb_function *find_func(struct usb_gadget *gadget, - int func_id) -{ - int i; - - for (i = 0; gadget->funcs[i] && gadget->funcs[i]->id != func_id; ++i); - - return gadget->funcs[i]; -} - -static int simple_id_to_gadget(struct usb_gadget_id *gadget_id, - struct usb_gadget **_gadget) -{ - struct usb_gadget *gadget; - unsigned int n_configs = 0; - /* zero terminates */ - int functions[2][sizeof(gadget_id->function_mask)*8]; - int n_functions; - struct usb_function **funcs; - int idx, i, j; - int ret; - - if (!gadget_id || !_gadget) - return -EINVAL; - - ret = alloc_default_gadget(&gadget); - if (ret) - goto out; - - /* - * Currently all gadgets use inly single configuration but - * slp-gadget is capable to handle two of them - * - * Order of interfaces in configuration is significant - * so in this switch we sort our functions in a correct order - */ - switch (gadget_id->function_mask) { - case USB_FUNCTION_SDB: - n_configs = 1; - functions[0][0] = USB_FUNCTION_SDB; - functions[0][1] = 0; - gadget->attrs.idProduct = 0x685d; - break; - case USB_FUNCTION_MTP: - n_configs = 1; - functions[0][0] = USB_FUNCTION_MTP; - functions[0][1] = 0; - gadget->attrs.idProduct = 0x6860; - break; - case USB_FUNCTION_RNDIS: - n_configs = 1; - functions[0][0] = USB_FUNCTION_RNDIS; - functions[0][1] = 0; - gadget->attrs.idProduct = 0x6863; - break; - case USB_FUNCTION_SDB | USB_FUNCTION_ACM: - n_configs = 1; - functions[0][0] = USB_FUNCTION_ACM; - functions[0][1] = USB_FUNCTION_SDB; - functions[0][2] = 0; - gadget->attrs.idProduct = 0x6860; - break; - case USB_FUNCTION_MTP | USB_FUNCTION_ACM | USB_FUNCTION_SDB: - n_configs = 1; - functions[0][0] = USB_FUNCTION_MTP; - functions[0][1] = USB_FUNCTION_ACM; - functions[0][2] = USB_FUNCTION_SDB; - functions[0][3] = 0; - gadget->attrs.idProduct = 0x6860; - break; - case USB_FUNCTION_MTP | USB_FUNCTION_ACM | USB_FUNCTION_SDB - | USB_FUNCTION_DIAG: - n_configs = 1; - functions[0][0] = USB_FUNCTION_MTP; - functions[0][1] = USB_FUNCTION_ACM; - functions[0][2] = USB_FUNCTION_SDB; - functions[0][3] = USB_FUNCTION_DIAG; - functions[0][4] = 0; - gadget->attrs.idProduct = 0x6860; - break; - case USB_FUNCTION_RNDIS | USB_FUNCTION_SDB: - n_configs = 1; - functions[0][0] = USB_FUNCTION_RNDIS; - functions[0][1] = USB_FUNCTION_SDB; - functions[0][2] = 0; - gadget->attrs.idProduct = 0x6864; - break; - case USB_FUNCTION_RNDIS | USB_FUNCTION_SDB | USB_FUNCTION_ACM | USB_FUNCTION_DIAG: - n_configs = 1; - functions[0][0] = USB_FUNCTION_RNDIS; - functions[0][1] = USB_FUNCTION_SDB; - functions[0][2] = USB_FUNCTION_ACM; - functions[0][3] = USB_FUNCTION_DIAG; - functions[0][4] = 0; - gadget->attrs.idProduct = 0x6864; - break; - case USB_FUNCTION_RNDIS | USB_FUNCTION_DIAG: - n_configs = 1; - functions[0][0] = USB_FUNCTION_RNDIS; - functions[0][1] = USB_FUNCTION_DIAG; - functions[0][2] = 0; - gadget->attrs.idProduct = 0x6864; - break; - case USB_FUNCTION_ACM | USB_FUNCTION_SDB | USB_FUNCTION_DM: - n_configs = 1; - functions[0][0] = USB_FUNCTION_ACM; - functions[0][1] = USB_FUNCTION_SDB; - functions[0][2] = USB_FUNCTION_DM; - functions[0][3] = 0; - gadget->attrs.idProduct = 0x6860; - break; - case USB_FUNCTION_DIAG | USB_FUNCTION_ACM | USB_FUNCTION_RMNET: - n_configs = 1; - functions[0][0] = USB_FUNCTION_DIAG; - functions[0][1] = USB_FUNCTION_ACM; - functions[0][2] = USB_FUNCTION_RMNET; - functions[0][3] = 0; - gadget->attrs.idProduct = 0x685d; - break; - }; - - if (n_configs > 2 || n_configs == 0) { - ret = -EINVAL; - goto free_gadget; - } - - n_functions = __builtin_popcount(gadget_id->function_mask); - - funcs = calloc(n_functions + 1, sizeof(*funcs)); - if (!funcs) { - ret = -ENOMEM; - goto free_gadget; - } - - gadget->funcs = funcs; - - idx = 0; - for (i = 0; i < ARRAY_SIZE(_available_funcs); ++i) { - int func_id = 1 << i; - - if (!(gadget_id->function_mask & func_id)) - continue; - - ret = _available_funcs[i]->clone(_available_funcs[i], - gadget->funcs + idx); - if (ret) - goto free_functions; - ++idx; - } - - for (j = 0; j < n_configs; ++j) { - struct usb_configuration *config; - int n_funcs_in_config; - - for (i = 0; functions[j][i]; ++i); - n_funcs_in_config = i; - - ret = alloc_default_config(&config); - if (ret) - goto free_configs; - - gadget->configs[j] = config; - config->funcs = calloc(n_funcs_in_config + 1, - sizeof(void *)); - if (!config->funcs) - goto free_configs; - - for (i = 0; functions[j][i]; ++i) - config->funcs[i] = find_func(gadget, functions[j][i]); - } - - *_gadget = gadget; - return 0; -free_configs: -free_functions: -free_gadget: - simple_cleanup_gadget(gadget); -out: - return ret; -} - -static int simple_translator_open(struct hw_info *info, - const char *id, struct hw_common **common) -{ - struct usb_gadget_translator *simple_translator; - - if (!info || !common) - return -EINVAL; - - simple_translator = zalloc(sizeof(*simple_translator)); - if (!simple_translator) - return -ENOMEM; - - simple_translator->common.info = info; - simple_translator->id_to_gadget = simple_id_to_gadget; - simple_translator->cleanup_gadget = simple_cleanup_gadget; - - *common = &simple_translator->common; - return 0; -} - -static int simple_translator_close(struct hw_common *common) -{ - struct usb_gadget_translator *simple_translator; - - if (!common) - return -EINVAL; - - simple_translator = container_of(common, struct usb_gadget_translator, - common); - - free(simple_translator); - return 0; -} - HARDWARE_MODULE_STRUCTURE = { .magic = HARDWARE_INFO_TAG, .hal_version = HARDWARE_INFO_VERSION, -- 2.7.4 From 6f13e9d8a1587ce155f57094ff282d0c8bfe0c54 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Pawe=C5=82=20Szewczyk?= Date: Thu, 28 Jun 2018 12:58:30 +0200 Subject: [PATCH 16/16] Add board HAL MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Change-Id: Ifcc9256bb722b32f8c3db3bdb873a4e6c88c8ef8 Signed-off-by: Paweł Szewczyk --- CMakeLists.txt | 1 + hw/board/CMakeLists.txt | 19 +++++++++++ hw/board/board.c | 91 +++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 111 insertions(+) create mode 100644 hw/board/CMakeLists.txt create mode 100755 hw/board/board.c diff --git a/CMakeLists.txt b/CMakeLists.txt index 7fab672..3653bc0 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -4,6 +4,7 @@ PROJECT(device-manager-artik C) SET(PREFIX ${CMAKE_INSTALL_PREFIX}) #ADD_SUBDIRECTORY(hw/battery) +ADD_SUBDIRECTORY(hw/board) ADD_SUBDIRECTORY(hw/display) #ADD_SUBDIRECTORY(hw/external_connection) ADD_SUBDIRECTORY(hw/led) diff --git a/hw/board/CMakeLists.txt b/hw/board/CMakeLists.txt new file mode 100644 index 0000000..5b8b5b4 --- /dev/null +++ b/hw/board/CMakeLists.txt @@ -0,0 +1,19 @@ +CMAKE_MINIMUM_REQUIRED(VERSION 2.6) +PROJECT(board C) + +SET(PREFIX ${CMAKE_INSTALL_PREFIX}) + +INCLUDE(FindPkgConfig) +pkg_check_modules(usb_gadget_pkgs REQUIRED hwcommon) + +FOREACH(flag ${usb_gadget_pkgs_CFLAGS}) + SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}") +ENDFOREACH(flag) + +SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -fvisibility=hidden") +SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS}") + +ADD_LIBRARY(${PROJECT_NAME} MODULE board.c) +TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${usb_gadget_pkgs_LDFLAGS}) +SET_TARGET_PROPERTIES(${PROJECT_NAME} PROPERTIES PREFIX "") +INSTALL(TARGETS ${PROJECT_NAME} DESTINATION ${LIB_INSTALL_DIR}/hw COMPONENT RuntimeLibraries) diff --git a/hw/board/board.c b/hw/board/board.c new file mode 100755 index 0000000..3c6b42d --- /dev/null +++ b/hw/board/board.c @@ -0,0 +1,91 @@ +/* + * libdevice-node + * + * Copyright (c) 2016 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#define _GNU_SOURCE +#include + +#include +#include +#include +#include + +#define SERIAL_FILE_PATH "/sys/firmware/devicetree/base/serial-number" +#define LINE_LEN 64 + +static int get_device_serial(char **out) +{ + FILE *fp; + char *line, *p; + + fp = fopen(SERIAL_FILE_PATH, "r"); + if (!fp) + return -1; + + line = malloc(LINE_LEN); + p = fgets(line, LINE_LEN, fp); + fclose(fp); + if (p == NULL) { + free(line); + return -1; + } + + *out = p; + return 0; +} + +static int board_open(struct hw_info *info, + const char *id, struct hw_common **common) +{ + struct hw_board *b; + + if (!info || !common) + return -EINVAL; + + b = calloc(1, sizeof(*b)); + if (!b) + return -ENOMEM; + + b->common.info = info; + b->get_device_serial = get_device_serial; + + *common = &b->common; + return 0; +} + +static int board_close(struct hw_common *common) +{ + struct hw_board *b; + + if (!common) + return -EINVAL; + + b = container_of(common, struct hw_board, common); + free(b); + + return 0; +} + +HARDWARE_MODULE_STRUCTURE = { + .magic = HARDWARE_INFO_TAG, + .hal_version = HARDWARE_INFO_VERSION, + .device_version = BOARD_HARDWARE_DEVICE_VERSION, + .id = BOARD_HARDWARE_DEVICE_ID, + .name = "device", + .open = board_open, + .close = board_close, +}; -- 2.7.4