blob: d6481a8ce25eb84f863c4bdc63a8e165561ba311 [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);
Arach MOHAMMED BRAHIMabf4b1c2018-01-29 11:24:53 +010034
STMicroelectronicse5060d52017-10-12 14:30:37 -070035
36typedef struct {
37 struct nfc_nci_device nci_device; // nci_device must be first struct member
38 // below declarations are private variables within HAL
39 nfc_stack_callback_t* p_cback;
40 nfc_stack_data_callback_t* p_data_cback;
41 HALHANDLE hHAL;
42} st21nfc_dev_t;
43
44char* halVersion = "ST21NFC NCI Version 3.0.0";
45uint8_t cmd_set_nfc_mode_enable[] = {0x2f, 0x02, 0x02, 0x02, 0x01};
46uint8_t hal_is_closed = 1;
47pthread_mutex_t hal_mtx = PTHREAD_MUTEX_INITIALIZER;
48
49uint8_t hal_dta_state = 0;
50
51
52/*
53 * NCI HAL method implementations. These must be overridden
54 */
55
56extern bool hal_wrapper_open(st21nfc_dev_t* dev, nfc_stack_callback_t* p_cback,
57 nfc_stack_data_callback_t* p_data_cback,
58 HALHANDLE* pHandle);
59
Arach MOHAMMED BRAHIM2d481292018-01-29 11:27:05 +010060extern int hal_wrapper_close(int call_cb);
STMicroelectronicse5060d52017-10-12 14:30:37 -070061
62static int hal_open(const struct nfc_nci_device* p_dev,
63 nfc_stack_callback_t* p_cback,
64 nfc_stack_data_callback_t* p_data_cback) {
65 bool result = false;
66
67 STLOG_HAL_D("NFC-NCI HAL: %s %s", __func__, halVersion);
68
69 (void)pthread_mutex_lock(&hal_mtx);
70 st21nfc_dev_t* dev = (st21nfc_dev_t*)p_dev;
71 if (! hal_is_closed ) {
Arach MOHAMMED BRAHIM2d481292018-01-29 11:27:05 +010072 hal_wrapper_close(0);
STMicroelectronicse5060d52017-10-12 14:30:37 -070073 }
74 dev->p_cback = p_cback;
75 dev->p_data_cback = p_data_cback;
76
77 hal_dta_state = 0;
78
79 result = hal_wrapper_open(dev, p_cback, p_data_cback, &dev->hHAL);
80
81 if (!result || !dev->hHAL) {
82 (void)pthread_mutex_unlock(&hal_mtx);
83 dev->p_cback(HAL_NFC_OPEN_CPLT_EVT, HAL_NFC_STATUS_FAILED);
84 return -1; // We are doomed, stop it here, NOW !
85 }
86 hal_is_closed = 0;
87 (void)pthread_mutex_unlock(&hal_mtx);
88 return 0;
89}
90
91static int hal_write(const struct nfc_nci_device* p_dev, uint16_t data_len,
92 const uint8_t* p_data) {
93 STLOG_HAL_D("NFC-NCI HAL: %s", __func__);
94
95 st21nfc_dev_t* dev = (st21nfc_dev_t*)p_dev;
96
97 /* check if HAL is closed */
98 int ret = (int)data_len;
99 (void)pthread_mutex_lock(&hal_mtx);
100 if ( hal_is_closed ) {
101 ret = 0;
102 }
103 (void)pthread_mutex_unlock(&hal_mtx);
104 if (!ret)
105 return ret;
106 if (!HalSendDownstream(dev->hHAL, p_data, data_len)) {
107 STLOG_HAL_E("NFC-NCI HAL: %s SendDownstream failed", __func__);
108 return 0;
109 }
110
111 return ret;
112}
113
114static int hal_core_initialized(const struct nfc_nci_device* p_dev,
115 uint8_t* p_core_init_rsp_params) {
116 STLOG_HAL_D("NFC-NCI HAL: %s", __func__);
117
118 st21nfc_dev_t* dev = (st21nfc_dev_t*)p_dev;
119
120 hal_dta_state = *p_core_init_rsp_params;
121
122 dev->p_cback(HAL_NFC_POST_INIT_CPLT_EVT, HAL_NFC_STATUS_OK);
123
124 return 0; // return != 0 to signal ready immediate
125}
126
127static int hal_pre_discover(const struct nfc_nci_device* p_dev) {
128 STLOG_HAL_D("NFC-NCI HAL: %s", __func__);
129
130 st21nfc_dev_t* dev = (st21nfc_dev_t*)p_dev;
131
132 return 0; // false if no vendor-specific pre-discovery actions are needed
133}
134
135static int hal_close(const struct nfc_nci_device* p_dev) {
136 STLOG_HAL_D("NFC-NCI HAL: %s", __func__);
137
138 st21nfc_dev_t* dev = (st21nfc_dev_t*)p_dev;
STMicroelectronicse5060d52017-10-12 14:30:37 -0700139
140 /* check if HAL is closed */
141 (void)pthread_mutex_lock(&hal_mtx);
142 if ( hal_is_closed ) {
143 (void)pthread_mutex_unlock(&hal_mtx);
144 return 1;
145 }
Arach MOHAMMED BRAHIM2d481292018-01-29 11:27:05 +0100146 if (hal_wrapper_close(1) == 0) {
STMicroelectronicse5060d52017-10-12 14:30:37 -0700147 hal_is_closed = 1;
148 (void)pthread_mutex_unlock(&hal_mtx);
149 return 1;
150 }
151 hal_is_closed = 1;
152 (void)pthread_mutex_unlock(&hal_mtx);
153
154 hal_dta_state = 0;
155
156 return 0;
157}
158
159static int hal_control_granted(const struct nfc_nci_device* p_dev) {
160 STLOG_HAL_D("NFC-NCI HAL: %s", __func__);
161
162 st21nfc_dev_t* dev = (st21nfc_dev_t*)p_dev;
163
164 return 0;
165}
166
167static int hal_power_cycle(const struct nfc_nci_device* p_dev) {
168 STLOG_HAL_D("NFC-NCI HAL: %s", __func__);
169
170 st21nfc_dev_t* dev = (st21nfc_dev_t*)p_dev;
171
172 /* check if HAL is closed */
173 int ret = HAL_NFC_STATUS_OK;
174 (void)pthread_mutex_lock(&hal_mtx);
175 if ( hal_is_closed ) {
176 ret = HAL_NFC_STATUS_FAILED;
177 }
178 (void)pthread_mutex_unlock(&hal_mtx);
179 if (ret != HAL_NFC_STATUS_OK)
180 return ret;
181 dev->p_cback(HAL_NFC_OPEN_CPLT_EVT, HAL_NFC_STATUS_OK);
182
183 return HAL_NFC_STATUS_OK;
184}
185
186/*
187 * Generic device handling below
188 */
189
190/* Close an opened nfc device instance */
191static int nfc_close(hw_device_t* dev) {
192 free(dev);
193 return 0;
194}
195
196static int nfc_open(const hw_module_t* module, const char* name,
197 hw_device_t** device) {
STMicroelectronicse5060d52017-10-12 14:30:37 -0700198
199 if (strcmp(name, NFC_NCI_CONTROLLER) == 0) {
200 st21nfc_dev_t* dev = calloc(1, sizeof(st21nfc_dev_t));
201
202 dev->nci_device.common.tag = HARDWARE_DEVICE_TAG;
203 dev->nci_device.common.version = 0x00010000; // [31:16] major, [15:0] minor
204 dev->nci_device.common.module = (struct hw_module_t*)module;
205 dev->nci_device.common.close = nfc_close;
206
207 // NCI HAL method pointers
208 dev->nci_device.open = hal_open;
209 dev->nci_device.write = hal_write;
210 dev->nci_device.core_initialized = hal_core_initialized;
211 dev->nci_device.pre_discover = hal_pre_discover;
212 dev->nci_device.close = hal_close;
213 dev->nci_device.control_granted = hal_control_granted;
214 dev->nci_device.power_cycle = hal_power_cycle;
215
216 *device = (hw_device_t*)dev;
217
218 // Initialize and get global logging level
219 InitializeSTLogLevel();
220
221 return 0;
222 } else {
223 return -EINVAL;
224 }
225}
226
227static struct hw_module_methods_t nfc_module_methods = {
228 .open = nfc_open,
229};
230
231struct nfc_nci_module_t HAL_MODULE_INFO_SYM = {
232 .common =
233 {
234 .tag = HARDWARE_MODULE_TAG,
235 .module_api_version = 0x0100, // [15:8] major, [7:0] minor (1.0)
236 .hal_api_version = 0x00, // 0 is only valid value
237 .id = "nfc_nci.st21nfc",
238 .name = "ST Micro ST21NFC NCI HW HAL",
239 .author = "ST Microelectronics SA ",
240 .methods = &nfc_module_methods,
241 },
242};