--- /dev/null
+/*
+ * 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;
+}
--- /dev/null
+/*
+ * 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;
+}
--- /dev/null
+/*
+ * 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__*/
--- /dev/null
+/*
+ * 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__ */
--- /dev/null
+/*
+ * 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__ */
--- /dev/null
+/*
+ * 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__ */
--- /dev/null
+/*
+ * 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__ */
+
--- /dev/null
+/*
+ * 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;
+}
+
--- /dev/null
+/*
+ * 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;
+}
--- /dev/null
+/*
+ * 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;
+}