blob: 7e14b92f5394c12c7e86cbd09592192bed0bd9c0 [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
Arach MOHAMMED BRAHIM703cc542018-03-28 18:00:05 +020044char* halVersion = "ST21NFC NCI Version 3.0.5";
STMicroelectronicse5060d52017-10-12 14:30:37 -070045uint8_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
Arach MOHAMMED BRAHIM89233c72018-02-08 16:29:42 +010081 if (!result || !dev->hHAL)
82 {
83 dev->p_cback(HAL_NFC_OPEN_CPLT_EVT, HAL_NFC_STATUS_FAILED);
84 (void) pthread_mutex_unlock(&hal_mtx);
85 return -1; // We are doomed, stop it here, NOW !
86 }
STMicroelectronicse5060d52017-10-12 14:30:37 -070087 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;
Arach MOHAMMED BRAHIM89233c72018-02-08 16:29:42 +0100100 (void) pthread_mutex_lock(&hal_mtx);
101 if (hal_is_closed)
102 {
103 ret = 0;
104 }
105
STMicroelectronicse5060d52017-10-12 14:30:37 -0700106 if (!ret)
Arach MOHAMMED BRAHIM89233c72018-02-08 16:29:42 +0100107 {
108 (void) pthread_mutex_unlock(&hal_mtx);
109 return ret;
110 }
111 if (!HalSendDownstream(dev->hHAL, p_data, data_len))
112 {
113 STLOG_HAL_E("NFC-NCI HAL: %s SendDownstream failed", __func__);
114 (void) pthread_mutex_unlock(&hal_mtx);
115 return 0;
116 }
117 (void) pthread_mutex_unlock(&hal_mtx);
STMicroelectronicse5060d52017-10-12 14:30:37 -0700118
119 return ret;
120}
121
122static int hal_core_initialized(const struct nfc_nci_device* p_dev,
123 uint8_t* p_core_init_rsp_params) {
124 STLOG_HAL_D("NFC-NCI HAL: %s", __func__);
125
Arach MOHAMMED BRAHIM89233c72018-02-08 16:29:42 +0100126 (void)pthread_mutex_lock(&hal_mtx);
STMicroelectronicse5060d52017-10-12 14:30:37 -0700127 st21nfc_dev_t* dev = (st21nfc_dev_t*)p_dev;
STMicroelectronicse5060d52017-10-12 14:30:37 -0700128 hal_dta_state = *p_core_init_rsp_params;
STMicroelectronicse5060d52017-10-12 14:30:37 -0700129 dev->p_cback(HAL_NFC_POST_INIT_CPLT_EVT, HAL_NFC_STATUS_OK);
Arach MOHAMMED BRAHIM89233c72018-02-08 16:29:42 +0100130 (void) pthread_mutex_unlock(&hal_mtx);
STMicroelectronicse5060d52017-10-12 14:30:37 -0700131
132 return 0; // return != 0 to signal ready immediate
133}
134
Arach MOHAMMED BRAHIMe58eecb2018-02-15 17:06:31 +0100135static int hal_pre_discover(__attribute__((unused)) const struct nfc_nci_device* p_dev) {
STMicroelectronicse5060d52017-10-12 14:30:37 -0700136 STLOG_HAL_D("NFC-NCI HAL: %s", __func__);
137
STMicroelectronicse5060d52017-10-12 14:30:37 -0700138 return 0; // false if no vendor-specific pre-discovery actions are needed
139}
140
Arach MOHAMMED BRAHIMe58eecb2018-02-15 17:06:31 +0100141static int hal_close(__attribute__((unused)) const struct nfc_nci_device* p_dev) {
STMicroelectronicse5060d52017-10-12 14:30:37 -0700142 STLOG_HAL_D("NFC-NCI HAL: %s", __func__);
143
STMicroelectronicse5060d52017-10-12 14:30:37 -0700144 /* check if HAL is closed */
145 (void)pthread_mutex_lock(&hal_mtx);
146 if ( hal_is_closed ) {
147 (void)pthread_mutex_unlock(&hal_mtx);
148 return 1;
149 }
Arach MOHAMMED BRAHIM2d481292018-01-29 11:27:05 +0100150 if (hal_wrapper_close(1) == 0) {
STMicroelectronicse5060d52017-10-12 14:30:37 -0700151 hal_is_closed = 1;
152 (void)pthread_mutex_unlock(&hal_mtx);
153 return 1;
154 }
155 hal_is_closed = 1;
156 (void)pthread_mutex_unlock(&hal_mtx);
157
158 hal_dta_state = 0;
159
160 return 0;
161}
162
Arach MOHAMMED BRAHIMe58eecb2018-02-15 17:06:31 +0100163static int hal_control_granted(__attribute__((unused)) const struct nfc_nci_device* p_dev) {
STMicroelectronicse5060d52017-10-12 14:30:37 -0700164 STLOG_HAL_D("NFC-NCI HAL: %s", __func__);
165
STMicroelectronicse5060d52017-10-12 14:30:37 -0700166 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;
Arach MOHAMMED BRAHIM89233c72018-02-08 16:29:42 +0100176 (void) pthread_mutex_lock(&hal_mtx);
177 if (hal_is_closed)
178 {
179 ret = HAL_NFC_STATUS_FAILED;
180 }
181
STMicroelectronicse5060d52017-10-12 14:30:37 -0700182 if (ret != HAL_NFC_STATUS_OK)
Arach MOHAMMED BRAHIM89233c72018-02-08 16:29:42 +0100183 {
184 (void) pthread_mutex_unlock(&hal_mtx);
185 return ret;
186 }
STMicroelectronicse5060d52017-10-12 14:30:37 -0700187 dev->p_cback(HAL_NFC_OPEN_CPLT_EVT, HAL_NFC_STATUS_OK);
188
Arach MOHAMMED BRAHIM89233c72018-02-08 16:29:42 +0100189 (void) pthread_mutex_unlock(&hal_mtx);
STMicroelectronicse5060d52017-10-12 14:30:37 -0700190 return HAL_NFC_STATUS_OK;
191}
192
193/*
194 * Generic device handling below
195 */
196
197/* Close an opened nfc device instance */
198static int nfc_close(hw_device_t* dev) {
Arach MOHAMMED BRAHIM89233c72018-02-08 16:29:42 +0100199 (void) pthread_mutex_lock(&hal_mtx);
STMicroelectronicse5060d52017-10-12 14:30:37 -0700200 free(dev);
Arach MOHAMMED BRAHIM89233c72018-02-08 16:29:42 +0100201 (void) pthread_mutex_unlock(&hal_mtx);
STMicroelectronicse5060d52017-10-12 14:30:37 -0700202 return 0;
203}
204
205static int nfc_open(const hw_module_t* module, const char* name,
206 hw_device_t** device) {
STMicroelectronicse5060d52017-10-12 14:30:37 -0700207
208 if (strcmp(name, NFC_NCI_CONTROLLER) == 0) {
209 st21nfc_dev_t* dev = calloc(1, sizeof(st21nfc_dev_t));
210
211 dev->nci_device.common.tag = HARDWARE_DEVICE_TAG;
212 dev->nci_device.common.version = 0x00010000; // [31:16] major, [15:0] minor
213 dev->nci_device.common.module = (struct hw_module_t*)module;
214 dev->nci_device.common.close = nfc_close;
215
216 // NCI HAL method pointers
217 dev->nci_device.open = hal_open;
218 dev->nci_device.write = hal_write;
219 dev->nci_device.core_initialized = hal_core_initialized;
220 dev->nci_device.pre_discover = hal_pre_discover;
221 dev->nci_device.close = hal_close;
222 dev->nci_device.control_granted = hal_control_granted;
223 dev->nci_device.power_cycle = hal_power_cycle;
224
225 *device = (hw_device_t*)dev;
226
227 // Initialize and get global logging level
228 InitializeSTLogLevel();
229
230 return 0;
231 } else {
232 return -EINVAL;
233 }
234}
235
236static struct hw_module_methods_t nfc_module_methods = {
237 .open = nfc_open,
238};
239
240struct nfc_nci_module_t HAL_MODULE_INFO_SYM = {
241 .common =
242 {
243 .tag = HARDWARE_MODULE_TAG,
244 .module_api_version = 0x0100, // [15:8] major, [7:0] minor (1.0)
245 .hal_api_version = 0x00, // 0 is only valid value
246 .id = "nfc_nci.st21nfc",
247 .name = "ST Micro ST21NFC NCI HW HAL",
248 .author = "ST Microelectronics SA ",
249 .methods = &nfc_module_methods,
250 },
251};