userial_linux.c revision a24be4f06674b2707b57904deaa0dff5a95823bd
1/****************************************************************************** 2 * 3 * Copyright (C) 1999-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#include "OverrideLog.h" 20#include <string.h> 21#include "gki.h" 22#include "nfc_hal_api.h" 23#include "nfc_hal_int.h" 24#include "userial.h" 25#include "nfc_target.h" 26 27#include <pthread.h> 28#include <termios.h> 29#include <fcntl.h> 30#include <errno.h> 31#include <stdio.h> 32#include <gki_int.h> 33#include "hcidefs.h" 34#include <poll.h> 35#include "upio.h" 36#include "bcm2079x.h" 37#include "config.h" 38 39#define HCISU_EVT EVENT_MASK(APPL_EVT_0) 40#define MAX_ERROR 10 41#define default_transport "/dev/bcm2079x" 42 43#define NUM_RESET_ATTEMPTS 5 44#define NFC_WAKE_ASSERTED_ON_POR UPIO_OFF 45 46#ifndef BTE_APPL_MAX_USERIAL_DEV_NAME 47#define BTE_APPL_MAX_USERIAL_DEV_NAME (256) 48#endif 49extern UINT8 appl_trace_level; 50 51 52/* Mapping of USERIAL_PORT_x to linux */ 53extern UINT32 ScrProtocolTraceFlag; 54static tUPIO_STATE current_nfc_wake_state = UPIO_OFF; 55int uart_port = 0; 56int isLowSpeedTransport = 0; 57int nfc_wake_delay = 0; 58int nfc_write_delay = 0; 59int gPowerOnDelay = 300; 60static int gPrePowerOffDelay = 0; // default value 61static int gPostPowerOffDelay = 0; // default value 62static pthread_mutex_t close_thread_mutex = PTHREAD_MUTEX_INITIALIZER; 63 64char userial_dev[BTE_APPL_MAX_USERIAL_DEV_NAME+1]; 65char power_control_dev[BTE_APPL_MAX_USERIAL_DEV_NAME+1]; 66tSNOOZE_MODE_CONFIG gSnoozeModeCfg = { 67 NFC_HAL_LP_SNOOZE_MODE_SPI_I2C, /* Sleep Mode (0=Disabled 1=UART 8=SPI/I2C) */ 68 NFC_HAL_LP_IDLE_THRESHOLD_HOST, /* Idle Threshold Host */ 69 NFC_HAL_LP_IDLE_THRESHOLD_HC, /* Idle Threshold HC */ 70 NFC_HAL_LP_ACTIVE_LOW, /* NFC Wake active mode (0=ActiveLow 1=ActiveHigh) */ 71 NFC_HAL_LP_ACTIVE_HIGH /* Host Wake active mode (0=ActiveLow 1=ActiveHigh) */ 72}; 73 74UINT8 bcmi2cnfc_client_addr = 0; 75UINT8 bcmi2cnfc_read_multi_packets = 0; 76 77#define USERIAL_Debug_verbose ((ScrProtocolTraceFlag & 0x80000000) == 0x80000000) 78 79#include <sys/socket.h> 80 81#define LOG_TAG "USERIAL_LINUX" 82 83static UINT8 spi_negotiation[10] = { 0xF0, /* CMD */ 84 0x00, /* SPI PARM Negotiation */ 85 0x01, /* SPI Version */ 86 0x00, /* SPI Mode:0, SPI_INT active low */ 87 0x00, /* 8Bit, MSB first, Little Endian byte order */ 88 0x00, /* Reserved */ 89 0xFF, /* Sleep timeout Lower Byte */ 90 0xFF, /* Sleep timeout Upper Byte */ 91 0x00, /* Reserved */ 92 0x00 /* Reserved */ 93}; 94static UINT8 spi_nego_res[20]; 95 96#include <ctype.h> 97 98#define USING_BRCM_USB TRUE 99 100/* use tc interface to change baudrate instead of close/open sequence which can fail on some platforms 101 * due to tx line movement when opeing/closing the UART. the 43xx do not like this. */ 102#ifndef USERIAL_USE_TCIO_BAUD_CHANGE 103#define USERIAL_USE_TCIO_BAUD_CHANGE FALSE 104#endif 105 106#ifndef USERIAL_USE_IO_BT_WAKE 107#define USERIAL_USE_IO_BT_WAKE FALSE 108#endif 109 110/* this are the ioctl values used for bt_wake ioctl via UART driver. you may need to redefine at for 111 * you platform! Logically they need to be unique and not colide with existing uart ioctl's. 112 */ 113#ifndef USERIAL_IO_BT_WAKE_ASSERT 114#define USERIAL_IO_BT_WAKE_ASSERT 0x8003 115#endif 116#ifndef USERIAL_IO_BT_WAKE_DEASSERT 117#define USERIAL_IO_BT_WAKE_DEASSERT 0x8004 118#endif 119#ifndef USERIAL_IO_BT_WAKE_GET_ST 120#define USERIAL_IO_BT_WAKE_GET_ST 0x8005 121#endif 122 123/* the read limit in this current implementation depends on the GKI_BUF3_SIZE 124 * It would be better to use some ring buffer from the USERIAL_Read() is reading 125 * instead of putting it into GKI buffers. 126 */ 127#define READ_LIMIT (USERIAL_POOL_BUF_SIZE-BT_HDR_SIZE) 128/* 129 * minimum buffer size requirement to read a full sized packet from NFCC = 255 + 4 byte header 130 */ 131#define MIN_BUFSIZE 259 132#define POLL_TIMEOUT 1000 133/* priority of the reader thread */ 134#define USERIAL_READ_TRHEAD_PRIO 90 135/* time (ms) to wait before trying to allocate again a GKI buffer */ 136#define NO_GKI_BUFFER_RECOVER_TIME 100 137#define MAX_SERIAL_PORT (USERIAL_PORT_15 + 1) 138 139extern void dumpbin(const char* data, int size); 140extern UINT8 *scru_dump_hex (UINT8 *p, char *p_title, UINT32 len, UINT32 trace_layer, UINT32 trace_type); 141 142static pthread_t worker_thread1 = 0; 143 144typedef struct { 145 volatile unsigned long bt_wake_state; 146 int sock; 147 tUSERIAL_CBACK *ser_cb; 148 UINT16 baud; 149 UINT8 data_bits; 150 UINT16 parity; 151 UINT8 stop_bits; 152 UINT8 port; 153 tUSERIAL_OPEN_CFG open_cfg; 154 int sock_power_control; 155 int client_device_address; 156 struct timespec write_time; 157} tLINUX_CB; 158 159static tLINUX_CB linux_cb; /* case of multipel port support use array : [MAX_SERIAL_PORT] */ 160 161void userial_close_thread(UINT32 params); 162 163static UINT8 device_name[BTE_APPL_MAX_USERIAL_DEV_NAME+1]; 164static int bSerialPortDevice = FALSE; 165static int _timeout = POLL_TIMEOUT; 166static BOOLEAN is_close_thread_is_waiting = FALSE; 167 168static int change_client_addr(int addr); 169 170int perf_log_every_count = 0; 171typedef struct { 172 const char* label; 173 long lapse; 174 long bytes; 175 long count; 176 long overhead; 177} tPERF_DATA; 178 179/******************************************************************************* 180** 181** Function perf_reset 182** 183** Description reset performance measurement data 184** 185** Returns none 186** 187*******************************************************************************/ 188void perf_reset(tPERF_DATA* t) 189{ 190 t->count = 191 t->bytes = 192 t->lapse = 0; 193} 194 195/******************************************************************************* 196** 197** Function perf_log 198** 199** Description produce a log entry of cvurrent performance data 200** 201** Returns none 202** 203*******************************************************************************/ 204void perf_log(tPERF_DATA* t) 205{ 206 // round to nearest ms 207 // t->lapse += 500; 208 // t->lapse /= 1000; 209 if (t->lapse) 210 { 211 if (t->bytes) 212 ALOGD( "%s:%s, bytes=%ld, lapse=%ld (%d.%02d kbps) (bus data rate %d.%02d kbps) overhead %d(%d percent)\n", 213 __func__, 214 t->label, t->bytes, t->lapse, 215 (int)(8 * t->bytes / t->lapse), (int)(800 * t->bytes / (t->lapse)) % 100, 216 (int)(9 * (t->bytes + t->count * t->overhead) / t->lapse), (int)(900 * (t->bytes + t->count * t->overhead) / (t->lapse)) % 100, 217 (int)(t->count * t->overhead), (int)(t->count * t->overhead * 100 / t->bytes) 218 ); 219 else 220 ALOGD( "%s:%s, lapse=%ld (average %ld)\n", __func__, 221 t->label, t->lapse, (int)t->lapse / t->count 222 ); 223 } 224 perf_reset(t); 225} 226 227/******************************************************************************* 228** 229** Function perf_update 230** 231** Description update perforamnce measurement data 232** 233** Returns none 234** 235*******************************************************************************/ 236void perf_update(tPERF_DATA* t, long lapse, long bytes) 237{ 238 if (!perf_log_every_count) 239 return; 240 // round to nearest ms 241 lapse += 500; 242 lapse /= 1000; 243 t->count++; 244 t->bytes += bytes; 245 t->lapse += lapse; 246 if (t->count == perf_log_every_count) 247 perf_log(t); 248} 249 250static tPERF_DATA perf_poll = {"USERIAL_Poll", 0, 0, 0, 0}; 251static tPERF_DATA perf_read = {"USERIAL_Read", 0, 0, 0, 9}; 252static tPERF_DATA perf_write = {"USERIAL_Write", 0, 0, 0, 3}; 253static tPERF_DATA perf_poll_2_poll = {"USERIAL_Poll_to_Poll", 0, 0, 0, 0}; 254static clock_t _poll_t0 = 0; 255 256static UINT32 userial_baud_tbl[] = 257{ 258 300, /* USERIAL_BAUD_300 0 */ 259 600, /* USERIAL_BAUD_600 1 */ 260 1200, /* USERIAL_BAUD_1200 2 */ 261 2400, /* USERIAL_BAUD_2400 3 */ 262 9600, /* USERIAL_BAUD_9600 4 */ 263 19200, /* USERIAL_BAUD_19200 5 */ 264 57600, /* USERIAL_BAUD_57600 6 */ 265 115200, /* USERIAL_BAUD_115200 7 */ 266 230400, /* USERIAL_BAUD_230400 8 */ 267 460800, /* USERIAL_BAUD_460800 9 */ 268 921600, /* USERIAL_BAUD_921600 10 */ 269 1000000, /* USERIAL_BAUD_1M 11 */ 270 1500000, /* USERIAL_BAUD_1_5M 12 */ 271 2000000, /* USERIAL_BAUD_2M 13 */ 272 3000000, /* USERIAL_BAUD_3M 14 */ 273 4000000 /* USERIAL_BAUD_4M 15 */ 274}; 275 276/******************************************************************************* 277** 278** Function wake_state 279** 280** Description return current state of NFC_WAKE gpio 281** 282** Returns GPIO value to wake NFCC 283** 284*******************************************************************************/ 285static inline int wake_state() 286{ 287 return ((gSnoozeModeCfg.nfc_wake_active_mode == NFC_HAL_LP_ACTIVE_HIGH) ? UPIO_ON : UPIO_OFF); 288} 289 290/******************************************************************************* 291** 292** Function sleep_state 293** 294** Description return current state of NFC_WAKE gpio 295** 296** Returns GPIO value to allow NFCC to goto sleep 297** 298*******************************************************************************/ 299static inline int sleep_state() 300{ 301 return ((gSnoozeModeCfg.nfc_wake_active_mode == NFC_HAL_LP_ACTIVE_HIGH) ? UPIO_OFF : UPIO_ON); 302} 303 304/******************************************************************************* 305** 306** Function isWake 307** 308** Description return current state of NFC_WAKE gpio based on the active mode setting 309** 310** Returns asserted_state if it's awake, deasserted_state if it's allowed to sleep 311** 312*******************************************************************************/ 313static inline int isWake(int state) 314{ 315 int asserted_state = ((gSnoozeModeCfg.nfc_wake_active_mode == NFC_HAL_LP_ACTIVE_HIGH) ? UPIO_ON : UPIO_OFF); 316 return (state != -1) ? 317 state == asserted_state : 318 current_nfc_wake_state == asserted_state; 319} 320 321/******************************************************************************* 322** 323** Function setWriteDelay 324** 325** Description Record a delay for the next write operation 326** 327** Input Parameter delay in milliseconds 328** 329** Comments use this function to register a delay before next write, 330** This is used in three instances: power up delay, wake delay 331** and write delay 332** 333*******************************************************************************/ 334static void setWriteDelay(int delay) 335{ 336 if (delay <= 0) { 337 // Set a minimum delay of 5ms between back-to-back writes 338 delay = 5; 339 } 340 341 clock_gettime(CLOCK_MONOTONIC, &linux_cb.write_time); 342 if (delay > 1000) 343 { 344 linux_cb.write_time.tv_sec += delay / 1000; 345 delay %= 1000; 346 } 347 unsigned long write_delay = delay * 1000 * 1000; 348 linux_cb.write_time.tv_nsec += write_delay; 349 if (linux_cb.write_time.tv_nsec > 1000*1000*1000) 350 { 351 linux_cb.write_time.tv_nsec -= 1000*1000*1000; 352 linux_cb.write_time.tv_sec++; 353 } 354} 355 356/******************************************************************************* 357** 358** Function doWriteDelay 359** 360** Description Execute a delay as registered in setWriteDelay() 361** 362** Output Parameter none 363** 364** Returns none 365** 366** Comments This function calls GKI_Delay to execute a delay to fulfill 367** the delay registered earlier. 368** 369*******************************************************************************/ 370static void doWriteDelay() 371{ 372 struct timespec now; 373 clock_gettime(CLOCK_MONOTONIC, &now); 374 long delay = 0; 375 376 if (now.tv_sec > linux_cb.write_time.tv_sec) 377 return; 378 else if (now.tv_sec == linux_cb.write_time.tv_sec) 379 { 380 if (now.tv_nsec > linux_cb.write_time.tv_nsec) 381 return; 382 delay = (linux_cb.write_time.tv_nsec - now.tv_nsec) / 1000000; 383 } 384 else 385 delay = (linux_cb.write_time.tv_sec - now.tv_sec) * 1000 + linux_cb.write_time.tv_nsec / 1000000 - now.tv_nsec / 1000000; 386 387 if (delay > 0 && delay < 1000) 388 { 389 ALOGD_IF((appl_trace_level>=BT_TRACE_LEVEL_DEBUG), "doWriteDelay() delay %ld ms", delay); 390 GKI_delay(delay); 391 } 392} 393 394/******************************************************************************* 395** 396** Function create_signal_fds 397** 398** Description create a socketpair for read thread to use 399** 400** Returns file descriptor 401** 402*******************************************************************************/ 403 404static int signal_fds[2]; 405static inline int create_signal_fds(struct pollfd* set) 406{ 407 if (signal_fds[0] == 0 && socketpair(AF_UNIX, SOCK_STREAM, 0, signal_fds) < 0) 408 { 409 ALOGE("%s create_signal_sockets:socketpair failed, errno: %d", __func__, errno); 410 return -1; 411 } 412 set->fd = signal_fds[0]; 413 return signal_fds[0]; 414} 415 416/******************************************************************************* 417** 418** Function close_signal_fds 419** 420** Description close the socketpair 421** 422** Returns none 423** 424*******************************************************************************/ 425static inline void close_signal_fds() 426{ 427 int stat = 0; 428 429 stat = close(signal_fds[0]); 430 if (stat == -1) 431 ALOGE ("%s, fail close index 0; errno=%d", __FUNCTION__, errno); 432 signal_fds[0] = 0; 433 434 stat = close(signal_fds[1]); 435 if (stat == -1) 436 ALOGE ("%s, fail close index 1; errno=%d", __FUNCTION__, errno); 437 signal_fds[1] = 0; 438} 439 440/******************************************************************************* 441** 442** Function send_wakeup_signal 443** 444** Description send a one byte data to the socket as signal to the read thread 445** for it to stop 446** 447** Returns number of bytes sent, or error no 448** 449*******************************************************************************/ 450static inline int send_wakeup_signal() 451{ 452 char sig_on = 1; 453 ALOGD("%s: Sending signal to %d", __func__, signal_fds[1]); 454 return send(signal_fds[1], &sig_on, sizeof(sig_on), 0); 455} 456 457/******************************************************************************* 458** 459** Function reset_signal 460** 461** Description read the one byte data from the socket 462** 463** Returns received data 464** 465*******************************************************************************/ 466static inline int reset_signal() 467{ 468 char sig_recv = 0; 469 ALOGD("%s: Receiving signal from %d", __func__, signal_fds[0]); 470 recv(signal_fds[0], &sig_recv, sizeof(sig_recv), MSG_WAITALL); 471 return (int)sig_recv; 472} 473 474/******************************************************************************* 475** 476** Function is_signaled 477** 478** Description test if there's data waiting on the socket 479** 480** Returns TRUE is data is available 481** 482*******************************************************************************/ 483static inline int is_signaled(struct pollfd* set) 484{ 485 return ((set->revents & POLLIN) == POLLIN) || ((set->revents & POLLRDNORM) == POLLRDNORM) ; 486} 487 488/******************************************************************************/ 489 490typedef unsigned char uchar; 491 492BUFFER_Q Userial_in_q; 493 494/******************************************************************************* 495 ** 496 ** Function USERIAL_GetLineSpeed 497 ** 498 ** Description This function convert USERIAL baud to line speed. 499 ** 500 ** Output Parameter None 501 ** 502 ** Returns line speed 503 ** 504 *******************************************************************************/ 505UDRV_API extern UINT32 USERIAL_GetLineSpeed(UINT8 baud) 506{ 507 return (baud <= USERIAL_BAUD_4M) ? 508 userial_baud_tbl[baud-USERIAL_BAUD_300] : 0; 509} 510 511/******************************************************************************* 512 ** 513 ** Function USERIAL_GetBaud 514 ** 515 ** Description This function convert line speed to USERIAL baud. 516 ** 517 ** Output Parameter None 518 ** 519 ** Returns line speed 520 ** 521 *******************************************************************************/ 522UDRV_API extern UINT8 USERIAL_GetBaud(UINT32 line_speed) 523{ 524 UINT8 i; 525 for (i = USERIAL_BAUD_300; i <= USERIAL_BAUD_921600; i++) 526 { 527 if (userial_baud_tbl[i-USERIAL_BAUD_300] == line_speed) 528 return i; 529 } 530 531 return USERIAL_BAUD_AUTO; 532} 533 534/******************************************************************************* 535** 536** Function USERIAL_Init 537** 538** Description This function initializes the serial driver. 539** 540** Output Parameter None 541** 542** Returns Nothing 543** 544*******************************************************************************/ 545 546UDRV_API void USERIAL_Init(void * p_cfg) 547{ 548 ALOGI(__FUNCTION__); 549 550 //if userial_close_thread() is waiting to run; let it go first; 551 //let it finish; then continue this function 552 while (TRUE) 553 { 554 pthread_mutex_lock(&close_thread_mutex); 555 if (is_close_thread_is_waiting) 556 { 557 pthread_mutex_unlock(&close_thread_mutex); 558 ALOGI("USERIAL_Open(): wait for close-thread"); 559 sleep (1); 560 } 561 else 562 break; 563 } 564 565 memset(&linux_cb, 0, sizeof(linux_cb)); 566 linux_cb.sock = -1; 567 linux_cb.ser_cb = NULL; 568 linux_cb.sock_power_control = -1; 569 linux_cb.client_device_address = 0; 570 GKI_init_q(&Userial_in_q); 571 pthread_mutex_unlock(&close_thread_mutex); 572} 573 574/******************************************************************************* 575 ** 576 ** Function my_read 577 ** 578 ** Description This function read a packet from driver. 579 ** 580 ** Output Parameter None 581 ** 582 ** Returns number of bytes in the packet or error code 583 ** 584 *******************************************************************************/ 585int my_read(int fd, uchar *pbuf, int len) 586{ 587 struct pollfd fds[2]; 588 589 int n = 0; 590 int ret = 0; 591 int count = 0; 592 int offset = 0; 593 clock_t t1, t2; 594 595 if (!isLowSpeedTransport && _timeout != POLL_TIMEOUT) 596 ALOGD_IF((appl_trace_level>=BT_TRACE_LEVEL_DEBUG), "%s: enter, pbuf=%lx, len = %d\n", __func__, (unsigned long)pbuf, len); 597 memset(pbuf, 0, len); 598 /* need to use select in order to avoid collistion between read and close on same fd */ 599 /* Initialize the input set */ 600 fds[0].fd = fd; 601 fds[0].events = POLLIN | POLLERR | POLLRDNORM; 602 fds[0].revents = 0; 603 604 create_signal_fds(&fds[1]); 605 fds[1].events = POLLIN | POLLERR | POLLRDNORM; 606 fds[1].revents = 0; 607 t1 = clock(); 608 n = poll(fds, 2, _timeout); 609 t2 = clock(); 610 perf_update(&perf_poll, t2 - t1, 0); 611 if (_poll_t0) 612 perf_update(&perf_poll_2_poll, t2 - _poll_t0, 0); 613 614 _poll_t0 = t2; 615 /* See if there was an error */ 616 if (n < 0) 617 { 618 ALOGD( "select failed; errno = %d\n", errno); 619 return -errno; 620 } 621 else if (n == 0) 622 return -EAGAIN; 623 624 if (is_signaled(&fds[1])) 625 { 626 ALOGD( "%s: exit signal received\n", __func__); 627 reset_signal(); 628 return -1; 629 } 630 if (!bSerialPortDevice || len < MIN_BUFSIZE) 631 count = len; 632 else 633 count = 1; 634 do { 635 t2 = clock(); 636 ret = read(fd, pbuf+offset, (size_t)count); 637 if (ret > 0) 638 perf_update(&perf_read, clock()-t2, ret); 639 640 if (ret <= 0 || !bSerialPortDevice || len < MIN_BUFSIZE) 641 break; 642 643 if (isLowSpeedTransport) 644 goto done; 645 646 if (offset == 0) 647 { 648 if (pbuf[offset] == HCIT_TYPE_NFC) 649 count = 3; 650 else if (pbuf[offset] == HCIT_TYPE_EVENT) 651 count = 2; 652 else 653 { 654 ALOGD( "%s: unknown HCIT type header pbuf[%d] = %x\n", __func__, offset, pbuf[offset]); 655 break; 656 } 657 offset = 1; 658 } 659 else if (offset == 1) 660 { 661 offset += count; 662 count = pbuf[offset-1]; 663 if (count > (len - offset)) //if (count > (remaining buffer size)) 664 count = len - offset; //only read what the remaining buffer size can hold 665 } 666 else 667 { 668 offset += ret; 669 count -= ret; 670 } 671 if (count == 0) 672 { 673 ret = offset; 674 break; 675 } 676 } while (count > 0); 677 678 679 #if VALIDATE_PACKET 680/* 681 * vallidate the packet structure 682 */ 683 if (ret > 0 && len >= MIN_BUFSIZE) 684 { 685 count = 0; 686 while (count < ret) 687 { 688 if (pbuf[count] == HCIT_TYPE_NFC) 689 { 690 if (USERIAL_Debug_verbose) 691 scru_dump_hex(pbuf+count, NULL, pbuf[count+3]+4, 0, 0); 692 count += pbuf[count+3]+4; 693 } 694 else if (pbuf[count] == HCIT_TYPE_EVENT) 695 { 696 if (USERIAL_Debug_verbose) 697 scru_dump_hex(pbuf+count, NULL, pbuf[count+2]+3, 0, 0); 698 count += pbuf[count+2]+3; 699 } 700 else 701 { 702 ALOGD( "%s: unknown HCIT type header pbuf[%d] = %x, remain %d bytes\n", __func__, count, pbuf[count], ret-count); 703 scru_dump_hex(pbuf+count, NULL, ret - count, 0, 0); 704 break; 705 } 706 } /* while*/ 707 } 708#endif 709done: 710 if (!isLowSpeedTransport) 711 ALOGD_IF((appl_trace_level>=BT_TRACE_LEVEL_DEBUG), "%s: return %d(0x%x) bytes, errno=%d count=%d, n=%d, timeout=%d\n", __func__, 712 ret, ret, errno, count, n, _timeout); 713 if (_timeout == POLL_TIMEOUT) 714 _timeout = -1; 715 return ret; 716} 717extern BOOLEAN gki_chk_buf_damage(void *p_buf); 718static int sRxLength = 0; 719 720/******************************************************************************* 721 ** 722 ** Function userial_read_thread 723 ** 724 ** Description entry point of read thread. 725 ** 726 ** Output Parameter None 727 ** 728 ** Returns 0 729 ** 730 *******************************************************************************/ 731UINT32 userial_read_thread(UINT32 arg) 732{ 733 int rx_length; 734 int error_count = 0; 735 int bErrorReported = 0; 736 int iMaxError = MAX_ERROR; 737 BT_HDR *p_buf = NULL; 738 739 worker_thread1 = pthread_self(); 740 741 ALOGD( "start userial_read_thread, id=%lx", worker_thread1); 742 _timeout = POLL_TIMEOUT; 743 744 for (;linux_cb.sock > 0;) 745 { 746 BT_HDR *p_buf; 747 UINT8 *current_packet; 748 749 if ((p_buf = (BT_HDR *) GKI_getpoolbuf( USERIAL_POOL_ID ) )!= NULL) 750 { 751 p_buf->offset = 0; 752 p_buf->layer_specific = 0; 753 754 current_packet = (UINT8 *) (p_buf + 1); 755 rx_length = my_read(linux_cb.sock, current_packet, READ_LIMIT); 756 757 } 758 else 759 { 760 ALOGE( "userial_read_thread(): unable to get buffer from GKI p_buf = %p poolid = %d\n", p_buf, USERIAL_POOL_ID); 761 rx_length = 0; /* paranoia setting */ 762 GKI_delay( NO_GKI_BUFFER_RECOVER_TIME ); 763 continue; 764 } 765 if (rx_length > 0) 766 { 767 bErrorReported = 0; 768 error_count = 0; 769 iMaxError = 3; 770 if (rx_length > sRxLength) 771 sRxLength = rx_length; 772 p_buf->len = (UINT16)rx_length; 773 GKI_enqueue(&Userial_in_q, p_buf); 774 if (!isLowSpeedTransport) 775 ALOGD_IF((appl_trace_level>=BT_TRACE_LEVEL_DEBUG), "userial_read_thread(): enqueued p_buf=%p, count=%d, length=%d\n", 776 p_buf, Userial_in_q.count, rx_length); 777 778 if (linux_cb.ser_cb != NULL) 779 (*linux_cb.ser_cb)(linux_cb.port, USERIAL_RX_READY_EVT, (tUSERIAL_EVT_DATA *)p_buf); 780 781 GKI_send_event(USERIAL_HAL_TASK, HCISU_EVT); 782 } 783 else 784 { 785 GKI_freebuf( p_buf ); 786 if (rx_length == -EAGAIN) 787 continue; 788 else if (rx_length == -1) 789 { 790 ALOGD( "userial_read_thread(): exiting\n"); 791 break; 792 } 793 else if (rx_length == 0 && !isWake(-1)) 794 continue; 795 ++error_count; 796 if (rx_length <= 0 && ((error_count > 0) && ((error_count % iMaxError) == 0))) 797 { 798 if (bErrorReported == 0) 799 { 800 ALOGE( "userial_read_thread(): my_read returned (%d) error count = %d, errno=%d return USERIAL_ERR_EVT\n", 801 rx_length, error_count, errno); 802 if (linux_cb.ser_cb != NULL) 803 (*linux_cb.ser_cb)(linux_cb.port, USERIAL_ERR_EVT, (tUSERIAL_EVT_DATA *)p_buf); 804 805 GKI_send_event(USERIAL_HAL_TASK, HCISU_EVT); 806 ++bErrorReported; 807 } 808 if (sRxLength == 0) 809 { 810 ALOGE( "userial_read_thread(): my_read returned (%d) error count = %d, errno=%d exit read thread\n", 811 rx_length, error_count, errno); 812 break; 813 } 814 } 815 } 816 } /* for */ 817 818 ALOGD( "userial_read_thread(): freeing GKI_buffers\n"); 819 while ((p_buf = (BT_HDR *) GKI_dequeue (&Userial_in_q)) != NULL) 820 { 821 GKI_freebuf(p_buf); 822 ALOGD("userial_read_thread: dequeued buffer from Userial_in_q\n"); 823 } 824 825 GKI_exit_task (GKI_get_taskid ()); 826 ALOGD( "USERIAL READ: EXITING TASK\n"); 827 828 return 0; 829} 830 831/******************************************************************************* 832 ** 833 ** Function userial_to_tcio_baud 834 ** 835 ** Description helper function converts USERIAL baud rates into TCIO conforming baud rates 836 ** 837 ** Output Parameter None 838 ** 839 ** Returns TRUE - success 840 ** FALSE - unsupported baud rate, default of 115200 is used 841 ** 842 *******************************************************************************/ 843BOOLEAN userial_to_tcio_baud(UINT8 cfg_baud, UINT32 * baud) 844{ 845 if (cfg_baud == USERIAL_BAUD_600) 846 *baud = B600; 847 else if (cfg_baud == USERIAL_BAUD_1200) 848 *baud = B1200; 849 else if (cfg_baud == USERIAL_BAUD_9600) 850 *baud = B9600; 851 else if (cfg_baud == USERIAL_BAUD_19200) 852 *baud = B19200; 853 else if (cfg_baud == USERIAL_BAUD_57600) 854 *baud = B57600; 855 else if (cfg_baud == USERIAL_BAUD_115200) 856 *baud = B115200 | CBAUDEX; 857 else if (cfg_baud == USERIAL_BAUD_230400) 858 *baud = B230400; 859 else if (cfg_baud == USERIAL_BAUD_460800) 860 *baud = B460800; 861 else if (cfg_baud == USERIAL_BAUD_921600) 862 *baud = B921600; 863 else if (cfg_baud == USERIAL_BAUD_1M) 864 *baud = B1000000; 865 else if (cfg_baud == USERIAL_BAUD_2M) 866 *baud = B2000000; 867 else if (cfg_baud == USERIAL_BAUD_3M) 868 *baud = B3000000; 869 else if (cfg_baud == USERIAL_BAUD_4M) 870 *baud = B4000000; 871 else 872 { 873 ALOGE( "USERIAL_Open: unsupported baud idx %i", cfg_baud ); 874 *baud = B115200; 875 return FALSE; 876 } 877 return TRUE; 878} 879 880#if (USERIAL_USE_IO_BT_WAKE==TRUE) 881/******************************************************************************* 882 ** 883 ** Function userial_io_init_bt_wake 884 ** 885 ** Description helper function to set the open state of the bt_wake if ioctl 886 ** is used. it should not hurt in the rfkill case but it might 887 ** be better to compile it out. 888 ** 889 ** Returns none 890 ** 891 *******************************************************************************/ 892void userial_io_init_bt_wake( int fd, unsigned long * p_wake_state ) 893{ 894 /* assert BT_WAKE for ioctl. should NOT hurt on rfkill version */ 895 ioctl( fd, USERIAL_IO_BT_WAKE_ASSERT, NULL); 896 ioctl( fd, USERIAL_IO_BT_WAKE_GET_ST, p_wake_state ); 897 if ( *p_wake_state == 0) 898 ALOGI("\n***userial_io_init_bt_wake(): Ooops, asserted BT_WAKE signal, but still got BT_WAKE state == to %d\n", 899 *p_wake_state ); 900 901 *p_wake_state = 1; 902} 903#endif 904 905/******************************************************************************* 906** 907** Function USERIAL_Open 908** 909** Description Open the indicated serial port with the given configuration 910** 911** Output Parameter None 912** 913** Returns Nothing 914** 915*******************************************************************************/ 916UDRV_API void USERIAL_Open(tUSERIAL_PORT port, tUSERIAL_OPEN_CFG *p_cfg, tUSERIAL_CBACK *p_cback) 917{ 918 UINT32 baud = 0; 919 UINT8 data_bits = 0; 920 UINT16 parity = 0; 921 UINT8 stop_bits = 0; 922 struct termios termios; 923 const char ttyusb[] = "/dev/ttyUSB"; 924 const char devtty[] = "/dev/tty"; 925 unsigned long num = 0; 926 int ret = 0; 927 928 ALOGI("USERIAL_Open(): enter"); 929 930 //if userial_close_thread() is waiting to run; let it go first; 931 //let it finish; then continue this function 932 while (TRUE) 933 { 934 pthread_mutex_lock(&close_thread_mutex); 935 if (is_close_thread_is_waiting) 936 { 937 pthread_mutex_unlock(&close_thread_mutex); 938 ALOGI("USERIAL_Open(): wait for close-thread"); 939 sleep (1); 940 } 941 else 942 break; 943 } 944 945 // restore default power off delay settings incase they were changed in userial_set_poweroff_delays() 946 gPrePowerOffDelay = 0; 947 gPostPowerOffDelay = 0; 948 949 if ( !GetStrValue ( NAME_TRANSPORT_DRIVER, userial_dev, sizeof ( userial_dev ) ) ) 950 strcpy ( userial_dev, default_transport ); 951 if ( GetNumValue ( NAME_UART_PORT, &num, sizeof ( num ) ) ) 952 uart_port = num; 953 if ( GetNumValue ( NAME_LOW_SPEED_TRANSPORT, &num, sizeof ( num ) ) ) 954 isLowSpeedTransport = num; 955 if ( GetNumValue ( NAME_NFC_WAKE_DELAY, &num, sizeof ( num ) ) ) 956 nfc_wake_delay = num; 957 if ( GetNumValue ( NAME_NFC_WRITE_DELAY, &num, sizeof ( num ) ) ) 958 nfc_write_delay = num; 959 if ( GetNumValue ( NAME_PERF_MEASURE_FREQ, &num, sizeof ( num ) ) ) 960 perf_log_every_count = num; 961 if ( GetNumValue ( NAME_POWER_ON_DELAY, &num, sizeof ( num ) ) ) 962 gPowerOnDelay = num; 963 if ( GetNumValue ( NAME_PRE_POWER_OFF_DELAY, &num, sizeof ( num ) ) ) 964 gPrePowerOffDelay = num; 965 if ( GetNumValue ( NAME_POST_POWER_OFF_DELAY, &num, sizeof ( num ) ) ) 966 gPostPowerOffDelay = num; 967 ALOGI("USERIAL_Open() device: %s port=%d, uart_port=%d WAKE_DELAY(%d) WRITE_DELAY(%d) POWER_ON_DELAY(%d) PRE_POWER_OFF_DELAY(%d) POST_POWER_OFF_DELAY(%d)", 968 (char*)userial_dev, port, uart_port, nfc_wake_delay, nfc_write_delay, gPowerOnDelay, gPrePowerOffDelay, 969 gPostPowerOffDelay); 970 971 strcpy((char*)device_name, (char*)userial_dev); 972 sRxLength = 0; 973 _poll_t0 = 0; 974 975 if ((strncmp(userial_dev, ttyusb, sizeof(ttyusb)-1) == 0) || 976 (strncmp(userial_dev, devtty, sizeof(devtty)-1) == 0) ) 977 { 978 if (uart_port >= MAX_SERIAL_PORT) 979 { 980 ALOGD( "Port > MAX_SERIAL_PORT\n"); 981 goto done_open; 982 } 983 bSerialPortDevice = TRUE; 984 sprintf((char*)device_name, "%s%d", (char*)userial_dev, uart_port); 985 ALOGI("USERIAL_Open() using device_name: %s ", (char*)device_name); 986 if (!userial_to_tcio_baud(p_cfg->baud, &baud)) 987 goto done_open; 988 989 if (p_cfg->fmt & USERIAL_DATABITS_8) 990 data_bits = CS8; 991 else if (p_cfg->fmt & USERIAL_DATABITS_7) 992 data_bits = CS7; 993 else if (p_cfg->fmt & USERIAL_DATABITS_6) 994 data_bits = CS6; 995 else if (p_cfg->fmt & USERIAL_DATABITS_5) 996 data_bits = CS5; 997 else 998 goto done_open; 999 1000 if (p_cfg->fmt & USERIAL_PARITY_NONE) 1001 parity = 0; 1002 else if (p_cfg->fmt & USERIAL_PARITY_EVEN) 1003 parity = PARENB; 1004 else if (p_cfg->fmt & USERIAL_PARITY_ODD) 1005 parity = (PARENB | PARODD); 1006 else 1007 goto done_open; 1008 1009 if (p_cfg->fmt & USERIAL_STOPBITS_1) 1010 stop_bits = 0; 1011 else if (p_cfg->fmt & USERIAL_STOPBITS_2) 1012 stop_bits = CSTOPB; 1013 else 1014 goto done_open; 1015 } 1016 else 1017 strcpy((char*)device_name, (char*)userial_dev); 1018 1019 { 1020 ALOGD("%s Opening %s\n", __FUNCTION__, device_name); 1021 if ((linux_cb.sock = open((char*)device_name, O_RDWR | O_NOCTTY )) == -1) 1022 { 1023 ALOGI("%s unable to open %s", __FUNCTION__, device_name); 1024 GKI_send_event(NFC_HAL_TASK, NFC_HAL_TASK_EVT_TERMINATE); 1025 goto done_open; 1026 } 1027 ALOGD( "%s sock = %d\n", __FUNCTION__, linux_cb.sock); 1028 if (GetStrValue ( NAME_POWER_CONTROL_DRIVER, power_control_dev, sizeof ( power_control_dev ) ) && 1029 power_control_dev[0] != '\0') 1030 { 1031 if (strcmp(power_control_dev, userial_dev) == 0) 1032 linux_cb.sock_power_control = linux_cb.sock; 1033 else 1034 { 1035 if ((linux_cb.sock_power_control = open((char*)power_control_dev, O_RDWR | O_NOCTTY )) == -1) 1036 { 1037 ALOGI("%s unable to open %s", __FUNCTION__, power_control_dev); 1038 } 1039 } 1040 } 1041 if ( bSerialPortDevice ) 1042 { 1043 tcflush(linux_cb.sock, TCIOFLUSH); 1044 tcgetattr(linux_cb.sock, &termios); 1045 1046 termios.c_cflag &= ~(CSIZE | PARENB); 1047 termios.c_cflag = CLOCAL|CREAD|data_bits|stop_bits|parity; 1048 if (!parity) 1049 termios.c_cflag |= IGNPAR; 1050 // termios.c_cflag &= ~CRTSCTS; 1051 termios.c_oflag = 0; 1052 termios.c_lflag &= ~(ECHO | ECHONL | ICANON | IEXTEN | ISIG); 1053 termios.c_iflag &= ~(BRKINT | ICRNL | INLCR | ISTRIP | IXON | IGNBRK | PARMRK | INPCK); 1054 termios.c_lflag = 0; 1055 termios.c_iflag = 0; 1056 cfsetospeed(&termios, baud); 1057 cfsetispeed(&termios, baud); 1058 1059 termios.c_cc[VTIME] = 0; 1060 termios.c_cc[VMIN] = 1; 1061 tcsetattr(linux_cb.sock, TCSANOW, &termios); 1062 1063 tcflush(linux_cb.sock, TCIOFLUSH); 1064 1065#if (USERIAL_USE_IO_BT_WAKE==TRUE) 1066 userial_io_init_bt_wake( linux_cb.sock, &linux_cb.bt_wake_state ); 1067#endif 1068 GKI_delay(gPowerOnDelay); 1069 } 1070 else 1071 { 1072 USERIAL_PowerupDevice(port); 1073 } 1074 } 1075 1076 linux_cb.ser_cb = p_cback; 1077 linux_cb.port = port; 1078 memcpy(&linux_cb.open_cfg, p_cfg, sizeof(tUSERIAL_OPEN_CFG)); 1079 GKI_create_task ((TASKPTR)userial_read_thread, USERIAL_HAL_TASK, (INT8*)"USERIAL_HAL_TASK", 0, 0, (pthread_cond_t*)NULL, NULL); 1080 1081 1082#if (defined USERIAL_DEBUG) && (USERIAL_DEBUG == TRUE) 1083 ALOGD( "Leaving USERIAL_Open\n"); 1084#endif 1085 1086#if (SERIAL_AMBA == TRUE) 1087 /* give 20ms time for reader thread */ 1088 GKI_delay(20); 1089#endif 1090 1091done_open: 1092 pthread_mutex_unlock(&close_thread_mutex); 1093 ALOGI("USERIAL_Open(): exit"); 1094 return; 1095} 1096 1097/******************************************************************************* 1098** 1099** Function USERIAL_Read 1100** 1101** Description Read data from a serial port using byte buffers. 1102** 1103** Output Parameter None 1104** 1105** Returns Number of bytes actually read from the serial port and 1106** copied into p_data. This may be less than len. 1107** 1108*******************************************************************************/ 1109 1110static BT_HDR *pbuf_USERIAL_Read = NULL; 1111 1112UDRV_API UINT16 USERIAL_Read(tUSERIAL_PORT port, UINT8 *p_data, UINT16 len) 1113{ 1114 UINT16 total_len = 0; 1115 UINT16 copy_len = 0; 1116 UINT8 * current_packet = NULL; 1117 1118#if (defined USERIAL_DEBUG) && (USERIAL_DEBUG == TRUE) 1119 ALOGD( "%s ++ len=%d pbuf_USERIAL_Read=%p, p_data=%p\n", __func__, len, pbuf_USERIAL_Read, p_data); 1120#endif 1121 do 1122 { 1123 if (pbuf_USERIAL_Read != NULL) 1124 { 1125 current_packet = ((UINT8 *)(pbuf_USERIAL_Read + 1)) + (pbuf_USERIAL_Read->offset); 1126 1127 if ((pbuf_USERIAL_Read->len) <= (len - total_len)) 1128 copy_len = pbuf_USERIAL_Read->len; 1129 else 1130 copy_len = (len - total_len); 1131 1132 memcpy((p_data + total_len), current_packet, copy_len); 1133 1134 total_len += copy_len; 1135 1136 pbuf_USERIAL_Read->offset += copy_len; 1137 pbuf_USERIAL_Read->len -= copy_len; 1138 1139 if (pbuf_USERIAL_Read->len == 0) 1140 { 1141 GKI_freebuf(pbuf_USERIAL_Read); 1142 pbuf_USERIAL_Read = NULL; 1143 } 1144 } 1145 1146 if (pbuf_USERIAL_Read == NULL && (total_len < len)) 1147 pbuf_USERIAL_Read = (BT_HDR *)GKI_dequeue(&Userial_in_q); 1148 1149 } while ((pbuf_USERIAL_Read != NULL) && (total_len < len)); 1150 1151#if (defined USERIAL_DEBUG) && (USERIAL_DEBUG == TRUE) 1152 ALOGD( "%s: returned %d bytes", __func__, total_len); 1153#endif 1154 return total_len; 1155} 1156 1157/******************************************************************************* 1158** 1159** Function USERIAL_Readbuf 1160** 1161** Description Read data from a serial port using GKI buffers. 1162** 1163** Output Parameter Pointer to a GKI buffer which contains the data. 1164** 1165** Returns Nothing 1166** 1167** Comments The caller of this function is responsible for freeing the 1168** GKI buffer when it is finished with the data. If there is 1169** no data to be read, the value of the returned pointer is 1170** NULL. 1171** 1172*******************************************************************************/ 1173 1174UDRV_API void USERIAL_ReadBuf(tUSERIAL_PORT port, BT_HDR **p_buf) 1175{ 1176 1177} 1178 1179/******************************************************************************* 1180** 1181** Function USERIAL_WriteBuf 1182** 1183** Description Write data to a serial port using a GKI buffer. 1184** 1185** Output Parameter None 1186** 1187** Returns TRUE if buffer accepted for write. 1188** FALSE if there is already a buffer being processed. 1189** 1190** Comments The buffer will be freed by the serial driver. Therefore, 1191** the application calling this function must not free the 1192** buffer. 1193** 1194*******************************************************************************/ 1195 1196UDRV_API BOOLEAN USERIAL_WriteBuf(tUSERIAL_PORT port, BT_HDR *p_buf) 1197{ 1198 return FALSE; 1199} 1200 1201/******************************************************************************* 1202** 1203** Function USERIAL_Write 1204** 1205** Description Write data to a serial port using a byte buffer. 1206** 1207** Output Parameter None 1208** 1209** Returns Number of bytes actually written to the transport. This 1210** may be less than len. 1211** 1212*******************************************************************************/ 1213UDRV_API UINT16 USERIAL_Write(tUSERIAL_PORT port, UINT8 *p_data, UINT16 len) 1214{ 1215 int ret = 0, total = 0; 1216 int i = 0; 1217 clock_t t; 1218 1219 ALOGD_IF((appl_trace_level>=BT_TRACE_LEVEL_DEBUG), "USERIAL_Write: (%d bytes)", len); 1220 pthread_mutex_lock(&close_thread_mutex); 1221 1222 doWriteDelay(); 1223 t = clock(); 1224 while (len != 0 && linux_cb.sock != -1) 1225 { 1226 ret = write(linux_cb.sock, p_data + total, len); 1227 if (ret < 0) 1228 { 1229 ALOGE("USERIAL_Write len = %d, ret = %d, errno = %d", len, ret, errno); 1230 break; 1231 } 1232 else 1233 { 1234 ALOGD_IF((appl_trace_level>=BT_TRACE_LEVEL_DEBUG), "USERIAL_Write len = %d, ret = %d", len, ret); 1235 } 1236 1237 total += ret; 1238 len -= ret; 1239 } 1240 perf_update(&perf_write, clock() - t, total); 1241 1242 /* register a delay for next write */ 1243 setWriteDelay(total * nfc_write_delay / 1000); 1244 1245 pthread_mutex_unlock(&close_thread_mutex); 1246 1247 return ((UINT16)total); 1248} 1249 1250/******************************************************************************* 1251** 1252** Function userial_change_rate 1253** 1254** Description change naud rate 1255** 1256** Output Parameter None 1257** 1258** Returns None 1259** 1260*******************************************************************************/ 1261void userial_change_rate(UINT8 baud) 1262{ 1263#if defined (USING_BRCM_USB) && (USING_BRCM_USB == FALSE) 1264 struct termios termios; 1265#endif 1266#if (USERIAL_USE_TCIO_BAUD_CHANGE==TRUE) 1267 UINT32 tcio_baud; 1268#endif 1269 1270#if defined (USING_BRCM_USB) && (USING_BRCM_USB == FALSE) 1271 tcflush(linux_cb.sock, TCIOFLUSH); 1272 1273 tcgetattr(linux_cb.sock, &termios); 1274 1275 cfmakeraw(&termios); 1276 cfsetospeed(&termios, baud); 1277 cfsetispeed(&termios, baud); 1278 1279 termios.c_cflag |= (CLOCAL | CREAD | CRTSCTS | stop_bits); 1280 1281 tcsetattr(linux_cb.sock, TCSANOW, &termios); 1282 tcflush(linux_cb.sock, TCIOFLUSH); 1283 1284#else 1285#if (USERIAL_USE_TCIO_BAUD_CHANGE==FALSE) 1286 fprintf(stderr, "userial_change_rate: Closing UART Port\n"); 1287 ALOGI("userial_change_rate: Closing UART Port\n"); 1288 USERIAL_Close(linux_cb.port); 1289 1290 GKI_delay(50); 1291 1292 /* change baud rate in settings - leave everything else the same */ 1293 linux_cb.open_cfg.baud = baud; 1294 1295 ALOGD( "userial_change_rate: Attempting to reopen the UART Port at 0x%08x\n", (unsigned int)USERIAL_GetLineSpeed(baud)); 1296 ALOGI("userial_change_rate: Attempting to reopen the UART Port at %i\n", (unsigned int)USERIAL_GetLineSpeed(baud)); 1297 1298 USERIAL_Open(linux_cb.port, &linux_cb.open_cfg, linux_cb.ser_cb); 1299#else /* amba uart */ 1300 fprintf(stderr, "userial_change_rate(): changeing baud rate via TCIO \n"); 1301 ALOGI( "userial_change_rate: (): changeing baud rate via TCIO \n"); 1302 /* change baud rate in settings - leave everything else the same */ 1303 linux_cb.open_cfg.baud = baud; 1304 if (!userial_to_tcio_baud(linux_cb.open_cfg.baud, &tcio_baud)) 1305 return; 1306 1307 tcflush(linux_cb.sock, TCIOFLUSH); 1308 1309 /* get current settings. they should be fine besides baud rate we want to change */ 1310 tcgetattr(linux_cb.sock, &termios); 1311 1312 /* set input/output baudrate */ 1313 cfsetospeed(&termios, tcio_baud); 1314 cfsetispeed(&termios, tcio_baud); 1315 tcsetattr(linux_cb.sock, TCSANOW, &termios); 1316 1317 tcflush(linux_cb.sock, TCIOFLUSH); 1318#endif 1319#endif /* USING_BRCM_USB */ 1320} 1321 1322/******************************************************************************* 1323** 1324** Function userial_close_port 1325** 1326** Description close the transport driver 1327** 1328** Returns Nothing 1329** 1330*******************************************************************************/ 1331void userial_close_port( void ) 1332{ 1333 USERIAL_Close(linux_cb.port); 1334} 1335 1336/******************************************************************************* 1337** 1338** Function USERIAL_Ioctl 1339** 1340** Description Perform an operation on a serial port. 1341** 1342** Output Parameter The p_data parameter is either an input or output depending 1343** on the operation. 1344** 1345** Returns Nothing 1346** 1347*******************************************************************************/ 1348 1349UDRV_API void USERIAL_Ioctl(tUSERIAL_PORT port, tUSERIAL_OP op, tUSERIAL_IOCTL_DATA *p_data) 1350{ 1351#if (defined LINUX_OS) && (LINUX_OS == TRUE) 1352 USB_SCO_CONTROL ioctl_data; 1353 1354 /* just ignore port parameter as we are using USB in this case */ 1355#endif 1356 1357 switch (op) 1358 { 1359 case USERIAL_OP_FLUSH: 1360 break; 1361 case USERIAL_OP_FLUSH_RX: 1362 break; 1363 case USERIAL_OP_FLUSH_TX: 1364 break; 1365 case USERIAL_OP_BAUD_WR: 1366 ALOGI( "USERIAL_Ioctl: Received USERIAL_OP_BAUD_WR on port: %d, ioctl baud%i\n", port, p_data->baud); 1367 linux_cb.port = port; 1368 userial_change_rate(p_data->baud); 1369 break; 1370 1371 default: 1372 break; 1373 } 1374 1375 return; 1376} 1377 1378 1379/******************************************************************************* 1380** 1381** Function USERIAL_SetPowerOffDelays 1382** 1383** Description Set power off delays used during USERIAL_Close(). The 1384** values in the conf. file setting override these if set. 1385** 1386** Returns None. 1387** 1388*******************************************************************************/ 1389UDRV_API void USERIAL_SetPowerOffDelays(int pre_poweroff_delay, int post_poweroff_delay) 1390{ 1391 gPrePowerOffDelay = pre_poweroff_delay; 1392 gPostPowerOffDelay = post_poweroff_delay; 1393} 1394 1395/******************************************************************************* 1396** 1397** Function USERIAL_Close 1398** 1399** Description Close a serial port 1400** 1401** Output Parameter None 1402** 1403** Returns Nothing 1404** 1405*******************************************************************************/ 1406UDRV_API void USERIAL_Close(tUSERIAL_PORT port) 1407{ 1408 pthread_attr_t attr; 1409 pthread_t close_thread; 1410 1411 ALOGD ("%s: enter", __FUNCTION__); 1412 // check to see if thread is already running 1413 if (pthread_mutex_trylock(&close_thread_mutex) == 0) 1414 { 1415 // mutex aquired so thread is not running 1416 is_close_thread_is_waiting = TRUE; 1417 pthread_mutex_unlock(&close_thread_mutex); 1418 1419 // close transport in a new thread so we don't block the caller 1420 // make thread detached, no other thread will join 1421 pthread_attr_init(&attr); 1422 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 1423 pthread_create( &close_thread, &attr, (void *)userial_close_thread, NULL); 1424 pthread_attr_destroy(&attr); 1425 } 1426 else 1427 { 1428 // mutex not aquired to thread is already running 1429 ALOGD( "USERIAL_Close(): already closing \n"); 1430 } 1431 ALOGD ("%s: exit", __FUNCTION__); 1432} 1433 1434 1435/******************************************************************************* 1436** 1437** Function userial_close_thread 1438** 1439** Description Thread to close USERIAL 1440** 1441** Returns None. 1442** 1443*******************************************************************************/ 1444void userial_close_thread(UINT32 params) 1445{ 1446 BT_HDR *p_buf = NULL; 1447 int result; 1448 1449 ALOGD( "%s: closing transport (%d)\n", __FUNCTION__, linux_cb.sock); 1450 pthread_mutex_lock(&close_thread_mutex); 1451 is_close_thread_is_waiting = FALSE; 1452 1453 if (linux_cb.sock <= 0) 1454 { 1455 ALOGD( "%s: already closed (%d)\n", __FUNCTION__, linux_cb.sock); 1456 pthread_mutex_unlock(&close_thread_mutex); 1457 return; 1458 } 1459 1460 send_wakeup_signal(); 1461 result = pthread_join( worker_thread1, NULL ); 1462 if ( result < 0 ) 1463 ALOGE( "%s: pthread_join() FAILED: result: %d", __FUNCTION__, result ); 1464 else 1465 ALOGD( "%s: pthread_join() joined: result: %d", __FUNCTION__, result ); 1466 1467 if (linux_cb.sock_power_control > 0) 1468 { 1469 result = ioctl(linux_cb.sock_power_control, BCMNFC_WAKE_CTL, sleep_state()); 1470 ALOGD("%s: Delay %dms before turning off the chip", __FUNCTION__, gPrePowerOffDelay); 1471 GKI_delay(gPrePowerOffDelay); 1472 result = ioctl(linux_cb.sock_power_control, BCMNFC_POWER_CTL, 0); 1473 ALOGD("%s: Delay %dms after turning off the chip", __FUNCTION__, gPostPowerOffDelay); 1474 GKI_delay(gPostPowerOffDelay); 1475 } 1476 result = close(linux_cb.sock); 1477 if (result == -1) 1478 ALOGE("%s: fail close linux_cb.sock; errno=%d", __FUNCTION__, errno); 1479 1480 if (linux_cb.sock_power_control > 0 && linux_cb.sock_power_control != linux_cb.sock) 1481 result = close(linux_cb.sock_power_control); 1482 if (result == -1) 1483 ALOGE("%s: fail close linux_cb.sock_power_control; errno=%d", __FUNCTION__, errno); 1484 1485 linux_cb.sock_power_control = -1; 1486 linux_cb.sock = -1; 1487 1488 close_signal_fds(); 1489 pthread_mutex_unlock(&close_thread_mutex); 1490 ALOGD("%s: exiting", __FUNCTION__); 1491} 1492 1493/******************************************************************************* 1494** 1495** Function USERIAL_Feature 1496** 1497** Description Check whether a feature of the serial API is supported. 1498** 1499** Output Parameter None 1500** 1501** Returns TRUE if the feature is supported 1502** FALSE if the feature is not supported 1503** 1504*******************************************************************************/ 1505 1506UDRV_API BOOLEAN USERIAL_Feature(tUSERIAL_FEATURE feature) 1507{ 1508 switch (feature) 1509 { 1510 case USERIAL_FEAT_PORT_1: 1511 case USERIAL_FEAT_PORT_2: 1512 case USERIAL_FEAT_PORT_3: 1513 case USERIAL_FEAT_PORT_4: 1514 1515 case USERIAL_FEAT_BAUD_600: 1516 case USERIAL_FEAT_BAUD_1200: 1517 case USERIAL_FEAT_BAUD_9600: 1518 case USERIAL_FEAT_BAUD_19200: 1519 case USERIAL_FEAT_BAUD_57600: 1520 case USERIAL_FEAT_BAUD_115200: 1521 1522 case USERIAL_FEAT_STOPBITS_1: 1523 case USERIAL_FEAT_STOPBITS_2: 1524 1525 case USERIAL_FEAT_PARITY_NONE: 1526 case USERIAL_FEAT_PARITY_EVEN: 1527 case USERIAL_FEAT_PARITY_ODD: 1528 1529 case USERIAL_FEAT_DATABITS_5: 1530 case USERIAL_FEAT_DATABITS_6: 1531 case USERIAL_FEAT_DATABITS_7: 1532 case USERIAL_FEAT_DATABITS_8: 1533 1534 case USERIAL_FEAT_FC_HW: 1535 case USERIAL_FEAT_BUF_BYTE: 1536 1537 case USERIAL_FEAT_OP_FLUSH_RX: 1538 case USERIAL_FEAT_OP_FLUSH_TX: 1539 return TRUE; 1540 default: 1541 return FALSE; 1542 } 1543 1544 return FALSE; 1545} 1546 1547/***************************************************************************** 1548** 1549** Function UPIO_Set 1550** 1551** Description 1552** This function sets one or more GPIO devices to the given state. 1553** Multiple GPIOs of the same type can be masked together to set more 1554** than one GPIO. This function can only be used on types UPIO_LED and 1555** UPIO_GENERAL. 1556** 1557** Input Parameters: 1558** type The type of device. 1559** pio Indicates the particular GPIOs. 1560** state The desired state. 1561** 1562** Output Parameter: 1563** None. 1564** 1565** Returns: 1566** None. 1567** 1568*****************************************************************************/ 1569UDRV_API void UPIO_Set(tUPIO_TYPE type, tUPIO pio, tUPIO_STATE new_state) 1570{ 1571 int ret; 1572 if (type == UPIO_GENERAL) 1573 { 1574 if (pio == NFC_HAL_LP_NFC_WAKE_GPIO) 1575 { 1576 if (new_state == UPIO_ON || new_state == UPIO_OFF) 1577 { 1578 if (linux_cb.sock_power_control > 0) 1579 { 1580 ALOGD("%s: ioctl, state=%d", __func__, new_state); 1581 ret = ioctl(linux_cb.sock_power_control, BCMNFC_WAKE_CTL, new_state); 1582 if (isWake(new_state) && nfc_wake_delay > 0 && new_state != current_nfc_wake_state) 1583 { 1584 ALOGD("%s: ioctl, old state=%d, insert delay for %d ms", __func__, current_nfc_wake_state, nfc_wake_delay); 1585 setWriteDelay(nfc_wake_delay); 1586 } 1587 current_nfc_wake_state = new_state; 1588 } 1589 } 1590 } 1591 } 1592} 1593 1594/***************************************************************************** 1595** 1596** Function setReadPacketSize 1597** 1598** Description 1599** This function sets the packetSize to the driver. 1600** this enables faster read operation of NCI/HCI responses 1601** 1602** Input Parameters: 1603** len number of bytes to read per operation. 1604** 1605** Output Parameter: 1606** None. 1607** 1608** Returns: 1609** None. 1610** 1611*****************************************************************************/ 1612void setReadPacketSize(int len) 1613{ 1614 int ret; 1615 ALOGD("%s: ioctl, len=%d", __func__, len); 1616 ret = ioctl(linux_cb.sock, BCMNFC_READ_FULL_PACKET, len); 1617} 1618 1619 1620UDRV_API BOOLEAN USERIAL_IsClosed() 1621{ 1622 return (linux_cb.sock == -1) ? TRUE : FALSE; 1623} 1624 1625UDRV_API void USERIAL_PowerupDevice(tUSERIAL_PORT port) 1626{ 1627 int ret = -1; 1628 unsigned long num = 0; 1629 unsigned int resetSuccess = 0; 1630 unsigned int numTries = 0; 1631 unsigned char spi_negotiation[64]; 1632 int delay = gPowerOnDelay; 1633 ALOGD("%s: enter", __FUNCTION__); 1634 1635 if ( GetNumValue ( NAME_READ_MULTI_PACKETS, &num, sizeof ( num ) ) ) 1636 bcmi2cnfc_read_multi_packets = num; 1637 1638 if (bcmi2cnfc_read_multi_packets > 0) 1639 ioctl(linux_cb.sock, BCMNFC_READ_MULTI_PACKETS, bcmi2cnfc_read_multi_packets); 1640 1641 while (!resetSuccess && numTries < NUM_RESET_ATTEMPTS) { 1642 if (numTries++ > 0) { 1643 ALOGW("BCM2079x: retrying reset, attempt %d/%d", numTries, NUM_RESET_ATTEMPTS); 1644 } 1645 if (linux_cb.sock_power_control > 0) 1646 { 1647 current_nfc_wake_state = NFC_WAKE_ASSERTED_ON_POR; 1648 ioctl(linux_cb.sock_power_control, BCMNFC_WAKE_CTL, NFC_WAKE_ASSERTED_ON_POR); 1649 ioctl(linux_cb.sock_power_control, BCMNFC_POWER_CTL, 0); 1650 GKI_delay(10); 1651 ret = ioctl(linux_cb.sock_power_control, BCMNFC_POWER_CTL, 1); 1652 } 1653 1654 ret = GetStrValue ( NAME_SPI_NEGOTIATION, (char*)spi_negotiation, sizeof ( spi_negotiation ) ); 1655 if (ret > 0 && spi_negotiation[0] > 0 && spi_negotiation[0] < sizeof ( spi_negotiation ) - 1) 1656 { 1657 int len = spi_negotiation[0]; 1658 /* Wake control is not available: Start SPI negotiation*/ 1659 USERIAL_Write(port, &spi_negotiation[1], len); 1660 USERIAL_Read(port, spi_negotiation, sizeof ( spi_negotiation )); 1661 } 1662 1663 if ( GetNumValue ( NAME_CLIENT_ADDRESS, &num, sizeof ( num ) ) ) 1664 bcmi2cnfc_client_addr = num & 0xFF; 1665 if (bcmi2cnfc_client_addr != 0 && 1666 0x07 < bcmi2cnfc_client_addr && 1667 bcmi2cnfc_client_addr < 0x78) 1668 { 1669 /* Delay needed after turning on chip */ 1670 GKI_delay(delay); 1671 ALOGD( "Change client address to %x\n", bcmi2cnfc_client_addr); 1672 ret = change_client_addr(bcmi2cnfc_client_addr); 1673 if (!ret) { 1674 resetSuccess = 1; 1675 linux_cb.client_device_address = bcmi2cnfc_client_addr; 1676 /* Delay long enough for address change */ 1677 delay = 100; 1678 } 1679 } else { 1680 resetSuccess = 1; 1681 } 1682 } 1683 1684 if (!resetSuccess) { 1685 ALOGE("BCM2079x: failed to initialize NFC controller"); 1686 } 1687 1688 GKI_delay(delay); 1689 ALOGD("%s: exit", __FUNCTION__); 1690} 1691 1692#define DEFAULT_CLIENT_ADDRESS 0x77 1693#define ALIAS_CLIENT_ADDRESS 0x79 1694static int change_client_addr(int addr) 1695{ 1696 int ret; 1697 int i; 1698 char addr_data[] = { 1699 0xFA, 0xF2, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x2A 1700 }; 1701 int size = sizeof(addr_data) - 1; 1702 1703 addr_data[5] = addr & 0xFF; 1704 1705 /* set the checksum */ 1706 ret = 0; 1707 for (i = 1; i < size; ++i) 1708 ret += addr_data[i]; 1709 addr_data[size] = (ret & 0xFF); 1710 ALOGD( "change_client_addr() change addr from 0x%x to 0x%x\n", DEFAULT_CLIENT_ADDRESS, addr); 1711 /* ignore the return code from IOCTL */ 1712 /* always revert back to the default client address */ 1713 ioctl(linux_cb.sock, BCMNFC_SET_CLIENT_ADDR, DEFAULT_CLIENT_ADDRESS); 1714 /* Send address change command (skipping first byte) */ 1715 ret = write(linux_cb.sock, &addr_data[1], size); 1716 1717 /* If it fails, it is likely a B3 we are talking to */ 1718 if (ret != size) { 1719 ALOGD( "change_client_addr() change addr to 0x%x by setting BSP address to 0x%x\n", addr, ALIAS_CLIENT_ADDRESS); 1720 /* legacy kernel */ 1721 ioctl(linux_cb.sock, BCMNFC_CHANGE_ADDR, addr); 1722 /* We'll tweak address to make it look like 0x1FA address */ 1723 ret = ioctl(linux_cb.sock, BCMNFC_SET_CLIENT_ADDR, ALIAS_CLIENT_ADDRESS); 1724 size++; 1725 ret = write(linux_cb.sock, addr_data, size); 1726 } 1727 1728 if (ret == size) { 1729 ALOGD( "change_client_addr() set client address 0x%x to client driver\n", addr); 1730 ret = ioctl(linux_cb.sock, BCMNFC_SET_CLIENT_ADDR, addr); 1731 } 1732 else { 1733 ret = -EIO; 1734 } 1735 return ret; 1736} 1737