15d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly/* 25d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly * Copyright (C) 2010 NXP Semiconductors 35d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly * 45d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly * Licensed under the Apache License, Version 2.0 (the "License"); 55d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly * you may not use this file except in compliance with the License. 65d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly * You may obtain a copy of the License at 75d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly * 85d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly * http://www.apache.org/licenses/LICENSE-2.0 95d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly * 105d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly * Unless required by applicable law or agreed to in writing, software 115d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly * distributed under the License is distributed on an "AS IS" BASIS, 125d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 135d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly * See the License for the specific language governing permissions and 145d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly * limitations under the License. 155d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly */ 165d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly 175d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly/** 185d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly * \file phDalNfc_i2c.c 195d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly * \brief DAL I2C port implementation for linux 205d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly * 215d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly * Project: Trusted NFC Linux 225d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly * 235d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly */ 245d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly 2552ffcd90d9da60151c4343bc25f272da65cf6b98Nick Pelly#define LOG_TAG "NFC_i2c" 26d4cb91ee6f74f187cc0e7ba9dc073b0a77c27dfaNick Pelly#include <cutils/log.h> 27b99be65c277b0cc65a00a33e784ed49461531737Martijn Coenen#include <hardware/nfc.h> 282940d97c95a997ea54e3b198256b8e71bac31010Nick Pelly#include <stdlib.h> 295d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly#include <unistd.h> 305d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly#include <fcntl.h> 315d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly#include <termios.h> 325d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly#include <sys/ioctl.h> 335d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly#include <sys/select.h> 34d4cb91ee6f74f187cc0e7ba9dc073b0a77c27dfaNick Pelly#include <errno.h> 355d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly 365d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly#include <phDal4Nfc_debug.h> 375d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly#include <phDal4Nfc_i2c.h> 385d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly#include <phOsalNfc.h> 395d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly#include <phNfcStatus.h> 405d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly#if defined(ANDROID) 415d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly#include <string.h> 425d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly#endif 435d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly 445d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pellytypedef struct 455d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly{ 465d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly int nHandle; 475d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly char nOpened; 485d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly 495d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly} phDal4Nfc_I2cPortContext_t; 505d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly 515d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly 525d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly/*----------------------------------------------------------------------------------- 535d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly VARIABLES 545d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly------------------------------------------------------------------------------------*/ 555d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pellystatic phDal4Nfc_I2cPortContext_t gI2cPortContext; 565d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly 575d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly 585d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly 595d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly/*----------------------------------------------------------------------------- 605d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly 615d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick PellyFUNCTION: phDal4Nfc_i2c_set_open_from_handle 625d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly 635d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick PellyPURPOSE: Initialize internal variables 645d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly 655d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly-----------------------------------------------------------------------------*/ 665d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly 675d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pellyvoid phDal4Nfc_i2c_initialize(void) 685d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly{ 695d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly memset(&gI2cPortContext, 0, sizeof(phDal4Nfc_I2cPortContext_t)); 705d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly} 715d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly 725d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly 735d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly/*----------------------------------------------------------------------------- 745d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly 755d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick PellyFUNCTION: phDal4Nfc_i2c_set_open_from_handle 765d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly 775d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick PellyPURPOSE: The application could have opened the link itself. So we just need 785d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly to get the handle and consider that the open operation has already 795d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly been done. 805d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly 815d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly-----------------------------------------------------------------------------*/ 825d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly 835d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pellyvoid phDal4Nfc_i2c_set_open_from_handle(phHal_sHwReference_t * pDalHwContext) 845d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly{ 85a5282496f1c25f5c8cfefd3b8bc4220ee2192881Colin Cross gI2cPortContext.nHandle = (int)(intptr_t) pDalHwContext->p_board_driver; 863e98767aaf73b4779a2bb39601806045b2ba1739Jeff Hamilton DAL_ASSERT_STR(gI2cPortContext.nHandle >= 0, "Bad passed com port handle"); 875d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly gI2cPortContext.nOpened = 1; 885d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly} 895d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly 905d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly/*----------------------------------------------------------------------------- 915d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly 925d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick PellyFUNCTION: phDal4Nfc_i2c_is_opened 935d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly 945d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick PellyPURPOSE: Returns if the link is opened or not. (0 = not opened; 1 = opened) 955d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly 965d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly-----------------------------------------------------------------------------*/ 975d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly 985d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pellyint phDal4Nfc_i2c_is_opened(void) 995d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly{ 1005d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly return gI2cPortContext.nOpened; 1015d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly} 1025d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly 1035d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly/*----------------------------------------------------------------------------- 1045d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly 1055d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick PellyFUNCTION: phDal4Nfc_i2c_flush 1065d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly 1075d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick PellyPURPOSE: Flushes the link ; clears the link buffers 1085d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly 1095d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly-----------------------------------------------------------------------------*/ 1105d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly 1115d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pellyvoid phDal4Nfc_i2c_flush(void) 1125d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly{ 1135d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly /* Nothing to do (driver has no internal buffers) */ 1145d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly} 1155d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly 1165d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly/*----------------------------------------------------------------------------- 1175d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly 1185d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick PellyFUNCTION: phDal4Nfc_i2c_close 1195d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly 1205d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick PellyPURPOSE: Closes the link 1215d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly 1225d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly-----------------------------------------------------------------------------*/ 1235d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly 1245d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pellyvoid phDal4Nfc_i2c_close(void) 1255d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly{ 1265d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly DAL_PRINT("Closing port\n"); 1275d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly if (gI2cPortContext.nOpened == 1) 1285d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly { 1295d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly close(gI2cPortContext.nHandle); 1305d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly gI2cPortContext.nHandle = 0; 1315d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly gI2cPortContext.nOpened = 0; 1325d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly } 1335d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly} 1345d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly 1355d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly/*----------------------------------------------------------------------------- 1365d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly 1375d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick PellyFUNCTION: phDal4Nfc_i2c_open_and_configure 1385d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly 1395d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick PellyPURPOSE: Closes the link 1405d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly 1415d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly-----------------------------------------------------------------------------*/ 1425d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly 1435d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick PellyNFCSTATUS phDal4Nfc_i2c_open_and_configure(pphDal4Nfc_sConfig_t pConfig, void ** pLinkHandle) 1445d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly{ 1455d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly DAL_ASSERT_STR(gI2cPortContext.nOpened==0, "Trying to open but already done!"); 1465d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly 147b99be65c277b0cc65a00a33e784ed49461531737Martijn Coenen DAL_DEBUG("Opening port=%s\n", pConfig->deviceNode); 1485d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly 1495d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly /* open port */ 150b99be65c277b0cc65a00a33e784ed49461531737Martijn Coenen gI2cPortContext.nHandle = open(pConfig->deviceNode, O_RDWR | O_NOCTTY); 1515d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly if (gI2cPortContext.nHandle < 0) 1525d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly { 1535d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly DAL_DEBUG("Open failed: open() returned %d\n", gI2cPortContext.nHandle); 1545d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly *pLinkHandle = NULL; 1555d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly return PHNFCSTVAL(CID_NFC_DAL, NFCSTATUS_INVALID_DEVICE); 1565d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly } 1575d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly 1585d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly gI2cPortContext.nOpened = 1; 159a5282496f1c25f5c8cfefd3b8bc4220ee2192881Colin Cross *pLinkHandle = (void*)(intptr_t)gI2cPortContext.nHandle; 1605d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly 1615d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly DAL_PRINT("Open succeed\n"); 1625d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly 1635d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly return NFCSTATUS_SUCCESS; 1645d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly} 1655d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly 1665d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly 1675d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly/*----------------------------------------------------------------------------- 1685d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly 1695d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick PellyFUNCTION: phDal4Nfc_i2c_read 1705d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly 1715d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick PellyPURPOSE: Reads nNbBytesToRead bytes and writes them in pBuffer. 1725d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly Returns the number of bytes really read or -1 in case of error. 1735d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly 1745d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly-----------------------------------------------------------------------------*/ 1755d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly 1765d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pellyint phDal4Nfc_i2c_read(uint8_t * pBuffer, int nNbBytesToRead) 1775d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly{ 178d4cb91ee6f74f187cc0e7ba9dc073b0a77c27dfaNick Pelly int ret; 179d4cb91ee6f74f187cc0e7ba9dc073b0a77c27dfaNick Pelly int numRead = 0; 180a74fcf0b7a509cb70b69c6362b704d8014edcab1Nick Pelly struct timeval tv; 181a74fcf0b7a509cb70b69c6362b704d8014edcab1Nick Pelly fd_set rfds; 182d4cb91ee6f74f187cc0e7ba9dc073b0a77c27dfaNick Pelly 183d4cb91ee6f74f187cc0e7ba9dc073b0a77c27dfaNick Pelly DAL_ASSERT_STR(gI2cPortContext.nOpened == 1, "read called but not opened!"); 184d4cb91ee6f74f187cc0e7ba9dc073b0a77c27dfaNick Pelly DAL_DEBUG("_i2c_read() called to read %d bytes", nNbBytesToRead); 185d4cb91ee6f74f187cc0e7ba9dc073b0a77c27dfaNick Pelly 186a74fcf0b7a509cb70b69c6362b704d8014edcab1Nick Pelly // Read with 2 second timeout, so that the read thread can be aborted 187a74fcf0b7a509cb70b69c6362b704d8014edcab1Nick Pelly // when the pn544 does not respond and we need to switch to FW download 188a74fcf0b7a509cb70b69c6362b704d8014edcab1Nick Pelly // mode. This should be done via a control socket instead. 189d4cb91ee6f74f187cc0e7ba9dc073b0a77c27dfaNick Pelly while (numRead < nNbBytesToRead) { 190a74fcf0b7a509cb70b69c6362b704d8014edcab1Nick Pelly FD_ZERO(&rfds); 191a74fcf0b7a509cb70b69c6362b704d8014edcab1Nick Pelly FD_SET(gI2cPortContext.nHandle, &rfds); 192a74fcf0b7a509cb70b69c6362b704d8014edcab1Nick Pelly tv.tv_sec = 2; 193a74fcf0b7a509cb70b69c6362b704d8014edcab1Nick Pelly tv.tv_usec = 0; 194a74fcf0b7a509cb70b69c6362b704d8014edcab1Nick Pelly ret = select(gI2cPortContext.nHandle + 1, &rfds, NULL, NULL, &tv); 195a74fcf0b7a509cb70b69c6362b704d8014edcab1Nick Pelly if (ret < 0) { 196a74fcf0b7a509cb70b69c6362b704d8014edcab1Nick Pelly DAL_DEBUG("select() errno=%d", errno); 197a74fcf0b7a509cb70b69c6362b704d8014edcab1Nick Pelly if (errno == EINTR || errno == EAGAIN) { 198a74fcf0b7a509cb70b69c6362b704d8014edcab1Nick Pelly continue; 199a74fcf0b7a509cb70b69c6362b704d8014edcab1Nick Pelly } 200a74fcf0b7a509cb70b69c6362b704d8014edcab1Nick Pelly return -1; 201a74fcf0b7a509cb70b69c6362b704d8014edcab1Nick Pelly } else if (ret == 0) { 202a74fcf0b7a509cb70b69c6362b704d8014edcab1Nick Pelly DAL_PRINT("timeout!"); 203a74fcf0b7a509cb70b69c6362b704d8014edcab1Nick Pelly return -1; 204a74fcf0b7a509cb70b69c6362b704d8014edcab1Nick Pelly } 205d4cb91ee6f74f187cc0e7ba9dc073b0a77c27dfaNick Pelly ret = read(gI2cPortContext.nHandle, pBuffer + numRead, nNbBytesToRead - numRead); 206d4cb91ee6f74f187cc0e7ba9dc073b0a77c27dfaNick Pelly if (ret > 0) { 207d4cb91ee6f74f187cc0e7ba9dc073b0a77c27dfaNick Pelly DAL_DEBUG("read %d bytes", ret); 208d4cb91ee6f74f187cc0e7ba9dc073b0a77c27dfaNick Pelly numRead += ret; 209d4cb91ee6f74f187cc0e7ba9dc073b0a77c27dfaNick Pelly } else if (ret == 0) { 210d4cb91ee6f74f187cc0e7ba9dc073b0a77c27dfaNick Pelly DAL_PRINT("_i2c_read() EOF"); 211d4cb91ee6f74f187cc0e7ba9dc073b0a77c27dfaNick Pelly return -1; 212d4cb91ee6f74f187cc0e7ba9dc073b0a77c27dfaNick Pelly } else { 213d4cb91ee6f74f187cc0e7ba9dc073b0a77c27dfaNick Pelly DAL_DEBUG("_i2c_read() errno=%d", errno); 214d4cb91ee6f74f187cc0e7ba9dc073b0a77c27dfaNick Pelly if (errno == EINTR || errno == EAGAIN) { 215d4cb91ee6f74f187cc0e7ba9dc073b0a77c27dfaNick Pelly continue; 216d4cb91ee6f74f187cc0e7ba9dc073b0a77c27dfaNick Pelly } 217d4cb91ee6f74f187cc0e7ba9dc073b0a77c27dfaNick Pelly return -1; 218d4cb91ee6f74f187cc0e7ba9dc073b0a77c27dfaNick Pelly } 219d4cb91ee6f74f187cc0e7ba9dc073b0a77c27dfaNick Pelly } 220d4cb91ee6f74f187cc0e7ba9dc073b0a77c27dfaNick Pelly return numRead; 2215d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly} 2225d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly 2235d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly/*----------------------------------------------------------------------------- 2245d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly 2255d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick PellyFUNCTION: phDal4Nfc_i2c_write 2265d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly 2275d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick PellyPURPOSE: Writes nNbBytesToWrite bytes from pBuffer to the link 2285d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly Returns the number of bytes that have been wrote to the interface or -1 in case of error. 2295d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly 2305d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly-----------------------------------------------------------------------------*/ 2315d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly 2325d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pellyint phDal4Nfc_i2c_write(uint8_t * pBuffer, int nNbBytesToWrite) 2335d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly{ 234d4cb91ee6f74f187cc0e7ba9dc073b0a77c27dfaNick Pelly int ret; 235d4cb91ee6f74f187cc0e7ba9dc073b0a77c27dfaNick Pelly int numWrote = 0; 236d4cb91ee6f74f187cc0e7ba9dc073b0a77c27dfaNick Pelly 237d4cb91ee6f74f187cc0e7ba9dc073b0a77c27dfaNick Pelly DAL_ASSERT_STR(gI2cPortContext.nOpened == 1, "write called but not opened!"); 238d4cb91ee6f74f187cc0e7ba9dc073b0a77c27dfaNick Pelly DAL_DEBUG("_i2c_write() called to write %d bytes\n", nNbBytesToWrite); 239d4cb91ee6f74f187cc0e7ba9dc073b0a77c27dfaNick Pelly 240d4cb91ee6f74f187cc0e7ba9dc073b0a77c27dfaNick Pelly while (numWrote < nNbBytesToWrite) { 241d4cb91ee6f74f187cc0e7ba9dc073b0a77c27dfaNick Pelly ret = write(gI2cPortContext.nHandle, pBuffer + numWrote, nNbBytesToWrite - numWrote); 242d4cb91ee6f74f187cc0e7ba9dc073b0a77c27dfaNick Pelly if (ret > 0) { 243d4cb91ee6f74f187cc0e7ba9dc073b0a77c27dfaNick Pelly DAL_DEBUG("wrote %d bytes", ret); 244d4cb91ee6f74f187cc0e7ba9dc073b0a77c27dfaNick Pelly numWrote += ret; 245d4cb91ee6f74f187cc0e7ba9dc073b0a77c27dfaNick Pelly } else if (ret == 0) { 246d4cb91ee6f74f187cc0e7ba9dc073b0a77c27dfaNick Pelly DAL_PRINT("_i2c_write() EOF"); 247d4cb91ee6f74f187cc0e7ba9dc073b0a77c27dfaNick Pelly return -1; 248d4cb91ee6f74f187cc0e7ba9dc073b0a77c27dfaNick Pelly } else { 249d4cb91ee6f74f187cc0e7ba9dc073b0a77c27dfaNick Pelly DAL_DEBUG("_i2c_write() errno=%d", errno); 250d4cb91ee6f74f187cc0e7ba9dc073b0a77c27dfaNick Pelly if (errno == EINTR || errno == EAGAIN) { 251d4cb91ee6f74f187cc0e7ba9dc073b0a77c27dfaNick Pelly continue; 252d4cb91ee6f74f187cc0e7ba9dc073b0a77c27dfaNick Pelly } 253d4cb91ee6f74f187cc0e7ba9dc073b0a77c27dfaNick Pelly return -1; 254d4cb91ee6f74f187cc0e7ba9dc073b0a77c27dfaNick Pelly } 255d4cb91ee6f74f187cc0e7ba9dc073b0a77c27dfaNick Pelly } 256d4cb91ee6f74f187cc0e7ba9dc073b0a77c27dfaNick Pelly 257d4cb91ee6f74f187cc0e7ba9dc073b0a77c27dfaNick Pelly return numWrote; 2585d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly} 2593e98767aaf73b4779a2bb39601806045b2ba1739Jeff Hamilton 2603e98767aaf73b4779a2bb39601806045b2ba1739Jeff Hamilton/*----------------------------------------------------------------------------- 2613e98767aaf73b4779a2bb39601806045b2ba1739Jeff Hamilton 2623e98767aaf73b4779a2bb39601806045b2ba1739Jeff HamiltonFUNCTION: phDal4Nfc_i2c_reset 2633e98767aaf73b4779a2bb39601806045b2ba1739Jeff Hamilton 2643e98767aaf73b4779a2bb39601806045b2ba1739Jeff HamiltonPURPOSE: Reset the PN544, using the VEN pin 2653e98767aaf73b4779a2bb39601806045b2ba1739Jeff Hamilton 2663e98767aaf73b4779a2bb39601806045b2ba1739Jeff Hamilton-----------------------------------------------------------------------------*/ 26754e2f9f2bcdedf1c0ffc2af1dca5f457544dd85bElliott Hughes#define PN544_SET_PWR _IOW(0xe9, 0x01, unsigned int) 2683e98767aaf73b4779a2bb39601806045b2ba1739Jeff Hamiltonint phDal4Nfc_i2c_reset(long level) 2693e98767aaf73b4779a2bb39601806045b2ba1739Jeff Hamilton{ 270d4cb91ee6f74f187cc0e7ba9dc073b0a77c27dfaNick Pelly DAL_DEBUG("phDal4Nfc_i2c_reset, VEN level = %ld", level); 27152ffcd90d9da60151c4343bc25f272da65cf6b98Nick Pelly 272d4cb91ee6f74f187cc0e7ba9dc073b0a77c27dfaNick Pelly return ioctl(gI2cPortContext.nHandle, PN544_SET_PWR, level); 2733e98767aaf73b4779a2bb39601806045b2ba1739Jeff Hamilton} 274