[1/6] fd passing: move interface code from daemon. 79/159779/3
authorSegwon <segwon.han@samsung.com>
Mon, 13 Nov 2017 04:30:38 +0000 (13:30 +0900)
committerSegwon Han <segwon.han@samsung.com>
Mon, 13 Nov 2017 08:13:05 +0000 (08:13 +0000)
   - move from "peripheral-bus/src/interface/"
   - in order to improve performance, the lib area has direct access to the kernel.
   - not yet include in the build.

Signed-off-by: Segwon <segwon.han@samsung.com>
Change-Id: Id3a047968f7018ef352b01aa93cb0450ecda1f4d

src/interface/gpio.c [new file with mode: 0644]
src/interface/i2c.c [new file with mode: 0644]
src/interface/include/gpio.h [new file with mode: 0644]
src/interface/include/i2c.h [new file with mode: 0644]
src/interface/include/pwm.h [new file with mode: 0644]
src/interface/include/spi.h [new file with mode: 0644]
src/interface/include/uart.h [new file with mode: 0644]
src/interface/pwm.c [new file with mode: 0644]
src/interface/spi.c [new file with mode: 0644]
src/interface/uart.c [new file with mode: 0644]

diff --git a/src/interface/gpio.c b/src/interface/gpio.c
new file mode 100644 (file)
index 0000000..77c73c8
--- /dev/null
@@ -0,0 +1,373 @@
+/*
+ * 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 <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <poll.h>
+
+#include "gpio.h"
+#include "peripheral_common.h"
+
+#define MAX_ERR_LEN 255
+
+int gpio_open(int gpiopin)
+{
+       int fd, len, status;
+       char gpio_export[GPIO_BUFFER_MAX] = {0, };
+
+       _D("gpiopin : %d", gpiopin);
+
+       fd = open(SYSFS_GPIO_DIR "/export", O_WRONLY);
+       if (fd < 0) {
+               char errmsg[MAX_ERR_LEN];
+               strerror_r(errno, errmsg, MAX_ERR_LEN);
+               _E("Can't Open /sys/class/gpio/export :%s\n", errmsg);
+               return -ENXIO;
+       }
+
+       len = snprintf(gpio_export, GPIO_BUFFER_MAX, "%d", gpiopin);
+       status = write(fd, gpio_export, len);
+
+       if (status != len) {
+               close(fd);
+               _E("Error: gpio open error \n");
+               return -EIO;
+       }
+
+       close(fd);
+
+       return 0;
+}
+
+int gpio_set_direction(int gpiopin, gpio_direction_e dir)
+{
+       int fd, status;
+       char gpio_dev[GPIO_BUFFER_MAX] = {0, };
+
+       _D("gpiopin : %d, dir : %d", gpiopin, dir);
+
+       snprintf(gpio_dev, GPIO_BUFFER_MAX, SYSFS_GPIO_DIR"/gpio%d/direction", gpiopin);
+       fd = open(gpio_dev, O_WRONLY);
+       if (fd < 0) {
+               char errmsg[MAX_ERR_LEN];
+               strerror_r(errno, errmsg, MAX_ERR_LEN);
+               _E("Can't Open /sys/class/gpio/gpio%d/direction: %s\n", gpiopin, errmsg);
+               return -ENXIO;
+       }
+
+       if (dir == GPIO_DIRECTION_IN)
+               status = write(fd, "in", strlen("in")+1);
+       else if (dir == GPIO_DIRECTION_OUT_HIGH)
+               status = write(fd, "high", strlen("high")+1);
+       else if (dir == GPIO_DIRECTION_OUT_LOW)
+               status = write(fd, "low", strlen("low")+1);
+       else {
+               close(fd);
+               _E("Error: gpio direction is wrong\n");
+               return -EIO;
+       }
+
+       if (status <= 0) {
+               close(fd);
+               _E("Error: gpio direction set error\n");
+               return -EIO;
+       }
+
+       close(fd);
+
+       return 0;
+}
+
+int gpio_get_direction(int gpiopin, gpio_direction_e *dir)
+{
+       int fd, len;
+       char gpio_dev[GPIO_BUFFER_MAX] = {0, };
+       char gpio_buf[GPIO_BUFFER_MAX] = {0, };
+
+       snprintf(gpio_dev, GPIO_BUFFER_MAX, SYSFS_GPIO_DIR"/gpio%d/direction", gpiopin);
+       fd = open(gpio_dev, O_RDONLY);
+
+       if (fd < 0) {
+               char errmsg[MAX_ERR_LEN];
+               strerror_r(errno, errmsg, MAX_ERR_LEN);
+               _E("Can't Open /sys/class/gpio/gpio%d/direction: %s\n", gpiopin, errmsg);
+               return -ENXIO;
+       }
+
+       len = read(fd, &gpio_buf, GPIO_BUFFER_MAX);
+       if (len <= 0) {
+               close(fd);
+               _E("Error: gpio direction read error\n");
+               return -EIO;
+       }
+
+       if (0 == strncmp(gpio_buf, "in", strlen("in")))
+               *dir = GPIO_DIRECTION_IN;
+       else if (0 == strncmp(gpio_buf, "out", strlen("out")))
+               *dir = GPIO_DIRECTION_OUT_LOW;
+       else {
+               close(fd);
+               _E("Error: gpio direction is wrong\n");
+               return -EIO;
+       }
+
+       close(fd);
+
+       return 0;
+}
+
+int gpio_set_edge_mode(int gpiopin, gpio_edge_e edge)
+{
+       int fd, status;
+       char gpio_dev[GPIO_BUFFER_MAX] = {0, };
+
+       _D("gpiopin : %d, edge : %d", gpiopin, edge);
+
+       snprintf(gpio_dev, GPIO_BUFFER_MAX, SYSFS_GPIO_DIR"/gpio%d/edge", gpiopin);
+       fd = open(gpio_dev, O_WRONLY);
+       if (fd < 0) {
+               char errmsg[MAX_ERR_LEN];
+               strerror_r(errno, errmsg, MAX_ERR_LEN);
+               _E("Can't Open /sys/class/gpio/gpio%d/edge: %s\n", gpiopin, errmsg);
+               return -ENXIO;
+       }
+
+       if (edge == GPIO_EDGE_NONE)
+               status = write(fd, "none", strlen("none")+1);
+       else if (edge == GPIO_EDGE_RISING)
+               status = write(fd, "rising", strlen("rising")+1);
+       else if (edge == GPIO_EDGE_FALLING)
+               status = write(fd, "falling", strlen("falling")+1);
+       else if (edge == GPIO_EDGE_BOTH)
+               status = write(fd, "both", strlen("both")+1);
+       else {
+               close(fd);
+               _E("Error: gpio edge is wrong\n");
+               return -EIO;
+       }
+
+       if (status <= 0) {
+               close(fd);
+               _E("Error: gpio edge set error\n");
+               return -EIO;
+       }
+
+       close(fd);
+
+       return 0;
+}
+
+int gpio_get_edge_mode(int gpiopin, gpio_edge_e *edge)
+{
+       int fd, len;
+       char gpio_dev[GPIO_BUFFER_MAX] = {0, };
+       char gpio_buf[GPIO_BUFFER_MAX] = {0, };
+
+       snprintf(gpio_dev, GPIO_BUFFER_MAX, SYSFS_GPIO_DIR"/gpio%d/edge", gpiopin);
+       fd = open(gpio_dev, O_RDONLY);
+
+       if (fd < 0) {
+               char errmsg[MAX_ERR_LEN];
+               strerror_r(errno, errmsg, MAX_ERR_LEN);
+               _E("Can't Open /sys/class/gpio/gpio%d/edge: %s\n", gpiopin, errmsg);
+               return -ENXIO;
+       }
+
+       len = read(fd, &gpio_buf, GPIO_BUFFER_MAX);
+       if (len <= 0) {
+               close(fd);
+               _E("Error: gpio edge read error\n");
+               return -EIO;
+       }
+
+       if (0 == strncmp(gpio_buf, "none", strlen("none")))
+               *edge = GPIO_EDGE_NONE;
+       else if (0 == strncmp(gpio_buf, "both", strlen("both")))
+               *edge = GPIO_EDGE_BOTH;
+       else if (0 == strncmp(gpio_buf, "rising", strlen("rising")))
+               *edge = GPIO_EDGE_RISING;
+       else if (0 == strncmp(gpio_buf, "falling", strlen("falling")))
+               *edge = GPIO_EDGE_FALLING;
+       else {
+               close(fd);
+               _E("Error: gpio edge is wrong\n");
+               return -EIO;
+       }
+
+       close(fd);
+
+       return 0;
+}
+
+int gpio_write(int gpiopin, int value)
+{
+       int fd, status;
+       char gpio_dev[GPIO_BUFFER_MAX] = {0, };
+
+       snprintf(gpio_dev, GPIO_BUFFER_MAX, SYSFS_GPIO_DIR"/gpio%d/value", gpiopin);
+       fd = open(gpio_dev, O_WRONLY);
+
+       if (fd < 0) {
+               char errmsg[MAX_ERR_LEN];
+               strerror_r(errno, errmsg, MAX_ERR_LEN);
+               _E("Can't Open /sys/class/gpio/gpio%d/value: %s\n", gpiopin, errmsg);
+               return -ENXIO;
+       }
+
+       if (value == 1)
+               status = write(fd, "1", strlen("1")+1);
+       else if (value == 0)
+               status = write(fd, "0", strlen("0")+1);
+       else {
+               close(fd);
+               _E("Error: gpio write value error \n");
+               return -EIO;
+       }
+
+       if (status <= 0) {
+               close(fd);
+               _E("Error: gpio write error\n");
+               return -EIO;
+       }
+
+       close(fd);
+
+       return 0;
+}
+
+int gpio_read(int gpiopin, int *value)
+{
+       int fd, len;
+       char gpio_dev[GPIO_BUFFER_MAX] = {0, };
+       char gpio_buf[GPIO_BUFFER_MAX] = {0, };
+
+       snprintf(gpio_dev, GPIO_BUFFER_MAX, SYSFS_GPIO_DIR"/gpio%d/value", gpiopin);
+       fd = open(gpio_dev, O_RDONLY);
+       if (fd < 0) {
+               char errmsg[MAX_ERR_LEN];
+               strerror_r(errno, errmsg, MAX_ERR_LEN);
+               _E("Can't Open /sys/class/gpio/gpio%d pin value: %s\n", gpiopin, errmsg);
+               return -ENXIO;
+       }
+
+       len = read(fd, &gpio_buf, 1);
+       close(fd);
+
+       if (len <= 0) {
+               _E("Error: gpio read error \n");
+               return -EIO;
+       }
+
+       if (0 == strncmp(gpio_buf, "1", strlen("1")))
+               *value = 1;
+       else if (0 == strncmp(gpio_buf, "0", strlen("0")))
+               *value = 0;
+       else {
+               _E("Error: gpio value is error \n");
+               return -EIO;
+       }
+
+       return 0;
+}
+
+int gpio_close(int gpiopin)
+{
+       int fd, len, status;
+       char gpio_unexport[GPIO_BUFFER_MAX] = {0, };
+
+       _D("gpiopin : %d", gpiopin);
+
+       fd = open(SYSFS_GPIO_DIR "/unexport", O_WRONLY);
+       if (fd < 0) {
+               char errmsg[MAX_ERR_LEN];
+               strerror_r(errno, errmsg, MAX_ERR_LEN);
+               _E("Can't Open /sys/class/gpio/unexport %s\n", errmsg);
+               return -ENXIO;
+       }
+
+       len = snprintf(gpio_unexport, GPIO_BUFFER_MAX, "%d", gpiopin);
+       status = write(fd, gpio_unexport, len);
+
+       if (status != len) {
+               close(fd);
+               _E("Error: gpio close error \n");
+               return -EIO;
+       }
+
+       close(fd);
+
+       return 0;
+}
+
+int gpio_open_isr(int gpiopin)
+{
+       int fd;
+       char gpio_dev[GPIO_BUFFER_MAX] = {0, };
+
+       snprintf(gpio_dev, sizeof(gpio_dev)-1, SYSFS_GPIO_DIR"/gpio%d/value", gpiopin);
+
+       _D("open isr string [%s]", gpio_dev);
+
+       fd = open(gpio_dev, O_RDONLY);
+       if (fd < 0) {
+               char errmsg[MAX_ERR_LEN];
+               strerror_r(errno, errmsg, MAX_ERR_LEN);
+               _E("Can't Open /sys/class/gpio/gpio%d pin value: %s\n", gpiopin, errmsg);
+               return -ENXIO;
+       }
+
+       return fd;
+}
+
+int gpio_close_isr(int fd)
+{
+       if (fd <= 0) return -EINVAL;
+
+       close(fd);
+
+       return 0;
+}
+
+int gpio_read_isr(void *fdset, char *rev_buf, int length)
+{
+       int poll_state = 0;
+       int len;
+       struct pollfd poll_events;
+
+       poll_events.fd = ((struct pollfd*)fdset)->fd;
+       poll_events.events = POLLPRI;
+       poll_events.revents = ((struct pollfd*)fdset)->revents;
+
+       poll_state = poll((struct pollfd*)&poll_events, 1, -1);  // 0 is going to return directly.
+
+       if (poll_state < 0) {
+               _E("poll() failed!\n");
+               return -EIO;
+       }
+
+       if (poll_events.revents & POLLPRI) {
+               lseek(poll_events.fd, 0, SEEK_SET);
+               len = read(poll_events.fd, rev_buf, length);
+               if (len == -1)
+                       return -EIO;
+       }
+
+       return poll_state;
+}
diff --git a/src/interface/i2c.c b/src/interface/i2c.c
new file mode 100644 (file)
index 0000000..0907cce
--- /dev/null
@@ -0,0 +1,136 @@
+/*
+ * 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 <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <sys/ioctl.h>
+
+#include "i2c.h"
+#include "peripheral_common.h"
+
+#define MAX_ERR_LEN 255
+
+int i2c_open(int bus, int *fd)
+{
+       int new_fd;
+       char i2c_dev[I2C_BUFFER_MAX] = {0,};
+
+       _D("bus : %d", bus);
+
+       snprintf(i2c_dev, sizeof(i2c_dev)-1, SYSFS_I2C_DIR"-%d", bus);
+       new_fd = open(i2c_dev, O_RDWR);
+       if (new_fd < 0) {
+               char errmsg[MAX_ERR_LEN];
+               strerror_r(errno, errmsg, MAX_ERR_LEN);
+               _E("Can't Open %s : %s", i2c_dev, errmsg);
+               return -ENXIO;
+       }
+       _D("fd : %d", new_fd);
+       *fd = new_fd;
+
+       return 0;
+}
+
+int i2c_close(int fd)
+{
+       int status;
+
+       _D("fd : %d", fd);
+       RETVM_IF(fd < 0, -EINVAL, "Invalid fd");
+
+       status = close(fd);
+       if (status < 0) {
+               char errmsg[MAX_ERR_LEN];
+               strerror_r(errno, errmsg, MAX_ERR_LEN);
+               _E("Failed to close fd : %d", fd);
+               return -EIO;
+       }
+
+       return 0;
+}
+
+int i2c_set_address(int fd, int address)
+{
+       int status;
+
+       _D("fd : %d, slave address : 0x%x", fd, address);
+       RETVM_IF(fd < 0, -EINVAL, "Invalid fd");
+
+       status = ioctl(fd, I2C_SLAVE, address);
+       if (status < 0) {
+               char errmsg[MAX_ERR_LEN];
+               strerror_r(errno, errmsg, MAX_ERR_LEN);
+               _E("Failed to set slave address(%x), fd : %d, errmsg : %s", address, fd, errmsg);
+               return status;
+       }
+
+       return 0;
+}
+
+int i2c_read(int fd, unsigned char *data, int length)
+{
+       int status;
+
+       RETVM_IF(fd < 0, -EINVAL, "Invalid fd : %d", fd);
+
+       status = read(fd, data, length);
+       if (status != length) {
+               char errmsg[MAX_ERR_LEN];
+               strerror_r(errno, errmsg, MAX_ERR_LEN);
+               _E("i2c read failed, fd : %d, errmsg : %s", fd, errmsg);
+               return -EIO;
+       }
+
+       return 0;
+}
+
+int i2c_write(int fd, const unsigned char *data, int length)
+{
+       int status;
+
+       RETVM_IF(fd < 0, -EINVAL, "Invalid fd : %d", fd);
+
+       status = write(fd, data, length);
+       if (status != length) {
+               char errmsg[MAX_ERR_LEN];
+               strerror_r(errno, errmsg, MAX_ERR_LEN);
+               _E("i2c write failed fd : %d, errmsg : %s", fd, errmsg);
+               return -EIO;
+       }
+
+       return 0;
+}
+
+int i2c_smbus_ioctl(int fd, struct i2c_smbus_ioctl_data *data)
+{
+       int status;
+
+       RETVM_IF(fd < 0, -EINVAL, "Invalid fd : %d", fd);
+
+       status = ioctl(fd, I2C_SMBUS, data);
+       if (status < 0) {
+               char errmsg[MAX_ERR_LEN];
+               strerror_r(errno, errmsg, MAX_ERR_LEN);
+               _E("i2c transaction failed fd : %d, errmsg : %s", fd, errmsg);
+               return -EIO;
+       }
+
+       return 0;
+}
diff --git a/src/interface/include/gpio.h b/src/interface/include/gpio.h
new file mode 100644 (file)
index 0000000..b0b7c5b
--- /dev/null
@@ -0,0 +1,48 @@
+/*
+ * 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 __GPIO_H__
+#define __GPIO_H__
+
+#define SYSFS_GPIO_DIR "/sys/class/gpio"
+#define GPIO_BUFFER_MAX 64
+
+typedef enum {
+       GPIO_DIRECTION_IN = 0,
+       GPIO_DIRECTION_OUT_HIGH = 1,
+       GPIO_DIRECTION_OUT_LOW = 2,
+} gpio_direction_e;
+
+typedef enum {
+       GPIO_EDGE_NONE = 0,
+       GPIO_EDGE_RISING = 1,
+       GPIO_EDGE_FALLING = 2,
+       GPIO_EDGE_BOTH = 3,
+} gpio_edge_e;
+
+int gpio_open(int gpiopin);
+int gpio_close(int gpiopin);
+int gpio_set_edge_mode(int gpiopin, gpio_edge_e edge);
+int gpio_get_edge_mode(int gpiopin, gpio_edge_e *edge);
+int gpio_set_direction(int gpiopin, gpio_direction_e dir);
+int gpio_get_direction(int gpiopin, gpio_direction_e *dir);
+int gpio_write(int gpiopin, int value);
+int gpio_read(int gpiopin, int *value);
+
+int gpio_open_isr(int gpiopin);
+int gpio_close_isr(int file_hndl);
+int gpio_read_isr(void *fdset, char *rev_buf, int length);
+#endif/*__GPIO_H__*/
diff --git a/src/interface/include/i2c.h b/src/interface/include/i2c.h
new file mode 100644 (file)
index 0000000..f0d4668
--- /dev/null
@@ -0,0 +1,65 @@
+/*
+ * 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 __I2C_H__
+#define __I2C_H__
+
+#include <stdint.h>
+
+#define SYSFS_I2C_DIR "/dev/i2c"
+#define I2C_BUFFER_MAX 64
+
+#define I2C_SLAVE      0x0703  /* Use this slave address */
+#define I2C_SMBUS      0x0720  /* SMBus transfer */
+
+/* i2c_smbus_xfer read or write markers */
+#define I2C_SMBUS_READ 1
+#define I2C_SMBUS_WRITE        0
+
+/* SMBus transaction types */
+#define I2C_SMBUS_QUICK                    0
+#define I2C_SMBUS_BYTE             1
+#define I2C_SMBUS_BYTE_DATA        2
+#define I2C_SMBUS_WORD_DATA        3
+
+/*
+ * Data for SMBus Messages
+ */
+#define I2C_SMBUS_BLOCK_MAX    32      /* As specified in SMBus standard */
+
+union i2c_smbus_data {
+       uint8_t byte;
+       uint16_t word;
+       uint8_t block[I2C_SMBUS_BLOCK_MAX + 2]; /* block[0] is used for length */
+                              /* and one more for user-space compatibility */
+};
+
+/* This is the structure as used in the I2C_SMBUS ioctl call */
+struct i2c_smbus_ioctl_data {
+       uint8_t read_write;
+       uint8_t command;
+       uint32_t size;
+       union i2c_smbus_data *data;
+};
+
+int i2c_open(int bus, int *fd);
+int i2c_close(int fd);
+int i2c_set_address(int fd, int address);
+int i2c_read(int fd, unsigned char *data, int length);
+int i2c_write(int fd, const unsigned char *data, int length);
+int i2c_smbus_ioctl(int fd, struct i2c_smbus_ioctl_data *data);
+
+#endif/* __I2C_H__ */
diff --git a/src/interface/include/pwm.h b/src/interface/include/pwm.h
new file mode 100644 (file)
index 0000000..26243d3
--- /dev/null
@@ -0,0 +1,125 @@
+/*
+ * 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 __PWM_H__
+#define __PWM_H__
+
+/**
+ * @brief Enumeration for Polarity
+ */
+typedef enum {
+       PWM_POLARITY_NORMAL = 0,
+       PWM_POLARITY_INVERSED,
+} pwm_polarity_e;
+
+/**
+* @brief pwm_open() init pwm pin.
+*
+* @param[in] chip pwm chip number
+* @param[in] pin pwm pin number
+* @return On success, 0 is returned. On failure, a negative value is returned.
+*/
+int pwm_open(int chip, int pin);
+
+/**
+* @brief pwm_close() deinit pwm pin.
+*
+* @param[in] chip pwm chip number
+* @param[in] pin pwm pin number
+* @return On success, 0 is returned. On failure, a negative value is returned.
+*/
+int pwm_close(int chip, int pin);
+
+/**
+* @brief pwm_set_period() sets the pwm period.
+*
+* @param[in] chip pwm chip number
+* @param[in] pin pwm pin number
+* @param[in] period pwm period
+* @return On success, 0 is returned. On failure, a negative value is returned.
+*/
+int pwm_set_period(int chip, int pin, int period);
+
+/**
+* @brief pwm_get_period() gets the pwm period.
+*
+* @param[in] chip pwm chip number
+* @param[in] pin pwm pin number
+* @param[out] period pwm period
+* @return On success, 0 is returned. On failure, a negative value is returned.
+*/
+int pwm_get_period(int chip, int pin, int *period);
+
+/**
+* @brief pwm_set_duty_cycle() sets the pwm duty cycle.
+*
+* @param[in] chip pwm chip number
+* @param[in] pin pwm pin number
+* @param[in] duty_cycle pwm duty cycle
+* @return On success, 0 is returned. On failure, a negative value is returned.
+*/
+int pwm_set_duty_cycle(int chip, int pin, int duty_cycle);
+
+/**
+* @brief pwm_get_duty_cycle() gets the pwm duty cycle.
+*
+* @param[in] chip pwm chip number
+* @param[in] pin pwm pin number
+* @param[out] duty_cycle pwm duty cycle
+* @return On success, 0 is returned. On failure, a negative value is returned.
+*/
+int pwm_get_duty_cycle(int chip, int pin, int *duty_cycle);
+
+/**
+* @brief pwm_set_polarity() sets the pwm polarity.
+*
+* @param[in] chip pwm chip number
+* @param[in] pin pwm pin number
+* @param[in] polarity pwm polarity
+* @return On success, 0 is returned. On failure, a negative value is returned.
+*/
+int pwm_set_polarity(int chip, int pin, pwm_polarity_e polarity);
+/**
+* @brief pwm_get_polarity() gets the pwm polarity.
+*
+* @param[in] chip pwm chip number
+* @param[in] pin pwm pin number
+* @param[out] polarity pwm polarity
+* @return On success, 0 is returned. On failure, a negative value is returned.
+*/
+int pwm_get_polarity(int chip, int pin, pwm_polarity_e *polarity);
+
+/**
+* @brief pwm_set_enable() sets the pwm state.
+*
+* @param[in] chip pwm chip number
+* @param[in] pin pwm pin number
+* @param[in] enable pwm enable/disabled state value
+* @return On success, 0 is returned. On failure, a negative value is returned.
+*/
+int pwm_set_enable(int chip, int pin, bool enable);
+
+/**
+* @brief pwm_get_enable() checks if pwm state is enabled.
+*
+* @param[in] chip pwm chip number
+* @param[in] pin pwm pin number
+* @param[out] enable pwm enable/disabled state value
+* @return On success, 0 is returned. On failure, a negative value is returned.
+*/
+int pwm_get_enable(int chip, int pin, bool *enable);
+
+#endif /* __PWM_H__ */
diff --git a/src/interface/include/spi.h b/src/interface/include/spi.h
new file mode 100644 (file)
index 0000000..9937c41
--- /dev/null
@@ -0,0 +1,31 @@
+/*
+ * 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 __SPI_H__
+#define __SPI_H__
+
+int spi_open(int bus, int cs, int *fd);
+int spi_close(int fd);
+int spi_set_mode(int fd, unsigned char mode);
+int spi_set_bit_order(int fd, unsigned char lsb);
+int spi_set_bits_per_word(int fd, unsigned char bits);
+int spi_set_frequency(int fd, unsigned int freq);
+int spi_get_buffer_size(int *bufsiz);
+int spi_read(int fd, unsigned char *rxbuf, int length);
+int spi_write(int fd, unsigned char *txbuf, int length);
+int spi_transfer(int fd, unsigned char *txbuf, unsigned char *rxbuf, int length);
+
+#endif /* __SPI_H__ */
diff --git a/src/interface/include/uart.h b/src/interface/include/uart.h
new file mode 100644 (file)
index 0000000..413b23e
--- /dev/null
@@ -0,0 +1,185 @@
+/*
+ * 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 __UART_H__
+#define __UART_H__
+
+#include <stdint.h>
+
+/**
+ * @brief Enumeration for Baud Rate
+ */
+typedef enum {
+       UART_BAUD_RATE_0 = 0,
+       UART_BAUD_RATE_50,
+       UART_BAUD_RATE_75,
+       UART_BAUD_RATE_110,
+       UART_BAUD_RATE_134,
+       UART_BAUD_RATE_150,
+       UART_BAUD_RATE_200,
+       UART_BAUD_RATE_300,
+       UART_BAUD_RATE_600,
+       UART_BAUD_RATE_1200,
+       UART_BAUD_RATE_1800,
+       UART_BAUD_RATE_2400,
+       UART_BAUD_RATE_4800,
+       UART_BAUD_RATE_9600,
+       UART_BAUD_RATE_19200,
+       UART_BAUD_RATE_38400,
+       UART_BAUD_RATE_57600,
+       UART_BAUD_RATE_115200,
+       UART_BAUD_RATE_230400
+} uart_baud_rate_e;
+
+/**
+ * @brief Enumeration for Byte Size
+ */
+typedef enum {
+       UART_BYTE_SIZE_5BIT = 0,
+       UART_BYTE_SIZE_6BIT,
+       UART_BYTE_SIZE_7BIT,
+       UART_BYTE_SIZE_8BIT
+} uart_byte_size_e;
+
+/**
+ * @brief Enumeration of Parity Bit
+ */
+typedef enum {
+       UART_PARITY_NONE = 0,
+       UART_PARITY_EVEN,
+       UART_PARITY_ODD
+} uart_parity_e;
+
+/**
+ * @brief Enumeration for Stop Bits
+ */
+typedef enum {
+       UART_STOP_BITS_1BIT = 0,
+       UART_STOP_BITS_2BIT
+} uart_stop_bits_e;
+
+/**
+* @brief uart_valid_baudrate() validation check of input baudrate
+*
+* @param[in] baudrate baudrate for uart
+* @return On success, valid input. On failure, NULL is returned.
+*/
+int uart_valid_baud_rate(unsigned int baud_rate);
+
+/**
+* @brief uart_open() initializes uart port.
+*
+* @param[in] port uart port
+* @param[in] file_hndl handle of uart port
+* @return On success, handle of uart_context is returned. On failure, NULL is returned.
+*/
+int uart_open(int port, int *file_hndl);
+
+/**
+* @brief uart_close() closes uart port.
+*
+* @param[in] file_hndl handle of uart_context
+* @return On success, 0 is returned. On failure, a negative value is returned.
+*/
+int uart_close(int file_hndl);
+
+/**
+* @brief uart_flush() flushes uart buffer.
+*
+* @param[in] file_hndl handle of uart_context
+* @return On success, 0 is returned. On failure, a negative value is returned.
+*/
+int uart_flush(int file_hndl);
+
+/**
+* @brief uart_set_baudrate() sets uart baud rate.
+*
+* @param[in] file_hndl handle of uart_context
+* @param[in] baud uart baud rate
+* @return On success, 0 is returned. On failure, a negative value is returned.
+*/
+int uart_set_baud_rate(int file_hndl, uart_baud_rate_e baud);
+
+/**
+* @brief uart_set_mode() sets byte size, parity bit and stop bits.
+*
+* @param[in] file_hndl handle of uart_context
+* @param[in] byte_size uart byte size
+* @param[in] parity uart parity type (even/odd/none)
+* @param[in] stop_bits uart stop bits
+* @return On success, 0 is returned. On failure, a negative value is returned.
+*/
+int uart_set_mode(int file_hndl, uart_byte_size_e byte_size, uart_parity_e parity, uart_stop_bits_e stop_bits);
+
+/**
+* @brief peripheral_bus_uart_set_byte_size() set byte size.
+*
+* @param[in] file_hndl handle of uart_context
+* @param[in] byte_size uart byte size
+* @return On success, 0 is returned. On failure, a negative value is returned.
+*/
+int uart_set_byte_size(int file_hndl, uart_byte_size_e byte_size);
+
+/**
+* @brief peripheral_bus_uart_set_parity() set parity bit.
+*
+* @param[in] file_hndl handle of uart_context
+* @param[in] parity uart parity type (even/odd/none)
+* @return On success, 0 is returned. On failure, a negative value is returned.
+*/
+int uart_set_parity(int file_hndl, uart_parity_e parity);
+
+/**
+* @brief peripheral_bus_uart_set_stop_bits() set stop bits.
+*
+* @param[in] file_hndl handle of uart_context
+* @param[in] stop_bits uart stop bits
+* @return On success, 0 is returned. On failure, a negative value is returned.
+*/
+int uart_set_stop_bits(int file_hndl, uart_stop_bits_e stop_bits);
+
+/**
+* @brief uart_set_flow_control() set flow control settings.
+*
+* @param[in] file_hndl handle of uart_context
+* @param[in] xonxoff ixon/ixoff
+* @param[in] rtscts rts/cts
+* @return On success, 0 is returned. On failure, a negative value is returned.
+*/
+int uart_set_flow_control(int file_hndl, bool xonxoff, bool rtscts);
+
+/**
+* @brief uart_read() reads data over uart bus.
+*
+* @param[in] file_hndl handle of uart_context
+* @param[in] buf the pointer of data buffer
+* @param[in] length size to read
+* @return On success, 0 is returned. On failure, a negative value is returned.
+*/
+int uart_read(int file_hndl, uint8_t *buf, unsigned int length);
+
+/**
+* @brief uart_write() writes data over uart bus.
+*
+* @param[in] file_hndl handle of uart_context
+* @param[in] buf the pointer of data buffer
+* @param[in] length size to write
+* @return On success, 0 is returned. On failure, a negative value is returned.
+*/
+int uart_write(int file_hndl, uint8_t *buf, unsigned int length);
+
+#endif /* __UART_H__ */
+
diff --git a/src/interface/pwm.c b/src/interface/pwm.c
new file mode 100644 (file)
index 0000000..2b6ebd8
--- /dev/null
@@ -0,0 +1,334 @@
+/*
+ * 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 <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <stdbool.h>
+
+#include "pwm.h"
+#include "peripheral_common.h"
+
+#define SYSFS_PWM_PATH "/sys/class/pwm"
+
+#define PATH_BUF_MAX   64
+#define PWM_BUF_MAX    16
+#define MAX_ERR_LEN    255
+
+int pwm_open(int chip, int pin)
+{
+       int fd, len, status;
+       char pwm_dev[PATH_BUF_MAX] = {0};
+       char pwm_buf[PWM_BUF_MAX] = {0};
+
+       _D("chip : %d, pin : %d", chip, pin);
+
+       snprintf(pwm_dev, PATH_BUF_MAX, SYSFS_PWM_PATH "/pwmchip%d/export", chip);
+       fd = open(pwm_dev, O_WRONLY);
+       if (fd < 0) {
+               char errmsg[MAX_ERR_LEN];
+               strerror_r(errno, errmsg, MAX_ERR_LEN);
+               _E("Can't Open %s, errmsg : %s", pwm_dev, errmsg);
+               return -ENXIO;
+       }
+
+       len = snprintf(pwm_buf, sizeof(pwm_buf), "%d", pin);
+       status = write(fd, pwm_buf, len);
+       if (status < 0) {
+               _E("Failed to export pwmchip%d, pwm%d", chip, pin);
+               close(fd);
+               return -EIO;
+       }
+       close(fd);
+
+       return 0;
+}
+
+int pwm_close(int chip, int pin)
+{
+       int fd, len, status;
+       char pwm_dev[PATH_BUF_MAX] = {0};
+       char pwm_buf[PWM_BUF_MAX] = {0};
+
+       _D("chip : %d, pin : %d", chip, pin);
+
+       snprintf(pwm_dev, PATH_BUF_MAX, SYSFS_PWM_PATH "/pwmchip%d/unexport", chip);
+       fd = open(pwm_dev, O_WRONLY);
+       if (fd < 0) {
+               char errmsg[MAX_ERR_LEN];
+               strerror_r(errno, errmsg, MAX_ERR_LEN);
+               _E("Can't Open %s, errmsg : %s", pwm_dev, errmsg);
+               return -ENXIO;
+       }
+
+       len = snprintf(pwm_buf, sizeof(pwm_buf), "%d", pin);
+       status = write(fd, pwm_buf, len);
+       if (status < 0) {
+               _E("Failed to unexport pwmchip%d, pwm%", chip, pin);
+               close(fd);
+               return -EIO;
+       }
+       close(fd);
+
+       return 0;
+}
+
+int pwm_set_period(int chip, int pin, int period)
+{
+       int fd, len, status;
+       char pwm_buf[PWM_BUF_MAX] = {0};
+       char pwm_dev[PATH_BUF_MAX] = {0};
+
+       _D("chip : %d, pin : %d, period : %d", chip, pin, period);
+
+       snprintf(pwm_dev, PATH_BUF_MAX, SYSFS_PWM_PATH "/pwmchip%d/pwm%d/period", chip, pin);
+       fd = open(pwm_dev, O_WRONLY);
+       if (fd < 0) {
+               char errmsg[MAX_ERR_LEN];
+               strerror_r(errno, errmsg, MAX_ERR_LEN);
+               _E("Can't Open %s, errmsg : %s", pwm_dev, errmsg);
+               return -ENXIO;
+       }
+
+       len = snprintf(pwm_buf, sizeof(pwm_buf), "%d", period);
+       status = write(fd, pwm_buf, len);
+       if (status < 0) {
+               close(fd);
+               _E("Failed to set period, path : %s", pwm_dev);
+               return -EIO;
+       }
+       close(fd);
+
+       return 0;
+}
+
+int pwm_get_period(int chip, int pin, int *period)
+{
+       int fd, result, status;
+       char pwm_buf[PWM_BUF_MAX] = {0};
+       char pwm_dev[PATH_BUF_MAX] = {0};
+
+       snprintf(pwm_dev, PATH_BUF_MAX, SYSFS_PWM_PATH "/pwmchip%d/pwm%d/period", chip, pin);
+       fd = open(pwm_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", pwm_dev, errmsg);
+               return -ENXIO;
+       }
+
+       status = read(fd, pwm_buf, PWM_BUF_MAX);
+       if (status < 0) {
+               close(fd);
+               _E("Failed to get period, path : %s", pwm_dev);
+               return -EIO;
+       }
+       result = atoi(pwm_buf);
+       *period = result;
+       close(fd);
+
+       return 0;
+}
+
+int pwm_set_duty_cycle(int chip, int pin, int duty_cycle)
+{
+       int fd, len, status;
+       char pwm_buf[PWM_BUF_MAX] = {0};
+       char pwm_dev[PATH_BUF_MAX] = {0};
+
+       _D("chip : %d, pin : %d, duty_cycle : %d", chip, pin, duty_cycle);
+
+       snprintf(pwm_dev, PATH_BUF_MAX, SYSFS_PWM_PATH "/pwmchip%d/pwm%d/duty_cycle", chip, pin);
+       fd = open(pwm_dev, O_WRONLY);
+       if (fd < 0) {
+               char errmsg[MAX_ERR_LEN];
+               strerror_r(errno, errmsg, MAX_ERR_LEN);
+               _E("Can't Open %s, errmsg : %s", pwm_dev, errmsg);
+               return -ENXIO;
+       }
+
+       len = snprintf(pwm_buf, sizeof(pwm_buf), "%d", duty_cycle);
+       status = write(fd, pwm_buf, len);
+       if (status < 0) {
+               close(fd);
+               _E("Failed to set duty cycle, path : %s", pwm_dev);
+               return -EIO;
+       }
+       close(fd);
+
+       return 0;
+}
+
+int pwm_get_duty_cycle(int chip, int pin, int *duty_cycle)
+{
+       int fd, result, status;
+       char pwm_buf[PWM_BUF_MAX] = {0};
+       char pwm_dev[PATH_BUF_MAX] = {0};
+
+       snprintf(pwm_dev, PATH_BUF_MAX, SYSFS_PWM_PATH "/pwmchip%d/pwm%d/duty_cycle", chip, pin);
+       fd = open(pwm_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", pwm_dev, errmsg);
+               return -ENXIO;
+       }
+
+       status = read(fd, pwm_buf, PWM_BUF_MAX);
+       if (status < 0) {
+               close(fd);
+               _E("Failed to get duty cycle, path : %s", pwm_dev);
+               return -EIO;
+       }
+       result = atoi(pwm_buf);
+       *duty_cycle = result;
+       close(fd);
+
+       return 0;
+}
+
+int pwm_set_polarity(int chip, int pin, pwm_polarity_e polarity)
+{
+       int fd, status;
+       char pwm_dev[PATH_BUF_MAX] = {0};
+
+       _D("chip : %d, pin : %d, polarity : %d", chip, pin, polarity);
+
+       snprintf(pwm_dev, PATH_BUF_MAX, SYSFS_PWM_PATH "/pwmchip%d/pwm%d/polarity", chip, pin);
+       fd = open(pwm_dev, O_WRONLY);
+       if (fd < 0) {
+               char errmsg[MAX_ERR_LEN];
+               strerror_r(errno, errmsg, MAX_ERR_LEN);
+               _E("Can't Open %s, errmsg : %s", pwm_dev, errmsg);
+               return -ENXIO;
+       }
+
+       if (polarity == PWM_POLARITY_NORMAL)
+               status = write(fd, "normal", strlen("normal")+1);
+       else if (polarity == PWM_POLARITY_INVERSED)
+               status = write(fd, "inversed", strlen("inversed")+1);
+       else {
+               _E("Invalid pwm polarity : %d", polarity);
+               close(fd);
+               return -EINVAL;
+       }
+
+       if (status <= 0) {
+               close(fd);
+               _E("Failed to set polarity, path : %s", pwm_dev);
+               return -EIO;
+       }
+       close(fd);
+
+       return 0;
+}
+
+int pwm_get_polarity(int chip, int pin, pwm_polarity_e *polarity)
+{
+       int fd, status;
+       char pwm_buf[PWM_BUF_MAX] = {0};
+       char pwm_dev[PATH_BUF_MAX] = {0};
+
+       snprintf(pwm_dev, PATH_BUF_MAX, SYSFS_PWM_PATH "/pwmchip%d/pwm%d/polarity", chip, pin);
+       fd = open(pwm_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", pwm_dev, errmsg);
+               return -ENXIO;
+       }
+
+       status = read(fd, pwm_buf, PWM_BUF_MAX);
+       if (status < 0) {
+               _E("Failed to get polarity, path : %s", pwm_dev);
+               close(fd);
+               return -EIO;
+       }
+
+       if (0 == strncmp(pwm_buf, "normal", strlen("normal")))
+               *polarity = PWM_POLARITY_NORMAL;
+       else if (0 == strncmp(pwm_buf, "inversed", strlen("inversed")))
+               *polarity = PWM_POLARITY_INVERSED;
+       else {
+               close(fd);
+               _E("Invalid pwm polarity : %d", pwm_buf);
+               return -EIO;
+       }
+       close(fd);
+
+       return 0;
+}
+
+int pwm_set_enable(int chip, int pin, bool enable)
+{
+       int fd, len, status;
+       char pwm_buf[PWM_BUF_MAX] = {0};
+       char pwm_dev[PATH_BUF_MAX] = {0};
+
+       _D("chip : %d, pin : %d, enable : %d", chip, pin, enable);
+
+       snprintf(pwm_dev, PATH_BUF_MAX, SYSFS_PWM_PATH "/pwmchip%d/pwm%d/enable", chip, pin);
+       fd = open(pwm_dev, O_WRONLY);
+       if (fd < 0) {
+               char errmsg[MAX_ERR_LEN];
+               strerror_r(errno, errmsg, MAX_ERR_LEN);
+               _E("Can't Open %s, errmsg : %s", pwm_dev, errmsg);
+               return -ENXIO;
+       }
+
+       len = snprintf(pwm_buf, sizeof(pwm_buf), "%d", enable);
+       status = write(fd, pwm_buf, len);
+       if (status < 0) {
+               close(fd);
+               _E("Failed to set enable, path : %s", pwm_dev);
+               return -EIO;
+       }
+       close(fd);
+
+       return 0;
+}
+
+int pwm_get_enable(int chip, int pin, bool *enable)
+{
+       int fd, result, status;
+       char pwm_buf[PWM_BUF_MAX] = {0};
+       char pwm_dev[PATH_BUF_MAX] = {0};
+
+       snprintf(pwm_dev, PATH_BUF_MAX, SYSFS_PWM_PATH "/pwmchip%d/pwm%d/enable", chip, pin);
+       fd = open(pwm_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", pwm_dev, errmsg);
+               return -ENXIO;
+       }
+
+       status = read(fd, pwm_buf, PWM_BUF_MAX);
+       if (status < 0) {
+               close(fd);
+               _E("Failed to get enable, path : %s", pwm_dev);
+               return -EIO;
+       }
+       result = atoi(pwm_buf);
+       *enable = !!result;
+       close(fd);
+
+       return 0;
+}
+
diff --git a/src/interface/spi.c b/src/interface/spi.c
new file mode 100644 (file)
index 0000000..1016a9e
--- /dev/null
@@ -0,0 +1,239 @@
+/*
+ * 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 <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <sys/ioctl.h>
+#include <linux/spi/spidev.h>
+
+#include "spi.h"
+#include "peripheral_common.h"
+
+#define SYSFS_SPI_DIR "/dev/spidev"
+#define SYSFS_SPI_BUFSIZ "/sys/module/spidev/parameters/bufsiz"
+#define SPI_BUFFER_MAX 64
+#define MAX_ERR_LEN 255
+
+int spi_open(int bus, int cs, int *fd)
+{
+       int new_fd = 0;
+       char spi_dev[SPI_BUFFER_MAX] = {0,};
+
+       _D("bus : %d, cs : %d", bus, cs);
+
+       snprintf(spi_dev, sizeof(spi_dev)-1, SYSFS_SPI_DIR"%d.%d", bus, cs);
+
+       new_fd = open(spi_dev, O_RDWR);
+       if (new_fd < 0) {
+               char errmsg[MAX_ERR_LEN];
+               strerror_r(errno, errmsg, MAX_ERR_LEN);
+               _E("Can't Open %s, errmsg : %s", spi_dev, errmsg);
+               return -ENXIO;
+       }
+       _D("fd : %d", new_fd);
+       *fd = new_fd;
+
+       return 0;
+}
+
+int spi_close(int fd)
+{
+       int status;
+
+       _D("fd : %d", fd);
+       RETVM_IF(fd < 0, -EINVAL, "Invalid fd");
+
+       status = close(fd);
+       if (status < 0) {
+               char errmsg[MAX_ERR_LEN];
+               strerror_r(errno, errmsg, MAX_ERR_LEN);
+               _E("Failed to close fd : %d", fd);
+               return -EIO;
+       }
+
+       return 0;
+}
+
+int spi_set_mode(int fd, unsigned char mode)
+{
+       int status;
+
+       _D("fd : %d, mode : %d", fd, mode);
+       RETVM_IF(fd < 0, -EINVAL, "Invalid fd");
+
+       status = ioctl(fd, SPI_IOC_WR_MODE, &mode);
+       if (status < 0) {
+               char errmsg[MAX_ERR_LEN];
+               strerror_r(errno, errmsg, MAX_ERR_LEN);
+               _E("Failed to set mode(%d) : %s", mode, errmsg);
+               return -EIO;
+       }
+
+       return 0;
+}
+
+int spi_set_bit_order(int fd, unsigned char lsb)
+{
+       int status;
+
+       _D("fd : %d, lsb : %d", fd, lsb);
+       RETVM_IF(fd < 0, -EINVAL, "Invalid fd");
+
+       status = ioctl(fd, SPI_IOC_WR_LSB_FIRST, &lsb);
+       if (status < 0) {
+               char errmsg[MAX_ERR_LEN];
+               strerror_r(errno, errmsg, MAX_ERR_LEN);
+               _E("Failed to set lsb first(%d), fd : %d, errmsg : %s", lsb, fd, errmsg);
+               return -EIO;
+       }
+
+       return 0;
+}
+
+int spi_set_bits_per_word(int fd, unsigned char bits)
+{
+       int status;
+
+       _D("fd : %d, bits : %d", fd, bits);
+       RETVM_IF(fd < 0, -EINVAL, "Invalid fd");
+
+       status = ioctl(fd, SPI_IOC_WR_BITS_PER_WORD, &bits);
+       if (status < 0) {
+               char errmsg[MAX_ERR_LEN];
+               strerror_r(errno, errmsg, MAX_ERR_LEN);
+               _E("Failed to set bits(%d), fd : %d, errmsg : %s", bits, fd, errmsg);
+               return -EIO;
+       }
+
+       return 0;
+}
+
+int spi_set_frequency(int fd, unsigned int freq)
+{
+       int status;
+
+       _D("fd : %d, freq : %d", fd, freq);
+       RETVM_IF(fd < 0, -EINVAL, "Invalid fd");
+
+       status = ioctl(fd, SPI_IOC_WR_MAX_SPEED_HZ, &freq);
+       if (status < 0) {
+               char errmsg[MAX_ERR_LEN];
+               strerror_r(errno, errmsg, MAX_ERR_LEN);
+               _E("Failed to set frequency(%d), fd : %d, errmsg : %s", freq, fd, errmsg);
+               return -EIO;
+       }
+
+       return 0;
+}
+
+int spi_get_buffer_size(int *bufsiz)
+{
+       int fd, result, status;
+       char spi_buf[SPI_BUFFER_MAX] = {0,};
+
+       fd = open(SYSFS_SPI_BUFSIZ, O_RDONLY);
+       if (fd < 0) {
+               char errmsg[MAX_ERR_LEN];
+               strerror_r(errno, errmsg, MAX_ERR_LEN);
+               _E("Can't Open %s, errmsg : %s", SYSFS_SPI_BUFSIZ, errmsg);
+               return -ENXIO;
+       }
+
+       status = read(fd, spi_buf, SPI_BUFFER_MAX);
+       if (status < 0) {
+               _E("Failed to get buffer size, path : %s", SYSFS_SPI_BUFSIZ);
+               close(fd);
+               return -EIO;
+       }
+       result = atoi(spi_buf);
+       *bufsiz = result;
+       close(fd);
+
+       return 0;
+}
+
+int spi_read(int fd, unsigned char *rxbuf, int length)
+{
+       int status;
+       struct spi_ioc_transfer xfer;
+
+       RETVM_IF(fd < 0, -EINVAL, "Invalid fd : %d", fd);
+
+       memset(&xfer, 0, sizeof(struct spi_ioc_transfer));
+       xfer.rx_buf = (unsigned long)rxbuf;
+       xfer.len = length;
+
+       status = ioctl(fd, SPI_IOC_MESSAGE(1), &xfer);
+       if (status < 0) {
+               char errmsg[MAX_ERR_LEN];
+               strerror_r(errno, errmsg, MAX_ERR_LEN);
+               _E("Failed to read data, fd : %d, length : %d, errmsg : %s", fd, length, errmsg);
+               return -EIO;
+       }
+
+       return 0;
+}
+
+int spi_write(int fd, unsigned char *txbuf, int length)
+{
+       int status;
+       struct spi_ioc_transfer xfer;
+
+       RETVM_IF(fd < 0, -EINVAL, "Invalid fd : %d", fd);
+
+       memset(&xfer, 0, sizeof(struct spi_ioc_transfer));
+       xfer.tx_buf = (unsigned long)txbuf;
+       xfer.len = length;
+
+       status = ioctl(fd, SPI_IOC_MESSAGE(1), &xfer);
+       if (status < 0) {
+               char errmsg[MAX_ERR_LEN];
+               strerror_r(errno, errmsg, MAX_ERR_LEN);
+               _E("Failed to write data(%d) : %s", length, errmsg);
+               return -EIO;
+       }
+
+       return 0;
+}
+
+int spi_transfer(int fd, unsigned char *txbuf, unsigned char *rxbuf, int length)
+{
+       int status;
+       struct spi_ioc_transfer xfer;
+
+       RETVM_IF(fd < 0, -EINVAL, "Invalid fd : %d", fd);
+
+       if (!txbuf || !rxbuf || length < 0) return -EINVAL;
+
+       memset(&xfer, 0, sizeof(xfer));
+       xfer.tx_buf = (unsigned long)txbuf;
+       xfer.rx_buf = (unsigned long)rxbuf;
+       xfer.len = length;
+
+       status = ioctl(fd, SPI_IOC_MESSAGE(1), &xfer);
+       if (status < 0) {
+               char errmsg[MAX_ERR_LEN];
+               strerror_r(errno, errmsg, MAX_ERR_LEN);
+               _E("Failed to exchange data(%d) : %s", length, errmsg);
+               return -EIO;
+       }
+
+       return 0;
+}
diff --git a/src/interface/uart.c b/src/interface/uart.c
new file mode 100644 (file)
index 0000000..34ff11e
--- /dev/null
@@ -0,0 +1,465 @@
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * 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 <string.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <termios.h>
+#include <stdbool.h>
+#include <sys/ioctl.h>
+
+#include "uart.h"
+#include "peripheral_common.h"
+
+#define PATH_BUF_MAX           64
+#define UART_BUF_MAX           16
+
+#define UART_BAUDRATE_SIZE     19
+
+#ifndef ARRAY_SIZE
+#define ARRAY_SIZE(x) (sizeof(x)/sizeof((x)[0]))
+#endif
+#define MAX_ERR_LEN 128
+
+char *sysfs_uart_path[] = {
+       "/dev/ttyS",
+       "/dev/ttyAMA",
+       "/dev/ttySAC",
+};
+
+static const int peripheral_uart_br[UART_BAUDRATE_SIZE] = {
+       B0,                     B50,            B75,            B110,           B134,
+       B150,           B200,           B300,           B600,           B1200,
+       B1800,          B2400,          B4800,          B9600,          B19200,
+       B38400,         B57600,         B115200,        B230400
+};
+
+static const int byteinfo[4] = {CS5, CS6, CS7, CS8};
+
+int uart_open(int port, int *file_hndl)
+{
+       int i, fd;
+       char uart_dev[PATH_BUF_MAX] = {0};
+
+       _D("port : %d", port);
+
+       for (i = 0; i < ARRAY_SIZE(sysfs_uart_path); i++) {
+               snprintf(uart_dev, PATH_BUF_MAX, "%s%d", sysfs_uart_path[i], port);
+               if (access(uart_dev, F_OK) == 0)
+                       break;
+       }
+       _D("uart_dev : %s", uart_dev);
+       if ((fd = open(uart_dev, O_RDWR | O_NOCTTY | O_NONBLOCK)) < 0) {
+               char errmsg[MAX_ERR_LEN];
+               strerror_r(errno, errmsg, MAX_ERR_LEN);
+               _E("can't open %s, errmsg : %s", uart_dev, errmsg);
+               return -ENXIO;
+       }
+       *file_hndl = fd;
+       return 0;
+}
+
+int uart_close(int file_hndl)
+{
+       int status;
+
+       _D("file_hndl : %d", file_hndl);
+
+       if (file_hndl < 0) {
+               _E("Invalid NULL parameter");
+               return -EINVAL;
+       }
+
+       status = uart_flush(file_hndl);
+       if (status < 0) {
+               char errmsg[MAX_ERR_LEN];
+               strerror_r(errno, errmsg, MAX_ERR_LEN);
+               _E("Failed to close fd : %d, errmsg : %s", file_hndl, errmsg);
+               return -EIO;
+       }
+
+       status = close(file_hndl);
+       if (status < 0) {
+               char errmsg[MAX_ERR_LEN];
+               strerror_r(errno, errmsg, MAX_ERR_LEN);
+               _E("Failed to close fd : %d, errmsg : %s", file_hndl, errmsg);
+               return -EIO;
+       }
+
+       return 0;
+}
+
+int uart_flush(int file_hndl)
+{
+       int ret;
+
+       if (!file_hndl) {
+               _E("Invalid NULL parameter");
+               return -EINVAL;
+       }
+
+       ret = tcflush(file_hndl, TCIOFLUSH);
+       if (ret < 0) {
+               char errmsg[MAX_ERR_LEN];
+               strerror_r(errno, errmsg, MAX_ERR_LEN);
+               _E("tcflush failed, errmsg : %s", errmsg);
+               return -1;
+       }
+
+       return 0;
+}
+
+int uart_set_baud_rate(int file_hndl, uart_baud_rate_e baud)
+{
+       int ret;
+       struct termios tio;
+
+       _D("file_hndl : %d, baud : %d", file_hndl, baud);
+
+       memset(&tio, 0, sizeof(tio));
+       if (!file_hndl) {
+               _E("Invalid NULL parameter");
+               return -EINVAL;
+       }
+
+       if (baud > UART_BAUD_RATE_230400) {
+               _E("Invalid parameter");
+               return -EINVAL;
+       }
+
+       ret = tcgetattr(file_hndl, &tio);
+       if (ret) {
+               char errmsg[MAX_ERR_LEN];
+               strerror_r(errno, errmsg, MAX_ERR_LEN);
+               _E("tcgetattr failed, errmsg : %s", errmsg);
+               return -1;
+       }
+       tio.c_cflag = peripheral_uart_br[baud];
+       tio.c_iflag = IGNPAR;
+       tio.c_oflag = 0;
+       tio.c_lflag = 0;
+       tio.c_cc[VMIN] = 1;
+       tio.c_cc[VTIME] = 0;
+
+       uart_flush(file_hndl);
+       ret = tcsetattr(file_hndl, TCSANOW, &tio);
+       if (ret) {
+               char errmsg[MAX_ERR_LEN];
+               strerror_r(errno, errmsg, MAX_ERR_LEN);
+               _E("tcsetattr failed, errmsg: %s", errmsg);
+               return -1;
+       }
+
+       return 0;
+}
+
+int uart_set_mode(int file_hndl, uart_byte_size_e byte_size, uart_parity_e parity, uart_stop_bits_e stop_bits)
+{
+       int ret;
+       struct termios tio;
+
+       _D("file_hndl : %d, bytesize : %d, parity : %d, stopbits : %d", file_hndl, byte_size, parity, stop_bits);
+
+       if (!file_hndl) {
+               _E("Invalid NULL parameter");
+               return -EINVAL;
+       }
+
+       if (byte_size > UART_BYTE_SIZE_8BIT) {
+               _E("Invalid bytesize parameter");
+               return -EINVAL;
+       }
+
+       ret = tcgetattr(file_hndl, &tio);
+       if (ret) {
+               char errmsg[MAX_ERR_LEN];
+               strerror_r(errno, errmsg, MAX_ERR_LEN);
+               _E("tcgetattr failed, errmsg: %s", errmsg);
+               return -1;
+       }
+
+       /* set byte size */
+       tio.c_cflag &= ~CSIZE;
+       tio.c_cflag |= byteinfo[byte_size];
+       tio.c_cflag |= (CLOCAL | CREAD);
+
+       /* set parity info */
+       switch (parity) {
+       case UART_PARITY_EVEN:
+               tio.c_cflag |= PARENB;
+               tio.c_cflag &= ~PARODD;
+               break;
+       case UART_PARITY_ODD:
+               tio.c_cflag |= PARENB;
+               tio.c_cflag |= PARODD;
+               break;
+       case UART_PARITY_NONE:
+       default:
+               tio.c_cflag &= ~PARENB;
+               tio.c_cflag &= ~PARODD;
+               break;
+       }
+
+       /* set stop bit */
+       switch (stop_bits) {
+       case UART_STOP_BITS_1BIT:
+               tio.c_cflag &= ~CSTOPB;
+               break;
+       case UART_STOP_BITS_2BIT:
+               tio.c_cflag |= CSTOPB;
+               break;
+       default:
+               _E("Invalid parameter stop_bits");
+               return -EINVAL;
+       }
+
+       uart_flush(file_hndl);
+       ret = tcsetattr(file_hndl, TCSANOW, &tio);
+       if (ret) {
+               char errmsg[MAX_ERR_LEN];
+               strerror_r(errno, errmsg, MAX_ERR_LEN);
+               _E("tcsetattr failed, errmsg : %s", errmsg);
+               return -1;
+       }
+
+       return 0;
+}
+
+int uart_set_byte_size(int file_hndl, uart_byte_size_e byte_size)
+{
+       int ret;
+       struct termios tio;
+
+       _D("file_hndl : %d, bytesize : %d", file_hndl, byte_size);
+
+       if (!file_hndl) {
+               _E("Invalid NULL parameter");
+               return -EINVAL;
+       }
+
+       if (byte_size > UART_BYTE_SIZE_8BIT) {
+               _E("Invalid bytesize parameter");
+               return -EINVAL;
+       }
+
+       ret = tcgetattr(file_hndl, &tio);
+       if (ret) {
+               char errmsg[MAX_ERR_LEN];
+               strerror_r(errno, errmsg, MAX_ERR_LEN);
+               _E("tcgetattr failed, errmsg: %s", errmsg);
+               return -1;
+       }
+
+       /* set byte size */
+       tio.c_cflag &= ~CSIZE;
+       tio.c_cflag |= byteinfo[byte_size];
+       tio.c_cflag |= (CLOCAL | CREAD);
+
+       uart_flush(file_hndl);
+       ret = tcsetattr(file_hndl, TCSANOW, &tio);
+       if (ret) {
+               char errmsg[MAX_ERR_LEN];
+               strerror_r(errno, errmsg, MAX_ERR_LEN);
+               _E("tcsetattr failed, errmsg : %s", errmsg);
+               return -1;
+       }
+
+       return 0;
+}
+
+int uart_set_parity(int file_hndl, uart_parity_e parity)
+{
+       int ret;
+       struct termios tio;
+
+       _D("file_hndl : %d, parity : %d", file_hndl, parity);
+
+       if (!file_hndl) {
+               _E("Invalid NULL parameter");
+               return -EINVAL;
+       }
+
+       ret = tcgetattr(file_hndl, &tio);
+       if (ret) {
+               char errmsg[MAX_ERR_LEN];
+               strerror_r(errno, errmsg, MAX_ERR_LEN);
+               _E("tcgetattr failed, errmsg: %s", errmsg);
+               return -1;
+       }
+
+       /* set parity info */
+       switch (parity) {
+       case UART_PARITY_EVEN:
+               tio.c_cflag |= PARENB;
+               tio.c_cflag &= ~PARODD;
+               break;
+       case UART_PARITY_ODD:
+               tio.c_cflag |= PARENB;
+               tio.c_cflag |= PARODD;
+               break;
+       case UART_PARITY_NONE:
+       default:
+               tio.c_cflag &= ~PARENB;
+               tio.c_cflag &= ~PARODD;
+               break;
+       }
+
+       uart_flush(file_hndl);
+       ret = tcsetattr(file_hndl, TCSANOW, &tio);
+       if (ret) {
+               char errmsg[MAX_ERR_LEN];
+               strerror_r(errno, errmsg, MAX_ERR_LEN);
+               _E("tcsetattr failed, errmsg : %s", errmsg);
+               return -1;
+       }
+
+       return 0;
+}
+
+int uart_set_stop_bits(int file_hndl, uart_stop_bits_e stop_bits)
+{
+       int ret;
+       struct termios tio;
+
+       _D("file_hndl : %d, stopbits : %d", file_hndl, stop_bits);
+
+       if (!file_hndl) {
+               _E("Invalid NULL parameter");
+               return -EINVAL;
+       }
+
+       ret = tcgetattr(file_hndl, &tio);
+       if (ret) {
+               char errmsg[MAX_ERR_LEN];
+               strerror_r(errno, errmsg, MAX_ERR_LEN);
+               _E("tcgetattr failed, errmsg: %s", errmsg);
+               return -1;
+       }
+
+       /* set stop bit */
+       switch (stop_bits) {
+       case UART_STOP_BITS_1BIT:
+               tio.c_cflag &= ~CSTOPB;
+               break;
+       case UART_STOP_BITS_2BIT:
+               tio.c_cflag |= CSTOPB;
+               break;
+       default:
+               _E("Invalid parameter stop_bits");
+               return -EINVAL;
+       }
+
+       uart_flush(file_hndl);
+       ret = tcsetattr(file_hndl, TCSANOW, &tio);
+       if (ret) {
+               char errmsg[MAX_ERR_LEN];
+               strerror_r(errno, errmsg, MAX_ERR_LEN);
+               _E("tcsetattr failed, errmsg : %s", errmsg);
+               return -1;
+       }
+
+       return 0;
+}
+
+int uart_set_flow_control(int file_hndl, bool xonxoff, bool rtscts)
+{
+       int ret;
+       struct termios tio;
+
+       _D("file_hndl : %d, xonxoff : %d, rtscts : %d", file_hndl, xonxoff, rtscts);
+
+       if (!file_hndl) {
+               _E("Invalid NULL parameter");
+               return -EINVAL;
+       }
+
+       ret = tcgetattr(file_hndl, &tio);
+       if (ret) {
+               char errmsg[MAX_ERR_LEN];
+               strerror_r(errno, errmsg, MAX_ERR_LEN);
+               _E("tcgetattr failed, errmsg : %s", errmsg);
+               return -1;
+       }
+
+       /* rtscts => 1: rts/cts on, 0: off */
+       if (rtscts)
+               tio.c_cflag |= CRTSCTS;
+       else
+               tio.c_cflag &= ~CRTSCTS;
+
+       /* xonxoff => 1: xon/xoff on, 0: off */
+       if (xonxoff)
+               tio.c_iflag |= (IXON | IXOFF | IXANY);
+       else
+               tio.c_iflag &= ~(IXON | IXOFF | IXANY);
+
+       ret = tcsetattr(file_hndl, TCSANOW, &tio);
+       if (ret) {
+               char errmsg[MAX_ERR_LEN];
+               strerror_r(errno, errmsg, MAX_ERR_LEN);
+               _E("tcsetattr failed, errmsg : %s", errmsg);
+               return -1;
+       }
+
+       return 0;
+}
+
+int uart_read(int file_hndl, uint8_t *buf, unsigned int length)
+{
+       int ret;
+
+       if (!file_hndl) {
+               _E("Invalid NULL parameter");
+               return -EINVAL;
+       }
+
+       ret = read(file_hndl, (void *)buf, length);
+       if (ret <= 0) {
+               if (errno == EAGAIN)
+                       return -EAGAIN;
+               char errmsg[MAX_ERR_LEN];
+               strerror_r(errno, errmsg, MAX_ERR_LEN);
+               _E("read failed, errmsg : %s", errmsg);
+               return -EIO;
+       }
+
+       return ret;
+}
+
+int uart_write(int file_hndl, uint8_t *buf, unsigned int length)
+{
+       int ret;
+
+       if (!file_hndl) {
+               _E("Invalid NULL parameter");
+               return -EINVAL;
+       }
+
+       ret = write(file_hndl, buf, length);
+       if (ret <= 0) {
+               if (errno == EAGAIN)
+                       return -EAGAIN;
+               char errmsg[MAX_ERR_LEN];
+               strerror_r(errno, errmsg, MAX_ERR_LEN);
+               _E("write failed, errmsg : %s", errmsg);
+               return -EIO;
+       }
+
+       return ret;
+}