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