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