/*
* TI TRF7970a RFID/NFC Transceiver Driver
*
* Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com
*
* Author: Erick Macias <emacias@ti.com>
* Author: Felipe Balbi <balbi@ti.com>
* Author: Mark A. Greer <mgreer@animalcreek.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 of
* the License as published by the Free Software Foundation.
*/
#include <linux/module.h>
#include <linux/device.h>
#include <linux/netdevice.h>
#include <linux/interrupt.h>
#include <linux/nfc.h>
#include <linux/skbuff.h>
#include <linux/delay.h>
#include <linux/gpio.h>
#include <linux/of.h>
#include <linux/of_gpio.h>
#include <linux/spi/spi.h>
#include <linux/regulator/consumer.h>
#include <net/nfc/nfc.h>
#include <net/nfc/digital.h>
/* There are 3 ways the host can communicate with the trf7970a:
* parallel mode, SPI with Slave Select (SS) mode, and SPI without
* SS mode. The driver only supports the two SPI modes.
*
* The trf7970a is very timing sensitive and the VIN, EN2, and EN
* pins must asserted in that order and with specific delays in between.
* The delays used in the driver were provided by TI and have been
* confirmed to work with this driver.
*
* Timeouts are implemented using the delayed workqueue kernel facility.
* Timeouts are required so things don't hang when there is no response
* from the trf7970a (or tag). Using this mechanism creates a race with
* interrupts, however. That is, an interrupt and a timeout could occur
* closely enough together that one is blocked by the mutex while the other
* executes. When the timeout handler executes first and blocks the
* interrupt handler, it will eventually set the state to IDLE so the
* interrupt handler will check the state and exit with no harm done.
* When the interrupt handler executes first and blocks the timeout handler,
* the cancel_delayed_work() call will know that it didn't cancel the
* work item (i.e., timeout) and will return zero. That return code is
* used by the timer handler to indicate that it should ignore the timeout
* once its unblocked.
*
* Aborting an active command isn't as simple as it seems because the only
* way to abort a command that's already been sent to the tag is so turn
* off power to the tag. If we do that, though, we'd have to go through
* the entire anticollision procedure again but the digital layer doesn't
* support that. So, if an abort is received before trf7970a_in_send_cmd()
* has sent the command to the tag, it simply returns -ECANCELED. If the
* command has already been sent to the tag, then the driver continues
* normally and recieves the response data (or error) but just before
* sending the data upstream, it frees the rx_skb and sends -ECANCELED
* upstream instead. If the command failed, that error will be sent
* upstream.
*
* When recieving data from a tag and the interrupt status register has
* only the SRX bit set, it means that all of the data has been received
* (once what's in the fifo has been read). However, depending on timing
* an interrupt status with only the SRX bit set may not be recived. In
* those cases, the timeout mechanism is used to wait 5 ms in case more
* data arrives. After 5 ms, it is assumed that all of the data has been
* received and the accumulated rx data is sent upstream. The
* 'TRF7970A_ST_WAIT_FOR_RX_DATA_CONT' state is used for this purpose
* (i.e., it indicates that some data has been received but we're not sure
* if there is more coming so a timeout in this state means all data has
* been received and there isn't an error). The delay is 5 ms since delays
* over 2 ms have been observed during testing (a little extra just in case).
*
* Type 2 write and sector select commands respond with a 4-bit ACK or NACK.
* Having only 4 bits in the FIFO won't normally generate an interrupt so
* driver enables the '4_bit_RX' bit of the Special Functions register 1
* to cause an interrupt in that case. Leaving that bit for a read command
* messes up the data returned so it is only enabled when the framing is
* 'NFC_DIGITAL_FRAMING_NFCA_T2T' and the command is not a read command.
* Unfortunately, that means that the driver has to peek into tx frames
* when the framing is 'NFC_DIGITAL_FRAMING_NFCA_T2T'. This is done by
* the trf7970a_per_cmd_config() routine.
*
* ISO/IEC 15693 frames specify whether to use single or double sub-carrier
* frequencies and whether to use low or high data rates in the flags byte
* of the frame. This means that the driver has to peek at all 15693 frames
* to determine what speed to set the communication to. In addition, write
* and lock commands use the OPTION flag to indicate that an EOF must be
* sent to the tag before it will send its response. So the driver has to
* examine all frames for that reason too.
*
* It is unclear how long to wait before sending the EOF. According to the
* Note under Table 1-1 in section 1.6 of
* http://www.ti.com/lit/ug/scbu011/scbu011.pdf, that wait should be at least
* 10 ms for TI Tag-it HF-I tags; however testing has shown that is not long
* enough. For this reason, the driver waits 20 ms which seems to work
* reliably.
*/
#define TRF7970A_SUPPORTED_PROTOCOLS \
(NFC_PROTO_MIFARE_MASK | NFC_PROTO_ISO14443_MASK | \
NFC_PROTO_ISO15693_MASK)
/* TX data must be prefixed with a FIFO reset cmd, a cmd that depends
* on what the current framing is, the address of the TX length byte 1
* register (0x1d), and the 2 byte length of the data to be transmitted.
* That totals 5 bytes.
*/
#define TRF7970A_TX_SKB_HEADROOM 5
#define TRF7970A_RX_SKB_ALLOC_SIZE 256
#define TRF7970A_FIFO_SIZE 128
/* TX length is 3 nibbles long ==> 4KB - 1 bytes max */
#define TRF7970A_TX_MAX (4096 - 1)
#define TRF7970A_WAIT_FOR_RX_DATA_TIMEOUT 5
#define TRF7970A_WAIT_FOR_FIFO_DRAIN_TIMEOUT 3
#define TRF7970A_WAIT_TO_ISSUE_ISO15693_EOF 20
/* Quirks */
/* Erratum: When reading IRQ Status register on trf7970a, we must issue a
* read continuous command for IRQ Status and Collision Position registers.
*/
#define TRF7970A_QUIRK_IRQ_STATUS_READ_ERRATA BIT(0)
/* Direct commands */
#define TRF7970A_CMD_IDLE 0x00
#define TRF7970A_CMD_SOFT_INIT 0x03
#define TRF7970A_CMD_RF_COLLISION 0x04
#defi