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