Add gpio instance managing 33/126933/4
authorjino.cho <jino.cho@samsung.com>
Tue, 25 Apr 2017 09:30:29 +0000 (18:30 +0900)
committerjino.cho <jino.cho@samsung.com>
Tue, 25 Apr 2017 11:31:08 +0000 (20:31 +0900)
Change-Id: I3c9e273de2fa8c28c7f1bbcb48afe61dc5598af8
Signed-off-by: jino.cho <jino.cho@samsung.com>
src/daemon/peripheral_bus.c
src/daemon/peripheral_bus.h
src/daemon/peripheral_bus_gpio.c
src/daemon/peripheral_bus_gpio.h
src/daemon/peripheral_io.xml

index 2aea58f..78f677d 100644 (file)
@@ -37,12 +37,11 @@ gboolean handle_gpio_open(
                gpointer user_data)
 {
        peripheral_error_e ret = PERIPHERAL_ERROR_NONE;
-       struct _peripheral_gpio_s st_gpio;
+       gint edge;
+       gint direction;
 
-       st_gpio.pin = pin;
-
-       ret = peripheral_bus_gpio_open(&st_gpio);
-       peripheral_io_gdbus_gpio_complete_open(gpio, invocation, ret);
+       ret = peripheral_bus_gpio_open(pin, &edge, &direction, user_data);
+       peripheral_io_gdbus_gpio_complete_open(gpio, invocation, edge, direction, ret);
 
        return true;
 }
@@ -54,11 +53,8 @@ gboolean handle_gpio_close(
                gpointer user_data)
 {
        peripheral_error_e ret = PERIPHERAL_ERROR_NONE;
-       struct _peripheral_gpio_s st_gpio;
-
-       st_gpio.pin = pin;
 
-       ret = peripheral_bus_gpio_close(&st_gpio);
+       ret = peripheral_bus_gpio_close(pin, user_data);
        peripheral_io_gdbus_gpio_complete_close(gpio, invocation, ret);
 
        return true;
@@ -71,12 +67,10 @@ gboolean handle_gpio_get_direction(
                gpointer user_data)
 {
        peripheral_error_e ret = PERIPHERAL_ERROR_NONE;
-       struct _peripheral_gpio_s st_gpio;
-
-       st_gpio.pin = pin;
+       gint direction;
 
-       ret = peripheral_bus_gpio_get_direction(&st_gpio);
-       peripheral_io_gdbus_gpio_complete_get_direction(gpio, invocation, st_gpio.direction, ret);
+       ret = peripheral_bus_gpio_get_direction(pin, &direction, user_data);
+       peripheral_io_gdbus_gpio_complete_get_direction(gpio, invocation, direction, ret);
 
        return true;
 }
@@ -89,12 +83,8 @@ gboolean handle_gpio_set_direction(
                gpointer user_data)
 {
        peripheral_error_e ret = PERIPHERAL_ERROR_NONE;
-       struct _peripheral_gpio_s st_gpio;
 
-       st_gpio.pin = pin;
-       st_gpio.direction = direction;
-
-       ret = peripheral_bus_gpio_set_direction(&st_gpio);
+       ret = peripheral_bus_gpio_set_direction(pin, direction, user_data);
        peripheral_io_gdbus_gpio_complete_set_direction(gpio, invocation, ret);
 
        return true;
@@ -107,12 +97,9 @@ gboolean handle_gpio_read(
                gpointer user_data)
 {
        peripheral_error_e ret = PERIPHERAL_ERROR_NONE;
-       struct _peripheral_gpio_s st_gpio;
-       gint32 read_value = 0;
-
-       st_gpio.pin = pin;
+       gint read_value = 0;
 
-       ret = peripheral_bus_gpio_read(&st_gpio, &read_value);
+       ret = peripheral_bus_gpio_read(pin, &read_value, user_data);
        peripheral_io_gdbus_gpio_complete_read(gpio, invocation, read_value, ret);
 
        return true;
@@ -126,11 +113,8 @@ gboolean handle_gpio_write(
                gpointer user_data)
 {
        peripheral_error_e ret = PERIPHERAL_ERROR_NONE;
-       struct _peripheral_gpio_s st_gpio;
 
-       st_gpio.pin = pin;
-
-       ret = peripheral_bus_gpio_write(&st_gpio, value);
+       ret = peripheral_bus_gpio_write(pin, value, user_data);
        peripheral_io_gdbus_gpio_complete_write(gpio, invocation, ret);
 
        return true;
@@ -143,12 +127,10 @@ gboolean handle_gpio_get_edge_mode(
                gpointer user_data)
 {
        peripheral_error_e ret = PERIPHERAL_ERROR_NONE;
-       struct _peripheral_gpio_s st_gpio;
-
-       st_gpio.pin = pin;
+       gint edge;
 
-       ret = peripheral_bus_gpio_get_edge(&st_gpio);
-       peripheral_io_gdbus_gpio_complete_get_edge_mode(gpio, invocation, st_gpio.edge, ret);
+       ret = peripheral_bus_gpio_get_edge(pin, &edge, user_data);
+       peripheral_io_gdbus_gpio_complete_get_edge_mode(gpio, invocation, edge, ret);
 
        return true;
 }
@@ -161,12 +143,8 @@ gboolean handle_gpio_set_edge_mode(
                gpointer user_data)
 {
        peripheral_error_e ret = PERIPHERAL_ERROR_NONE;
-       struct _peripheral_gpio_s st_gpio;
-
-       st_gpio.pin = pin;
-       st_gpio.edge = edge;
 
-       ret = peripheral_bus_gpio_set_edge(&st_gpio);
+       ret = peripheral_bus_gpio_set_edge(pin, edge, user_data);
        peripheral_io_gdbus_gpio_complete_set_edge_mode(gpio, invocation, ret);
 
        return true;
@@ -423,45 +401,44 @@ gboolean handle_pwm_get_period(
 }
 
 
-static gboolean __gpio_init(GDBusConnection *connection)
+static gboolean __gpio_init(peripheral_bus_s *pb_data)
 {
        GDBusObjectManagerServer *manager;
-       PeripheralIoGdbusGpio *gpio_skeleton;
        gboolean ret = FALSE;
        GError *error = NULL;
 
        /* Add interface to default object path */
-       gpio_skeleton = peripheral_io_gdbus_gpio_skeleton_new();
+       pb_data->gpio_skeleton = peripheral_io_gdbus_gpio_skeleton_new();
        /* Register for method callbacks as signal callbacks */
-       g_signal_connect(gpio_skeleton,
+       g_signal_connect(pb_data->gpio_skeleton,
                        "handle-open",
                        G_CALLBACK(handle_gpio_open),
                        NULL);
-       g_signal_connect(gpio_skeleton,
+       g_signal_connect(pb_data->gpio_skeleton,
                        "handle-close",
                        G_CALLBACK(handle_gpio_close),
                        NULL);
-       g_signal_connect(gpio_skeleton,
+       g_signal_connect(pb_data->gpio_skeleton,
                        "handle-get-direction",
                        G_CALLBACK(handle_gpio_get_direction),
                        NULL);
-       g_signal_connect(gpio_skeleton,
+       g_signal_connect(pb_data->gpio_skeleton,
                        "handle-set-direction",
                        G_CALLBACK(handle_gpio_set_direction),
                        NULL);
-       g_signal_connect(gpio_skeleton,
+       g_signal_connect(pb_data->gpio_skeleton,
                        "handle-read",
                        G_CALLBACK(handle_gpio_read),
                        NULL);
-       g_signal_connect(gpio_skeleton,
+       g_signal_connect(pb_data->gpio_skeleton,
                        "handle-write",
                        G_CALLBACK(handle_gpio_write),
                        NULL);
-       g_signal_connect(gpio_skeleton,
+       g_signal_connect(pb_data->gpio_skeleton,
                        "handle-get-edge-mode",
                        G_CALLBACK(handle_gpio_get_edge_mode),
                        NULL);
-       g_signal_connect(gpio_skeleton,
+       g_signal_connect(pb_data->gpio_skeleton,
                        "handle-set-edge-mode",
                        G_CALLBACK(handle_gpio_set_edge_mode),
                        NULL);
@@ -469,12 +446,12 @@ static gboolean __gpio_init(GDBusConnection *connection)
        manager = g_dbus_object_manager_server_new(PERIPHERAL_DBUS_GPIO_PATH);
 
        /* Set connection to 'manager' */
-       g_dbus_object_manager_server_set_connection(manager, connection);
+       g_dbus_object_manager_server_set_connection(manager, pb_data->connection);
 
        /* Export 'manager' interface on peripheral-io DBUS */
        ret = g_dbus_interface_skeleton_export(
-               G_DBUS_INTERFACE_SKELETON(gpio_skeleton),
-               connection, PERIPHERAL_DBUS_GPIO_PATH, &error);
+               G_DBUS_INTERFACE_SKELETON(pb_data->gpio_skeleton),
+               pb_data->connection, PERIPHERAL_DBUS_GPIO_PATH, &error);
 
        if (ret == FALSE) {
                _E("Can not skeleton_export %s", error->message);
@@ -592,7 +569,10 @@ static void on_bus_acquired(GDBusConnection *connection,
                                                        const gchar *name,
                                                        gpointer user_data)
 {
-       if (__gpio_init(connection) == FALSE)
+       peripheral_bus_s *pb_data = (peripheral_bus_s*)user_data;
+
+       pb_data->connection = connection;
+       if (__gpio_init(pb_data) == FALSE)
                _E("Can not signal connect");
 
        if (__i2c_init(connection) == FALSE)
index 176f80b..1a2d65a 100644 (file)
 typedef struct {
        /* daemon variable */
        /* devices */
+       GList *gpio_list;
        /* gdbus variable */
        guint reg_id;
        GDBusConnection *connection;
+       PeripheralIoGdbusGpio *gpio_skeleton;
 } peripheral_bus_s;
+
+typedef struct {
+       /* gpio info */
+       int pin;
+       int direction;
+       int edge;
+       /* interrupt variable */
+       int value_fd;
+       GIOChannel *io;
+       guint io_id;
+} peripheral_bus_gpio_data_s;
+
+typedef peripheral_bus_gpio_data_s * pb_gpio_data_h;
+
 #endif /* __PERIPHERAL_BUS_H__ */
index f49e8e1..bf9ad16 100644 (file)
 #include <peripheral_internal.h>
 
 #include "gpio.h"
+#include "peripheral_io_gdbus.h"
+#include "peripheral_bus.h"
 #include "peripheral_common.h"
 
 
-int peripheral_bus_gpio_open(peripheral_gpio_h gpio)
+static pb_gpio_data_h peripheral_bus_gpio_data_get(int pin, GList **list)
 {
-       gpio_edge_e edge;
-       gpio_direction_e direction;
+       GList *gpio_list = *list;
+       GList *link;
+       pb_gpio_data_h gpio_data = NULL;
 
-       if (gpio_open(gpio->pin) < 0) {
-               _E("gpio_open error");
-               return PERIPHERAL_ERROR_INVALID_PARAMETER;
+       if (!gpio_list)
+               return NULL;
+
+       link = gpio_list;
+       while (link) {
+               gpio_data = (pb_gpio_data_h)link->data;
+               if (gpio_data->pin == pin)
+                       return gpio_data;
+
+               link = g_list_next(link);
        }
 
-       if (gpio_get_edge_mode(gpio->pin, (gpio_edge_e*)&edge) < 0) {
-               gpio_close(gpio->pin);
-               _E("gpio_get_edge_mode error");
-               return PERIPHERAL_ERROR_INVALID_PARAMETER;
+       return NULL;
+}
+
+static pb_gpio_data_h peripheral_bus_gpio_data_new(int pin, GList **list)
+{
+       GList *gpio_list = *list;
+       pb_gpio_data_h gpio_data;
+
+       gpio_data = (pb_gpio_data_h)calloc(1, sizeof(peripheral_bus_gpio_data_s));
+       if (gpio_data == NULL) {
+               _E("failed to allocate peripheral_bus_gpio_data_s");
+               return NULL;
        }
-       gpio->edge = edge;
 
-       if (gpio_get_direction(gpio->pin, (gpio_direction_e*)&direction) < 0) {
-               gpio_close(gpio->pin);
-               _E("gpio_get_direction error");
-               return PERIPHERAL_ERROR_INVALID_PARAMETER;
+       *list = g_list_append(gpio_list, gpio_data);
+
+       gpio_data->pin = pin;
+
+       return gpio_data;
+}
+
+static void peripheral_bus_gpio_data_free(int pin, GList **list)
+{
+       GList *gpio_list = *list;
+       GList *link;
+       pb_gpio_data_h gpio_data;
+
+       if (gpio_list == NULL)
+               return;
+
+       link = gpio_list;
+       while (link) {
+               gpio_data = (pb_gpio_data_h)link->data;
+
+               if (gpio_data->pin == pin) {
+                       *list = g_list_remove_link(gpio_list, link);
+                       free(link->data);
+                       g_list_free(link);
+                       return;
+               }
+               link = g_list_next(link);
        }
-       gpio->direction = direction;
+}
+
+int peripheral_bus_gpio_open(gint pin, gint *edge, gint *direction, gpointer user_data)
+{
+       peripheral_bus_s *pb_data = (peripheral_bus_s*)user_data;
+       pb_gpio_data_h gpio;
+       int ret;
+
+       gpio = peripheral_bus_gpio_data_get(pin, &pb_data->gpio_list);
+       if (gpio) {
+               _E("gpio %d is busy", pin);
+               return PERIPHERAL_ERROR_RESOURCE_BUSY;
+       }
+
+       if ((ret = gpio_open(pin)) < 0) {
+               _E("gpio_open error (%d)", ret);
+               goto open_err;
+       }
+
+       if ((ret = gpio_get_edge_mode(pin, (gpio_edge_e*)edge))  < 0) {
+               _E("gpio_get_edge_mode error (%d)", ret);
+               goto err;
+       }
+
+       if ((ret = gpio_get_direction(pin, (gpio_direction_e*)direction)) < 0) {
+               _E("gpio_get_direction error (%d)", ret);
+               goto err;
+       }
+
+       gpio = peripheral_bus_gpio_data_new(pin, &pb_data->gpio_list);
+       if (!gpio) {
+               _E("peripheral_bus_gpio_data_new error");
+               ret = PERIPHERAL_ERROR_UNKNOWN;
+               goto err;
+       }
+
+       gpio->pin = pin;
+       gpio->edge = *edge;
+       gpio->direction = *direction;
 
        return PERIPHERAL_ERROR_NONE;
+
+err:
+       gpio_close(gpio->pin);
+
+open_err:
+       return ret;
 }
 
-int peripheral_bus_gpio_set_direction(peripheral_gpio_h gpio)
+int peripheral_bus_gpio_set_direction(gint pin, gint direction, gpointer user_data)
 {
-       return gpio_set_direction(gpio->pin, (gpio_direction_e)gpio->direction);
+       peripheral_bus_s *pb_data = (peripheral_bus_s*)user_data;
+       pb_gpio_data_h gpio;
+       int ret;
+
+       gpio = peripheral_bus_gpio_data_get(pin, &pb_data->gpio_list);
+       if (!gpio) {
+               _E("peripheral_bus_gpio_data_get error");
+               return PERIPHERAL_ERROR_UNKNOWN;
+       }
+
+       gpio->direction = direction;
+
+       if ((ret = gpio_set_direction(pin, (gpio_direction_e)direction)) < 0) {
+               _E("gpio_set_direction error (%d)", ret);
+               return ret;
+       }
+
+       return PERIPHERAL_ERROR_NONE;
 }
 
-int peripheral_bus_gpio_get_direction(peripheral_gpio_h gpio)
+int peripheral_bus_gpio_get_direction(gint pin, gint *direction, gpointer user_data)
 {
-       return gpio_get_direction(gpio->pin, (gpio_direction_e*)&gpio->direction);
+       peripheral_bus_s *pb_data = (peripheral_bus_s*)user_data;
+       pb_gpio_data_h gpio;
+       int ret;
+
+       gpio = peripheral_bus_gpio_data_get(pin, &pb_data->gpio_list);
+       if (!gpio) {
+               _E("peripheral_bus_gpio_data_get error");
+               return PERIPHERAL_ERROR_UNKNOWN;
+       }
+
+       if ((ret = gpio_get_direction(pin, (gpio_direction_e*)direction)) < 0) {
+               _E("gpio_get_direction error (%d)", ret);
+               return ret;
+       }
+
+       gpio->direction = *direction;
+
+       return PERIPHERAL_ERROR_NONE;
 }
 
-int peripheral_bus_gpio_set_edge(peripheral_gpio_h gpio)
+int peripheral_bus_gpio_set_edge(gint pin, gint edge, gpointer user_data)
 {
-       return gpio_set_edge_mode(gpio->pin, (gpio_edge_e)gpio->edge);
+       peripheral_bus_s *pb_data = (peripheral_bus_s*)user_data;
+       pb_gpio_data_h gpio;
+       int ret;
+
+       gpio = peripheral_bus_gpio_data_get(pin, &pb_data->gpio_list);
+       if (!gpio) {
+               _E("peripheral_bus_gpio_data_get error");
+               return PERIPHERAL_ERROR_UNKNOWN;
+       }
+
+       gpio->edge = edge;
+
+       if ((ret = gpio_set_edge_mode(pin, (gpio_edge_e)edge)) < 0) {
+               _E("gpio_set_edge_mode error (%d)", ret);
+               return ret;
+       }
+
+       return PERIPHERAL_ERROR_NONE;
 }
 
-int peripheral_bus_gpio_get_edge(peripheral_gpio_h gpio)
+int peripheral_bus_gpio_get_edge(gint pin, gint *edge, gpointer user_data)
 {
-       return gpio_get_edge_mode(gpio->pin, (gpio_edge_e*)&gpio->edge);
+       peripheral_bus_s *pb_data = (peripheral_bus_s*)user_data;
+       pb_gpio_data_h gpio;
+       int ret;
+
+       gpio = peripheral_bus_gpio_data_get(pin, &pb_data->gpio_list);
+       if (!gpio) {
+               _E("peripheral_bus_gpio_data_get error");
+               return PERIPHERAL_ERROR_UNKNOWN;
+       }
+
+       if ((ret = gpio_get_edge_mode(pin, (gpio_edge_e*)edge)) < 0) {
+               _E("gpio_get_edge_mode error (%d)", ret);
+               return ret;
+       }
+
+       gpio->edge = *edge;
+
+       return PERIPHERAL_ERROR_NONE;
 }
 
-int peripheral_bus_gpio_write(peripheral_gpio_h gpio, int value)
+int peripheral_bus_gpio_write(gint pin, gint value, gpointer user_data)
 {
-       return gpio_write(gpio->pin, value);
+       peripheral_bus_s *pb_data = (peripheral_bus_s*)user_data;
+       pb_gpio_data_h gpio;
+       int ret;
+
+       gpio = peripheral_bus_gpio_data_get(pin, &pb_data->gpio_list);
+       if (!gpio) {
+               _E("peripheral_bus_gpio_data_get error");
+               return PERIPHERAL_ERROR_UNKNOWN;
+       }
+
+       if ((ret = gpio_write(pin, value)) < 0) {
+               _E("gpio_write error (%d)", ret);
+               return ret;
+       }
+
+       return PERIPHERAL_ERROR_NONE;
 }
 
-int peripheral_bus_gpio_read(peripheral_gpio_h gpio, int *read_value)
+int peripheral_bus_gpio_read(gint pin, gint *value, gpointer user_data)
 {
-       return gpio_read(gpio->pin, read_value);
+       peripheral_bus_s *pb_data = (peripheral_bus_s*)user_data;
+       pb_gpio_data_h gpio;
+       int ret;
+
+       gpio = peripheral_bus_gpio_data_get(pin, &pb_data->gpio_list);
+       if (!gpio) {
+               _E("peripheral_bus_gpio_data_get error");
+               return PERIPHERAL_ERROR_UNKNOWN;
+       }
+
+       if ((ret = gpio_read(pin, value)) < 0) {
+               _E("gpio_read error (%d)", ret);
+               return ret;
+       }
+
+       return PERIPHERAL_ERROR_NONE;
 }
 
-int peripheral_bus_gpio_close(peripheral_gpio_h gpio)
+int peripheral_bus_gpio_close(gint pin, gpointer user_data)
 {
-       return gpio_close(gpio->pin);
+       peripheral_bus_s *pb_data = (peripheral_bus_s*)user_data;
+       int ret;
+
+       peripheral_bus_gpio_data_free(pin, &pb_data->gpio_list);
+
+       if ((ret = gpio_close(pin)) < 0) {
+               _E("gpio_close error (%d)", ret);
+               return ret;
+       }
+
+       return PERIPHERAL_ERROR_NONE;
 }
index 48b6cb3..5236fee 100644 (file)
 #ifndef __PERIPHERAL_BUS_GPIO_H__
 #define __PERIPHERAL_BUS_GPIO_H__
 
-int peripheral_bus_gpio_open(peripheral_gpio_h gpio);
-int peripheral_bus_gpio_set_direction(peripheral_gpio_h gpio);
-int peripheral_bus_gpio_get_direction(peripheral_gpio_h gpio);
-int peripheral_bus_gpio_set_edge(peripheral_gpio_h gpio);
-int peripheral_bus_gpio_get_edge(peripheral_gpio_h gpio);
-int peripheral_bus_gpio_write(peripheral_gpio_h gpio, int value);
-int peripheral_bus_gpio_read(peripheral_gpio_h gpio, int *read_value);
-int peripheral_bus_gpio_close(peripheral_gpio_h gpio);
+int peripheral_bus_gpio_open(gint pin, gint *edge, gint *direction, gpointer user_data);
+int peripheral_bus_gpio_set_direction(gint pin, gint direction, gpointer user_data);
+int peripheral_bus_gpio_get_direction(gint pin, gint *direction, gpointer user_data);
+int peripheral_bus_gpio_set_edge(gint pin, gint edge, gpointer user_data);
+int peripheral_bus_gpio_get_edge(gint pin, gint *edge, gpointer user_data);
+int peripheral_bus_gpio_write(gint pin, gint value, gpointer user_data);
+int peripheral_bus_gpio_read(gint pin, gint *value, gpointer user_data);
+int peripheral_bus_gpio_close(gint pin, gpointer user_data);
 
 #endif /* __PERIPHERAL_BUS_GPIO_H__ */
index 40672ad..a99cbbc 100644 (file)
@@ -3,6 +3,8 @@
        <interface name="org.tizen.peripheral_io.gpio">
                <method name="Open">
                        <arg type="i" name="pin" direction="in"/>
+                       <arg type="i" name="edge" direction="out"/>
+                       <arg type="i" name="direction" direction="out"/>
                        <arg type="i" name="result" direction="out"/>
                </method>
                <method name="Close">