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