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