4 * Copyright (c) 2013 Samsung Electronics Co. Ltd. All rights reserved.
\r
6 * Licensed under the Apache License, Version 2.0 (the "License");
\r
7 * you may not use this file except in compliance with the License.
\r
8 * You may obtain a copy of the License at
\r
10 * http://www.apache.org/licenses/LICENSE-2.0
\r
12 * Unless required by applicable law or agreed to in writing, software
\r
13 * distributed under the License is distributed on an "AS IS" BASIS,
\r
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
\r
15 * See the License for the specific language governing permissions and
\r
16 * limitations under the License.
\r
22 #include <termios.h>
\r
24 #include <sys/time.h>
\r
25 #include <sys/mman.h>
\r
28 #include <sys/ioctl.h>
\r
38 # define TIOCMODG TIOCMGET
\r
41 # define TIOCMODG MCGETA
\r
48 # define TIOCMODS TIOCMSET
\r
51 # define TIOCMODS MCSETA
\r
56 #define VDPRAM_OPEN_PATH "/dev/vdpram0"
\r
58 /* DPRAM ioctls for DPRAM tty devices */
\r
59 #define IOC_MZ_MAGIC ('h')
\r
60 #define HN_DPRAM_PHONE_ON _IO (IOC_MZ_MAGIC, 0xd0)
\r
61 #define HN_DPRAM_PHONE_OFF _IO (IOC_MZ_MAGIC, 0xd1)
\r
62 #define HN_DPRAM_PHONE_GETSTATUS _IOR(IOC_MZ_MAGIC, 0xd2, guint)
\r
64 /* Retry parameters */
65 #define SLEEP_TIME_IN_SEC 0
66 #define SLEEP_TIME_IN_MSEC 50
68 #define MAX_RETRY_COUNT 10
70 typedef struct tty_old_setting TtyOldSetting;
\r
72 struct tty_old_setting {
74 struct termios termiosVal;
\r
75 TtyOldSetting *next;
\r
76 TtyOldSetting *prev;
\r
79 static TtyOldSetting *ttyold_head = NULL;
\r
82 * Insert TTY old settings
84 static void __insert_tty_oldsetting(TtyOldSetting *me)
\r
92 ttyold_head->prev = me;
94 me->next = ttyold_head;
\r
100 * Search TTY old settings
102 static TtyOldSetting *__search_tty_oldsetting(gint fd)
\r
104 TtyOldSetting *tty = ttyold_head;
\r
109 if (tty->fd == fd) {
\r
110 dbg("tty for fd [%d] found!!!", fd);
120 * Remove TTY old settings
122 static void __remove_tty_oldsetting(TtyOldSetting *me)
\r
130 me->prev->next = me->next;
132 ttyold_head = me->next;
135 me->next->prev = me->prev;
139 * Set hardware flow control
141 static void __tty_sethwf(gint fd, gint on)
\r
143 struct termios tty;
\r
147 if (tcgetattr(fd, &tty))
\r
148 err("__tty_sethwf: tcgetattr:");
\r
151 tty.c_cflag |= CRTSCTS;
153 tty.c_cflag &= ~CRTSCTS;
155 if (tcsetattr(fd, TCSANOW, &tty))
\r
156 err("__tty_sethwf: tcsetattr:");
\r
160 * Set RTS line. Sometimes dropped. Linux specific?
162 static gint __tty_setrts(gint fd)
\r
168 if (-1 == ioctl(fd, TIOCMODG, &mcs))
\r
169 err("icotl: TIOCMODG");
\r
173 if (-1 == ioctl(fd, TIOCMODS, &mcs))
\r
174 err("icotl: TIOCMODS");
\r
180 * Set baudrate, parity and number of bits
182 static gboolean __tty_setparms(gint fd,
\r
183 gchar *baudr, gchar *par, gchar *bits, gchar *stop, gint hwf, gint swf)
\r
187 gint bit = bits[0];
\r
188 gint stop_bit = stop[0];
\r
190 struct termios tty;
\r
191 TtyOldSetting *old_setting = NULL;
\r
195 old_setting = g_try_new0(TtyOldSetting, 1);
197 if (old_setting == NULL)
\r
200 old_setting->fd = fd;
\r
202 if (tcgetattr(fd, &tty) < 0) {
\r
207 if (tcgetattr(fd, &old_setting->termiosVal) < 0) {
\r
212 __insert_tty_oldsetting(old_setting);
\r
216 /* We generate mark and space parity ourself. */
\r
217 if (bit == '7' && (par[0] == 'M' || par[0] == 'S'))
\r
220 /* Check if 'baudr' is really a number */
\r
221 if ((newbaud = (atol(baudr) / 100)) == 0 && baudr[0] != '0')
\r
270 err("invaid baud rate");
\r
275 cfsetospeed(&tty, (speed_t) spd);
276 cfsetispeed(&tty, (speed_t) spd);
281 tty.c_cflag = (tty.c_cflag & ~CSIZE) | CS5;
285 tty.c_cflag = (tty.c_cflag & ~CSIZE) | CS6;
289 tty.c_cflag = (tty.c_cflag & ~CSIZE) | CS7;
294 tty.c_cflag = (tty.c_cflag & ~CSIZE) | CS8;
300 tty.c_cflag &= ~CSTOPB;
305 tty.c_cflag |= CSTOPB;
309 /* Set into raw, no echo mode */
\r
310 tty.c_iflag = IGNBRK;
\r
313 tty.c_cflag |= CLOCAL | CREAD;
\r
314 tty.c_cc[VMIN] = 1;
\r
315 tty.c_cc[VTIME] = 1;
\r
318 tty.c_iflag |= IXON | IXOFF;
320 tty.c_iflag &= ~(IXON | IXOFF | IXANY);
322 tty.c_cflag &= ~(PARENB | PARODD);
\r
325 tty.c_cflag |= PARENB;
326 else if (par[0] == 'O')
\r
327 tty.c_cflag |= (PARENB | PARODD);
329 if (tcsetattr(fd, TCSANOW, &tty) < 0) {
\r
335 __tty_sethwf(fd, hwf);
\r
343 static gboolean __tty_close(gint fd)
\r
345 TtyOldSetting *old_setting = NULL;
\r
349 /* Get previous settings */
350 old_setting = __search_tty_oldsetting(fd);
\r
351 if (old_setting == NULL) {
352 dbg("No previous settings found!!!");
356 if (tcsetattr(fd, TCSAFLUSH, &old_setting->termiosVal) < 0) {
\r
361 /* Remove the previous setting configured */
362 __remove_tty_oldsetting(old_setting);
\r
376 static void __sleep(gint sec, gint msec)
383 select(0, NULL, NULL, NULL, &tv);
387 * Close the VDPRAM device
389 gboolean vdpram_close(gint fd)
\r
395 /* Close VDPRAM Device */
396 ret = __tty_close(fd);
\r
402 * Open the VDPRAM device
404 gint vdpram_open (void)
\r
413 /* Open DPRAM device */
414 fd = open(VDPRAM_OPEN_PATH, O_RDWR);
\r
416 err("Open VDPRAM file - [FAIL] Error: [%s]", strerror(errno));
419 dbg("Open VDPRAM file - [SUCCESS] fd: [%d] path: [%s]",
420 fd, VDPRAM_OPEN_PATH);
423 /* Set device parameters */
424 if (__tty_setparms(fd, "115200", "N", "8", "1", 0, 0) != TRUE) {
425 err("Set TTY device parameters - [FAIL]");
427 /* Close VDPRAM Device */
428 (void)vdpram_close(fd);
\r
432 dbg("Set TTY device parameters - [SUCCESS]");
435 /* TODO: No need to check Status. Delete */
436 cmd = HN_DPRAM_PHONE_GETSTATUS;
\r
437 if (ioctl(fd, cmd, &val) < 0) {
438 err("Get Phone status - [FAIL] fd: [d] cmd: [%d] val: [%d]",
442 (void)vdpram_close(fd);
\r
446 dbg("Get Phone status - [SUCCESS]");
455 gboolean vdpram_poweron(gint fd)
457 if (ioctl(fd, HN_DPRAM_PHONE_ON, NULL) < 0) {
\r
458 err("Phone Power ON [FAIL] - fd: [%d] Error: [%s]", fd, strerror(errno));
462 dbg("Phone Power ON [SUCCESS] - fd: [%d]", fd);
468 * Power OFF the Phone
470 gboolean vdpram_poweroff(gint fd)
472 if (ioctl(fd, HN_DPRAM_PHONE_OFF, NULL) < 0) {
\r
473 err("Phone Power OFF [FAIL] - fd: [%d] Error: [%s]", fd, strerror(errno));
477 dbg("Phone Power OFF [SUCCESS] - fd: [%d]", fd);
483 * Read data from VDPRAM
485 gint vdpram_tty_read(gint fd, void *buf, size_t buf_len)
\r
489 if ((actual = read(fd, buf, buf_len)) < 0) {
\r
490 err("Read [FAIL] - fd: [%d] Error: [%s]", fd, strerror(errno));
497 * Write data to VDPRAM
499 gint vdpram_tty_write(gint fd, void *buf, size_t buf_len)
\r
505 while(actual < buf_len) {
\r
506 /* Write to Device */
507 ret = write(fd, (guchar *)buf, buf_len - actual);
\r
509 err("Write [FAIL] - fd: [%d] Error: [%s]",
510 fd, strerror(errno));
512 if ((errno == EAGAIN) || (errno == EBUSY)) {
513 /* Sleep for 50 msecs */
514 __sleep(SLEEP_TIME_IN_SEC, SLEEP_TIME_IN_MSEC);
516 if (retry == MAX_RETRY_COUNT) {
517 err("Maximum retries completed!!!");
525 if (actual != buf_len)
526 err("Write [FAIL] - fd: [%d]", fd);
528 err("Write [FAIL] - Error: [%s]", strerror(errno));
534 dbg("Write Actual bytes: [%d] Written bytes: [%d]", actual, ret);