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: userial_vendor.c 20 * 21 * Description: Contains vendor-specific userial functions 22 * 23 ******************************************************************************/ 24 25 #define LOG_TAG "bt_userial_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 "userial_vendor.h" 34 35 bt_hci_transport_device_type bt_hci_set_transport() 36 { 37 int ret; 38 char transport_type[10] = {0,}; 39 bt_hci_transport_device_type bt_hci_transport_device; 40 41 ret = property_get("ro.qualcomm.bt.hci_transport", transport_type, NULL); 42 if(ret == 0) 43 printf("ro.qualcomm.bt.hci_transport not set\n"); 44 else 45 printf("ro.qualcomm.bt.hci_transport: %s \n", transport_type); 46 47 if (!strcasecmp(transport_type, "smd")) 48 { 49 bt_hci_transport_device.type = BT_HCI_SMD; 50 bt_hci_transport_device.name = APPS_RIVA_BT_CMD_CH; 51 bt_hci_transport_device.pkt_ind = 1; 52 } 53 else{ 54 bt_hci_transport_device.type = BT_HCI_UART; 55 bt_hci_transport_device.name = BT_HS_UART_DEVICE; 56 bt_hci_transport_device.pkt_ind = 0; 57 } 58 59 return bt_hci_transport_device; 60 } 61 62 #define NUM_OF_DEVS 2 63 static char *s_pszDevSmd[] = { 64 "/dev/smd3", 65 "/dev/smd2" 66 }; 67 68 int bt_hci_init_transport(int *pFd) 69 { 70 int i = 0; 71 int fd; 72 for(i=0; i < NUM_OF_DEVS; i++){ 73 fd = bt_hci_init_transport_id(i); 74 if(fd < 0 ){ 75 return -1; 76 } 77 pFd[i] = fd; 78 } 79 return 0; 80 } 81 82 int bt_hci_init_transport_id (int chId ) 83 { 84 struct termios term; 85 int fd = -1; 86 int retry = 0; 87 88 if(chId > 2 || chId <0) 89 return -1; 90 91 fd = open(s_pszDevSmd[chId], (O_RDWR | O_NOCTTY)); 92 93 while ((-1 == fd) && (retry < 7)) { 94 ALOGE("init_transport: Cannot open %s: %s\n. Retry after 2 seconds", 95 bt_hci_transport_device.name, strerror(errno)); 96 usleep(2000000); 97 fd = open(bt_hci_transport_device.name, (O_RDWR | O_NOCTTY)); 98 retry++; 99 } 100 101 if (-1 == fd) 102 { 103 ALOGE("init_transport: Cannot open %s: %s\n", 104 bt_hci_transport_device.name, strerror(errno)); 105 return -1; 106 } 107 108 /* Sleep (0.5sec) added giving time for the smd port to be successfully 109 opened internally. Currently successful return from open doesn't 110 ensure the smd port is successfully opened. 111 TODO: Following sleep to be removed once SMD port is successfully 112 opened immediately on return from the aforementioned open call */ 113 if(BT_HCI_SMD == bt_hci_transport_device.type) 114 usleep(500000); 115 116 if (tcflush(fd, TCIOFLUSH) < 0) 117 { 118 ALOGE("init_uart: Cannot flush %s\n", bt_hci_transport_device.name); 119 close(fd); 120 return -1; 121 } 122 123 if (tcgetattr(fd, &term) < 0) 124 { 125 ALOGE("init_uart: Error while getting attributes\n"); 126 close(fd); 127 return -1; 128 } 129 130 cfmakeraw(&term); 131 132 /* JN: Do I need to make flow control configurable, since 4020 cannot 133 * disable it? 134 */ 135 term.c_cflag |= (CRTSCTS | CLOCAL); 136 137 if (tcsetattr(fd, TCSANOW, &term) < 0) 138 { 139 ALOGE("init_uart: Error while getting attributes\n"); 140 close(fd); 141 return -1; 142 } 143 144 ALOGI("Done intiailizing UART\n"); 145 return fd; 146 } 147 148 int bt_hci_deinit_transport(int *pFd) 149 { 150 close(pFd[0]); 151 close(pFd[1]); 152 return TRUE; 153 } 154