From: Adrian Szyndela Date: Wed, 9 Jun 2021 09:23:25 +0000 (+0200) Subject: i2c: replace gdbus with direct implementation X-Git-Tag: submit/tizen/20210629.011533~20 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=ed7be9c59cac96ea1f52f3e28581f95b0c8eafc2;p=platform%2Fcore%2Fapi%2Fperipheral-io.git i2c: replace gdbus with direct implementation Move open/close code from peripheral-bus. Add flocks() where appropriate. Change-Id: I57bffbe463cacf2674484e8d8cf8fadfe672218f --- diff --git a/CMakeLists.txt b/CMakeLists.txt index 43c0b29..8fea6c2 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -67,7 +67,6 @@ SET(SOURCES src/peripheral_gpio.c src/interface/peripheral_interface_spi.c src/interface/peripheral_interface_uart.c src/gdbus/peripheral_gdbus_gpio.c - src/gdbus/peripheral_gdbus_i2c.c src/gdbus/peripheral_gdbus_pwm.c src/gdbus/peripheral_gdbus_adc.c src/gdbus/peripheral_gdbus_uart.c diff --git a/include/gdbus/peripheral_gdbus_i2c.h b/include/gdbus/peripheral_gdbus_i2c.h deleted file mode 100644 index 643d7c8..0000000 --- a/include/gdbus/peripheral_gdbus_i2c.h +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Copyright (c) 2016-2017 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. - */ - -#ifndef __PERIPHERAL_GDBUS_I2C_H__ -#define __PERIPHERAL_GDBUS_I2C_H__ - -#include "peripheral_gdbus_common.h" - -int peripheral_gdbus_i2c_open(peripheral_i2c_h i2c, int bus, int address); -int peripheral_gdbus_i2c_open_flags(peripheral_i2c_h i2c, int bus, int address, int flags); -int peripheral_gdbus_i2c_close(peripheral_i2c_h i2c); - -#endif /* __PERIPHERAL_GDBUS_I2C_H__ */ diff --git a/include/interface/peripheral_interface_common.h b/include/interface/peripheral_interface_common.h index d6137ce..675c3fb 100644 --- a/include/interface/peripheral_interface_common.h +++ b/include/interface/peripheral_interface_common.h @@ -46,4 +46,4 @@ typedef struct predefined_type { int len; } predefined_type_s; -#endif /*__PERIPHERAL_INTERFACE_COMMON_H__*/ \ No newline at end of file +#endif /*__PERIPHERAL_INTERFACE_COMMON_H__*/ diff --git a/include/peripheral_handle.h b/include/peripheral_handle.h index b3ca528..b766364 100644 --- a/include/peripheral_handle.h +++ b/include/peripheral_handle.h @@ -54,7 +54,6 @@ struct _peripheral_gpio_s { * @brief Internal struct for i2c context */ struct _peripheral_i2c_s { - uint handle; int fd; }; diff --git a/src/gdbus/peripheral_gdbus_i2c.c b/src/gdbus/peripheral_gdbus_i2c.c deleted file mode 100644 index fe3a5f7..0000000 --- a/src/gdbus/peripheral_gdbus_i2c.c +++ /dev/null @@ -1,167 +0,0 @@ -/* - * Copyright (c) 2016-2017 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 "peripheral_gdbus_i2c.h" - -#define I2C_FD_INDEX 0 - -static PeripheralIoGdbusI2c *i2c_proxy = NULL; - -static int __i2c_proxy_init(void) -{ - GError *error = NULL; - - if (i2c_proxy != NULL) { - _E("I2c proxy is already created"); - g_object_ref(i2c_proxy); - return PERIPHERAL_ERROR_NONE; - } - - i2c_proxy = peripheral_io_gdbus_i2c_proxy_new_for_bus_sync( - G_BUS_TYPE_SYSTEM, - G_DBUS_PROXY_FLAGS_NONE, - PERIPHERAL_GDBUS_NAME, - PERIPHERAL_GDBUS_I2C_PATH, - NULL, - &error); - - if (i2c_proxy == NULL) { - if (error) { - _E("Failed to create i2c proxy : %s", error->message); - g_error_free(error); - } - return PERIPHERAL_ERROR_IO_ERROR; - } - - return PERIPHERAL_ERROR_NONE; -} - -static int __i2c_proxy_deinit(void) -{ - RETVM_IF(i2c_proxy == NULL, PERIPHERAL_ERROR_IO_ERROR, "I2c proxy is NULL"); - - g_object_unref(i2c_proxy); - if (!G_IS_OBJECT(i2c_proxy)) - i2c_proxy = NULL; - - return PERIPHERAL_ERROR_NONE; -} - -int peripheral_gdbus_i2c_open(peripheral_i2c_h i2c, int bus, int address) -{ - int ret; - GError *error = NULL; - GUnixFDList *fd_list = NULL; - - ret = __i2c_proxy_init(); - if (ret != PERIPHERAL_ERROR_NONE) - return ret; - - if (peripheral_io_gdbus_i2c_call_open_sync( - i2c_proxy, - bus, - address, - NULL, - &i2c->handle, - &ret, - &fd_list, - NULL, - &error) == FALSE) { - _E("Failed to request daemon to i2c open : %s", error->message); - g_error_free(error); - return PERIPHERAL_ERROR_IO_ERROR; - } - - // TODO : If ret is not PERIPHERAL_ERROR_NONE, fd list it NULL from daemon. - if (ret != PERIPHERAL_ERROR_NONE) - return ret; - - i2c->fd = g_unix_fd_list_get(fd_list, I2C_FD_INDEX, &error); - if (i2c->fd < 0) { - _E("Failed to get fd for i2c : %s", error->message); - g_error_free(error); - ret = PERIPHERAL_ERROR_IO_ERROR; - } - - g_object_unref(fd_list); - - return ret; -} - -int peripheral_gdbus_i2c_open_flags(peripheral_i2c_h i2c, int bus, int address, int flags) -{ - int ret; - GError *error = NULL; - GUnixFDList *fd_list = NULL; - - ret = __i2c_proxy_init(); - if (ret != PERIPHERAL_ERROR_NONE) - return ret; - - if (peripheral_io_gdbus_i2c_call_open_flags_sync( - i2c_proxy, - bus, - address, - flags, - NULL, - &i2c->handle, - &ret, - &fd_list, - NULL, - &error) == FALSE) { - _E("Failed to request daemon to i2c open : %s", error->message); - g_error_free(error); - return PERIPHERAL_ERROR_IO_ERROR; - } - - // TODO : If ret is not PERIPHERAL_ERROR_NONE, fd list it NULL from daemon. - if (ret != PERIPHERAL_ERROR_NONE) - return ret; - - i2c->fd = g_unix_fd_list_get(fd_list, I2C_FD_INDEX, &error); - if (i2c->fd < 0) { - _E("Failed to get fd for i2c : %s", error->message); - g_error_free(error); - ret = PERIPHERAL_ERROR_IO_ERROR; - } - - g_object_unref(fd_list); - - return ret; -} - -int peripheral_gdbus_i2c_close(peripheral_i2c_h i2c) -{ - RETVM_IF(i2c_proxy == NULL, PERIPHERAL_ERROR_IO_ERROR, "I2c proxy is NULL"); - - int ret; - GError *error = NULL; - - if (peripheral_io_gdbus_i2c_call_close_sync( - i2c_proxy, - i2c->handle, - &ret, - NULL, - &error) == FALSE) { - _E("Failed to request daemon to i2c close : %s", error->message); - g_error_free(error); - return PERIPHERAL_ERROR_IO_ERROR; - } - - __i2c_proxy_deinit(); - - return ret; -} diff --git a/src/peripheral_i2c.c b/src/peripheral_i2c.c index 5f493f2..b97f4c1 100644 --- a/src/peripheral_i2c.c +++ b/src/peripheral_i2c.c @@ -13,13 +13,14 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - +#include #include +#include +#include #include #include "peripheral_io.h" #include "peripheral_handle.h" -#include "peripheral_gdbus_i2c.h" #include "peripheral_interface_i2c.h" #include "peripheral_log.h" @@ -56,41 +57,29 @@ static bool __is_feature_supported(void) return (i2c_feature == I2C_FEATURE_TRUE ? true : false); } -int peripheral_i2c_open(int bus, int address, peripheral_i2c_h *i2c) -{ - peripheral_i2c_h handle; - int ret = PERIPHERAL_ERROR_NONE; - - RETVM_IF(__is_feature_supported() == false, PERIPHERAL_ERROR_NOT_SUPPORTED, "I2C feature is not supported"); - RETVM_IF(i2c == NULL, PERIPHERAL_ERROR_INVALID_PARAMETER, "Invalid i2c handle"); - RETVM_IF(bus < 0 || address < 0, PERIPHERAL_ERROR_INVALID_PARAMETER, "Invalid parameter"); - - handle = (peripheral_i2c_h)malloc(sizeof(struct _peripheral_i2c_s)); - if (handle == NULL) { - _E("Failed to allocate peripheral_i2c_h"); - return PERIPHERAL_ERROR_OUT_OF_MEMORY; - } - - ret = peripheral_gdbus_i2c_open(handle, bus, address); - if (ret != PERIPHERAL_ERROR_NONE) { - _E("Failed to open i2c communication, ret : %d", ret); - free(handle); - handle = NULL; +static inline void cleanup_handlep(peripheral_i2c_h *handle) { + if (*handle != NULL) { + if ((*handle)->fd != -1) + close((*handle)->fd); + free(*handle); } - - *i2c = handle; - - return ret; } int peripheral_i2c_open_flags(int bus, int address, peripheral_open_flags_e flags, peripheral_i2c_h *i2c) { - peripheral_i2c_h handle; int ret = PERIPHERAL_ERROR_NONE; + int lock_type = LOCK_EX; + +#define DEV_PATH_BASE "/dev/i2c-" + char path[sizeof(DEV_PATH_BASE "0000000000")] = {0, }; /* space for /dev/i2c-%d */ RETVM_IF(__is_feature_supported() == false, PERIPHERAL_ERROR_NOT_SUPPORTED, "I2C feature is not supported"); RETVM_IF(i2c == NULL, PERIPHERAL_ERROR_INVALID_PARAMETER, "Invalid i2c handle"); RETVM_IF(bus < 0 || address < 0, PERIPHERAL_ERROR_INVALID_PARAMETER, "Invalid parameter"); + RETVM_IF(flags != PERIPHERAL_OPEN_FLAGS_PRIVATE && flags != PERIPHERAL_OPEN_FLAGS_SHARED, + PERIPHERAL_ERROR_INVALID_PARAMETER, "Invalid flags"); + + __attribute__ ((cleanup(cleanup_handlep))) peripheral_i2c_h handle = NULL; handle = (peripheral_i2c_h)malloc(sizeof(struct _peripheral_i2c_s)); if (handle == NULL) { @@ -98,16 +87,35 @@ int peripheral_i2c_open_flags(int bus, int address, peripheral_open_flags_e flag return PERIPHERAL_ERROR_OUT_OF_MEMORY; } - ret = peripheral_gdbus_i2c_open_flags(handle, bus, address, flags); - if (ret != PERIPHERAL_ERROR_NONE) { - _E("Failed to open i2c communication, ret : %d", ret); - free(handle); - handle = NULL; + snprintf(path, sizeof path, DEV_PATH_BASE "%d", bus); + handle->fd = open(path, O_RDWR | O_CLOEXEC); + CHECK_ERROR(handle->fd < 0); + + ret = ioctl(handle->fd, I2C_SLAVE, address); + CHECK_ERROR(ret); + + if (flags == PERIPHERAL_OPEN_FLAGS_SHARED) + lock_type = LOCK_SH; + + if (flock(handle->fd, lock_type | LOCK_NB)) { + if (errno == EWOULDBLOCK) { + _E("bus : %d, address : 0x%x is not available", bus, address); + return PERIPHERAL_ERROR_RESOURCE_BUSY; + } else { + _E("bus : %d, address : 0x%x flock() error: %d", bus, address, errno); + return PERIPHERAL_ERROR_IO_ERROR; + } } *i2c = handle; + handle = NULL; - return ret; + return PERIPHERAL_ERROR_NONE; +} + +int peripheral_i2c_open(int bus, int address, peripheral_i2c_h *i2c) +{ + return peripheral_i2c_open_flags(bus, address, PERIPHERAL_OPEN_FLAGS_PRIVATE, i2c); } int peripheral_i2c_close(peripheral_i2c_h i2c) @@ -117,10 +125,6 @@ int peripheral_i2c_close(peripheral_i2c_h i2c) RETVM_IF(__is_feature_supported() == false, PERIPHERAL_ERROR_NOT_SUPPORTED, "I2C feature is not supported"); RETVM_IF(i2c == NULL, PERIPHERAL_ERROR_INVALID_PARAMETER, "i2c handle is NULL"); - ret = peripheral_gdbus_i2c_close(i2c); - if (ret != PERIPHERAL_ERROR_NONE) - _E("Failed to close i2c communcation, ret : %d", ret); - peripheral_interface_i2c_close(i2c); free(i2c);