blob: 1d69df18be19dc5631005d163157173b230f4dc8 [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>
Arach MOHAMMED BRAHIM5d595ec2018-04-03 11:44:44 +020027#include <pthread.h>
STMicroelectronicse5060d52017-10-12 14:30:37 -070028
29#include "android_logmsg.h"
30#include "halcore.h"
31
32extern void HalCoreCallback(void* context, uint32_t event, const void* d,
33 size_t length);
34extern bool I2cOpenLayer(void* dev, HAL_CALLBACK callb, HALHANDLE* pHandle);
Arach MOHAMMED BRAHIMabf4b1c2018-01-29 11:24:53 +010035
STMicroelectronicse5060d52017-10-12 14:30:37 -070036
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
Arach MOHAMMED BRAHIM703cc542018-03-28 18:00:05 +020045char* halVersion = "ST21NFC NCI Version 3.0.5";
STMicroelectronicse5060d52017-10-12 14:30:37 -070046uint8_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
Arach MOHAMMED BRAHIM2d481292018-01-29 11:27:05 +010061extern int hal_wrapper_close(int call_cb);
STMicroelectronicse5060d52017-10-12 14:30:37 -070062
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 ) {
Arach MOHAMMED BRAHIM2d481292018-01-29 11:27:05 +010073 hal_wrapper_close(0);
STMicroelectronicse5060d52017-10-12 14:30:37 -070074 }
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
Arach MOHAMMED BRAHIM89233c72018-02-08 16:29:42 +010082 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 }
STMicroelectronicse5060d52017-10-12 14:30:37 -070088 hal_is_closed = 0;
89 (void)pthread_mutex_unlock(&hal_mtx);
90 return 0;
91}
92
93static 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;
Arach MOHAMMED BRAHIM89233c72018-02-08 16:29:42 +0100101 (void) pthread_mutex_lock(&hal_mtx);
102 if (hal_is_closed)
103 {
104 ret = 0;
105 }
106
STMicroelectronicse5060d52017-10-12 14:30:37 -0700107 if (!ret)
Arach MOHAMMED BRAHIM89233c72018-02-08 16:29:42 +0100108 {
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);
STMicroelectronicse5060d52017-10-12 14:30:37 -0700119
120 return ret;
121}
122
123static 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
Arach MOHAMMED BRAHIM89233c72018-02-08 16:29:42 +0100127 (void)pthread_mutex_lock(&hal_mtx);
STMicroelectronicse5060d52017-10-12 14:30:37 -0700128 st21nfc_dev_t* dev = (st21nfc_dev_t*)p_dev;
STMicroelectronicse5060d52017-10-12 14:30:37 -0700129 hal_dta_state = *p_core_init_rsp_params;
STMicroelectronicse5060d52017-10-12 14:30:37 -0700130 dev->p_cback(HAL_NFC_POST_INIT_CPLT_EVT, HAL_NFC_STATUS_OK);
Arach MOHAMMED BRAHIM89233c72018-02-08 16:29:42 +0100131 (void) pthread_mutex_unlock(&hal_mtx);
STMicroelectronicse5060d52017-10-12 14:30:37 -0700132
133 return 0; // return != 0 to signal ready immediate
134}
135
Arach MOHAMMED BRAHIMe58eecb2018-02-15 17:06:31 +0100136static int hal_pre_discover(__attribute__((unused)) const struct nfc_nci_device* p_dev) {
STMicroelectronicse5060d52017-10-12 14:30:37 -0700137 STLOG_HAL_D("NFC-NCI HAL: %s", __func__);
138
STMicroelectronicse5060d52017-10-12 14:30:37 -0700139 return 0; // false if no vendor-specific pre-discovery actions are needed
140}
141
Arach MOHAMMED BRAHIMe58eecb2018-02-15 17:06:31 +0100142static int hal_close(__attribute__((unused)) const struct nfc_nci_device* p_dev) {
STMicroelectronicse5060d52017-10-12 14:30:37 -0700143 STLOG_HAL_D("NFC-NCI HAL: %s", __func__);
144
STMicroelectronicse5060d52017-10-12 14:30:37 -0700145 /* 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 }
Arach MOHAMMED BRAHIM2d481292018-01-29 11:27:05 +0100151 if (hal_wrapper_close(1) == 0) {
STMicroelectronicse5060d52017-10-12 14:30:37 -0700152 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
Arach MOHAMMED BRAHIMe58eecb2018-02-15 17:06:31 +0100164static int hal_control_granted(__attribute__((unused)) const struct nfc_nci_device* p_dev) {
STMicroelectronicse5060d52017-10-12 14:30:37 -0700165 STLOG_HAL_D("NFC-NCI HAL: %s", __func__);
166
STMicroelectronicse5060d52017-10-12 14:30:37 -0700167 return 0;
168}
169
170static 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;
Arach MOHAMMED BRAHIM89233c72018-02-08 16:29:42 +0100177 (void) pthread_mutex_lock(&hal_mtx);
178 if (hal_is_closed)
179 {
180 ret = HAL_NFC_STATUS_FAILED;
181 }
182
STMicroelectronicse5060d52017-10-12 14:30:37 -0700183 if (ret != HAL_NFC_STATUS_OK)
Arach MOHAMMED BRAHIM89233c72018-02-08 16:29:42 +0100184 {
185 (void) pthread_mutex_unlock(&hal_mtx);
186 return ret;
187 }
STMicroelectronicse5060d52017-10-12 14:30:37 -0700188 dev->p_cback(HAL_NFC_OPEN_CPLT_EVT, HAL_NFC_STATUS_OK);
189
Arach MOHAMMED BRAHIM89233c72018-02-08 16:29:42 +0100190 (void) pthread_mutex_unlock(&hal_mtx);
STMicroelectronicse5060d52017-10-12 14:30:37 -0700191 return HAL_NFC_STATUS_OK;
192}
193
194/*
195 * Generic device handling below
196 */
197
198/* Close an opened nfc device instance */
199static int nfc_close(hw_device_t* dev) {
Arach MOHAMMED BRAHIM89233c72018-02-08 16:29:42 +0100200 (void) pthread_mutex_lock(&hal_mtx);
STMicroelectronicse5060d52017-10-12 14:30:37 -0700201 free(dev);
Arach MOHAMMED BRAHIM89233c72018-02-08 16:29:42 +0100202 (void) pthread_mutex_unlock(&hal_mtx);
STMicroelectronicse5060d52017-10-12 14:30:37 -0700203 return 0;
204}
205
206static int nfc_open(const hw_module_t* module, const char* name,
207 hw_device_t** device) {
STMicroelectronicse5060d52017-10-12 14:30:37 -0700208
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
237static struct hw_module_methods_t nfc_module_methods = {
238 .open = nfc_open,
239};
240
241struct 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};