1 /******************************************************************************
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 #include <pthread.h>
28
29 #include "android_logmsg.h"
30 #include "halcore.h"
31
32 extern void HalCoreCallback(void* context, uint32_t event, const void* d,
33 size_t length);
34 extern bool I2cOpenLayer(void* dev, HAL_CALLBACK callb, HALHANDLE* pHandle);
35
36
37 typedef 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
45 char* halVersion = "ST21NFC NCI Version 3.0.5";
46 uint8_t cmd_set_nfc_mode_enable[] = {0x2f, 0x02, 0x02, 0x02, 0x01};
47 uint8_t hal_is_closed = 1;
48 pthread_mutex_t hal_mtx = PTHREAD_MUTEX_INITIALIZER;
49
50 uint8_t hal_dta_state = 0;
51
52
53 /*
54 * NCI HAL method implementations. These must be overridden
55 */
56
57 extern 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
61 extern int hal_wrapper_close(int call_cb);
62
hal_open(const struct nfc_nci_device * p_dev,nfc_stack_callback_t * p_cback,nfc_stack_data_callback_t * p_data_cback)63 static 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(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 {
84 dev->p_cback(HAL_NFC_OPEN_CPLT_EVT, HAL_NFC_STATUS_FAILED);
85 (void) pthread_mutex_unlock(&hal_mtx);
86 return -1; // We are doomed, stop it here, NOW !
87 }
88 hal_is_closed = 0;
89 (void)pthread_mutex_unlock(&hal_mtx);
90 return 0;
91 }
92
hal_write(const struct nfc_nci_device * p_dev,uint16_t data_len,const uint8_t * p_data)93 static int hal_write(const struct nfc_nci_device* p_dev, uint16_t data_len,
94 const uint8_t* p_data) {
95 STLOG_HAL_D("NFC-NCI HAL: %s", __func__);
96
97 st21nfc_dev_t* dev = (st21nfc_dev_t*)p_dev;
98
99 /* check if HAL is closed */
100 int ret = (int)data_len;
101 (void) pthread_mutex_lock(&hal_mtx);
102 if (hal_is_closed)
103 {
104 ret = 0;
105 }
106
107 if (!ret)
108 {
109 (void) pthread_mutex_unlock(&hal_mtx);
110 return ret;
111 }
112 if (!HalSendDownstream(dev->hHAL, p_data, data_len))
113 {
114 STLOG_HAL_E("NFC-NCI HAL: %s SendDownstream failed", __func__);
115 (void) pthread_mutex_unlock(&hal_mtx);
116 return 0;
117 }
118 (void) pthread_mutex_unlock(&hal_mtx);
119
120 return ret;
121 }
122
hal_core_initialized(const struct nfc_nci_device * p_dev,uint8_t * p_core_init_rsp_params)123 static int hal_core_initialized(const struct nfc_nci_device* p_dev,
124 uint8_t* p_core_init_rsp_params) {
125 STLOG_HAL_D("NFC-NCI HAL: %s", __func__);
126
127 (void)pthread_mutex_lock(&hal_mtx);
128 st21nfc_dev_t* dev = (st21nfc_dev_t*)p_dev;
129 hal_dta_state = *p_core_init_rsp_params;
130 dev->p_cback(HAL_NFC_POST_INIT_CPLT_EVT, HAL_NFC_STATUS_OK);
131 (void) pthread_mutex_unlock(&hal_mtx);
132
133 return 0; // return != 0 to signal ready immediate
134 }
135
hal_pre_discover(const struct nfc_nci_device * p_dev)136 static int hal_pre_discover(__attribute__((unused)) const struct nfc_nci_device* p_dev) {
137 STLOG_HAL_D("NFC-NCI HAL: %s", __func__);
138
139 return 0; // false if no vendor-specific pre-discovery actions are needed
140 }
141
hal_close(const struct nfc_nci_device * p_dev)142 static int hal_close(__attribute__((unused)) const struct nfc_nci_device* p_dev) {
143 STLOG_HAL_D("NFC-NCI HAL: %s", __func__);
144
145 /* check if HAL is closed */
146 (void)pthread_mutex_lock(&hal_mtx);
147 if ( hal_is_closed ) {
148 (void)pthread_mutex_unlock(&hal_mtx);
149 return 1;
150 }
151 if (hal_wrapper_close(1) == 0) {
152 hal_is_closed = 1;
153 (void)pthread_mutex_unlock(&hal_mtx);
154 return 1;
155 }
156 hal_is_closed = 1;
157 (void)pthread_mutex_unlock(&hal_mtx);
158
159 hal_dta_state = 0;
160
161 return 0;
162 }
163
hal_control_granted(const struct nfc_nci_device * p_dev)164 static int hal_control_granted(__attribute__((unused)) const struct nfc_nci_device* p_dev) {
165 STLOG_HAL_D("NFC-NCI HAL: %s", __func__);
166
167 return 0;
168 }
169
hal_power_cycle(const struct nfc_nci_device * p_dev)170 static int hal_power_cycle(const struct nfc_nci_device* p_dev) {
171 STLOG_HAL_D("NFC-NCI HAL: %s", __func__);
172
173 st21nfc_dev_t* dev = (st21nfc_dev_t*)p_dev;
174
175 /* check if HAL is closed */
176 int ret = HAL_NFC_STATUS_OK;
177 (void) pthread_mutex_lock(&hal_mtx);
178 if (hal_is_closed)
179 {
180 ret = HAL_NFC_STATUS_FAILED;
181 }
182
183 if (ret != HAL_NFC_STATUS_OK)
184 {
185 (void) pthread_mutex_unlock(&hal_mtx);
186 return ret;
187 }
188 dev->p_cback(HAL_NFC_OPEN_CPLT_EVT, HAL_NFC_STATUS_OK);
189
190 (void) pthread_mutex_unlock(&hal_mtx);
191 return HAL_NFC_STATUS_OK;
192 }
193
194 /*
195 * Generic device handling below
196 */
197
198 /* Close an opened nfc device instance */
nfc_close(hw_device_t * dev)199 static int nfc_close(hw_device_t* dev) {
200 (void) pthread_mutex_lock(&hal_mtx);
201 free(dev);
202 (void) pthread_mutex_unlock(&hal_mtx);
203 return 0;
204 }
205
nfc_open(const hw_module_t * module,const char * name,hw_device_t ** device)206 static int nfc_open(const hw_module_t* module, const char* name,
207 hw_device_t** device) {
208
209 if (strcmp(name, NFC_NCI_CONTROLLER) == 0) {
210 st21nfc_dev_t* dev = calloc(1, sizeof(st21nfc_dev_t));
211
212 dev->nci_device.common.tag = HARDWARE_DEVICE_TAG;
213 dev->nci_device.common.version = 0x00010000; // [31:16] major, [15:0] minor
214 dev->nci_device.common.module = (struct hw_module_t*)module;
215 dev->nci_device.common.close = nfc_close;
216
217 // NCI HAL method pointers
218 dev->nci_device.open = hal_open;
219 dev->nci_device.write = hal_write;
220 dev->nci_device.core_initialized = hal_core_initialized;
221 dev->nci_device.pre_discover = hal_pre_discover;
222 dev->nci_device.close = hal_close;
223 dev->nci_device.control_granted = hal_control_granted;
224 dev->nci_device.power_cycle = hal_power_cycle;
225
226 *device = (hw_device_t*)dev;
227
228 // Initialize and get global logging level
229 InitializeSTLogLevel();
230
231 return 0;
232 } else {
233 return -EINVAL;
234 }
235 }
236
237 static struct hw_module_methods_t nfc_module_methods = {
238 .open = nfc_open,
239 };
240
241 struct nfc_nci_module_t HAL_MODULE_INFO_SYM = {
242 .common =
243 {
244 .tag = HARDWARE_MODULE_TAG,
245 .module_api_version = 0x0100, // [15:8] major, [7:0] minor (1.0)
246 .hal_api_version = 0x00, // 0 is only valid value
247 .id = "nfc_nci.st21nfc",
248 .name = "ST Micro ST21NFC NCI HW HAL",
249 .author = "ST Microelectronics SA ",
250 .methods = &nfc_module_methods,
251 },
252 };
253