Add functions for the adc device 66/133266/4
authorjino.cho <jino.cho@samsung.com>
Thu, 1 Jun 2017 01:34:29 +0000 (10:34 +0900)
committerjino.cho <jino.cho@samsung.com>
Mon, 12 Jun 2017 06:47:45 +0000 (15:47 +0900)
This patch support the adc device. And, it should work properly
if the patch for peripheral-io is applied together.

Change-Id: I08d9f518bbc554deaf9ced1007534adee05f2911
Signed-off-by: jino.cho <jino.cho@samsung.com>
CMakeLists.txt
src/daemon/peripheral_bus.c
src/daemon/peripheral_bus.h
src/daemon/peripheral_bus_adc.c [new file with mode: 0644]
src/daemon/peripheral_bus_adc.h [new file with mode: 0644]
src/daemon/peripheral_io.xml
src/interface/adc.c
src/interface/include/adc.h

index f0ed98b..b70cf58 100644 (file)
@@ -23,6 +23,7 @@ SET(SRCS
        src/daemon/peripheral_bus.c
        src/daemon/peripheral_bus_util.c
        src/daemon/peripheral_bus_pwm.c
+       src/daemon/peripheral_bus_adc.c
        src/daemon/peripheral_bus_i2c.c
        src/daemon/peripheral_bus_gpio.c
        src/daemon/peripheral_bus_uart.c
index 7c548a6..5e96f8e 100644 (file)
@@ -27,6 +27,7 @@
 #include "peripheral_bus_gpio.h"
 #include "peripheral_bus_i2c.h"
 #include "peripheral_bus_pwm.h"
+#include "peripheral_bus_adc.h"
 #include "peripheral_bus_uart.h"
 #include "peripheral_bus_spi.h"
 #include "peripheral_common.h"
@@ -65,7 +66,6 @@ static void __pwm_on_name_vanished(GDBusConnection *connection,
        peripheral_bus_pwm_close(pwm_handle);
 }
 
-
 static void __uart_on_name_vanished(GDBusConnection *connection,
                const gchar     *name,
                gpointer         user_data)
@@ -748,6 +748,33 @@ gboolean handle_pwm_get_enable(
        return true;
 }
 
+gboolean handle_adc_read(
+               PeripheralIoGdbusAdc *adc,
+               GDBusMethodInvocation *invocation,
+               guint device,
+               guint channel,
+               gpointer user_data)
+{
+       peripheral_bus_s *pb_data = (peripheral_bus_s*)user_data;
+       peripheral_error_e ret = PERIPHERAL_ERROR_NONE;
+       int data = 0;
+
+       if (pb_data->adc_path == NULL) {
+               pb_data->adc_path = peripheral_bus_adc_get_path(device);
+               if (pb_data->adc_path == NULL) {
+                       ret = PERIPHERAL_ERROR_UNKNOWN;
+                       goto out;
+               }
+       }
+
+       ret = peripheral_bus_adc_read(device, channel, pb_data->adc_path, &data);
+
+out:
+       peripheral_io_gdbus_adc_complete_read(adc, invocation, data, ret);
+
+       return true;
+}
+
 gboolean handle_uart_open(
                PeripheralIoGdbusUart *uart,
                GDBusMethodInvocation *invocation,
@@ -1609,6 +1636,37 @@ static gboolean __pwm_init(peripheral_bus_s *pb_data)
        return true;
 }
 
+static gboolean __adc_init(peripheral_bus_s *pb_data)
+{
+       GDBusObjectManagerServer *manager;
+       gboolean ret = FALSE;
+       GError *error = NULL;
+
+       /* Add interface to default object path */
+       pb_data->adc_skeleton = peripheral_io_gdbus_adc_skeleton_new();
+       g_signal_connect(pb_data->adc_skeleton,
+                       "handle-read",
+                       G_CALLBACK(handle_adc_read),
+                       pb_data);
+
+       manager = g_dbus_object_manager_server_new(PERIPHERAL_GDBUS_ADC_PATH);
+
+       /* Set connection to 'manager' */
+       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(pb_data->adc_skeleton),
+               pb_data->connection, PERIPHERAL_GDBUS_ADC_PATH, &error);
+
+       if (ret == FALSE) {
+               _E("Can not skeleton_export %s", error->message);
+               g_error_free(error);
+       }
+
+       return true;
+}
+
 static gboolean __uart_init(peripheral_bus_s *pb_data)
 {
        GDBusObjectManagerServer *manager;
@@ -1763,6 +1821,9 @@ static void on_bus_acquired(GDBusConnection *connection,
        if (__pwm_init(pb_data) == FALSE)
                _E("Can not signal connect");
 
+       if (__adc_init(pb_data) == FALSE)
+               _E("Can not signal connect");
+
        if (__uart_init(pb_data) == FALSE)
                _E("Can not signal connect");
 
@@ -1793,6 +1854,8 @@ int main(int argc, char *argv[])
                return -1;
        }
 
+       pb_data->adc_path = NULL;
+
        owner_id = g_bus_own_name(G_BUS_TYPE_SYSTEM,
                                                          PERIPHERAL_GDBUS_NAME,
                                                          (GBusNameOwnerFlags) (G_BUS_NAME_OWNER_FLAGS_ALLOW_REPLACEMENT
@@ -1813,8 +1876,11 @@ int main(int argc, char *argv[])
        _D("Enter main loop!");
        g_main_loop_run(loop);
 
-       if (pb_data)
+       if (pb_data) {
+               if (pb_data->adc_path)
+                       free(pb_data->adc_path);
                free(pb_data);
+       }
 
        if (loop != NULL)
                g_main_loop_unref(loop);
index 89bbeda..d1282c1 100644 (file)
@@ -23,6 +23,7 @@
 
 typedef struct {
        /* daemon variable */
+       char *adc_path;
        /* devices */
        GList *gpio_list;
        GList *i2c_list;
@@ -35,6 +36,7 @@ typedef struct {
        PeripheralIoGdbusGpio *gpio_skeleton;
        PeripheralIoGdbusI2c *i2c_skeleton;
        PeripheralIoGdbusPwm *pwm_skeleton;
+       PeripheralIoGdbusAdc *adc_skeleton;
        PeripheralIoGdbusUart *uart_skeleton;
        PeripheralIoGdbusSpi *spi_skeleton;
 } peripheral_bus_s;
diff --git a/src/daemon/peripheral_bus_adc.c b/src/daemon/peripheral_bus_adc.c
new file mode 100644 (file)
index 0000000..66044e0
--- /dev/null
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 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 <stdio.h>
+#include <stdlib.h>
+#include <gio/gio.h>
+
+#include <peripheral_io.h>
+
+#include "adc.h"
+#include "peripheral_bus.h"
+#include "peripheral_common.h"
+#include "peripheral_bus_util.h"
+
+#define SYSFS_ADC_PATH_MAX             128
+
+char *peripheral_bus_adc_get_path(unsigned int device)
+{
+       char *path;
+       int ret;
+
+       path = calloc(1, SYSFS_ADC_PATH_MAX);
+       if (path == NULL) {
+               _E("failed to allocate path buffer");
+               return NULL;
+       }
+
+       ret = adc_get_path(device, path, SYSFS_ADC_PATH_MAX);
+       if (ret < 0) {
+               _E("failed to get adc path");
+               free(path);
+               return NULL;
+       }
+
+       return path;
+}
+
+int peripheral_bus_adc_read(unsigned int device, unsigned int channel, char *path, int *data)
+{
+       if (path == NULL) return PERIPHERAL_ERROR_INVALID_PARAMETER;
+
+       return adc_read(device, channel, path, data);
+}
diff --git a/src/daemon/peripheral_bus_adc.h b/src/daemon/peripheral_bus_adc.h
new file mode 100644 (file)
index 0000000..436214b
--- /dev/null
@@ -0,0 +1,23 @@
+/*
+ * Copyright (c) 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_BUS_ADC_H__
+#define __PERIPHERAL_BUS_ADC_H__
+
+char *peripheral_bus_adc_get_path(unsigned int device);
+int peripheral_bus_adc_read(unsigned int device, unsigned int channel, char *path, int *data);
+
+#endif /* __PERIPHERAL_BUS_ADC_H__ */
index ea4b1f9..16b3cd2 100644 (file)
                        <arg type="i" name="result" direction="out"/>
                </method>
        </interface>
+       <interface name="org.tizen.peripheral_io.adc">
+               <method name="Read">
+                       <arg type="u" name="device" direction="in"/>
+                       <arg type="u" name="channel" direction="in"/>
+                       <arg type="i" name="value" direction="out"/>
+                       <arg type="i" name="result" direction="out"/>
+               </method>
+       </interface>
        <interface name="org.tizen.peripheral_io.uart">
                <method name="Open">
                        <arg type="i" name="port" direction="in"/>
index 44dba95..508538a 100644 (file)
 #include "peripheral_common.h"
 
 #define SYSFS_ADC_PATH         "/sys/bus/iio/devices/iio:device"
+#define SYSFS_ADC_PATH_OLD     "/sys/bus/iio/devices/device"
 
 #define PATH_BUF_MAX           64
-#define ADC_BUF_MAX                    16
+#define ADC_BUF_MAX            16
+#define MAX_ERR_LEN            255
 
-int adc_get_device_name(char **dev_name)
+int adc_get_path(unsigned int device, char *path, int length)
 {
-       int fd;
-       int device = 0;
-       int bytes;
-       char buf[PATH_BUF_MAX];
+       char adc_dev[PATH_BUF_MAX] = {0};
 
-       snprintf(buf, PATH_BUF_MAX, "%s%d%s", SYSFS_ADC_PATH, device, "/name");
-       if ((fd = open(buf, O_RDONLY)) < 0) {
-               _E("Cannot open %s, errno : %d", buf, errno);
-               return -ENXIO;
+       snprintf(adc_dev, PATH_BUF_MAX, "%s%d", SYSFS_ADC_PATH, device);
+       if (access(adc_dev, F_OK) == 0) {
+               strncpy(path, SYSFS_ADC_PATH, length);
+               return 0;
+       } else {
+               char errmsg[MAX_ERR_LEN];
+               strerror_r(errno, errmsg, MAX_ERR_LEN);
+               _E("Can't Open %s, errmsg : %s", adc_dev, errmsg);
        }
 
-       if ((bytes = read(fd, buf, PATH_BUF_MAX)) == -1) {
-               _E("Cannot read %s, errno : %d", buf, errno);
-               close(fd);
-               return -EIO;
+       snprintf(adc_dev, PATH_BUF_MAX, "%s%d", SYSFS_ADC_PATH_OLD, device);
+       if (access(adc_dev, F_OK) == 0) {
+               strncpy(path, SYSFS_ADC_PATH_OLD, length);
+               return 0;
+       } else {
+               char errmsg[MAX_ERR_LEN];
+               strerror_r(errno, errmsg, MAX_ERR_LEN);
+               _E("Can't Open %s, errmsg : %s", adc_dev, errmsg);
        }
 
-       *dev_name = strndup(buf, PATH_BUF_MAX);
-       close(fd);
-
-       return 0;
+       return -ENXIO;
 }
 
-int adc_get_data(int channel, char *devName, int *data)
+int adc_read(unsigned int device, unsigned int channel, char *path, int *data)
 {
-       int fd;
-       int device = 0; /* for get adc device name, /sys/devices/[devName]/iio:device"0" */
-       char fName[PATH_BUF_MAX] = {0};
-       char voltage[ADC_BUF_MAX] = {0};
-       int bytes;
+       int fd, result, status;
+       char adc_buf[ADC_BUF_MAX] = {0};
+       char adc_dev[PATH_BUF_MAX] = {0};
 
-       snprintf(fName, PATH_BUF_MAX, "%s%s%s%d%s%d%s", "/sys/devices/", devName, "/iio:device", device, "/in_voltage", channel, "_raw");
-       if ((fd = open(fName, O_RDONLY)) < 0) {
-               _E("Error[%d]: can't open adc%d channel, %s--[%d]\n", errno, channel, __FUNCTION__, __LINE__);
+       snprintf(adc_dev, PATH_BUF_MAX, "%s%d%s%d%s", path, device, "/in_voltage", channel, "_raw");
+       fd = open(adc_dev, O_RDONLY);
+       if (fd < 0) {
+               char errmsg[MAX_ERR_LEN];
+               strerror_r(errno, errmsg, MAX_ERR_LEN);
+               _E("Can't Open %s, errmsg : %s", adc_dev, errmsg);
                return -ENXIO;
        }
-       bytes = read(fd, voltage, ADC_BUF_MAX);
-       if (bytes == -1) {
+
+       status = read(fd, adc_buf, ADC_BUF_MAX);
+       if (status < 0) {
                close(fd);
+               _E("Failed to get adc, path : %s", adc_dev);
                return -EIO;
        }
-
-       *data = atoi(voltage);
+       result = atoi(adc_buf);
+       *data = result;
        close(fd);
 
        return 0;
index 2531db2..9f39cf7 100644 (file)
 #define __ADC_H__
 
 /**
-* @brief adc_init() find adc device name.
+* @brief adc_get_path() get adc device path.
 *
-* @param[out] dev_name The name of adc device node which must be freed.
-* @return On success, 0 is returned. On failure, a negative value is returned.
+* @param[in] device The adc device number
+* @param[in] channel The adc channel number
+* @param[out] *path The buffer for the adc device path
+* @param[in] length The max length of the path buffer
+* @return 0 on success, otherwise a negative error value
 */
-int adc_get_device_name(char **dev_name);
+int adc_get_path(unsigned int device, char *path, int length);
 
 /**
-* @brief adc_get_data() get adc data.
+* @brief adc_read() get adc data.
 *
-* @param[in] channel adc channel number
-* @param[in] *devName adc device name
-* @param[in] *data adc value
-* @return On success, voltage is returned. On failure, a negative value is returned.
+* @param[in] device The adc device number
+* @param[in] channel The adc channel number
+* @param[in] *path The adc device path
+* @param[in] *data The adc value
+* @return 0 on success, otherwise a negative error value
 */
-int adc_get_data(int channel, char *devName, int *data);
+int adc_read(unsigned int device, unsigned int channel, char *path, int *data);
 
 #endif /* __ADC_H__ */