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