From dba4d811c41be1bc3656bd8700d86ea492c3ab16 Mon Sep 17 00:00:00 2001 From: lokilee73 Date: Tue, 26 Feb 2019 19:08:34 +0900 Subject: [PATCH] Add bezel for wearable target Change-Id: Id9e95809b20c0593bc46a0d6139a2802f75a3ad6 Signed-off-by: lokilee73 --- CMakeLists.txt | 3 +- hw/bezel/CMakeLists.txt | 19 +++++ hw/bezel/bezel.c | 181 ++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 202 insertions(+), 1 deletion(-) create mode 100644 hw/bezel/CMakeLists.txt create mode 100644 hw/bezel/bezel.c diff --git a/CMakeLists.txt b/CMakeLists.txt index 47b02ce..89092ae 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -9,4 +9,5 @@ ADD_SUBDIRECTORY(hw/external_connection) ADD_SUBDIRECTORY(hw/touchscreen) ADD_SUBDIRECTORY(hw/usb_gadget) ADD_SUBDIRECTORY(hw/usb_client) -ADD_SUBDIRECTORY(hw/thermal) \ No newline at end of file +ADD_SUBDIRECTORY(hw/thermal) +ADD_SUBDIRECTORY(hw/bezel) \ No newline at end of file diff --git a/hw/bezel/CMakeLists.txt b/hw/bezel/CMakeLists.txt new file mode 100644 index 0000000..36a47e7 --- /dev/null +++ b/hw/bezel/CMakeLists.txt @@ -0,0 +1,19 @@ +CMAKE_MINIMUM_REQUIRED(VERSION 2.6) +PROJECT(bezel C) + +SET(PREFIX ${CMAKE_INSTALL_PREFIX}) + +INCLUDE(FindPkgConfig) +pkg_check_modules(bezel_pkgs REQUIRED hwcommon dlog) + +FOREACH(flag ${bezel_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 bezel.c) +TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${bezel_pkgs_LDFLAGS}) +SET_TARGET_PROPERTIES(${PROJECT_NAME} PROPERTIES PREFIX "") +INSTALL(TARGETS ${PROJECT_NAME} DESTINATION ${LIB_INSTALL_DIR}/hw COMPONENT RuntimeLibraries) diff --git a/hw/bezel/bezel.c b/hw/bezel/bezel.c new file mode 100644 index 0000000..289d443 --- /dev/null +++ b/hw/bezel/bezel.c @@ -0,0 +1,181 @@ +/* + * device-node + * + * Copyright (c) 2019 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. + */ + + +#include +#include +#include +#include +#include +#include + +#include +#include + +#define INPUT_PATH "/sys/class/input/" +#define KEY_CAPABILITIES_PATH "/device/capabilities/key" +#define ENABLED_PATH "/device/enabled" +#define bezel_CAPABILITY 10000 + +static char *bezel_node; + +static int bezel_probe(void) +{ + DIR *d; + struct dirent *dir; + char buf[PATH_MAX]; + int val, ret = -ENOTSUP; + + d = opendir(INPUT_PATH); + if (!d) + return -errno; + + while ((dir = readdir(d))) { + if (dir->d_name[0] == '.') + continue; + snprintf(buf, sizeof(buf), "%s%s%s", INPUT_PATH, + dir->d_name, KEY_CAPABILITIES_PATH); + + ret = sys_get_int(buf, &val); + if (ret < 0 || val != bezel_CAPABILITY) + continue; + + snprintf(buf, sizeof(buf), "%s%s%s", INPUT_PATH, + dir->d_name, ENABLED_PATH); + + if (bezel_node) + free(bezel_node); + + bezel_node = strndup(buf, strlen(buf)); + if (bezel_node) { + _I("bezel node (%s)", bezel_node); + ret = 0; + } else { + _E("strndup() failed"); + ret = -ENOMEM; + } + break; + } + closedir(d); + + return ret; +} + +static int bezel_get_state(enum bezel_state *state) +{ + int ret, val; + + if (!bezel_node || !(*bezel_node)) + return -ENOENT; + + if (!state) + return -EINVAL; + + ret = sys_get_int(bezel_node, &val); + if (ret < 0) { + _E("Failed to get bezel state (%d)", ret); + return ret; + } + + switch (val) { + case BEZEL_TURNOFF: + *state = BEZEL_TURNOFF; + break; + case BEZEL_TURNON: + *state = BEZEL_TURNON; + break; + default: + _E("Failed to get bezel state (%d)", val); + return -EINVAL; + } + + return 0; +} + +static int bezel_set_state(enum bezel_state state) +{ + int ret, val; + + if (!bezel_node || !(*bezel_node)) + return -ENOENT; + + switch (state) { + case BEZEL_TURNOFF: + val = BEZEL_TURNOFF; + break; + case BEZEL_TURNON: + val = BEZEL_TURNON; + break; + default: + _E("Invalid input (%d)", state); + return -EINVAL; + } + + ret = sys_set_int(bezel_node, val); + if (ret < 0) + _E("Failed to change bezel state (%d)", ret); + + return ret; +} + +static int bezel_open(struct hw_info *info, + const char *id, struct hw_common **common) +{ + struct bezel_device *bezel_dev; + + if (!info || !common) + return -EINVAL; + + if (bezel_probe() < 0) + return -ENOTSUP; + + bezel_dev = calloc(1, sizeof(struct bezel_device)); + if (!bezel_dev) + return -ENOMEM; + + bezel_dev->common.info = info; + bezel_dev->get_state = bezel_get_state; + bezel_dev->set_state = bezel_set_state; + + *common = (struct hw_common *)bezel_dev; + return 0; +} + +static int bezel_close(struct hw_common *common) +{ + if (!common) + return -EINVAL; + + free(common); + if (bezel_node) { + free(bezel_node); + bezel_node = NULL; + } + + return 0; +} + +HARDWARE_MODULE_STRUCTURE = { + .magic = HARDWARE_INFO_TAG, + .hal_version = HARDWARE_INFO_VERSION, + .device_version = BEZEL_HARDWARE_DEVICE_VERSION, + .id = BEZEL_HARDWARE_DEVICE_ID, + .name = "bezel", + .open = bezel_open, + .close = bezel_close, +}; -- 2.7.4