4 * Copyright (c) 2012 Samsung Electronics Co., Ltd. All rights reserved.
\r
6 * Contact: Junhwan An <jh48.an@samsung.com>
\r
8 * Licensed under the Apache License, Version 2.0 (the "License");
\r
9 * you may not use this file except in compliance with the License.
\r
10 * You may obtain a copy of the License at
\r
12 * http://www.apache.org/licenses/LICENSE-2.0
\r
14 * Unless required by applicable law or agreed to in writing, software
\r
15 * distributed under the License is distributed on an "AS IS" BASIS,
\r
16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
\r
17 * See the License for the specific language governing permissions and
\r
18 * limitations under the License.
\r
24 #include <termios.h>
\r
26 #include <sys/time.h>
\r
27 #include <sys/mman.h>
\r
30 #include <sys/ioctl.h>
\r
33 #include "legacy/TelUtility.h"
\r
35 #include "vdpram_dump.h"
\r
39 # define TIOCMODG TIOCMGET
\r
42 # define TIOCMODG MCGETA
\r
49 # define TIOCMODS TIOCMSET
\r
52 # define TIOCMODS MCSETA
\r
57 typedef struct _tty_old_setting_t{
\r
59 struct termios termiosVal;
\r
60 struct _tty_old_setting_t *next;
\r
61 struct _tty_old_setting_t *prev;
\r
62 } tty_old_setting_t;
\r
64 #define VDPRAM_OPEN_PATH "/dev/dpram/0"
\r
66 /* DPRAM ioctls for DPRAM tty devices */
\r
67 #define IOC_MZ_MAGIC ('h')
\r
68 #define HN_DPRAM_PHONE_ON _IO (IOC_MZ_MAGIC, 0xd0)
\r
69 #define HN_DPRAM_PHONE_OFF _IO (IOC_MZ_MAGIC, 0xd1)
\r
70 #define HN_DPRAM_PHONE_GETSTATUS _IOR(IOC_MZ_MAGIC, 0xd2, unsigned int)
\r
72 static tty_old_setting_t *ttyold_head = NULL;
\r
74 /* static functions */
\r
75 static void __insert_tty_oldsetting(tty_old_setting_t *me)
\r
77 dbg("Function Enterence.");
\r
83 ttyold_head->prev = me;
\r
85 me->next = ttyold_head;
\r
90 static tty_old_setting_t *__search_tty_oldsetting(int fd)
\r
92 tty_old_setting_t *tty = NULL;
\r
94 dbg("Function Enterence.");
\r
96 if (ttyold_head == NULL)
\r
102 if (tty->fd == fd) {
\r
103 dbg("oldsetting for inputted fd is found");
\r
107 if (tty->next == NULL) {
\r
108 dbg("No oldsetting is found");
\r
119 static void __remove_tty_oldsetting(tty_old_setting_t *me)
\r
121 dbg( "Function Enterence.");
\r
127 me->prev->next = me->next;
\r
129 ttyold_head = me->next;
\r
132 me->next->prev = me->prev;
\r
135 /* Set hardware flow control.
\r
137 static void __tty_sethwf(int fd, int on)
\r
139 struct termios tty;
\r
141 dbg("Function Enterence.");
\r
143 if (tcgetattr(fd, &tty))
\r
144 err("__tty_sethwf: tcgetattr:");
\r
147 tty.c_cflag |= CRTSCTS;
\r
149 tty.c_cflag &= ~CRTSCTS;
\r
151 if (tcsetattr(fd, TCSANOW, &tty))
\r
152 err("__tty_sethwf: tcsetattr:");
\r
156 * Set RTS line. Sometimes dropped. Linux specific?
\r
158 static int __tty_setrts(int fd)
\r
162 dbg("Function Enterence.");
\r
164 if (-1 == ioctl(fd, TIOCMODG, &mcs))
\r
165 err("icotl: TIOCMODG");
\r
169 if (-1 == ioctl(fd, TIOCMODS, &mcs))
\r
170 err("icotl: TIOCMODS");
\r
176 * Set baudrate, parity and number of bits.
\r
178 static int __tty_setparms(int fd, char* baudr, char* par, char* bits, char* stop, int hwf, int swf)
\r
183 int stop_bit = stop[0];
\r
185 struct termios tty;
\r
186 tty_old_setting_t *old_setting = NULL;
\r
188 dbg("Function Enterence.");
\r
190 old_setting = calloc(sizeof(tty_old_setting_t), 1);
\r
192 if (old_setting == NULL)
\r
193 return TAPI_API_SYSTEM_OUT_OF_MEM;
\r
195 old_setting->fd = fd;
\r
197 if (tcgetattr(fd, &tty) < 0) {
\r
199 return TAPI_API_TRANSPORT_LAYER_FAILURE;
\r
202 if (tcgetattr(fd, &old_setting->termiosVal) < 0) {
\r
204 return TAPI_API_TRANSPORT_LAYER_FAILURE;
\r
207 __insert_tty_oldsetting(old_setting);
\r
211 /* We generate mark and space parity ourself. */
\r
212 if (bit == '7' && (par[0] == 'M' || par[0] == 'S'))
\r
215 /* Check if 'baudr' is really a number */
\r
216 if ((newbaud = (atol(baudr) / 100)) == 0 && baudr[0] != '0')
\r
266 err("invaid baud rate");
\r
271 cfsetospeed(&tty, (speed_t) spd);
\r
272 cfsetispeed(&tty, (speed_t) spd);
\r
278 tty.c_cflag = (tty.c_cflag & ~CSIZE) | CS5;
\r
282 tty.c_cflag = (tty.c_cflag & ~CSIZE) | CS6;
\r
286 tty.c_cflag = (tty.c_cflag & ~CSIZE) | CS7;
\r
291 tty.c_cflag = (tty.c_cflag & ~CSIZE) | CS8;
\r
298 tty.c_cflag &= ~CSTOPB;
\r
303 tty.c_cflag |= CSTOPB;
\r
307 /* Set into raw, no echo mode */
\r
308 tty.c_iflag = IGNBRK;
\r
311 tty.c_cflag |= CLOCAL | CREAD;
\r
312 tty.c_cc[VMIN] = 1;
\r
313 tty.c_cc[VTIME] = 1;
\r
316 tty.c_iflag |= IXON | IXOFF;
\r
318 tty.c_iflag &= ~(IXON | IXOFF | IXANY);
\r
320 tty.c_cflag &= ~(PARENB | PARODD);
\r
323 tty.c_cflag |= PARENB;
\r
324 else if (par[0] == 'O')
\r
325 tty.c_cflag |= (PARENB | PARODD);
\r
327 if (tcsetattr(fd, TCSANOW, &tty) < 0) {
\r
329 return TAPI_API_TRANSPORT_LAYER_FAILURE;
\r
333 __tty_sethwf(fd, hwf);
\r
335 return TAPI_API_SUCCESS;
\r
339 static int __tty_close(int fd)
\r
341 tty_old_setting_t *old_setting = NULL;
\r
343 dbg("Function Enterence.");
\r
345 old_setting = __search_tty_oldsetting(fd);
\r
346 if (old_setting == NULL)
\r
347 return TAPI_API_SUCCESS;
\r
349 if (tcsetattr(fd, TCSAFLUSH, &old_setting->termiosVal) < 0) {
\r
350 err("close failed");
\r
351 return TAPI_API_TRANSPORT_LAYER_FAILURE;
\r
354 __remove_tty_oldsetting(old_setting);
\r
360 return TAPI_API_SUCCESS;
\r
364 * restore the old settings before close.
\r
366 int vdpram_close(int fd)
\r
368 int ret = TAPI_API_SUCCESS;
\r
370 dbg("Function Enterence.");
\r
372 ret = __tty_close(fd);
\r
378 * Open the vdpram fd.
\r
380 int vdpram_open (void)
\r
385 unsigned int cmd =0;
\r
387 fd = open(VDPRAM_OPEN_PATH, O_RDWR);
\r
390 err("#### Failed to open vdpram file: error no hex %x", errno);
\r
394 dbg("#### Success to open vdpram file. fd:%d, path:%s", fd, VDPRAM_OPEN_PATH);
\r
397 if (__tty_setparms(fd, "115200", "N", "8", "1", 0, 0) != TAPI_API_SUCCESS) {
\r
402 dbg("#### Success set tty vdpram params. fd:%d", fd);
\r
404 /*TODO: No need to check Status. Delete*/
\r
405 cmd = HN_DPRAM_PHONE_GETSTATUS;
\r
407 if (ioctl(fd, cmd, &val) < 0) {
\r
408 err("#### ioctl failed fd:%d, cmd:%lu, val:%d", fd,cmd,val);
\r
413 dbg("#### ioctl Success fd:%d, cmd:%lu, val:%d", fd,cmd,val);
\r
420 * power on the phone.
\r
422 int vdpram_poweron(int fd)
\r
426 if (ioctl(fd, HN_DPRAM_PHONE_ON, NULL) < 0) {
\r
427 err("Phone Power On failed (fd:%d)", fd);
\r
431 dbg("Phone Power On success (fd:%d)", fd);
\r
438 * Power Off the Phone.
\r
440 int vdpram_poweroff(int fd)
\r
444 if (ioctl(fd, HN_DPRAM_PHONE_OFF, NULL) < 0) {
\r
445 err("Phone Power Off failed.");
\r
449 dbg("Phone Power Off success.");
\r
457 * Read data from vdpram.
\r
460 int vdpram_tty_read(int nFd, void* buf, size_t nbytes)
\r
464 if ((actual = read(nFd, buf, nbytes)) < 0) {
\r
465 dbg("[TRANSPORT DPRAM]read failed.");
\r
467 vdpram_hex_dump(IPC_RX, actual, buf);
\r
472 static void __selectsleep(int sec,int msec)
\r
477 select(0,NULL,NULL,NULL,&tv);
\r
482 * Write data to vdpram.
\r
484 int vdpram_tty_write(int nFd, void* buf, size_t nbytes)
\r
491 vdpram_hex_dump(IPC_TX, nbytes, buf);
\r
492 ret = write(nFd, (unsigned char* )buf, nbytes - actual);
\r
494 if ((ret < 0 && errno == EAGAIN) || (ret < 0 && errno == EBUSY)) {
\r
495 err("write failed. retry.. ret[%d] with errno[%d] ",ret, errno);
\r
496 __selectsleep(0,50);
\r
506 if (actual != nbytes)
\r
507 err("write failed.ret[%d]",ret);
\r
509 err("errno [%d]",errno);
\r
516 } while(actual < nbytes);
\r