blob: e6fc91f0397db151c9fe125aba6941ca96deded4 [file] [log] [blame]
STMicroelectronicse5060d52017-10-12 14:30:37 -07001/******************************************************************************
2 *
3 * Copyright (C) 1999-2012 Broadcom Corporation
4 * Copyright (C) 2013 ST Microelectronics S.A.
5 *
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at:
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
17 *
18 * Modified by ST Microelectronics S.A. (adaptation of nfc_nci.c for ST21NFC
19 *NCI version)
20 *
21 ******************************************************************************/
22
23#include <cutils/properties.h>
24#include <errno.h>
25#include <hardware/nfc.h>
26#include <string.h>
27
28#include "android_logmsg.h"
29#include "halcore.h"
30
31extern void HalCoreCallback(void* context, uint32_t event, const void* d,
32 size_t length);
33extern bool I2cOpenLayer(void* dev, HAL_CALLBACK callb, HALHANDLE* pHandle);
34extern int I2cWriteCmd(const uint8_t* x, size_t len);
35extern int GetNumValue(const char* name, void* p_value, unsigned long len);
36
37typedef struct {
38 struct nfc_nci_device nci_device; // nci_device must be first struct member
39 // below declarations are private variables within HAL
40 nfc_stack_callback_t* p_cback;
41 nfc_stack_data_callback_t* p_data_cback;
42 HALHANDLE hHAL;
43} st21nfc_dev_t;
44
45char* halVersion = "ST21NFC NCI Version 3.0.0";
46uint8_t cmd_set_nfc_mode_enable[] = {0x2f, 0x02, 0x02, 0x02, 0x01};
47uint8_t hal_is_closed = 1;
48pthread_mutex_t hal_mtx = PTHREAD_MUTEX_INITIALIZER;
49
50uint8_t hal_dta_state = 0;
51
52
53/*
54 * NCI HAL method implementations. These must be overridden
55 */
56
57extern bool hal_wrapper_open(st21nfc_dev_t* dev, nfc_stack_callback_t* p_cback,
58 nfc_stack_data_callback_t* p_data_cback,
59 HALHANDLE* pHandle);
60
61extern int hal_wrapper_close(st21nfc_dev_t* dev, int call_cb);
62
63static int hal_open(const struct nfc_nci_device* p_dev,
64 nfc_stack_callback_t* p_cback,
65 nfc_stack_data_callback_t* p_data_cback) {
66 bool result = false;
67
68 STLOG_HAL_D("NFC-NCI HAL: %s %s", __func__, halVersion);
69
70 (void)pthread_mutex_lock(&hal_mtx);
71 st21nfc_dev_t* dev = (st21nfc_dev_t*)p_dev;
72 if (! hal_is_closed ) {
73 hal_wrapper_close(dev, 0);
74 }
75 dev->p_cback = p_cback;
76 dev->p_data_cback = p_data_cback;
77
78 hal_dta_state = 0;
79
80 result = hal_wrapper_open(dev, p_cback, p_data_cback, &dev->hHAL);
81
82 if (!result || !dev->hHAL) {
83 (void)pthread_mutex_unlock(&hal_mtx);
84 dev->p_cback(HAL_NFC_OPEN_CPLT_EVT, HAL_NFC_STATUS_FAILED);
85 return -1; // We are doomed, stop it here, NOW !
86 }
87 hal_is_closed = 0;
88 (void)pthread_mutex_unlock(&hal_mtx);
89 return 0;
90}
91
92static int hal_write(const struct nfc_nci_device* p_dev, uint16_t data_len,
93 const uint8_t* p_data) {
94 STLOG_HAL_D("NFC-NCI HAL: %s", __func__);
95
96 st21nfc_dev_t* dev = (st21nfc_dev_t*)p_dev;
97
98 /* check if HAL is closed */
99 int ret = (int)data_len;
100 (void)pthread_mutex_lock(&hal_mtx);
101 if ( hal_is_closed ) {
102 ret = 0;
103 }
104 (void)pthread_mutex_unlock(&hal_mtx);
105 if (!ret)
106 return ret;
107 if (!HalSendDownstream(dev->hHAL, p_data, data_len)) {
108 STLOG_HAL_E("NFC-NCI HAL: %s SendDownstream failed", __func__);
109 return 0;
110 }
111
112 return ret;
113}
114
115static int hal_core_initialized(const struct nfc_nci_device* p_dev,
116 uint8_t* p_core_init_rsp_params) {
117 STLOG_HAL_D("NFC-NCI HAL: %s", __func__);
118
119 st21nfc_dev_t* dev = (st21nfc_dev_t*)p_dev;
120
121 hal_dta_state = *p_core_init_rsp_params;
122
123 dev->p_cback(HAL_NFC_POST_INIT_CPLT_EVT, HAL_NFC_STATUS_OK);
124
125 return 0; // return != 0 to signal ready immediate
126}
127
128static int hal_pre_discover(const struct nfc_nci_device* p_dev) {
129 STLOG_HAL_D("NFC-NCI HAL: %s", __func__);
130
131 st21nfc_dev_t* dev = (st21nfc_dev_t*)p_dev;
132
133 return 0; // false if no vendor-specific pre-discovery actions are needed
134}
135
136static int hal_close(const struct nfc_nci_device* p_dev) {
137 STLOG_HAL_D("NFC-NCI HAL: %s", __func__);
138
139 st21nfc_dev_t* dev = (st21nfc_dev_t*)p_dev;
140 uint8_t cmd = 'X';
141
142 /* check if HAL is closed */
143 (void)pthread_mutex_lock(&hal_mtx);
144 if ( hal_is_closed ) {
145 (void)pthread_mutex_unlock(&hal_mtx);
146 return 1;
147 }
148 if (hal_wrapper_close(dev, 1) == 0) {
149 hal_is_closed = 1;
150 (void)pthread_mutex_unlock(&hal_mtx);
151 return 1;
152 }
153 hal_is_closed = 1;
154 (void)pthread_mutex_unlock(&hal_mtx);
155
156 hal_dta_state = 0;
157
158 return 0;
159}
160
161static int hal_control_granted(const struct nfc_nci_device* p_dev) {
162 STLOG_HAL_D("NFC-NCI HAL: %s", __func__);
163
164 st21nfc_dev_t* dev = (st21nfc_dev_t*)p_dev;
165
166 return 0;
167}
168
169static int hal_power_cycle(const struct nfc_nci_device* p_dev) {
170 STLOG_HAL_D("NFC-NCI HAL: %s", __func__);
171
172 st21nfc_dev_t* dev = (st21nfc_dev_t*)p_dev;
173
174 /* check if HAL is closed */
175 int ret = HAL_NFC_STATUS_OK;
176 (void)pthread_mutex_lock(&hal_mtx);
177 if ( hal_is_closed ) {
178 ret = HAL_NFC_STATUS_FAILED;
179 }
180 (void)pthread_mutex_unlock(&hal_mtx);
181 if (ret != HAL_NFC_STATUS_OK)
182 return ret;
183 dev->p_cback(HAL_NFC_OPEN_CPLT_EVT, HAL_NFC_STATUS_OK);
184
185 return HAL_NFC_STATUS_OK;
186}
187
188/*
189 * Generic device handling below
190 */
191
192/* Close an opened nfc device instance */
193static int nfc_close(hw_device_t* dev) {
194 free(dev);
195 return 0;
196}
197
198static int nfc_open(const hw_module_t* module, const char* name,
199 hw_device_t** device) {
200 unsigned long num = 0;
201 char valueStr[PROPERTY_VALUE_MAX] = {0};
202
203 if (strcmp(name, NFC_NCI_CONTROLLER) == 0) {
204 st21nfc_dev_t* dev = calloc(1, sizeof(st21nfc_dev_t));
205
206 dev->nci_device.common.tag = HARDWARE_DEVICE_TAG;
207 dev->nci_device.common.version = 0x00010000; // [31:16] major, [15:0] minor
208 dev->nci_device.common.module = (struct hw_module_t*)module;
209 dev->nci_device.common.close = nfc_close;
210
211 // NCI HAL method pointers
212 dev->nci_device.open = hal_open;
213 dev->nci_device.write = hal_write;
214 dev->nci_device.core_initialized = hal_core_initialized;
215 dev->nci_device.pre_discover = hal_pre_discover;
216 dev->nci_device.close = hal_close;
217 dev->nci_device.control_granted = hal_control_granted;
218 dev->nci_device.power_cycle = hal_power_cycle;
219
220 *device = (hw_device_t*)dev;
221
222 // Initialize and get global logging level
223 InitializeSTLogLevel();
224
225 return 0;
226 } else {
227 return -EINVAL;
228 }
229}
230
231static struct hw_module_methods_t nfc_module_methods = {
232 .open = nfc_open,
233};
234
235struct nfc_nci_module_t HAL_MODULE_INFO_SYM = {
236 .common =
237 {
238 .tag = HARDWARE_MODULE_TAG,
239 .module_api_version = 0x0100, // [15:8] major, [7:0] minor (1.0)
240 .hal_api_version = 0x00, // 0 is only valid value
241 .id = "nfc_nci.st21nfc",
242 .name = "ST Micro ST21NFC NCI HW HAL",
243 .author = "ST Microelectronics SA ",
244 .methods = &nfc_module_methods,
245 },
246};