aboutsummaryrefslogtreecommitdiff
path: root/pn54x/tml/phTmlNfc_i2c.c
diff options
context:
space:
mode:
authorArian <arian.kulmer@web.de>2019-09-30 11:10:42 +0200
committerArian <arian.kulmer@web.de>2019-10-25 22:17:12 +0200
commit9224c881cf3f8575194823a6c779c0d65c42258a (patch)
treeac8a018ff4fdea5a589ca7ee3d88cd88d0d460ba /pn54x/tml/phTmlNfc_i2c.c
parentfbdbc276d9f25e67e49a7ca03002b838cc9c8548 (diff)
shinano-common: pn54x: Import from lineage-15.1
* https://github.com/LineageOS/android_system_nfc/tree/lineage-15.1/halimpl/pn54x/common * support for pn54x has been dropped in lineage-16.0 and above Change-Id: I19f2c3a6e3066bf9aaaaf4ddcd7d7ad867de0ed8
Diffstat (limited to 'pn54x/tml/phTmlNfc_i2c.c')
-rw-r--r--pn54x/tml/phTmlNfc_i2c.c315
1 files changed, 315 insertions, 0 deletions
diff --git a/pn54x/tml/phTmlNfc_i2c.c b/pn54x/tml/phTmlNfc_i2c.c
new file mode 100644
index 0000000..781f19b
--- /dev/null
+++ b/pn54x/tml/phTmlNfc_i2c.c
@@ -0,0 +1,315 @@
+/*
+ * Copyright (C) 2010-2014 NXP Semiconductors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*
+ * DAL I2C port implementation for linux
+ *
+ * Project: Trusted NFC Linux
+ *
+ */
+#include <errno.h>
+#include <fcntl.h>
+#include <hardware/nfc.h>
+#include <stdlib.h>
+#include <sys/ioctl.h>
+#include <sys/select.h>
+#include <termios.h>
+#include <unistd.h>
+
+#include <phNfcStatus.h>
+#include <phNxpLog.h>
+#include <phTmlNfc_i2c.h>
+#include <string.h>
+#include "phNxpNciHal_utils.h"
+
+#define CRC_LEN 2
+#define NORMAL_MODE_HEADER_LEN 3
+#define FW_DNLD_HEADER_LEN 2
+#define FW_DNLD_LEN_OFFSET 1
+#define NORMAL_MODE_LEN_OFFSET 2
+#define FRAGMENTSIZE_MAX PHNFC_I2C_FRAGMENT_SIZE
+static bool_t bFwDnldFlag = false;
+extern phTmlNfc_i2cfragmentation_t fragmentation_enabled;
+
+/*******************************************************************************
+**
+** Function phTmlNfc_i2c_close
+**
+** Description Closes PN54X device
+**
+** Parameters pDevHandle - device handle
+**
+** Returns None
+**
+*******************************************************************************/
+void phTmlNfc_i2c_close(void* pDevHandle) {
+ if (NULL != pDevHandle) {
+ close((intptr_t)pDevHandle);
+ }
+
+ return;
+}
+
+/*******************************************************************************
+**
+** Function phTmlNfc_i2c_open_and_configure
+**
+** Description Open and configure PN54X device
+**
+** Parameters pConfig - hardware information
+** pLinkHandle - device handle
+**
+** Returns NFC status:
+** NFCSTATUS_SUCCESS - open_and_configure operation success
+** NFCSTATUS_INVALID_DEVICE - device open operation failure
+**
+*******************************************************************************/
+NFCSTATUS phTmlNfc_i2c_open_and_configure(pphTmlNfc_Config_t pConfig,
+ void** pLinkHandle) {
+ int nHandle;
+
+ NXPLOG_TML_D("Opening port=%s\n", pConfig->pDevName);
+ /* open port */
+ nHandle = open((const char*)pConfig->pDevName, O_RDWR);
+ if (nHandle < 0) {
+ NXPLOG_TML_E("_i2c_open() Failed: retval %x", nHandle);
+ *pLinkHandle = NULL;
+ return NFCSTATUS_INVALID_DEVICE;
+ }
+
+ *pLinkHandle = (void*)((intptr_t)nHandle);
+
+ /*Reset PN54X*/
+ phTmlNfc_i2c_reset((void*)((intptr_t)nHandle), 0);
+ usleep(10 * 1000);
+ phTmlNfc_i2c_reset((void*)((intptr_t)nHandle), 1);
+
+ return NFCSTATUS_SUCCESS;
+}
+
+/*******************************************************************************
+**
+** Function phTmlNfc_i2c_read
+**
+** Description Reads requested number of bytes from PN54X device into given
+** buffer
+**
+** Parameters pDevHandle - valid device handle
+** pBuffer - buffer for read data
+** nNbBytesToRead - number of bytes requested to be read
+**
+** Returns numRead - number of successfully read bytes
+** -1 - read operation failure
+**
+*******************************************************************************/
+int phTmlNfc_i2c_read(void* pDevHandle, uint8_t* pBuffer, int nNbBytesToRead) {
+ int ret_Read;
+ int ret_Select;
+ int numRead = 0;
+ struct timeval tv;
+ fd_set rfds;
+ uint16_t totalBtyesToRead = 0;
+
+ int i;
+ UNUSED(nNbBytesToRead);
+ if (NULL == pDevHandle) {
+ return -1;
+ }
+
+ if (bFwDnldFlag == false) {
+ totalBtyesToRead = NORMAL_MODE_HEADER_LEN;
+ } else {
+ totalBtyesToRead = FW_DNLD_HEADER_LEN;
+ }
+
+ /* Read with 2 second timeout, so that the read thread can be aborted
+ when the PN54X does not respond and we need to switch to FW download
+ mode. This should be done via a control socket instead. */
+ FD_ZERO(&rfds);
+ FD_SET((intptr_t)pDevHandle, &rfds);
+ tv.tv_sec = 2;
+ tv.tv_usec = 1;
+
+ ret_Select =
+ select((int)((intptr_t)pDevHandle + (int)1), &rfds, NULL, NULL, &tv);
+ if (ret_Select < 0) {
+ NXPLOG_TML_E("i2c select() errno : %x", errno);
+ return -1;
+ } else if (ret_Select == 0) {
+ NXPLOG_TML_E("i2c select() Timeout");
+ return -1;
+ } else {
+ ret_Read = read((intptr_t)pDevHandle, pBuffer, totalBtyesToRead - numRead);
+ if (ret_Read > 0) {
+ numRead += ret_Read;
+ } else if (ret_Read == 0) {
+ NXPLOG_TML_E("_i2c_read() [hdr]EOF");
+ return -1;
+ } else {
+ NXPLOG_TML_E("_i2c_read() [hdr] errno : %x", errno);
+ return -1;
+ }
+
+ if (bFwDnldFlag == false) {
+ totalBtyesToRead = NORMAL_MODE_HEADER_LEN;
+ } else {
+ totalBtyesToRead = FW_DNLD_HEADER_LEN;
+ }
+
+ if (numRead < totalBtyesToRead) {
+ ret_Read =
+ read((intptr_t)pDevHandle, pBuffer, totalBtyesToRead - numRead);
+ if (ret_Read != totalBtyesToRead - numRead) {
+ NXPLOG_TML_E("_i2c_read() [hdr] errno : %x", errno);
+ return -1;
+ } else {
+ numRead += ret_Read;
+ }
+ }
+ if (bFwDnldFlag == true) {
+ totalBtyesToRead =
+ pBuffer[FW_DNLD_LEN_OFFSET] + FW_DNLD_HEADER_LEN + CRC_LEN;
+ } else {
+ totalBtyesToRead =
+ pBuffer[NORMAL_MODE_LEN_OFFSET] + NORMAL_MODE_HEADER_LEN;
+ }
+ if ((totalBtyesToRead - numRead) != 0) {
+ ret_Read = read((intptr_t)pDevHandle, (pBuffer + numRead),
+ totalBtyesToRead - numRead);
+ if (ret_Read > 0) {
+ numRead += ret_Read;
+ } else if (ret_Read == 0) {
+ NXPLOG_TML_E("_i2c_read() [pyld] EOF");
+ return -1;
+ } else {
+ if (bFwDnldFlag == false) {
+ NXPLOG_TML_E("_i2c_read() [hdr] received");
+ phNxpNciHal_print_packet("RECV", pBuffer, NORMAL_MODE_HEADER_LEN);
+ }
+ NXPLOG_TML_E("_i2c_read() [pyld] errno : %x", errno);
+ return -1;
+ }
+ } else {
+ NXPLOG_TML_E("_>>>>> Empty packet recieved !!");
+ }
+ }
+ return numRead;
+}
+
+/*******************************************************************************
+**
+** Function phTmlNfc_i2c_write
+**
+** Description Writes requested number of bytes from given buffer into
+** PN54X device
+**
+** Parameters pDevHandle - valid device handle
+** pBuffer - buffer for read data
+** nNbBytesToWrite - number of bytes requested to be written
+**
+** Returns numWrote - number of successfully written bytes
+** -1 - write operation failure
+**
+*******************************************************************************/
+int phTmlNfc_i2c_write(void* pDevHandle, uint8_t* pBuffer,
+ int nNbBytesToWrite) {
+ int ret;
+ int numWrote = 0;
+ int i;
+ int numBytes = nNbBytesToWrite;
+ if (NULL == pDevHandle) {
+ return -1;
+ }
+ if (fragmentation_enabled == I2C_FRAGMENATATION_DISABLED &&
+ nNbBytesToWrite > FRAGMENTSIZE_MAX) {
+ NXPLOG_TML_E(
+ "i2c_write() data larger than maximum I2C size,enable I2C "
+ "fragmentation");
+ return -1;
+ }
+ while (numWrote < nNbBytesToWrite) {
+ if (fragmentation_enabled == I2C_FRAGMENTATION_ENABLED &&
+ nNbBytesToWrite > FRAGMENTSIZE_MAX) {
+ if (nNbBytesToWrite - numWrote > FRAGMENTSIZE_MAX) {
+ numBytes = numWrote + FRAGMENTSIZE_MAX;
+ } else {
+ numBytes = nNbBytesToWrite;
+ }
+ }
+ ret = write((intptr_t)pDevHandle, pBuffer + numWrote, numBytes - numWrote);
+ if (ret > 0) {
+ numWrote += ret;
+ if (fragmentation_enabled == I2C_FRAGMENTATION_ENABLED &&
+ numWrote < nNbBytesToWrite) {
+ usleep(500);
+ }
+ } else if (ret == 0) {
+ NXPLOG_TML_E("_i2c_write() EOF");
+ return -1;
+ } else {
+ NXPLOG_TML_E("_i2c_write() errno : %x", errno);
+ if (errno == EINTR || errno == EAGAIN) {
+ continue;
+ }
+ return -1;
+ }
+ }
+
+ return numWrote;
+}
+
+/*******************************************************************************
+**
+** Function phTmlNfc_i2c_reset
+**
+** Description Reset PN54X device, using VEN pin
+**
+** Parameters pDevHandle - valid device handle
+** level - reset level
+**
+** Returns 0 - reset operation success
+** -1 - reset operation failure
+**
+*******************************************************************************/
+#define PN544_SET_PWR _IOW(0xe9, 0x01, unsigned int)
+int phTmlNfc_i2c_reset(void* pDevHandle, long level) {
+ int ret;
+ NXPLOG_TML_D("phTmlNfc_i2c_reset(), VEN level %ld", level);
+
+ if (NULL == pDevHandle) {
+ return -1;
+ }
+
+ ret = ioctl((intptr_t)pDevHandle, PN544_SET_PWR, level);
+ if (level == 2 && ret == 0) {
+ bFwDnldFlag = true;
+ } else {
+ bFwDnldFlag = false;
+ }
+ return ret;
+}
+
+/*******************************************************************************
+**
+** Function getDownloadFlag
+**
+** Description Returns the current mode
+**
+** Parameters none
+**
+** Returns Current mode download/NCI
+*******************************************************************************/
+bool_t getDownloadFlag(void) { return bFwDnldFlag; }