1 /*
2 * Copyright 2012 The Android Open Source Project
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 /******************************************************************************
18 *
19 * Filename: hci_smd.c
20 *
21 * Description: Contains vendor-specific userial functions
22 *
23 ******************************************************************************/
24
25 #define LOG_TAG "bt_vendor"
26
27 #include <log/log.h>
28 #include <termios.h>
29 #include <fcntl.h>
30 #include <errno.h>
31 #include <stdio.h>
32 #include <unistd.h>
33 #include "bt_vendor_qcom.h"
34 #include "hci_smd.h"
35 #include <string.h>
36 #include <cutils/properties.h>
37
38 /*****************************************************************************
39 ** Macros & Constants
40 *****************************************************************************/
41 #define NUM_OF_DEVS 2
42 static char *s_pszDevSmd[] = {
43 "/dev/smd3",
44 "/dev/smd2"
45 };
46
47 /******************************************************************************
48 ** Externs
49 ******************************************************************************/
50 extern int is_bt_ssr_hci;
51
52
53 /*****************************************************************************
54 ** Functions
55 *****************************************************************************/
56
bt_hci_init_transport_id(int chId)57 int bt_hci_init_transport_id (int chId )
58 {
59 struct termios term;
60 int fd = -1;
61 int retry = 0;
62 char ssrvalue[92]= {'\0'};
63
64 ssrvalue[0] = '0';
65 if(chId >= 2 || chId <0)
66 return -1;
67
68 fd = open(s_pszDevSmd[chId], (O_RDWR | O_NOCTTY));
69
70 while ((-1 == fd) && (retry < 7)) {
71 ALOGE("init_transport: Cannot open %s: %s\n. Retry after 2 seconds",
72 s_pszDevSmd[chId], strerror(errno));
73 usleep(2000000);
74 fd = open(s_pszDevSmd[chId], (O_RDWR | O_NOCTTY));
75 retry++;
76 }
77
78 if (-1 == fd)
79 {
80 ALOGE("init_transport: Cannot open %s: %s\n",
81 s_pszDevSmd[chId], strerror(errno));
82 return -1;
83 }
84
85 /* Sleep (0.5sec) added giving time for the smd port to be successfully
86 opened internally. Currently successful return from open doesn't
87 ensure the smd port is successfully opened.
88 TODO: Following sleep to be removed once SMD port is successfully
89 opened immediately on return from the aforementioned open call */
90
91 property_get("bluetooth.isSSR", ssrvalue, "");
92
93 if(ssrvalue[0] == '1')
94 {
95 /*reset the SSR flag */
96 if(chId == 1)
97 {
98 if(property_set("bluetooth.isSSR", "0") < 0)
99 {
100 ALOGE("SSR: hci_smd.c:SSR case : error in setting up property new\n ");
101 }
102 else
103 {
104 ALOGE("SSR: hci_smd.c:SSR case : Reset the SSr Flag new\n ");
105 }
106 }
107 ALOGE("hci_smd.c:IN SSR sleep for 500 msec New \n");
108 usleep(500000);
109 }
110
111 if (tcflush(fd, TCIOFLUSH) < 0)
112 {
113 ALOGE("init_uart: Cannot flush %s\n", s_pszDevSmd[chId]);
114 close(fd);
115 return -1;
116 }
117
118 if (tcgetattr(fd, &term) < 0)
119 {
120 ALOGE("init_uart: Error while getting attributes\n");
121 close(fd);
122 return -1;
123 }
124
125 cfmakeraw(&term);
126
127 /* JN: Do I need to make flow control configurable, since 4020 cannot
128 * disable it?
129 */
130 term.c_cflag |= (CRTSCTS | CLOCAL);
131
132 if (tcsetattr(fd, TCSANOW, &term) < 0)
133 {
134 ALOGE("init_uart: Error while getting attributes\n");
135 close(fd);
136 return -1;
137 }
138
139 ALOGI("Done intiailizing UART\n");
140 return fd;
141 }
142
bt_hci_init_transport(int * pFd)143 int bt_hci_init_transport(int *pFd)
144 {
145 int i = 0;
146 int fd;
147 for(i=0; i < NUM_OF_DEVS; i++){
148 fd = bt_hci_init_transport_id(i);
149 if(fd < 0 ){
150 return -1;
151 }
152 pFd[i] = fd;
153 }
154 return 0;
155 }
156
bt_hci_deinit_transport(int * pFd)157 int bt_hci_deinit_transport(int *pFd)
158 {
159 close(pFd[0]);
160 close(pFd[1]);
161 return TRUE;
162 }
163