Remove unnecessary condition check in uart.c
[platform/core/system/peripheral-bus.git] / src / interface / uart.c
1 /*
2  * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 #include <stdio.h>
18 #include <stdlib.h>
19 #include <string.h>
20 #include <errno.h>
21 #include <fcntl.h>
22 #include <unistd.h>
23 #include <termios.h>
24 #include <stdbool.h>
25 #include <sys/ioctl.h>
26
27 #include "uart.h"
28 #include "peripheral_common.h"
29
30 #define PATH_BUF_MAX            64
31 #define UART_BUF_MAX            16
32
33 #define UART_BAUDRATE_SIZE      19
34
35 #ifndef ARRAY_SIZE
36 #define ARRAY_SIZE(x) (sizeof(x)/sizeof((x)[0]))
37 #endif
38 #define MAX_ERR_LEN 128
39
40 char *sysfs_uart_path[] = {
41         "/dev/ttyS",
42         "/dev/ttyAMA",
43         "/dev/ttySAC",
44 };
45
46 static const int peripheral_uart_br[UART_BAUDRATE_SIZE] = {
47         B0,                     B50,            B75,            B110,           B134,
48         B150,           B200,           B300,           B600,           B1200,
49         B1800,          B2400,          B4800,          B9600,          B19200,
50         B38400,         B57600,         B115200,        B230400
51 };
52
53 static const int byteinfo[4] = {CS5, CS6, CS7, CS8};
54
55 int uart_open(int port, int *file_hndl)
56 {
57         int i, fd;
58         char uart_dev[PATH_BUF_MAX] = {0};
59
60         _D("port : %d", port);
61
62         for (i = 0; i < ARRAY_SIZE(sysfs_uart_path); i++) {
63                 snprintf(uart_dev, PATH_BUF_MAX, "%s%d", sysfs_uart_path[i], port);
64                 if (access(uart_dev, F_OK) == 0)
65                         break;
66         }
67         _D("uart_dev : %s", uart_dev);
68         if ((fd = open(uart_dev, O_RDWR | O_NOCTTY | O_NONBLOCK)) < 0) {
69                 char errmsg[MAX_ERR_LEN];
70                 strerror_r(errno, errmsg, MAX_ERR_LEN);
71                 _E("can't open %s, errmsg : %s", uart_dev, errmsg);
72                 return -ENXIO;
73         }
74         *file_hndl = fd;
75         return 0;
76 }
77
78 int uart_close(int file_hndl)
79 {
80         _D("file_hndl : %d", file_hndl);
81
82         if (!file_hndl) {
83                 _E("Invalid NULL parameter");
84                 return -EINVAL;
85         }
86         close(file_hndl);
87         return 0;
88 }
89
90 int uart_flush(int file_hndl)
91 {
92         int ret;
93
94         if (!file_hndl) {
95                 _E("Invalid NULL parameter");
96                 return -EINVAL;
97         }
98
99         ret = tcflush(file_hndl, TCIOFLUSH);
100         if (ret < 0) {
101                 char errmsg[MAX_ERR_LEN];
102                 strerror_r(errno, errmsg, MAX_ERR_LEN);
103                 _E("tcflush failed, errmsg : %s", errmsg);
104                 return -1;
105         }
106
107         return 0;
108 }
109
110 int uart_set_baudrate(int file_hndl, uart_baudrate_e baud)
111 {
112         int ret;
113         struct termios tio;
114
115         _D("file_hndl : %d, baud : %d", file_hndl, baud);
116
117         memset(&tio, 0, sizeof(tio));
118         if (!file_hndl) {
119                 _E("Invalid NULL parameter");
120                 return -EINVAL;
121         }
122
123         if (baud > UART_BAUDRATE_230400) {
124                 _E("Invalid parameter");
125                 return -EINVAL;
126         }
127
128         ret = tcgetattr(file_hndl, &tio);
129         if (ret) {
130                 char errmsg[MAX_ERR_LEN];
131                 strerror_r(errno, errmsg, MAX_ERR_LEN);
132                 _E("tcgetattr failed, errmsg : %s", errmsg);
133                 return -1;
134         }
135         tio.c_cflag = peripheral_uart_br[baud];
136         tio.c_iflag = IGNPAR;
137         tio.c_oflag = 0;
138         tio.c_lflag = 0;
139         tio.c_cc[VMIN] = 1;
140         tio.c_cc[VTIME] = 0;
141
142         uart_flush(file_hndl);
143         ret = tcsetattr(file_hndl, TCSANOW, &tio);
144         if (ret) {
145                 char errmsg[MAX_ERR_LEN];
146                 strerror_r(errno, errmsg, MAX_ERR_LEN);
147                 _E("tcsetattr failed, errmsg: %s", errmsg);
148                 return -1;
149         }
150
151         return 0;
152 }
153
154 int uart_set_mode(int file_hndl, uart_bytesize_e bytesize, uart_parity_e parity, uart_stopbits_e stopbits)
155 {
156         int ret;
157         struct termios tio;
158
159         _D("file_hndl : %d, bytesize : %d, parity : %d, stopbits : %d", file_hndl, bytesize, parity, stopbits);
160
161         if (!file_hndl) {
162                 _E("Invalid NULL parameter");
163                 return -EINVAL;
164         }
165
166         if (bytesize > UART_BYTESIZE_8BIT) {
167                 _E("Invalid bytesize parameter");
168                 return -EINVAL;
169         }
170
171         ret = tcgetattr(file_hndl, &tio);
172         if (ret) {
173                 char errmsg[MAX_ERR_LEN];
174                 strerror_r(errno, errmsg, MAX_ERR_LEN);
175                 _E("tcgetattr failed, errmsg: %s", errmsg);
176                 return -1;
177         }
178
179         /* set byte size */
180         tio.c_cflag &= ~CSIZE;
181         tio.c_cflag |= byteinfo[bytesize];
182         tio.c_cflag |= (CLOCAL | CREAD);
183
184         /* set parity info */
185         switch (parity) {
186         case UART_PARITY_EVEN:
187                 tio.c_cflag |= PARENB;
188                 tio.c_cflag &= ~PARODD;
189                 break;
190         case UART_PARITY_ODD:
191                 tio.c_cflag |= PARENB;
192                 tio.c_cflag |= PARODD;
193                 break;
194         case UART_PARITY_NONE:
195         default:
196                 tio.c_cflag &= ~PARENB;
197                 tio.c_cflag &= ~PARODD;
198                 break;
199         }
200
201         /* set stop bit */
202         switch (stopbits) {
203         case UART_STOPBITS_1BIT:
204                 tio.c_cflag &= ~CSTOPB;
205                 break;
206         case UART_STOPBITS_2BIT:
207                 tio.c_cflag |= CSTOPB;
208                 break;
209         default:
210                 _E("Invalid parameter stopbits");
211                 return -EINVAL;
212         }
213
214         uart_flush(file_hndl);
215         ret = tcsetattr(file_hndl, TCSANOW, &tio);
216         if (ret) {
217                 char errmsg[MAX_ERR_LEN];
218                 strerror_r(errno, errmsg, MAX_ERR_LEN);
219                 _E("tcsetattr failed, errmsg : %s", errmsg);
220                 return -1;
221         }
222
223         return 0;
224 }
225
226 int uart_set_flowcontrol(int file_hndl, bool xonxoff, bool rtscts)
227 {
228         int ret;
229         struct termios tio;
230
231         _D("file_hndl : %d, xonxoff : %d, rtscts : %d", file_hndl, xonxoff, rtscts);
232
233         if (!file_hndl) {
234                 _E("Invalid NULL parameter");
235                 return -EINVAL;
236         }
237
238         ret = tcgetattr(file_hndl, &tio);
239         if (ret) {
240                 char errmsg[MAX_ERR_LEN];
241                 strerror_r(errno, errmsg, MAX_ERR_LEN);
242                 _E("tcgetattr failed, errmsg : %s", errmsg);
243                 return -1;
244         }
245
246         /* rtscts => 1: rts/cts on, 0: off */
247         if (rtscts)
248                 tio.c_cflag |= CRTSCTS;
249         else
250                 tio.c_cflag &= ~CRTSCTS;
251
252         /* xonxoff => 1: xon/xoff on, 0: off */
253         if (xonxoff)
254                 tio.c_iflag |= (IXON | IXOFF | IXANY);
255         else
256                 tio.c_iflag &= ~(IXON | IXOFF | IXANY);
257
258         ret = tcsetattr(file_hndl, TCSANOW, &tio);
259         if (ret) {
260                 char errmsg[MAX_ERR_LEN];
261                 strerror_r(errno, errmsg, MAX_ERR_LEN);
262                 _E("tcsetattr failed, errmsg : %s", errmsg);
263                 return -1;
264         }
265
266         return 0;
267 }
268
269 int uart_read(int file_hndl, uint8_t *buf, unsigned int length)
270 {
271         int ret;
272
273         if (!file_hndl) {
274                 _E("Invalid NULL parameter");
275                 return -EINVAL;
276         }
277
278         ret = read(file_hndl, (void *)buf, length);
279         if ((errno != EAGAIN && errno != EINTR) && ret < 0) {
280                 char errmsg[MAX_ERR_LEN];
281                 strerror_r(errno, errmsg, MAX_ERR_LEN);
282                 _E("read failed, errmsg : %s", errmsg);
283                 return -EIO;
284         }
285
286         return ret;
287 }
288
289 int uart_write(int file_hndl, uint8_t *buf, unsigned int length)
290 {
291         int ret;
292
293         if (!file_hndl) {
294                 _E("Invalid NULL parameter");
295                 return -EINVAL;
296         }
297
298         ret = write(file_hndl, buf, length);
299         if (ret < 0) {
300                 char errmsg[MAX_ERR_LEN];
301                 strerror_r(errno, errmsg, MAX_ERR_LEN);
302                 _E("write failed, errmsg : %s", errmsg);
303                 return -EIO;
304         }
305
306         return ret;
307 }