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