gpio: flatten structure - remove 'interface' 57/260257/5
authorAdrian Szyndela <adrian.s@samsung.com>
Tue, 22 Jun 2021 14:28:06 +0000 (16:28 +0200)
committerAdrian Szyndela <adrian.s@samsung.com>
Fri, 25 Jun 2021 09:51:36 +0000 (11:51 +0200)
Merge src/peripheral_gpio.c with src/interface/peripheral_interface_gpio.c,
with additions from include/interface/peripheral_interface_gpio.h.

Change-Id: I45f9eda5cf4ab47995db43bf934ab7176670b867

CMakeLists.txt
include/interface/peripheral_interface_gpio.h [deleted file]
src/interface/peripheral_interface_gpio.c [deleted file]
src/peripheral_gpio.c

index 742b7b4..fbd65b5 100644 (file)
@@ -60,7 +60,6 @@ SET(SOURCES src/peripheral_gpio.c
                        src/peripheral_adc.c
                        src/peripheral_uart.c
                        src/peripheral_spi.c
-                       src/interface/peripheral_interface_gpio.c
                        src/interface/peripheral_interface_pwm.c
                        src/gdbus/peripheral_gdbus_pwm.c
                        src/gdbus/peripheral_io_gdbus.c)
diff --git a/include/interface/peripheral_interface_gpio.h b/include/interface/peripheral_interface_gpio.h
deleted file mode 100644 (file)
index bfc7b09..0000000
+++ /dev/null
@@ -1,38 +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_INTERFACE_GPIO_H__
-#define __PERIPHERAL_INTERFACE_GPIO_H__
-
-#include "peripheral_interface_common.h"
-
-#define GPIO_BUFFER_MAX 64
-
-void peripheral_interface_gpio_close(peripheral_gpio_h gpio);
-
-int peripheral_interface_gpio_set_initial_edge_into_handle(peripheral_gpio_h gpio);
-int peripheral_interface_gpio_set_edge_mode(peripheral_gpio_h gpio, peripheral_gpio_edge_e edge);
-
-int peripheral_interface_gpio_set_initial_direction_into_handle(peripheral_gpio_h gpio);
-int peripheral_interface_gpio_set_direction(peripheral_gpio_h gpio, peripheral_gpio_direction_e direction);
-
-int peripheral_interface_gpio_write(peripheral_gpio_h gpio, uint32_t value);
-int peripheral_interface_gpio_read(peripheral_gpio_h gpio, uint32_t *value);
-
-int peripheral_interface_gpio_set_interrupted_cb(peripheral_gpio_h gpio, peripheral_gpio_interrupted_cb callback, void *user_data);
-int peripheral_interface_gpio_unset_interrupted_cb(peripheral_gpio_h gpio);
-
-#endif/*__PERIPHERAL_INTERFACE_GPIO_H__*/
\ No newline at end of file
diff --git a/src/interface/peripheral_interface_gpio.c b/src/interface/peripheral_interface_gpio.c
deleted file mode 100644 (file)
index f4765f7..0000000
+++ /dev/null
@@ -1,291 +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 <poll.h>
-#include <string.h>
-#include "peripheral_handle.h"
-#include "peripheral_interface_gpio.h"
-
-#define GPIO_INTERRUPTED_CALLBACK_UNSET 0
-#define GPIO_INTERRUPTED_CALLBACK_SET   1
-
-int peripheral_interface_gpio_set_initial_direction_into_handle(peripheral_gpio_h gpio)
-{
-       static predefined_type_s types[2] = {
-               {"in",   2},
-               {"out",  3},
-       };
-
-       int index;
-       char gpio_buf[GPIO_BUFFER_MAX] = {0, };
-
-       int ret = read(gpio->fd_direction, &gpio_buf, GPIO_BUFFER_MAX);
-       CHECK_ERROR(ret <= 0);
-
-       for (index = 0; index < 2; index++) {
-               if (!strncmp(gpio_buf, types[index].type, types[index].len)) {
-                       // PERIPHERAL_GPIO_DIRECTION_OUT_INITIALLY_HIGH and PERIPHERAL_GPIO_DIRECTION_OUT_INITIALLY_LOW : out type
-                       gpio->direction = (peripheral_gpio_direction_e)index;
-
-                       /*
-                        * Also write to direction for the very first time after boot
-                        * to ensure that the pin is fully initialized.
-                        * Without this, writing to 'edge' is not possible.
-                        */
-                       ret = write(gpio->fd_direction, types[index].type, types[index].len);
-                       CHECK_ERROR(ret != types[index].len);
-
-                       return PERIPHERAL_ERROR_NONE;
-               }
-       }
-
-       return PERIPHERAL_ERROR_IO_ERROR;
-}
-
-/*
- *      [edge_mode]                [direction]
- *
- *          none -----------------> in, out (O)
- *
- * rising, falling, both ---------> in (O)
- *                          \
- *                           -----> out (X)
- */
-int peripheral_interface_gpio_set_direction(peripheral_gpio_h gpio, peripheral_gpio_direction_e direction)
-{
-       RETV_IF(gpio->direction == direction, PERIPHERAL_ERROR_NONE);
-       RETV_IF(gpio->edge != PERIPHERAL_GPIO_EDGE_NONE, PERIPHERAL_ERROR_IO_ERROR);
-
-       static predefined_type_s types[3] = {
-               {"in",   2},
-               {"high", 4},
-               {"low",  3}
-       };
-
-       int ret = write(gpio->fd_direction, types[direction].type, types[direction].len);
-       CHECK_ERROR(ret != types[direction].len);
-
-       gpio->direction = direction;
-
-       return PERIPHERAL_ERROR_NONE;
-}
-
-int peripheral_interface_gpio_set_initial_edge_into_handle(peripheral_gpio_h gpio)
-{
-       static predefined_type_s types[4] = {
-               {"none",    4},
-               {"rising",  6},
-               {"falling", 7},
-               {"both",    4}
-       };
-
-       int index;
-       char gpio_buf[GPIO_BUFFER_MAX] = {0, };
-
-       int ret = read(gpio->fd_edge, &gpio_buf, GPIO_BUFFER_MAX);
-       CHECK_ERROR(ret <= 0);
-
-       for (index = 0; index < 4; index++) {
-               if (!strncmp(gpio_buf, types[index].type, types[index].len)) {
-                       gpio->edge = (peripheral_gpio_edge_e)index;
-                       return PERIPHERAL_ERROR_NONE;
-               }
-       }
-
-       return PERIPHERAL_ERROR_IO_ERROR;
-}
-
-/*
- * [direction]          [edge_mode]
- *
- *    in ---------> none, rising, falling, both (O)
- *
- *    out --------> none (O)
- *          \
- *           -----> rising, falling, both (X)
- */
-int peripheral_interface_gpio_set_edge_mode(peripheral_gpio_h gpio, peripheral_gpio_edge_e edge)
-{
-       RETV_IF(gpio->edge == edge, PERIPHERAL_ERROR_NONE);
-       RETV_IF(gpio->direction != PERIPHERAL_GPIO_DIRECTION_IN, PERIPHERAL_ERROR_IO_ERROR);
-
-       static predefined_type_s types[4] = {
-               {"none",    4},
-               {"rising",  6},
-               {"falling", 7},
-               {"both",    4}
-       };
-
-       int ret = write(gpio->fd_edge, types[edge].type, types[edge].len);
-       CHECK_ERROR(ret != types[edge].len);
-
-       gpio->edge = edge;
-
-       return PERIPHERAL_ERROR_NONE;
-}
-
-/*
- * [direction]     [value]
- *
- *    in ---------> write (X)
- *    out --------> write (O)
- */
-int peripheral_interface_gpio_write(peripheral_gpio_h gpio, uint32_t value)
-{
-       RETV_IF(gpio->direction == PERIPHERAL_GPIO_DIRECTION_IN, PERIPHERAL_ERROR_IO_ERROR);
-
-       static predefined_type_s types[2] = {
-               {"0", 1},
-               {"1", 1}
-       };
-
-       int ret = write(gpio->fd_value, types[value].type, types[value].len);
-       CHECK_ERROR(ret != types[value].len);
-
-       return PERIPHERAL_ERROR_NONE;
-}
-
-/*
- * [direction]     [value]
- *
- *    in ---------> read (O)
- *    out --------> read (O)
- */
-int peripheral_interface_gpio_read(peripheral_gpio_h gpio, uint32_t *value)
-{
-       int ret;
-       int length = 1;
-       char gpio_buf[GPIO_BUFFER_MAX] = {0, };
-
-       ret = pread(gpio->fd_value, &gpio_buf, length, 0);
-       CHECK_ERROR(ret != length);
-
-       if (gpio_buf[0] == '0') {
-               *value = 0;
-       } else if (gpio_buf[0] == '1') {
-               *value = 1;
-       } else {
-               _E("Error: gpio value is error \n");
-               return PERIPHERAL_ERROR_IO_ERROR;
-       }
-
-       return PERIPHERAL_ERROR_NONE;
-}
-
-void peripheral_interface_gpio_close(peripheral_gpio_h gpio)
-{
-       peripheral_interface_gpio_unset_interrupted_cb(gpio);
-
-       close(gpio->fd_direction);
-       close(gpio->fd_edge);
-       close(gpio->fd_value);
-}
-
-static gboolean __peripheral_interface_gpio_interrupted_cb_invoke(gpointer data)
-{
-       peripheral_gpio_h gpio = (peripheral_gpio_h)data;
-       gpio->cb_info.cb(gpio, gpio->cb_info.error, gpio->cb_info.user_data);
-       free(gpio);
-       gpio = NULL;
-       return FALSE;
-}
-
-static gpointer __peripheral_interface_gpio_poll(void *data)
-{
-       peripheral_gpio_h gpio = (peripheral_gpio_h)data;
-
-       int ret;
-       int poll_state = 0;
-       struct pollfd poll_fd;
-
-       poll_fd.fd = gpio->fd_value;
-       poll_fd.events = POLLPRI;
-
-       uint32_t value;
-
-       while (g_atomic_int_get(&gpio->cb_info.status) == GPIO_INTERRUPTED_CALLBACK_SET) {
-
-               poll_state = poll(&poll_fd, 1, 3000);
-
-               if (poll_state == 0)
-                       continue;
-
-               if (poll_state < 0) {
-                       _E("poll failed!");
-                       gpio->cb_info.error = PERIPHERAL_ERROR_IO_ERROR;
-                       g_idle_add_full(G_PRIORITY_HIGH_IDLE, __peripheral_interface_gpio_interrupted_cb_invoke, gpio, NULL);
-                       break;
-               }
-
-               if (poll_fd.revents & POLLPRI) {
-                       ret = peripheral_interface_gpio_read(gpio, &value);
-                       if (ret != PERIPHERAL_ERROR_NONE)
-                               continue;
-               } else {
-                       continue;
-               }
-
-               if (gpio->edge == PERIPHERAL_GPIO_EDGE_NONE)
-                       continue;
-
-               if (gpio->edge == PERIPHERAL_GPIO_EDGE_RISING && value == 0)
-                       continue;
-
-               if (gpio->edge == PERIPHERAL_GPIO_EDGE_FALLING && value == 1)
-                       continue;
-
-               gpio->cb_info.error = PERIPHERAL_ERROR_NONE;
-               gpio->cb_info.value = value;
-
-               // copy structure for callback to prevent race condition
-               // otherwise e.g. gpio pin value could be changed during callback call
-               peripheral_gpio_h gpio_copy = (peripheral_gpio_h)calloc(1, sizeof(struct _peripheral_gpio_s));
-               if (gpio_copy == NULL) {
-                       _E("memory allocation for callback failed.");
-                       continue;
-               }
-               memcpy(gpio_copy, gpio, sizeof(struct _peripheral_gpio_s));
-               g_idle_add_full(G_PRIORITY_HIGH_IDLE, __peripheral_interface_gpio_interrupted_cb_invoke, gpio_copy, NULL);
-       }
-
-       return NULL;
-}
-
-int peripheral_interface_gpio_set_interrupted_cb(peripheral_gpio_h gpio, peripheral_gpio_interrupted_cb callback, void *user_data)
-{
-       RETV_IF(gpio->direction != PERIPHERAL_GPIO_DIRECTION_IN, PERIPHERAL_ERROR_IO_ERROR);
-
-       peripheral_interface_gpio_unset_interrupted_cb(gpio);
-
-       gpio->cb_info.cb = callback;
-       gpio->cb_info.user_data = user_data;
-       g_atomic_int_set(&gpio->cb_info.status, GPIO_INTERRUPTED_CALLBACK_SET);
-       gpio->cb_info.thread = g_thread_new(NULL, __peripheral_interface_gpio_poll, gpio);
-
-       return PERIPHERAL_ERROR_NONE;
-}
-
-int peripheral_interface_gpio_unset_interrupted_cb(peripheral_gpio_h gpio)
-{
-       g_atomic_int_set(&gpio->cb_info.status, GPIO_INTERRUPTED_CALLBACK_UNSET);
-
-       if (gpio->cb_info.thread != NULL) {
-               g_thread_join(gpio->cb_info.thread);
-               gpio->cb_info.thread = NULL;
-       }
-
-       return PERIPHERAL_ERROR_NONE;
-}
index fe6fc9d..86da489 100644 (file)
@@ -21,8 +21,7 @@
 #include <system_info.h>
 
 #include "peripheral_io.h"
-#include "peripheral_handle.h"
-#include "peripheral_interface_gpio.h"
+#include "peripheral_interface_common.h"
 #include "peripheral_log.h"
 
 #define PERIPHERAL_IO_GPIO_FEATURE "http://tizen.org/feature/peripheral_io.gpio"
 #define GPIO_STRUCTURE_VERMAGIC 13712
 #define GPIO_CALLBACK_STRUCTURE_VERMAGIC 14469
 
+#define GPIO_INTERRUPTED_CALLBACK_UNSET 0
+#define GPIO_INTERRUPTED_CALLBACK_SET   1
+
+#define GPIO_BUFFER_MAX 64
+
 static int gpio_feature = GPIO_FEATURE_UNKNOWN;
 
 static bool __is_feature_supported(void)
@@ -257,6 +261,64 @@ static inline void cleanup_handlep(peripheral_gpio_h *handle) {
        cleanup_handle(*handle);
 }
 
+static int peripheral_gpio_set_initial_direction_into_handle(peripheral_gpio_h gpio)
+{
+       static predefined_type_s types[2] = {
+               {"in",   2},
+               {"out",  3},
+       };
+
+       int index;
+       char gpio_buf[GPIO_BUFFER_MAX] = {0, };
+
+       int ret = read(gpio->fd_direction, &gpio_buf, GPIO_BUFFER_MAX);
+       CHECK_ERROR(ret <= 0);
+
+       for (index = 0; index < 2; index++) {
+               if (!strncmp(gpio_buf, types[index].type, types[index].len)) {
+                       // PERIPHERAL_GPIO_DIRECTION_OUT_INITIALLY_HIGH and PERIPHERAL_GPIO_DIRECTION_OUT_INITIALLY_LOW : out type
+                       gpio->direction = (peripheral_gpio_direction_e)index;
+
+                       /*
+                        * Also write to direction for the very first time after boot
+                        * to ensure that the pin is fully initialized.
+                        * Without this, writing to 'edge' is not possible.
+                        */
+                       ret = write(gpio->fd_direction, types[index].type, types[index].len);
+                       CHECK_ERROR(ret != types[index].len);
+
+                       return PERIPHERAL_ERROR_NONE;
+               }
+       }
+
+       return PERIPHERAL_ERROR_IO_ERROR;
+}
+
+static int peripheral_gpio_set_initial_edge_into_handle(peripheral_gpio_h gpio)
+{
+       static predefined_type_s types[4] = {
+               {"none",    4},
+               {"rising",  6},
+               {"falling", 7},
+               {"both",    4}
+       };
+
+       int index;
+       char gpio_buf[GPIO_BUFFER_MAX] = {0, };
+
+       int ret = read(gpio->fd_edge, &gpio_buf, GPIO_BUFFER_MAX);
+       CHECK_ERROR(ret <= 0);
+
+       for (index = 0; index < 4; index++) {
+               if (!strncmp(gpio_buf, types[index].type, types[index].len)) {
+                       gpio->edge = (peripheral_gpio_edge_e)index;
+                       return PERIPHERAL_ERROR_NONE;
+               }
+       }
+
+       return PERIPHERAL_ERROR_IO_ERROR;
+}
+
 /**
  * @brief Initializes(export) gpio pin and creates gpio handle.
  */
@@ -323,15 +385,15 @@ int peripheral_gpio_open(int gpio_pin, peripheral_gpio_h *gpio)
 
        lock = peripheral_gpio_unlock_export(lock);
 
-       ret = peripheral_interface_gpio_set_initial_direction_into_handle(handle);
+       ret = peripheral_gpio_set_initial_direction_into_handle(handle);
        if (ret != PERIPHERAL_ERROR_NONE) {
-               _E("Failed to peripheral_interface_gpio_set_initial_direction_into_handle()");
+               _E("Failed to peripheral_gpio_set_initial_direction_into_handle()");
                return ret;
        }
 
-       ret = peripheral_interface_gpio_set_initial_edge_into_handle(handle);
+       ret = peripheral_gpio_set_initial_edge_into_handle(handle);
        if (ret != PERIPHERAL_ERROR_NONE) {
-               _E("Failed to peripheral_interface_gpio_set_initial_edge_into_handle()");
+               _E("Failed to peripheral_gpio_set_initial_edge_into_handle()");
                return ret;
        }
 
@@ -351,7 +413,7 @@ int peripheral_gpio_close(peripheral_gpio_h gpio)
        RETVM_IF(__is_feature_supported() == false, PERIPHERAL_ERROR_NOT_SUPPORTED, "GPIO feature is not supported");
        RETVM_IF(gpio == NULL, PERIPHERAL_ERROR_INVALID_PARAMETER, "gpio handle is NULL");
 
-       peripheral_interface_gpio_unset_interrupted_cb(gpio);
+       peripheral_gpio_unset_interrupted_cb(gpio);
 
        cleanup_handlep(&gpio);
 
@@ -367,7 +429,30 @@ int peripheral_gpio_set_direction(peripheral_gpio_h gpio, peripheral_gpio_direct
        RETVM_IF(gpio == NULL, PERIPHERAL_ERROR_INVALID_PARAMETER, "gpio handle is NULL");
        RETVM_IF((direction < PERIPHERAL_GPIO_DIRECTION_IN) || (direction > PERIPHERAL_GPIO_DIRECTION_OUT_INITIALLY_LOW), PERIPHERAL_ERROR_INVALID_PARAMETER, "Invalid direction input");
 
-       return peripheral_interface_gpio_set_direction(gpio, direction);
+       /*
+        *      [edge_mode]                [direction]
+        *
+        *          none -----------------> in, out (O)
+        *
+        * rising, falling, both ---------> in (O)
+        *                          \
+        *                           -----> out (X)
+        */
+       RETV_IF(gpio->direction == direction, PERIPHERAL_ERROR_NONE);
+       RETV_IF(gpio->edge != PERIPHERAL_GPIO_EDGE_NONE, PERIPHERAL_ERROR_IO_ERROR);
+
+       static predefined_type_s types[3] = {
+               {"in",   2},
+               {"high", 4},
+               {"low",  3}
+       };
+
+       int ret = write(gpio->fd_direction, types[direction].type, types[direction].len);
+       CHECK_ERROR(ret != types[direction].len);
+
+       gpio->direction = direction;
+
+       return PERIPHERAL_ERROR_NONE;
 }
 
 /**
@@ -379,7 +464,101 @@ int peripheral_gpio_set_edge_mode(peripheral_gpio_h gpio, peripheral_gpio_edge_e
        RETVM_IF(gpio == NULL, PERIPHERAL_ERROR_INVALID_PARAMETER, "gpio handle is NULL");
        RETVM_IF((edge < PERIPHERAL_GPIO_EDGE_NONE) || (edge > PERIPHERAL_GPIO_EDGE_BOTH), PERIPHERAL_ERROR_INVALID_PARAMETER, "edge input is invalid");
 
-       return peripheral_interface_gpio_set_edge_mode(gpio, edge);
+       /*
+        * [direction]          [edge_mode]
+        *
+        *    in ---------> none, rising, falling, both (O)
+        *
+        *    out --------> none (O)
+        *          \
+        *           -----> rising, falling, both (X)
+        */
+       RETV_IF(gpio->edge == edge, PERIPHERAL_ERROR_NONE);
+       RETV_IF(gpio->direction != PERIPHERAL_GPIO_DIRECTION_IN, PERIPHERAL_ERROR_IO_ERROR);
+
+       static predefined_type_s types[4] = {
+               {"none",    4},
+               {"rising",  6},
+               {"falling", 7},
+               {"both",    4}
+       };
+
+       int ret = write(gpio->fd_edge, types[edge].type, types[edge].len);
+       CHECK_ERROR(ret != types[edge].len);
+
+       gpio->edge = edge;
+
+       return PERIPHERAL_ERROR_NONE;
+}
+
+static gboolean __peripheral_gpio_interrupted_cb_invoke(gpointer data)
+{
+       peripheral_gpio_h gpio = (peripheral_gpio_h)data;
+       gpio->cb_info.cb(gpio, gpio->cb_info.error, gpio->cb_info.user_data);
+       free(gpio);
+       gpio = NULL;
+       return FALSE;
+}
+
+static gpointer __peripheral_gpio_poll(void *data)
+{
+       peripheral_gpio_h gpio = (peripheral_gpio_h)data;
+
+       int ret;
+       int poll_state = 0;
+       struct pollfd poll_fd;
+
+       poll_fd.fd = gpio->fd_value;
+       poll_fd.events = POLLPRI;
+
+       uint32_t value;
+
+       while (g_atomic_int_get(&gpio->cb_info.status) == GPIO_INTERRUPTED_CALLBACK_SET) {
+
+               poll_state = poll(&poll_fd, 1, 3000);
+
+               if (poll_state == 0)
+                       continue;
+
+               if (poll_state < 0) {
+                       _E("poll failed!");
+                       gpio->cb_info.error = PERIPHERAL_ERROR_IO_ERROR;
+                       g_idle_add_full(G_PRIORITY_HIGH_IDLE, __peripheral_gpio_interrupted_cb_invoke, gpio, NULL);
+                       break;
+               }
+
+               if (poll_fd.revents & POLLPRI) {
+                       ret = peripheral_gpio_read(gpio, &value);
+                       if (ret != PERIPHERAL_ERROR_NONE)
+                               continue;
+               } else {
+                       continue;
+               }
+
+               if (gpio->edge == PERIPHERAL_GPIO_EDGE_NONE)
+                       continue;
+
+               if (gpio->edge == PERIPHERAL_GPIO_EDGE_RISING && value == 0)
+                       continue;
+
+               if (gpio->edge == PERIPHERAL_GPIO_EDGE_FALLING && value == 1)
+                       continue;
+
+               gpio->cb_info.error = PERIPHERAL_ERROR_NONE;
+               gpio->cb_info.value = value;
+
+               // copy structure for callback to prevent race condition
+               // otherwise e.g. gpio pin value could be changed during callback call
+               peripheral_gpio_h gpio_copy = (peripheral_gpio_h)calloc(1, sizeof(struct _peripheral_gpio_s));
+               if (gpio_copy == NULL) {
+                       _E("memory allocation for callback failed.");
+                       continue;
+               }
+               memcpy(gpio_copy, gpio, sizeof(struct _peripheral_gpio_s));
+               g_idle_add_full(G_PRIORITY_HIGH_IDLE, __peripheral_gpio_interrupted_cb_invoke, gpio_copy, NULL);
+       }
+
+       return NULL;
 }
 
 /**
@@ -390,8 +569,16 @@ int peripheral_gpio_set_interrupted_cb(peripheral_gpio_h gpio, peripheral_gpio_i
        RETVM_IF(__is_feature_supported() == false, PERIPHERAL_ERROR_NOT_SUPPORTED, "GPIO feature is not supported");
        RETVM_IF(gpio == NULL, PERIPHERAL_ERROR_INVALID_PARAMETER, "gpio handle is NULL");
        RETVM_IF(callback == NULL, PERIPHERAL_ERROR_INVALID_PARAMETER, "gpio interrupted callback is NULL");
+       RETV_IF(gpio->direction != PERIPHERAL_GPIO_DIRECTION_IN, PERIPHERAL_ERROR_IO_ERROR);
 
-       return peripheral_interface_gpio_set_interrupted_cb(gpio, callback, user_data);
+       peripheral_gpio_unset_interrupted_cb(gpio);
+
+       gpio->cb_info.cb = callback;
+       gpio->cb_info.user_data = user_data;
+       g_atomic_int_set(&gpio->cb_info.status, GPIO_INTERRUPTED_CALLBACK_SET);
+       gpio->cb_info.thread = g_thread_new(NULL, __peripheral_gpio_poll, gpio);
+
+       return PERIPHERAL_ERROR_NONE;
 }
 
 /**
@@ -402,7 +589,14 @@ int peripheral_gpio_unset_interrupted_cb(peripheral_gpio_h gpio)
        RETVM_IF(__is_feature_supported() == false, PERIPHERAL_ERROR_NOT_SUPPORTED, "GPIO feature is not supported");
        RETVM_IF(gpio == NULL, PERIPHERAL_ERROR_INVALID_PARAMETER, "gpio handle is NULL");
 
-       return peripheral_interface_gpio_unset_interrupted_cb(gpio);
+       g_atomic_int_set(&gpio->cb_info.status, GPIO_INTERRUPTED_CALLBACK_UNSET);
+
+       if (gpio->cb_info.thread != NULL) {
+               g_thread_join(gpio->cb_info.thread);
+               gpio->cb_info.thread = NULL;
+       }
+
+       return PERIPHERAL_ERROR_NONE;
 }
 
 /**
@@ -413,8 +607,29 @@ int peripheral_gpio_read(peripheral_gpio_h gpio, uint32_t *value)
        RETVM_IF(__is_feature_supported() == false, PERIPHERAL_ERROR_NOT_SUPPORTED, "GPIO feature is not supported");
        RETVM_IF(gpio == NULL, PERIPHERAL_ERROR_INVALID_PARAMETER, "gpio handle is NULL");
        RETVM_IF(value == NULL, PERIPHERAL_ERROR_INVALID_PARAMETER, "gpio read value is invalid");
+       /*
+        * [direction]     [value]
+        *
+        *    in ---------> read (O)
+        *    out --------> read (O)
+        */
+       int ret;
+       int length = 1;
+       char gpio_buf[GPIO_BUFFER_MAX] = {0, };
+
+       ret = pread(gpio->fd_value, &gpio_buf, length, 0);
+       CHECK_ERROR(ret != length);
 
-       return peripheral_interface_gpio_read(gpio, value);
+       if (gpio_buf[0] == '0') {
+               *value = 0;
+       } else if (gpio_buf[0] == '1') {
+               *value = 1;
+       } else {
+               _E("Error: gpio value is error \n");
+               return PERIPHERAL_ERROR_IO_ERROR;
+       }
+
+       return PERIPHERAL_ERROR_NONE;
 }
 
 /**
@@ -425,6 +640,21 @@ int peripheral_gpio_write(peripheral_gpio_h gpio, uint32_t value)
        RETVM_IF(__is_feature_supported() == false, PERIPHERAL_ERROR_NOT_SUPPORTED, "GPIO feature is not supported");
        RETVM_IF(gpio == NULL, PERIPHERAL_ERROR_INVALID_PARAMETER, "gpio handle is NULL");
        RETVM_IF((value != 0) && (value != 1), PERIPHERAL_ERROR_INVALID_PARAMETER, "gpio value is invalid");
+       /*
+        * [direction]     [value]
+        *
+        *    in ---------> write (X)
+        *    out --------> write (O)
+        */
+       RETV_IF(gpio->direction == PERIPHERAL_GPIO_DIRECTION_IN, PERIPHERAL_ERROR_IO_ERROR);
+
+       static predefined_type_s types[2] = {
+               {"0", 1},
+               {"1", 1}
+       };
 
-       return peripheral_interface_gpio_write(gpio, value);
+       int ret = write(gpio->fd_value, types[value].type, types[value].len);
+       CHECK_ERROR(ret != types[value].len);
+
+       return PERIPHERAL_ERROR_NONE;
 }