1 /****************************************************************************** 2 * 3 * Copyright (C) 2009-2012 Broadcom Corporation 4 * 5 * Licensed under the Apache License, Version 2.0 (the "License"); 6 * you may not use this file except in compliance with the License. 7 * You may obtain a copy of the License at: 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 * 17 ******************************************************************************/ 18 19 /****************************************************************************** 20 * 21 * Filename: userial_vendor.c 22 * 23 * Description: Contains vendor-specific userial functions 24 * 25 ******************************************************************************/ 26 27 #define LOG_TAG "bt_userial_vendor" 28 29 #include <utils/Log.h> 30 #include <termios.h> 31 #include <fcntl.h> 32 #include <errno.h> 33 #include <stdio.h> 34 #include <string.h> 35 #include "bt_vendor_brcm.h" 36 #include "userial.h" 37 #include "userial_vendor.h" 38 39 /****************************************************************************** 40 ** Constants & Macros 41 ******************************************************************************/ 42 43 #ifndef VNDUSERIAL_DBG 44 #define VNDUSERIAL_DBG FALSE 45 #endif 46 47 #if (VNDUSERIAL_DBG == TRUE) 48 #define VNDUSERIALDBG(param, ...) {ALOGD(param, ## __VA_ARGS__);} 49 #else 50 #define VNDUSERIALDBG(param, ...) {} 51 #endif 52 53 #define VND_PORT_NAME_MAXLEN 256 54 55 /****************************************************************************** 56 ** Local type definitions 57 ******************************************************************************/ 58 59 /* vendor serial control block */ 60 typedef struct 61 { 62 int fd; /* fd to Bluetooth device */ 63 struct termios termios; /* serial terminal of BT port */ 64 char port_name[VND_PORT_NAME_MAXLEN]; 65 } vnd_userial_cb_t; 66 67 /****************************************************************************** 68 ** Static variables 69 ******************************************************************************/ 70 71 static vnd_userial_cb_t vnd_userial; 72 73 /***************************************************************************** 74 ** Helper Functions 75 *****************************************************************************/ 76 77 /******************************************************************************* 78 ** 79 ** Function userial_to_tcio_baud 80 ** 81 ** Description helper function converts USERIAL baud rates into TCIO 82 ** conforming baud rates 83 ** 84 ** Returns TRUE/FALSE 85 ** 86 *******************************************************************************/ 87 uint8_t userial_to_tcio_baud(uint8_t cfg_baud, uint32_t *baud) 88 { 89 if (cfg_baud == USERIAL_BAUD_115200) 90 *baud = B115200; 91 else if (cfg_baud == USERIAL_BAUD_4M) 92 *baud = B4000000; 93 else if (cfg_baud == USERIAL_BAUD_3M) 94 *baud = B3000000; 95 else if (cfg_baud == USERIAL_BAUD_2M) 96 *baud = B2000000; 97 else if (cfg_baud == USERIAL_BAUD_1M) 98 *baud = B1000000; 99 else if (cfg_baud == USERIAL_BAUD_921600) 100 *baud = B921600; 101 else if (cfg_baud == USERIAL_BAUD_460800) 102 *baud = B460800; 103 else if (cfg_baud == USERIAL_BAUD_230400) 104 *baud = B230400; 105 else if (cfg_baud == USERIAL_BAUD_57600) 106 *baud = B57600; 107 else if (cfg_baud == USERIAL_BAUD_19200) 108 *baud = B19200; 109 else if (cfg_baud == USERIAL_BAUD_9600) 110 *baud = B9600; 111 else if (cfg_baud == USERIAL_BAUD_1200) 112 *baud = B1200; 113 else if (cfg_baud == USERIAL_BAUD_600) 114 *baud = B600; 115 else 116 { 117 ALOGE( "userial vendor open: unsupported baud idx %i", cfg_baud); 118 *baud = B115200; 119 return FALSE; 120 } 121 122 return TRUE; 123 } 124 125 #if (BT_WAKE_VIA_USERIAL_IOCTL==TRUE) 126 /******************************************************************************* 127 ** 128 ** Function userial_ioctl_init_bt_wake 129 ** 130 ** Description helper function to set the open state of the bt_wake if ioctl 131 ** is used. it should not hurt in the rfkill case but it might 132 ** be better to compile it out. 133 ** 134 ** Returns none 135 ** 136 *******************************************************************************/ 137 void userial_ioctl_init_bt_wake(int fd) 138 { 139 uint32_t bt_wake_state; 140 141 #if (BT_WAKE_USERIAL_LDISC==TRUE) 142 int ldisc = N_BRCM_HCI; /* brcm sleep mode support line discipline */ 143 144 /* attempt to load enable discipline driver */ 145 if (ioctl(vnd_userial.fd, TIOCSETD, &ldisc) < 0) 146 { 147 VNDUSERIALDBG("USERIAL_Open():fd %d, TIOCSETD failed: error %d for ldisc: %d", 148 fd, errno, ldisc); 149 } 150 #endif 151 152 153 154 /* assert BT_WAKE through ioctl */ 155 ioctl(fd, USERIAL_IOCTL_BT_WAKE_ASSERT, NULL); 156 ioctl(fd, USERIAL_IOCTL_BT_WAKE_GET_ST, &bt_wake_state); 157 VNDUSERIALDBG("userial_ioctl_init_bt_wake read back BT_WAKE state=%i", \ 158 bt_wake_state); 159 } 160 #endif // (BT_WAKE_VIA_USERIAL_IOCTL==TRUE) 161 162 163 /***************************************************************************** 164 ** Userial Vendor API Functions 165 *****************************************************************************/ 166 167 /******************************************************************************* 168 ** 169 ** Function userial_vendor_init 170 ** 171 ** Description Initialize userial vendor-specific control block 172 ** 173 ** Returns None 174 ** 175 *******************************************************************************/ 176 void userial_vendor_init(void) 177 { 178 vnd_userial.fd = -1; 179 snprintf(vnd_userial.port_name, VND_PORT_NAME_MAXLEN, "%s", \ 180 BLUETOOTH_UART_DEVICE_PORT); 181 } 182 183 /******************************************************************************* 184 ** 185 ** Function userial_vendor_open 186 ** 187 ** Description Open the serial port with the given configuration 188 ** 189 ** Returns device fd 190 ** 191 *******************************************************************************/ 192 int userial_vendor_open(tUSERIAL_CFG *p_cfg) 193 { 194 uint32_t baud; 195 uint8_t data_bits; 196 uint16_t parity; 197 uint8_t stop_bits; 198 199 vnd_userial.fd = -1; 200 201 if (!userial_to_tcio_baud(p_cfg->baud, &baud)) 202 { 203 return -1; 204 } 205 206 if(p_cfg->fmt & USERIAL_DATABITS_8) 207 data_bits = CS8; 208 else if(p_cfg->fmt & USERIAL_DATABITS_7) 209 data_bits = CS7; 210 else if(p_cfg->fmt & USERIAL_DATABITS_6) 211 data_bits = CS6; 212 else if(p_cfg->fmt & USERIAL_DATABITS_5) 213 data_bits = CS5; 214 else 215 { 216 ALOGE("userial vendor open: unsupported data bits"); 217 return -1; 218 } 219 220 if(p_cfg->fmt & USERIAL_PARITY_NONE) 221 parity = 0; 222 else if(p_cfg->fmt & USERIAL_PARITY_EVEN) 223 parity = PARENB; 224 else if(p_cfg->fmt & USERIAL_PARITY_ODD) 225 parity = (PARENB | PARODD); 226 else 227 { 228 ALOGE("userial vendor open: unsupported parity bit mode"); 229 return -1; 230 } 231 232 if(p_cfg->fmt & USERIAL_STOPBITS_1) 233 stop_bits = 0; 234 else if(p_cfg->fmt & USERIAL_STOPBITS_2) 235 stop_bits = CSTOPB; 236 else 237 { 238 ALOGE("userial vendor open: unsupported stop bits"); 239 return -1; 240 } 241 242 ALOGI("userial vendor open: opening %s", vnd_userial.port_name); 243 244 if ((vnd_userial.fd = open(vnd_userial.port_name, O_RDWR)) == -1) 245 { 246 ALOGE("userial vendor open: unable to open %s", vnd_userial.port_name); 247 return -1; 248 } 249 250 tcflush(vnd_userial.fd, TCIOFLUSH); 251 252 tcgetattr(vnd_userial.fd, &vnd_userial.termios); 253 cfmakeraw(&vnd_userial.termios); 254 vnd_userial.termios.c_cflag |= (CRTSCTS | stop_bits); 255 tcsetattr(vnd_userial.fd, TCSANOW, &vnd_userial.termios); 256 tcflush(vnd_userial.fd, TCIOFLUSH); 257 258 tcsetattr(vnd_userial.fd, TCSANOW, &vnd_userial.termios); 259 tcflush(vnd_userial.fd, TCIOFLUSH); 260 tcflush(vnd_userial.fd, TCIOFLUSH); 261 262 /* set input/output baudrate */ 263 cfsetospeed(&vnd_userial.termios, baud); 264 cfsetispeed(&vnd_userial.termios, baud); 265 tcsetattr(vnd_userial.fd, TCSANOW, &vnd_userial.termios); 266 267 #if (BT_WAKE_VIA_USERIAL_IOCTL==TRUE) 268 userial_ioctl_init_bt_wake(vnd_userial.fd); 269 #endif 270 271 ALOGI("device fd = %d open", vnd_userial.fd); 272 273 return vnd_userial.fd; 274 } 275 276 /******************************************************************************* 277 ** 278 ** Function userial_vendor_close 279 ** 280 ** Description Conduct vendor-specific close work 281 ** 282 ** Returns None 283 ** 284 *******************************************************************************/ 285 void userial_vendor_close(void) 286 { 287 int result; 288 289 if (vnd_userial.fd == -1) 290 return; 291 292 #if (BT_WAKE_VIA_USERIAL_IOCTL==TRUE) 293 /* de-assert bt_wake BEFORE closing port */ 294 ioctl(vnd_userial.fd, USERIAL_IOCTL_BT_WAKE_DEASSERT, NULL); 295 #endif 296 297 ALOGI("device fd = %d close", vnd_userial.fd); 298 // flush Tx before close to make sure no chars in buffer 299 tcflush(vnd_userial.fd, TCIOFLUSH); 300 if ((result = close(vnd_userial.fd)) < 0) 301 ALOGE( "close(fd:%d) FAILED result:%d", vnd_userial.fd, result); 302 303 vnd_userial.fd = -1; 304 } 305 306 /******************************************************************************* 307 ** 308 ** Function userial_vendor_set_baud 309 ** 310 ** Description Set new baud rate 311 ** 312 ** Returns None 313 ** 314 *******************************************************************************/ 315 void userial_vendor_set_baud(uint8_t userial_baud) 316 { 317 uint32_t tcio_baud; 318 319 userial_to_tcio_baud(userial_baud, &tcio_baud); 320 321 cfsetospeed(&vnd_userial.termios, tcio_baud); 322 cfsetispeed(&vnd_userial.termios, tcio_baud); 323 tcsetattr(vnd_userial.fd, TCSANOW, &vnd_userial.termios); 324 } 325 326 /******************************************************************************* 327 ** 328 ** Function userial_vendor_ioctl 329 ** 330 ** Description ioctl inteface 331 ** 332 ** Returns None 333 ** 334 *******************************************************************************/ 335 void userial_vendor_ioctl(userial_vendor_ioctl_op_t op, void *p_data) 336 { 337 switch(op) 338 { 339 #if (BT_WAKE_VIA_USERIAL_IOCTL==TRUE) 340 case USERIAL_OP_ASSERT_BT_WAKE: 341 VNDUSERIALDBG("## userial_vendor_ioctl: Asserting BT_Wake ##"); 342 ioctl(vnd_userial.fd, USERIAL_IOCTL_BT_WAKE_ASSERT, NULL); 343 break; 344 345 case USERIAL_OP_DEASSERT_BT_WAKE: 346 VNDUSERIALDBG("## userial_vendor_ioctl: De-asserting BT_Wake ##"); 347 ioctl(vnd_userial.fd, USERIAL_IOCTL_BT_WAKE_DEASSERT, NULL); 348 break; 349 350 case USERIAL_OP_GET_BT_WAKE_STATE: 351 ioctl(vnd_userial.fd, USERIAL_IOCTL_BT_WAKE_GET_ST, p_data); 352 break; 353 #endif // (BT_WAKE_VIA_USERIAL_IOCTL==TRUE) 354 355 default: 356 break; 357 } 358 } 359 360 /******************************************************************************* 361 ** 362 ** Function userial_set_port 363 ** 364 ** Description Configure UART port name 365 ** 366 ** Returns 0 : Success 367 ** Otherwise : Fail 368 ** 369 *******************************************************************************/ 370 int userial_set_port(char *p_conf_name, char *p_conf_value, int param) 371 { 372 strcpy(vnd_userial.port_name, p_conf_value); 373 374 return 0; 375 } 376 377