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