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