trf7970a.c revision 4542e8345af6076c87d036c7bd3f9dfa30768b1e
1165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer/*
2165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer * TI TRF7970a RFID/NFC Transceiver Driver
3165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer *
4165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer * Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com
5165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer *
6165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer * Author: Erick Macias <emacias@ti.com>
7165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer * Author: Felipe Balbi <balbi@ti.com>
8165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer * Author: Mark A. Greer <mgreer@animalcreek.com>
9165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer *
10165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer * This program is free software: you can redistribute it and/or modify
11165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer * it under the terms of the GNU General Public License version 2  of
12165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer * the License as published by the Free Software Foundation.
13165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer */
14165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
15165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer#include <linux/module.h>
16165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer#include <linux/device.h>
17165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer#include <linux/netdevice.h>
18165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer#include <linux/interrupt.h>
19e6403b7c756f9d694332870ba0c2be7a4aa0b8c0Mark A. Greer#include <linux/pm_runtime.h>
20165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer#include <linux/nfc.h>
21165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer#include <linux/skbuff.h>
22165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer#include <linux/delay.h>
23165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer#include <linux/gpio.h>
24165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer#include <linux/of.h>
25165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer#include <linux/of_gpio.h>
26165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer#include <linux/spi/spi.h>
27165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer#include <linux/regulator/consumer.h>
28165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
29165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer#include <net/nfc/nfc.h>
30165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer#include <net/nfc/digital.h>
31165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
32165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer/* There are 3 ways the host can communicate with the trf7970a:
33165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer * parallel mode, SPI with Slave Select (SS) mode, and SPI without
34165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer * SS mode.  The driver only supports the two SPI modes.
35165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer *
36165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer * The trf7970a is very timing sensitive and the VIN, EN2, and EN
37165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer * pins must asserted in that order and with specific delays in between.
38165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer * The delays used in the driver were provided by TI and have been
3995064bd95a822659f4a606b485aba5009d70fc88Mark A. Greer * confirmed to work with this driver.  There is a bug with the current
4095064bd95a822659f4a606b485aba5009d70fc88Mark A. Greer * version of the trf7970a that requires that EN2 remain low no matter
4195064bd95a822659f4a606b485aba5009d70fc88Mark A. Greer * what.  If it goes high, it will generate an RF field even when in
4295064bd95a822659f4a606b485aba5009d70fc88Mark A. Greer * passive target mode.  TI has indicated that the chip will work okay
4395064bd95a822659f4a606b485aba5009d70fc88Mark A. Greer * when EN2 is left low.  The 'en2-rf-quirk' device tree property
4495064bd95a822659f4a606b485aba5009d70fc88Mark A. Greer * indicates that trf7970a currently being used has the erratum and
4595064bd95a822659f4a606b485aba5009d70fc88Mark A. Greer * that EN2 must be kept low.
46165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer *
47165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer * Timeouts are implemented using the delayed workqueue kernel facility.
48165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer * Timeouts are required so things don't hang when there is no response
49165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer * from the trf7970a (or tag).  Using this mechanism creates a race with
50165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer * interrupts, however.  That is, an interrupt and a timeout could occur
51165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer * closely enough together that one is blocked by the mutex while the other
52165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer * executes.  When the timeout handler executes first and blocks the
53165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer * interrupt handler, it will eventually set the state to IDLE so the
54165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer * interrupt handler will check the state and exit with no harm done.
55165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer * When the interrupt handler executes first and blocks the timeout handler,
56165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer * the cancel_delayed_work() call will know that it didn't cancel the
57165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer * work item (i.e., timeout) and will return zero.  That return code is
58165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer * used by the timer handler to indicate that it should ignore the timeout
59165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer * once its unblocked.
60165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer *
61165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer * Aborting an active command isn't as simple as it seems because the only
62165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer * way to abort a command that's already been sent to the tag is so turn
63165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer * off power to the tag.  If we do that, though, we'd have to go through
64165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer * the entire anticollision procedure again but the digital layer doesn't
65165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer * support that.  So, if an abort is received before trf7970a_in_send_cmd()
66165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer * has sent the command to the tag, it simply returns -ECANCELED.  If the
67165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer * command has already been sent to the tag, then the driver continues
68165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer * normally and recieves the response data (or error) but just before
69165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer * sending the data upstream, it frees the rx_skb and sends -ECANCELED
70165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer * upstream instead.  If the command failed, that error will be sent
71165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer * upstream.
72165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer *
73165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer * When recieving data from a tag and the interrupt status register has
74165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer * only the SRX bit set, it means that all of the data has been received
75165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer * (once what's in the fifo has been read).  However, depending on timing
76165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer * an interrupt status with only the SRX bit set may not be recived.  In
775fa3af352b991e2e5c674728411d1cc4a4923e4dMark A. Greer * those cases, the timeout mechanism is used to wait 20 ms in case more
785fa3af352b991e2e5c674728411d1cc4a4923e4dMark A. Greer * data arrives.  After 20 ms, it is assumed that all of the data has been
79165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer * received and the accumulated rx data is sent upstream.  The
80165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer * 'TRF7970A_ST_WAIT_FOR_RX_DATA_CONT' state is used for this purpose
81165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer * (i.e., it indicates that some data has been received but we're not sure
82165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer * if there is more coming so a timeout in this state means all data has
835fa3af352b991e2e5c674728411d1cc4a4923e4dMark A. Greer * been received and there isn't an error).  The delay is 20 ms since delays
845fa3af352b991e2e5c674728411d1cc4a4923e4dMark A. Greer * of ~16 ms have been observed during testing.
85165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer *
86165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer * Type 2 write and sector select commands respond with a 4-bit ACK or NACK.
87165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer * Having only 4 bits in the FIFO won't normally generate an interrupt so
88165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer * driver enables the '4_bit_RX' bit of the Special Functions register 1
89165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer * to cause an interrupt in that case.  Leaving that bit for a read command
90165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer * messes up the data returned so it is only enabled when the framing is
91165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer * 'NFC_DIGITAL_FRAMING_NFCA_T2T' and the command is not a read command.
92165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer * Unfortunately, that means that the driver has to peek into tx frames
93165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer * when the framing is 'NFC_DIGITAL_FRAMING_NFCA_T2T'.  This is done by
94165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer * the trf7970a_per_cmd_config() routine.
959d9304b32154be5908a3abbb46215297b9ce0a4cMark A. Greer *
969d9304b32154be5908a3abbb46215297b9ce0a4cMark A. Greer * ISO/IEC 15693 frames specify whether to use single or double sub-carrier
979d9304b32154be5908a3abbb46215297b9ce0a4cMark A. Greer * frequencies and whether to use low or high data rates in the flags byte
989d9304b32154be5908a3abbb46215297b9ce0a4cMark A. Greer * of the frame.  This means that the driver has to peek at all 15693 frames
999d9304b32154be5908a3abbb46215297b9ce0a4cMark A. Greer * to determine what speed to set the communication to.  In addition, write
1009d9304b32154be5908a3abbb46215297b9ce0a4cMark A. Greer * and lock commands use the OPTION flag to indicate that an EOF must be
1019d9304b32154be5908a3abbb46215297b9ce0a4cMark A. Greer * sent to the tag before it will send its response.  So the driver has to
1029d9304b32154be5908a3abbb46215297b9ce0a4cMark A. Greer * examine all frames for that reason too.
1039d9304b32154be5908a3abbb46215297b9ce0a4cMark A. Greer *
1049d9304b32154be5908a3abbb46215297b9ce0a4cMark A. Greer * It is unclear how long to wait before sending the EOF.  According to the
1059d9304b32154be5908a3abbb46215297b9ce0a4cMark A. Greer * Note under Table 1-1 in section 1.6 of
1069d9304b32154be5908a3abbb46215297b9ce0a4cMark A. Greer * http://www.ti.com/lit/ug/scbu011/scbu011.pdf, that wait should be at least
1079d9304b32154be5908a3abbb46215297b9ce0a4cMark A. Greer * 10 ms for TI Tag-it HF-I tags; however testing has shown that is not long
1089d9304b32154be5908a3abbb46215297b9ce0a4cMark A. Greer * enough.  For this reason, the driver waits 20 ms which seems to work
1099d9304b32154be5908a3abbb46215297b9ce0a4cMark A. Greer * reliably.
110165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer */
111165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
1128006289108fa9635d16a65d9db16da06d7dce201Mark A. Greer#define TRF7970A_SUPPORTED_PROTOCOLS \
1139d9304b32154be5908a3abbb46215297b9ce0a4cMark A. Greer		(NFC_PROTO_MIFARE_MASK | NFC_PROTO_ISO14443_MASK |	\
1146857bb96271cd40ffb38825d43897d716310e3dbMark A. Greer		 NFC_PROTO_ISO14443_B_MASK | NFC_PROTO_FELICA_MASK | \
1156857bb96271cd40ffb38825d43897d716310e3dbMark A. Greer		 NFC_PROTO_ISO15693_MASK)
116165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
117e6403b7c756f9d694332870ba0c2be7a4aa0b8c0Mark A. Greer#define TRF7970A_AUTOSUSPEND_DELAY		30000 /* 30 seconds */
118e6403b7c756f9d694332870ba0c2be7a4aa0b8c0Mark A. Greer
119165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer/* TX data must be prefixed with a FIFO reset cmd, a cmd that depends
120165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer * on what the current framing is, the address of the TX length byte 1
121165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer * register (0x1d), and the 2 byte length of the data to be transmitted.
122165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer * That totals 5 bytes.
123165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer */
124165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer#define TRF7970A_TX_SKB_HEADROOM		5
125165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
126165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer#define TRF7970A_RX_SKB_ALLOC_SIZE		256
127165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
128165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer#define TRF7970A_FIFO_SIZE			128
129165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
130165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer/* TX length is 3 nibbles long ==> 4KB - 1 bytes max */
131165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer#define TRF7970A_TX_MAX				(4096 - 1)
132165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
1335fa3af352b991e2e5c674728411d1cc4a4923e4dMark A. Greer#define TRF7970A_WAIT_FOR_RX_DATA_TIMEOUT	20
134165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer#define TRF7970A_WAIT_FOR_FIFO_DRAIN_TIMEOUT	3
1359d9304b32154be5908a3abbb46215297b9ce0a4cMark A. Greer#define TRF7970A_WAIT_TO_ISSUE_ISO15693_EOF	20
136165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
137165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer/* Quirks */
138165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer/* Erratum: When reading IRQ Status register on trf7970a, we must issue a
139165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer * read continuous command for IRQ Status and Collision Position registers.
140165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer */
141772079eb77587e0242752fa67685a8132d899f79Mark A. Greer#define TRF7970A_QUIRK_IRQ_STATUS_READ		BIT(0)
14295064bd95a822659f4a606b485aba5009d70fc88Mark A. Greer#define TRF7970A_QUIRK_EN2_MUST_STAY_LOW	BIT(1)
143165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
144165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer/* Direct commands */
145165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer#define TRF7970A_CMD_IDLE			0x00
146165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer#define TRF7970A_CMD_SOFT_INIT			0x03
147165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer#define TRF7970A_CMD_RF_COLLISION		0x04
148165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer#define TRF7970A_CMD_RF_COLLISION_RESPONSE_N	0x05
149165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer#define TRF7970A_CMD_RF_COLLISION_RESPONSE_0	0x06
150165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer#define TRF7970A_CMD_FIFO_RESET			0x0f
151165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer#define TRF7970A_CMD_TRANSMIT_NO_CRC		0x10
152165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer#define TRF7970A_CMD_TRANSMIT			0x11
153165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer#define TRF7970A_CMD_DELAY_TRANSMIT_NO_CRC	0x12
154165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer#define TRF7970A_CMD_DELAY_TRANSMIT		0x13
155165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer#define TRF7970A_CMD_EOF			0x14
156165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer#define TRF7970A_CMD_CLOSE_SLOT			0x15
157165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer#define TRF7970A_CMD_BLOCK_RX			0x16
158165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer#define TRF7970A_CMD_ENABLE_RX			0x17
159165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer#define TRF7970A_CMD_TEST_EXT_RF		0x18
160165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer#define TRF7970A_CMD_TEST_INT_RF		0x19
161165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer#define TRF7970A_CMD_RX_GAIN_ADJUST		0x1a
162165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
163165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer/* Bits determining whether its a direct command or register R/W,
164165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer * whether to use a continuous SPI transaction or not, and the actual
165165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer * direct cmd opcode or regster address.
166165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer */
167165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer#define TRF7970A_CMD_BIT_CTRL			BIT(7)
168165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer#define TRF7970A_CMD_BIT_RW			BIT(6)
169165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer#define TRF7970A_CMD_BIT_CONTINUOUS		BIT(5)
170165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer#define TRF7970A_CMD_BIT_OPCODE(opcode)		((opcode) & 0x1f)
171165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
172165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer/* Registers addresses */
173165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer#define TRF7970A_CHIP_STATUS_CTRL		0x00
174165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer#define TRF7970A_ISO_CTRL			0x01
175165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer#define TRF7970A_ISO14443B_TX_OPTIONS		0x02
176165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer#define TRF7970A_ISO14443A_HIGH_BITRATE_OPTIONS	0x03
177165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer#define TRF7970A_TX_TIMER_SETTING_H_BYTE	0x04
178165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer#define TRF7970A_TX_TIMER_SETTING_L_BYTE	0x05
179165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer#define TRF7970A_TX_PULSE_LENGTH_CTRL		0x06
180165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer#define TRF7970A_RX_NO_RESPONSE_WAIT		0x07
181165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer#define TRF7970A_RX_WAIT_TIME			0x08
182165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer#define TRF7970A_MODULATOR_SYS_CLK_CTRL		0x09
183165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer#define TRF7970A_RX_SPECIAL_SETTINGS		0x0a
184165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer#define TRF7970A_REG_IO_CTRL			0x0b
185165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer#define TRF7970A_IRQ_STATUS			0x0c
186165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer#define TRF7970A_COLLISION_IRQ_MASK		0x0d
187165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer#define TRF7970A_COLLISION_POSITION		0x0e
188165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer#define TRF7970A_RSSI_OSC_STATUS		0x0f
189165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer#define TRF7970A_SPECIAL_FCN_REG1		0x10
190165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer#define TRF7970A_SPECIAL_FCN_REG2		0x11
191165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer#define TRF7970A_RAM1				0x12
192165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer#define TRF7970A_RAM2				0x13
193165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer#define TRF7970A_ADJUTABLE_FIFO_IRQ_LEVELS	0x14
194165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer#define TRF7970A_NFC_LOW_FIELD_LEVEL		0x16
195165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer#define TRF7970A_NFCID1				0x17
196165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer#define TRF7970A_NFC_TARGET_LEVEL		0x18
197165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer#define TRF79070A_NFC_TARGET_PROTOCOL		0x19
198165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer#define TRF7970A_TEST_REGISTER1			0x1a
199165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer#define TRF7970A_TEST_REGISTER2			0x1b
200165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer#define TRF7970A_FIFO_STATUS			0x1c
201165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer#define TRF7970A_TX_LENGTH_BYTE1		0x1d
202165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer#define TRF7970A_TX_LENGTH_BYTE2		0x1e
203165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer#define TRF7970A_FIFO_IO_REGISTER		0x1f
204165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
205165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer/* Chip Status Control Register Bits */
206165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer#define TRF7970A_CHIP_STATUS_VRS5_3		BIT(0)
207165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer#define TRF7970A_CHIP_STATUS_REC_ON		BIT(1)
208165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer#define TRF7970A_CHIP_STATUS_AGC_ON		BIT(2)
209165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer#define TRF7970A_CHIP_STATUS_PM_ON		BIT(3)
210165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer#define TRF7970A_CHIP_STATUS_RF_PWR		BIT(4)
211165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer#define TRF7970A_CHIP_STATUS_RF_ON		BIT(5)
212165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer#define TRF7970A_CHIP_STATUS_DIRECT		BIT(6)
213165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer#define TRF7970A_CHIP_STATUS_STBY		BIT(7)
214165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
215165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer/* ISO Control Register Bits */
216165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer#define TRF7970A_ISO_CTRL_15693_SGL_1OF4_662	0x00
217165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer#define TRF7970A_ISO_CTRL_15693_SGL_1OF256_662	0x01
218165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer#define TRF7970A_ISO_CTRL_15693_SGL_1OF4_2648	0x02
219165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer#define TRF7970A_ISO_CTRL_15693_SGL_1OF256_2648	0x03
220165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer#define TRF7970A_ISO_CTRL_15693_DBL_1OF4_667a	0x04
221165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer#define TRF7970A_ISO_CTRL_15693_DBL_1OF256_667	0x05
222165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer#define TRF7970A_ISO_CTRL_15693_DBL_1OF4_2669	0x06
223165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer#define TRF7970A_ISO_CTRL_15693_DBL_1OF256_2669	0x07
224165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer#define TRF7970A_ISO_CTRL_14443A_106		0x08
225165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer#define TRF7970A_ISO_CTRL_14443A_212		0x09
226165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer#define TRF7970A_ISO_CTRL_14443A_424		0x0a
227165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer#define TRF7970A_ISO_CTRL_14443A_848		0x0b
228165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer#define TRF7970A_ISO_CTRL_14443B_106		0x0c
229165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer#define TRF7970A_ISO_CTRL_14443B_212		0x0d
230165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer#define TRF7970A_ISO_CTRL_14443B_424		0x0e
231165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer#define TRF7970A_ISO_CTRL_14443B_848		0x0f
232165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer#define TRF7970A_ISO_CTRL_FELICA_212		0x1a
233165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer#define TRF7970A_ISO_CTRL_FELICA_424		0x1b
234165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer#define TRF7970A_ISO_CTRL_RFID			BIT(5)
235165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer#define TRF7970A_ISO_CTRL_DIR_MODE		BIT(6)
236165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer#define TRF7970A_ISO_CTRL_RX_CRC_N		BIT(7)	/* true == No CRC */
237165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
238165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer#define TRF7970A_ISO_CTRL_RFID_SPEED_MASK	0x1f
239165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
240165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer/* Modulator and SYS_CLK Control Register Bits */
241165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer#define TRF7970A_MODULATOR_DEPTH(n)		((n) & 0x7)
242165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer#define TRF7970A_MODULATOR_DEPTH_ASK10		(TRF7970A_MODULATOR_DEPTH(0))
243165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer#define TRF7970A_MODULATOR_DEPTH_OOK		(TRF7970A_MODULATOR_DEPTH(1))
244165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer#define TRF7970A_MODULATOR_DEPTH_ASK7		(TRF7970A_MODULATOR_DEPTH(2))
245165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer#define TRF7970A_MODULATOR_DEPTH_ASK8_5		(TRF7970A_MODULATOR_DEPTH(3))
246165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer#define TRF7970A_MODULATOR_DEPTH_ASK13		(TRF7970A_MODULATOR_DEPTH(4))
247165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer#define TRF7970A_MODULATOR_DEPTH_ASK16		(TRF7970A_MODULATOR_DEPTH(5))
248165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer#define TRF7970A_MODULATOR_DEPTH_ASK22		(TRF7970A_MODULATOR_DEPTH(6))
249165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer#define TRF7970A_MODULATOR_DEPTH_ASK30		(TRF7970A_MODULATOR_DEPTH(7))
250165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer#define TRF7970A_MODULATOR_EN_ANA		BIT(3)
251165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer#define TRF7970A_MODULATOR_CLK(n)		(((n) & 0x3) << 4)
252165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer#define TRF7970A_MODULATOR_CLK_DISABLED		(TRF7970A_MODULATOR_CLK(0))
253165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer#define TRF7970A_MODULATOR_CLK_3_6		(TRF7970A_MODULATOR_CLK(1))
254165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer#define TRF7970A_MODULATOR_CLK_6_13		(TRF7970A_MODULATOR_CLK(2))
255165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer#define TRF7970A_MODULATOR_CLK_13_27		(TRF7970A_MODULATOR_CLK(3))
256165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer#define TRF7970A_MODULATOR_EN_OOK		BIT(6)
257165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer#define TRF7970A_MODULATOR_27MHZ		BIT(7)
258165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
259165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer/* IRQ Status Register Bits */
260165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer#define TRF7970A_IRQ_STATUS_NORESP		BIT(0) /* ISO15693 only */
261165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer#define TRF7970A_IRQ_STATUS_COL			BIT(1)
262165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer#define TRF7970A_IRQ_STATUS_FRAMING_EOF_ERROR	BIT(2)
263165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer#define TRF7970A_IRQ_STATUS_PARITY_ERROR	BIT(3)
264165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer#define TRF7970A_IRQ_STATUS_CRC_ERROR		BIT(4)
265165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer#define TRF7970A_IRQ_STATUS_FIFO		BIT(5)
266165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer#define TRF7970A_IRQ_STATUS_SRX			BIT(6)
267165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer#define TRF7970A_IRQ_STATUS_TX			BIT(7)
268165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
269165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer#define TRF7970A_IRQ_STATUS_ERROR				\
270165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		(TRF7970A_IRQ_STATUS_COL |			\
271165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		 TRF7970A_IRQ_STATUS_FRAMING_EOF_ERROR |	\
272165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		 TRF7970A_IRQ_STATUS_PARITY_ERROR |		\
273165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		 TRF7970A_IRQ_STATUS_CRC_ERROR)
274165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
275165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer#define TRF7970A_SPECIAL_FCN_REG1_COL_7_6		BIT(0)
276165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer#define TRF7970A_SPECIAL_FCN_REG1_14_ANTICOLL		BIT(1)
277165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer#define TRF7970A_SPECIAL_FCN_REG1_4_BIT_RX		BIT(2)
278165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer#define TRF7970A_SPECIAL_FCN_REG1_SP_DIR_MODE		BIT(3)
279165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer#define TRF7970A_SPECIAL_FCN_REG1_NEXT_SLOT_37US	BIT(4)
280165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer#define TRF7970A_SPECIAL_FCN_REG1_PAR43			BIT(5)
281165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
282165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer#define TRF7970A_ADJUTABLE_FIFO_IRQ_LEVELS_WLH_124	(0x0 << 2)
283165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer#define TRF7970A_ADJUTABLE_FIFO_IRQ_LEVELS_WLH_120	(0x1 << 2)
284165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer#define TRF7970A_ADJUTABLE_FIFO_IRQ_LEVELS_WLH_112	(0x2 << 2)
285165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer#define TRF7970A_ADJUTABLE_FIFO_IRQ_LEVELS_WLH_96	(0x3 << 2)
286165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer#define TRF7970A_ADJUTABLE_FIFO_IRQ_LEVELS_WLL_4	0x0
287165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer#define TRF7970A_ADJUTABLE_FIFO_IRQ_LEVELS_WLL_8	0x1
288165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer#define TRF7970A_ADJUTABLE_FIFO_IRQ_LEVELS_WLL_16	0x2
289165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer#define TRF7970A_ADJUTABLE_FIFO_IRQ_LEVELS_WLL_32	0x3
290165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
291165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer#define TRF7970A_FIFO_STATUS_OVERFLOW		BIT(7)
292165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
293165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer/* NFC (ISO/IEC 14443A) Type 2 Tag commands */
294165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer#define NFC_T2T_CMD_READ			0x30
295165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
2969d9304b32154be5908a3abbb46215297b9ce0a4cMark A. Greer/* ISO 15693 commands codes */
2979d9304b32154be5908a3abbb46215297b9ce0a4cMark A. Greer#define ISO15693_CMD_INVENTORY			0x01
2989d9304b32154be5908a3abbb46215297b9ce0a4cMark A. Greer#define ISO15693_CMD_READ_SINGLE_BLOCK		0x20
2999d9304b32154be5908a3abbb46215297b9ce0a4cMark A. Greer#define ISO15693_CMD_WRITE_SINGLE_BLOCK		0x21
3009d9304b32154be5908a3abbb46215297b9ce0a4cMark A. Greer#define ISO15693_CMD_LOCK_BLOCK			0x22
3019d9304b32154be5908a3abbb46215297b9ce0a4cMark A. Greer#define ISO15693_CMD_READ_MULTIPLE_BLOCK	0x23
3029d9304b32154be5908a3abbb46215297b9ce0a4cMark A. Greer#define ISO15693_CMD_WRITE_MULTIPLE_BLOCK	0x24
3039d9304b32154be5908a3abbb46215297b9ce0a4cMark A. Greer#define ISO15693_CMD_SELECT			0x25
3049d9304b32154be5908a3abbb46215297b9ce0a4cMark A. Greer#define ISO15693_CMD_RESET_TO_READY		0x26
3059d9304b32154be5908a3abbb46215297b9ce0a4cMark A. Greer#define ISO15693_CMD_WRITE_AFI			0x27
3069d9304b32154be5908a3abbb46215297b9ce0a4cMark A. Greer#define ISO15693_CMD_LOCK_AFI			0x28
3079d9304b32154be5908a3abbb46215297b9ce0a4cMark A. Greer#define ISO15693_CMD_WRITE_DSFID		0x29
3089d9304b32154be5908a3abbb46215297b9ce0a4cMark A. Greer#define ISO15693_CMD_LOCK_DSFID			0x2a
3099d9304b32154be5908a3abbb46215297b9ce0a4cMark A. Greer#define ISO15693_CMD_GET_SYSTEM_INFO		0x2b
3109d9304b32154be5908a3abbb46215297b9ce0a4cMark A. Greer#define ISO15693_CMD_GET_MULTIPLE_BLOCK_SECURITY_STATUS	0x2c
3119d9304b32154be5908a3abbb46215297b9ce0a4cMark A. Greer
3129d9304b32154be5908a3abbb46215297b9ce0a4cMark A. Greer/* ISO 15693 request and response flags */
3139d9304b32154be5908a3abbb46215297b9ce0a4cMark A. Greer#define ISO15693_REQ_FLAG_SUB_CARRIER		BIT(0)
3149d9304b32154be5908a3abbb46215297b9ce0a4cMark A. Greer#define ISO15693_REQ_FLAG_DATA_RATE		BIT(1)
3159d9304b32154be5908a3abbb46215297b9ce0a4cMark A. Greer#define ISO15693_REQ_FLAG_INVENTORY		BIT(2)
3169d9304b32154be5908a3abbb46215297b9ce0a4cMark A. Greer#define ISO15693_REQ_FLAG_PROTOCOL_EXT		BIT(3)
3179d9304b32154be5908a3abbb46215297b9ce0a4cMark A. Greer#define ISO15693_REQ_FLAG_SELECT		BIT(4)
3189d9304b32154be5908a3abbb46215297b9ce0a4cMark A. Greer#define ISO15693_REQ_FLAG_AFI			BIT(4)
3199d9304b32154be5908a3abbb46215297b9ce0a4cMark A. Greer#define ISO15693_REQ_FLAG_ADDRESS		BIT(5)
3209d9304b32154be5908a3abbb46215297b9ce0a4cMark A. Greer#define ISO15693_REQ_FLAG_NB_SLOTS		BIT(5)
3219d9304b32154be5908a3abbb46215297b9ce0a4cMark A. Greer#define ISO15693_REQ_FLAG_OPTION		BIT(6)
3229d9304b32154be5908a3abbb46215297b9ce0a4cMark A. Greer
3239d9304b32154be5908a3abbb46215297b9ce0a4cMark A. Greer#define ISO15693_REQ_FLAG_SPEED_MASK \
3249d9304b32154be5908a3abbb46215297b9ce0a4cMark A. Greer		(ISO15693_REQ_FLAG_SUB_CARRIER | ISO15693_REQ_FLAG_DATA_RATE)
3259d9304b32154be5908a3abbb46215297b9ce0a4cMark A. Greer
326165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greerenum trf7970a_state {
327165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	TRF7970A_ST_OFF,
328165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	TRF7970A_ST_IDLE,
329165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	TRF7970A_ST_IDLE_RX_BLOCKED,
330165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	TRF7970A_ST_WAIT_FOR_TX_FIFO,
331165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	TRF7970A_ST_WAIT_FOR_RX_DATA,
332165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	TRF7970A_ST_WAIT_FOR_RX_DATA_CONT,
3339d9304b32154be5908a3abbb46215297b9ce0a4cMark A. Greer	TRF7970A_ST_WAIT_TO_ISSUE_EOF,
334165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	TRF7970A_ST_MAX
335165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer};
336165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
337165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greerstruct trf7970a {
338165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	enum trf7970a_state		state;
339165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	struct device			*dev;
340165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	struct spi_device		*spi;
341165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	struct regulator		*regulator;
342165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	struct nfc_digital_dev		*ddev;
343165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	u32				quirks;
344165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	bool				aborting;
345165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	struct sk_buff			*tx_skb;
346165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	struct sk_buff			*rx_skb;
347165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	nfc_digital_cmd_complete_t	cb;
348165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	void				*cb_arg;
349ebcc5a0d08e6a680558ed74f5dd724427ff5a29bMark A. Greer	u8				chip_status_ctrl;
350165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	u8				iso_ctrl;
35149d19cc794e73c3383283a5366ff31572d71a795Mark A. Greer	u8				iso_ctrl_tech;
35212e9ade309db51e7ea26be3b4fd5bc6057ddc175Mark A. Greer	u8				modulator_sys_clk_ctrl;
353165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	u8				special_fcn_reg1;
354165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	int				technology;
355165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	int				framing;
356165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	u8				tx_cmd;
3579d9304b32154be5908a3abbb46215297b9ce0a4cMark A. Greer	bool				issue_eof;
358165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	int				en2_gpio;
359165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	int				en_gpio;
360165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	struct mutex			lock;
361165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	unsigned int			timeout;
362165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	bool				ignore_timeout;
363165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	struct delayed_work		timeout_work;
364165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer};
365165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
366165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
367165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greerstatic int trf7970a_cmd(struct trf7970a *trf, u8 opcode)
368165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer{
369165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	u8 cmd = TRF7970A_CMD_BIT_CTRL | TRF7970A_CMD_BIT_OPCODE(opcode);
370165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	int ret;
371165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
372165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	dev_dbg(trf->dev, "cmd: 0x%x\n", cmd);
373165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
374165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	ret = spi_write(trf->spi, &cmd, 1);
375165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	if (ret)
376165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		dev_err(trf->dev, "%s - cmd: 0x%x, ret: %d\n", __func__, cmd,
377165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer				ret);
378165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	return ret;
379165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer}
380165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
381165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greerstatic int trf7970a_read(struct trf7970a *trf, u8 reg, u8 *val)
382165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer{
383165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	u8 addr = TRF7970A_CMD_BIT_RW | reg;
384165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	int ret;
385165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
386165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	ret = spi_write_then_read(trf->spi, &addr, 1, val, 1);
387165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	if (ret)
388165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		dev_err(trf->dev, "%s - addr: 0x%x, ret: %d\n", __func__, addr,
389165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer				ret);
390165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
391165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	dev_dbg(trf->dev, "read(0x%x): 0x%x\n", addr, *val);
392165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
393165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	return ret;
394165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer}
395165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
3963e7f335689ebfa0a68814dfe9f0588076fb9ad01Mark A. Greerstatic int trf7970a_read_cont(struct trf7970a *trf, u8 reg, u8 *buf, size_t len)
397165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer{
398165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	u8 addr = reg | TRF7970A_CMD_BIT_RW | TRF7970A_CMD_BIT_CONTINUOUS;
3993e7f335689ebfa0a68814dfe9f0588076fb9ad01Mark A. Greer	struct spi_transfer t[2];
4003e7f335689ebfa0a68814dfe9f0588076fb9ad01Mark A. Greer	struct spi_message m;
401165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	int ret;
402165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
403165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	dev_dbg(trf->dev, "read_cont(0x%x, %zd)\n", addr, len);
404165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
4053e7f335689ebfa0a68814dfe9f0588076fb9ad01Mark A. Greer	spi_message_init(&m);
4063e7f335689ebfa0a68814dfe9f0588076fb9ad01Mark A. Greer
4073e7f335689ebfa0a68814dfe9f0588076fb9ad01Mark A. Greer	memset(&t, 0, sizeof(t));
4083e7f335689ebfa0a68814dfe9f0588076fb9ad01Mark A. Greer
4093e7f335689ebfa0a68814dfe9f0588076fb9ad01Mark A. Greer	t[0].tx_buf = &addr;
4103e7f335689ebfa0a68814dfe9f0588076fb9ad01Mark A. Greer	t[0].len = sizeof(addr);
4113e7f335689ebfa0a68814dfe9f0588076fb9ad01Mark A. Greer	spi_message_add_tail(&t[0], &m);
4123e7f335689ebfa0a68814dfe9f0588076fb9ad01Mark A. Greer
4133e7f335689ebfa0a68814dfe9f0588076fb9ad01Mark A. Greer	t[1].rx_buf = buf;
4143e7f335689ebfa0a68814dfe9f0588076fb9ad01Mark A. Greer	t[1].len = len;
4153e7f335689ebfa0a68814dfe9f0588076fb9ad01Mark A. Greer	spi_message_add_tail(&t[1], &m);
4163e7f335689ebfa0a68814dfe9f0588076fb9ad01Mark A. Greer
4173e7f335689ebfa0a68814dfe9f0588076fb9ad01Mark A. Greer	ret = spi_sync(trf->spi, &m);
418165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	if (ret)
419165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		dev_err(trf->dev, "%s - addr: 0x%x, ret: %d\n", __func__, addr,
420165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer				ret);
421165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	return ret;
422165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer}
423165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
424165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greerstatic int trf7970a_write(struct trf7970a *trf, u8 reg, u8 val)
425165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer{
426165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	u8 buf[2] = { reg, val };
427165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	int ret;
428165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
429165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	dev_dbg(trf->dev, "write(0x%x): 0x%x\n", reg, val);
430165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
431165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	ret = spi_write(trf->spi, buf, 2);
432165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	if (ret)
433165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		dev_err(trf->dev, "%s - write: 0x%x 0x%x, ret: %d\n", __func__,
434165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer				buf[0], buf[1], ret);
435165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
436165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	return ret;
437165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer}
438165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
439165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greerstatic int trf7970a_read_irqstatus(struct trf7970a *trf, u8 *status)
440165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer{
441165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	int ret;
442165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	u8 buf[2];
443165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	u8 addr;
444165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
445165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	addr = TRF7970A_IRQ_STATUS | TRF7970A_CMD_BIT_RW;
446165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
447772079eb77587e0242752fa67685a8132d899f79Mark A. Greer	if (trf->quirks & TRF7970A_QUIRK_IRQ_STATUS_READ) {
448165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		addr |= TRF7970A_CMD_BIT_CONTINUOUS;
449165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		ret = spi_write_then_read(trf->spi, &addr, 1, buf, 2);
450165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	} else {
451165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		ret = spi_write_then_read(trf->spi, &addr, 1, buf, 1);
452165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	}
453165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
454165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	if (ret)
455165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		dev_err(trf->dev, "%s - irqstatus: Status read failed: %d\n",
456165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer				__func__, ret);
457165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	else
458165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		*status = buf[0];
459165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
460165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	return ret;
461165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer}
462165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
463165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greerstatic void trf7970a_send_upstream(struct trf7970a *trf)
464165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer{
465165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	u8 rssi;
466165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
467165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	dev_kfree_skb_any(trf->tx_skb);
468165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	trf->tx_skb = NULL;
469165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
470165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	if (trf->rx_skb && !IS_ERR(trf->rx_skb) && !trf->aborting)
471165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		print_hex_dump_debug("trf7970a rx data: ", DUMP_PREFIX_NONE,
472165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer				16, 1, trf->rx_skb->data, trf->rx_skb->len,
473165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer				false);
474165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
475165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	/* According to the manual it is "good form" to reset the fifo and
476165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	 * read the RSSI levels & oscillator status register here.  It doesn't
477165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	 * explain why.
478165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	 */
479165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	trf7970a_cmd(trf, TRF7970A_CMD_FIFO_RESET);
480165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	trf7970a_read(trf, TRF7970A_RSSI_OSC_STATUS, &rssi);
481165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
482165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	trf->state = TRF7970A_ST_IDLE;
483165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
484165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	if (trf->aborting) {
485165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		dev_dbg(trf->dev, "Abort process complete\n");
486165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
487165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		if (!IS_ERR(trf->rx_skb)) {
488165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer			kfree_skb(trf->rx_skb);
489165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer			trf->rx_skb = ERR_PTR(-ECANCELED);
490165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		}
491165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
492165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		trf->aborting = false;
493165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	}
494165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
495165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	trf->cb(trf->ddev, trf->cb_arg, trf->rx_skb);
496165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
497165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	trf->rx_skb = NULL;
498165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer}
499165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
500165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greerstatic void trf7970a_send_err_upstream(struct trf7970a *trf, int errno)
501165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer{
502165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	dev_dbg(trf->dev, "Error - state: %d, errno: %d\n", trf->state, errno);
503165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
504165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	kfree_skb(trf->rx_skb);
505165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	trf->rx_skb = ERR_PTR(errno);
506165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
507165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	trf7970a_send_upstream(trf);
508165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer}
509165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
510165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greerstatic int trf7970a_transmit(struct trf7970a *trf, struct sk_buff *skb,
511165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		unsigned int len)
512165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer{
513165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	unsigned int timeout;
514165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	int ret;
515165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
516165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	print_hex_dump_debug("trf7970a tx data: ", DUMP_PREFIX_NONE,
517165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer			16, 1, skb->data, len, false);
518165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
519165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	ret = spi_write(trf->spi, skb->data, len);
520165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	if (ret) {
521165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		dev_err(trf->dev, "%s - Can't send tx data: %d\n", __func__,
522165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer				ret);
523165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		return ret;
524165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	}
525165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
526165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	skb_pull(skb, len);
527165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
528165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	if (skb->len > 0) {
529165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		trf->state = TRF7970A_ST_WAIT_FOR_TX_FIFO;
530165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		timeout = TRF7970A_WAIT_FOR_FIFO_DRAIN_TIMEOUT;
531165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	} else {
5329d9304b32154be5908a3abbb46215297b9ce0a4cMark A. Greer		if (trf->issue_eof) {
5339d9304b32154be5908a3abbb46215297b9ce0a4cMark A. Greer			trf->state = TRF7970A_ST_WAIT_TO_ISSUE_EOF;
5349d9304b32154be5908a3abbb46215297b9ce0a4cMark A. Greer			timeout = TRF7970A_WAIT_TO_ISSUE_ISO15693_EOF;
5359d9304b32154be5908a3abbb46215297b9ce0a4cMark A. Greer		} else {
5369d9304b32154be5908a3abbb46215297b9ce0a4cMark A. Greer			trf->state = TRF7970A_ST_WAIT_FOR_RX_DATA;
5379d9304b32154be5908a3abbb46215297b9ce0a4cMark A. Greer			timeout = trf->timeout;
5389d9304b32154be5908a3abbb46215297b9ce0a4cMark A. Greer		}
539165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	}
540165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
541165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	dev_dbg(trf->dev, "Setting timeout for %d ms, state: %d\n", timeout,
542165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer			trf->state);
543165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
544165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	schedule_delayed_work(&trf->timeout_work, msecs_to_jiffies(timeout));
545165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
546165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	return 0;
547165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer}
548165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
549165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greerstatic void trf7970a_fill_fifo(struct trf7970a *trf)
550165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer{
551165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	struct sk_buff *skb = trf->tx_skb;
552165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	unsigned int len;
553165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	int ret;
554165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	u8 fifo_bytes;
555165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
556165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	ret = trf7970a_read(trf, TRF7970A_FIFO_STATUS, &fifo_bytes);
557165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	if (ret) {
558165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		trf7970a_send_err_upstream(trf, ret);
559165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		return;
560165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	}
561165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
562165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	dev_dbg(trf->dev, "Filling FIFO - fifo_bytes: 0x%x\n", fifo_bytes);
563165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
5644542e8345af6076c87d036c7bd3f9dfa30768b1eMark A. Greer	fifo_bytes &= ~TRF7970A_FIFO_STATUS_OVERFLOW;
565165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
566165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	/* Calculate how much more data can be written to the fifo */
567165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	len = TRF7970A_FIFO_SIZE - fifo_bytes;
568165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	len = min(skb->len, len);
569165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
570165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	ret = trf7970a_transmit(trf, skb, len);
571165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	if (ret)
572165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		trf7970a_send_err_upstream(trf, ret);
573165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer}
574165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
575165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greerstatic void trf7970a_drain_fifo(struct trf7970a *trf, u8 status)
576165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer{
577165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	struct sk_buff *skb = trf->rx_skb;
578165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	int ret;
579165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	u8 fifo_bytes;
580165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
581165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	if (status & TRF7970A_IRQ_STATUS_ERROR) {
582165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		trf7970a_send_err_upstream(trf, -EIO);
583165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		return;
584165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	}
585165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
586165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	ret = trf7970a_read(trf, TRF7970A_FIFO_STATUS, &fifo_bytes);
587165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	if (ret) {
588165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		trf7970a_send_err_upstream(trf, ret);
589165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		return;
590165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	}
591165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
592165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	dev_dbg(trf->dev, "Draining FIFO - fifo_bytes: 0x%x\n", fifo_bytes);
593165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
5944542e8345af6076c87d036c7bd3f9dfa30768b1eMark A. Greer	fifo_bytes &= ~TRF7970A_FIFO_STATUS_OVERFLOW;
5954542e8345af6076c87d036c7bd3f9dfa30768b1eMark A. Greer
596165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	if (!fifo_bytes)
597165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		goto no_rx_data;
598165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
599165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	if (fifo_bytes > skb_tailroom(skb)) {
600165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		skb = skb_copy_expand(skb, skb_headroom(skb),
601165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer				max_t(int, fifo_bytes,
602165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer					TRF7970A_RX_SKB_ALLOC_SIZE),
603165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer				GFP_KERNEL);
604165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		if (!skb) {
605165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer			trf7970a_send_err_upstream(trf, -ENOMEM);
606165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer			return;
607165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		}
608165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
609165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		kfree_skb(trf->rx_skb);
610165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		trf->rx_skb = skb;
611165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	}
612165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
613165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	ret = trf7970a_read_cont(trf, TRF7970A_FIFO_IO_REGISTER,
614165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer			skb_put(skb, fifo_bytes), fifo_bytes);
615165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	if (ret) {
616165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		trf7970a_send_err_upstream(trf, ret);
617165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		return;
618165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	}
619165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
620165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	/* If received Type 2 ACK/NACK, shift right 4 bits and pass up */
621165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	if ((trf->framing == NFC_DIGITAL_FRAMING_NFCA_T2T) && (skb->len == 1) &&
622165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer			(trf->special_fcn_reg1 ==
623165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer				 TRF7970A_SPECIAL_FCN_REG1_4_BIT_RX)) {
624165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		skb->data[0] >>= 4;
625165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		status = TRF7970A_IRQ_STATUS_SRX;
626165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	} else {
627165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		trf->state = TRF7970A_ST_WAIT_FOR_RX_DATA_CONT;
628165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	}
629165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
630165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greerno_rx_data:
631165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	if (status == TRF7970A_IRQ_STATUS_SRX) { /* Receive complete */
632165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		trf7970a_send_upstream(trf);
633165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		return;
634165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	}
635165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
636165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	dev_dbg(trf->dev, "Setting timeout for %d ms\n",
637165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer			TRF7970A_WAIT_FOR_RX_DATA_TIMEOUT);
638165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
639165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	schedule_delayed_work(&trf->timeout_work,
640165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer			msecs_to_jiffies(TRF7970A_WAIT_FOR_RX_DATA_TIMEOUT));
641165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer}
642165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
643165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greerstatic irqreturn_t trf7970a_irq(int irq, void *dev_id)
644165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer{
645165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	struct trf7970a *trf = dev_id;
646165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	int ret;
647165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	u8 status;
648165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
649165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	mutex_lock(&trf->lock);
650165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
651165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	if (trf->state == TRF7970A_ST_OFF) {
652165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		mutex_unlock(&trf->lock);
653165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		return IRQ_NONE;
654165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	}
655165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
656165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	ret = trf7970a_read_irqstatus(trf, &status);
657165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	if (ret) {
658165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		mutex_unlock(&trf->lock);
659165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		return IRQ_NONE;
660165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	}
661165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
662165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	dev_dbg(trf->dev, "IRQ - state: %d, status: 0x%x\n", trf->state,
663165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer			status);
664165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
665165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	if (!status) {
666165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		mutex_unlock(&trf->lock);
667165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		return IRQ_NONE;
668165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	}
669165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
670165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	switch (trf->state) {
671165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	case TRF7970A_ST_IDLE:
672165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	case TRF7970A_ST_IDLE_RX_BLOCKED:
673165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		/* If getting interrupts caused by RF noise, turn off the
674165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		 * receiver to avoid unnecessary interrupts.  It will be
675165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		 * turned back on in trf7970a_in_send_cmd() when the next
676165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		 * command is issued.
677165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		 */
678165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		if (status & TRF7970A_IRQ_STATUS_ERROR) {
679165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer			trf7970a_cmd(trf, TRF7970A_CMD_BLOCK_RX);
680165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer			trf->state = TRF7970A_ST_IDLE_RX_BLOCKED;
681165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		}
682165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
683165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		trf7970a_cmd(trf, TRF7970A_CMD_FIFO_RESET);
684165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		break;
685165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	case TRF7970A_ST_WAIT_FOR_TX_FIFO:
686165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		if (status & TRF7970A_IRQ_STATUS_TX) {
687165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer			trf->ignore_timeout =
688165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer				!cancel_delayed_work(&trf->timeout_work);
689165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer			trf7970a_fill_fifo(trf);
690165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		} else {
691165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer			trf7970a_send_err_upstream(trf, -EIO);
692165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		}
693165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		break;
694165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	case TRF7970A_ST_WAIT_FOR_RX_DATA:
695165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	case TRF7970A_ST_WAIT_FOR_RX_DATA_CONT:
696165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		if (status & TRF7970A_IRQ_STATUS_SRX) {
697165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer			trf->ignore_timeout =
698165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer				!cancel_delayed_work(&trf->timeout_work);
699165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer			trf7970a_drain_fifo(trf, status);
7004dd836e46c3ddcb2020646c867be589658440be0Mark A. Greer		} else if (status == TRF7970A_IRQ_STATUS_TX) {
7014dd836e46c3ddcb2020646c867be589658440be0Mark A. Greer			trf7970a_cmd(trf, TRF7970A_CMD_FIFO_RESET);
7024dd836e46c3ddcb2020646c867be589658440be0Mark A. Greer		} else {
703165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer			trf7970a_send_err_upstream(trf, -EIO);
704165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		}
705165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		break;
7069d9304b32154be5908a3abbb46215297b9ce0a4cMark A. Greer	case TRF7970A_ST_WAIT_TO_ISSUE_EOF:
7079d9304b32154be5908a3abbb46215297b9ce0a4cMark A. Greer		if (status != TRF7970A_IRQ_STATUS_TX)
7089d9304b32154be5908a3abbb46215297b9ce0a4cMark A. Greer			trf7970a_send_err_upstream(trf, -EIO);
7099d9304b32154be5908a3abbb46215297b9ce0a4cMark A. Greer		break;
710165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	default:
711165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		dev_err(trf->dev, "%s - Driver in invalid state: %d\n",
712165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer				__func__, trf->state);
713165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	}
714165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
715165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	mutex_unlock(&trf->lock);
716165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	return IRQ_HANDLED;
717165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer}
718165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
7199d9304b32154be5908a3abbb46215297b9ce0a4cMark A. Greerstatic void trf7970a_issue_eof(struct trf7970a *trf)
7209d9304b32154be5908a3abbb46215297b9ce0a4cMark A. Greer{
7219d9304b32154be5908a3abbb46215297b9ce0a4cMark A. Greer	int ret;
7229d9304b32154be5908a3abbb46215297b9ce0a4cMark A. Greer
7239d9304b32154be5908a3abbb46215297b9ce0a4cMark A. Greer	dev_dbg(trf->dev, "Issuing EOF\n");
7249d9304b32154be5908a3abbb46215297b9ce0a4cMark A. Greer
7259d9304b32154be5908a3abbb46215297b9ce0a4cMark A. Greer	ret = trf7970a_cmd(trf, TRF7970A_CMD_FIFO_RESET);
7269d9304b32154be5908a3abbb46215297b9ce0a4cMark A. Greer	if (ret)
7279d9304b32154be5908a3abbb46215297b9ce0a4cMark A. Greer		trf7970a_send_err_upstream(trf, ret);
7289d9304b32154be5908a3abbb46215297b9ce0a4cMark A. Greer
7299d9304b32154be5908a3abbb46215297b9ce0a4cMark A. Greer	ret = trf7970a_cmd(trf, TRF7970A_CMD_EOF);
7309d9304b32154be5908a3abbb46215297b9ce0a4cMark A. Greer	if (ret)
7319d9304b32154be5908a3abbb46215297b9ce0a4cMark A. Greer		trf7970a_send_err_upstream(trf, ret);
7329d9304b32154be5908a3abbb46215297b9ce0a4cMark A. Greer
7339d9304b32154be5908a3abbb46215297b9ce0a4cMark A. Greer	trf->state = TRF7970A_ST_WAIT_FOR_RX_DATA;
7349d9304b32154be5908a3abbb46215297b9ce0a4cMark A. Greer
7359d9304b32154be5908a3abbb46215297b9ce0a4cMark A. Greer	dev_dbg(trf->dev, "Setting timeout for %d ms, state: %d\n",
7369d9304b32154be5908a3abbb46215297b9ce0a4cMark A. Greer			trf->timeout, trf->state);
7379d9304b32154be5908a3abbb46215297b9ce0a4cMark A. Greer
7389d9304b32154be5908a3abbb46215297b9ce0a4cMark A. Greer	schedule_delayed_work(&trf->timeout_work,
7399d9304b32154be5908a3abbb46215297b9ce0a4cMark A. Greer			msecs_to_jiffies(trf->timeout));
7409d9304b32154be5908a3abbb46215297b9ce0a4cMark A. Greer}
7419d9304b32154be5908a3abbb46215297b9ce0a4cMark A. Greer
742165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greerstatic void trf7970a_timeout_work_handler(struct work_struct *work)
743165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer{
744165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	struct trf7970a *trf = container_of(work, struct trf7970a,
745165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer			timeout_work.work);
746165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
747165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	dev_dbg(trf->dev, "Timeout - state: %d, ignore_timeout: %d\n",
748165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer			trf->state, trf->ignore_timeout);
749165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
750165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	mutex_lock(&trf->lock);
751165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
752165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	if (trf->ignore_timeout)
753165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		trf->ignore_timeout = false;
754165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	else if (trf->state == TRF7970A_ST_WAIT_FOR_RX_DATA_CONT)
755165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		trf7970a_send_upstream(trf); /* No more rx data so send up */
7569d9304b32154be5908a3abbb46215297b9ce0a4cMark A. Greer	else if (trf->state == TRF7970A_ST_WAIT_TO_ISSUE_EOF)
7579d9304b32154be5908a3abbb46215297b9ce0a4cMark A. Greer		trf7970a_issue_eof(trf);
758165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	else
759165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		trf7970a_send_err_upstream(trf, -ETIMEDOUT);
760165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
761165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	mutex_unlock(&trf->lock);
762165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer}
763165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
764165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greerstatic int trf7970a_init(struct trf7970a *trf)
765165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer{
766165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	int ret;
767165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
768165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	dev_dbg(trf->dev, "Initializing device - state: %d\n", trf->state);
769165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
770165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	ret = trf7970a_cmd(trf, TRF7970A_CMD_SOFT_INIT);
771165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	if (ret)
772165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		goto err_out;
773165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
774165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	ret = trf7970a_cmd(trf, TRF7970A_CMD_IDLE);
775165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	if (ret)
776165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		goto err_out;
777165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
778b887eb09d3cbda145d9fff4b9a56c384edd07ed7Mark A. Greer	/* Must clear NFC Target Detection Level reg due to erratum */
779b887eb09d3cbda145d9fff4b9a56c384edd07ed7Mark A. Greer	ret = trf7970a_write(trf, TRF7970A_NFC_TARGET_LEVEL, 0);
780b887eb09d3cbda145d9fff4b9a56c384edd07ed7Mark A. Greer	if (ret)
781b887eb09d3cbda145d9fff4b9a56c384edd07ed7Mark A. Greer		goto err_out;
782b887eb09d3cbda145d9fff4b9a56c384edd07ed7Mark A. Greer
783165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	ret = trf7970a_write(trf, TRF7970A_ADJUTABLE_FIFO_IRQ_LEVELS,
784165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer			TRF7970A_ADJUTABLE_FIFO_IRQ_LEVELS_WLH_96 |
785165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer			TRF7970A_ADJUTABLE_FIFO_IRQ_LEVELS_WLL_32);
786165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	if (ret)
787165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		goto err_out;
788165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
789165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	ret = trf7970a_write(trf, TRF7970A_SPECIAL_FCN_REG1, 0);
790165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	if (ret)
791165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		goto err_out;
792165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
793165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	trf->special_fcn_reg1 = 0;
794165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
79549d19cc794e73c3383283a5366ff31572d71a795Mark A. Greer	trf->iso_ctrl = 0xff;
796165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	return 0;
797165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
798165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greererr_out:
799165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	dev_dbg(trf->dev, "Couldn't init device: %d\n", ret);
800165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	return ret;
801165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer}
802165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
803165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greerstatic void trf7970a_switch_rf_off(struct trf7970a *trf)
804165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer{
805165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	dev_dbg(trf->dev, "Switching rf off\n");
806165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
807a1d2dc5b407ae18b59b7a129c93c8eb5ad7b1c80Mark A. Greer	trf->chip_status_ctrl &= ~TRF7970A_CHIP_STATUS_RF_ON;
808a1d2dc5b407ae18b59b7a129c93c8eb5ad7b1c80Mark A. Greer
809a1d2dc5b407ae18b59b7a129c93c8eb5ad7b1c80Mark A. Greer	trf7970a_write(trf, TRF7970A_CHIP_STATUS_CTRL, trf->chip_status_ctrl);
810a1d2dc5b407ae18b59b7a129c93c8eb5ad7b1c80Mark A. Greer
811165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	trf->aborting = false;
812165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	trf->state = TRF7970A_ST_OFF;
813e6403b7c756f9d694332870ba0c2be7a4aa0b8c0Mark A. Greer
814e6403b7c756f9d694332870ba0c2be7a4aa0b8c0Mark A. Greer	pm_runtime_mark_last_busy(trf->dev);
815e6403b7c756f9d694332870ba0c2be7a4aa0b8c0Mark A. Greer	pm_runtime_put_autosuspend(trf->dev);
816165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer}
817165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
81818422e686ef043b9abe004326ac9ffa1e38b81ecMark A. Greerstatic void trf7970a_switch_rf_on(struct trf7970a *trf)
819165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer{
820165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	dev_dbg(trf->dev, "Switching rf on\n");
821165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
822e6403b7c756f9d694332870ba0c2be7a4aa0b8c0Mark A. Greer	pm_runtime_get_sync(trf->dev);
823165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
824e6403b7c756f9d694332870ba0c2be7a4aa0b8c0Mark A. Greer	trf->state = TRF7970A_ST_IDLE;
825165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer}
826165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
827165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greerstatic int trf7970a_switch_rf(struct nfc_digital_dev *ddev, bool on)
828165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer{
829165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	struct trf7970a *trf = nfc_digital_get_drvdata(ddev);
830165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
831165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	dev_dbg(trf->dev, "Switching RF - state: %d, on: %d\n", trf->state, on);
832165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
833165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	mutex_lock(&trf->lock);
834165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
835165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	if (on) {
836165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		switch (trf->state) {
837165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		case TRF7970A_ST_OFF:
83818422e686ef043b9abe004326ac9ffa1e38b81ecMark A. Greer			trf7970a_switch_rf_on(trf);
839165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer			break;
840165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		case TRF7970A_ST_IDLE:
841165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		case TRF7970A_ST_IDLE_RX_BLOCKED:
842165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer			break;
843165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		default:
844165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer			dev_err(trf->dev, "%s - Invalid request: %d %d\n",
845165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer					__func__, trf->state, on);
846165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer			trf7970a_switch_rf_off(trf);
847165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		}
848165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	} else {
849165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		switch (trf->state) {
850165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		case TRF7970A_ST_OFF:
851165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer			break;
852165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		default:
853165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer			dev_err(trf->dev, "%s - Invalid request: %d %d\n",
854165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer					__func__, trf->state, on);
855165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer			/* FALLTHROUGH */
856165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		case TRF7970A_ST_IDLE:
857165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		case TRF7970A_ST_IDLE_RX_BLOCKED:
858165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer			trf7970a_switch_rf_off(trf);
859165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		}
860165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	}
861165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
862165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	mutex_unlock(&trf->lock);
86318422e686ef043b9abe004326ac9ffa1e38b81ecMark A. Greer	return 0;
864165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer}
865165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
866165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greerstatic int trf7970a_config_rf_tech(struct trf7970a *trf, int tech)
867165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer{
868165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	int ret = 0;
869165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
870165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	dev_dbg(trf->dev, "rf technology: %d\n", tech);
871165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
872165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	switch (tech) {
873165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	case NFC_DIGITAL_RF_TECH_106A:
87449d19cc794e73c3383283a5366ff31572d71a795Mark A. Greer		trf->iso_ctrl_tech = TRF7970A_ISO_CTRL_14443A_106;
87512e9ade309db51e7ea26be3b4fd5bc6057ddc175Mark A. Greer		trf->modulator_sys_clk_ctrl = TRF7970A_MODULATOR_DEPTH_OOK;
876165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		break;
877742b1f9fa292a1b8f5c8368464e114c9b71c2a81Mark A. Greer	case NFC_DIGITAL_RF_TECH_106B:
878742b1f9fa292a1b8f5c8368464e114c9b71c2a81Mark A. Greer		trf->iso_ctrl_tech = TRF7970A_ISO_CTRL_14443B_106;
879742b1f9fa292a1b8f5c8368464e114c9b71c2a81Mark A. Greer		trf->modulator_sys_clk_ctrl = TRF7970A_MODULATOR_DEPTH_ASK10;
880742b1f9fa292a1b8f5c8368464e114c9b71c2a81Mark A. Greer		break;
8816857bb96271cd40ffb38825d43897d716310e3dbMark A. Greer	case NFC_DIGITAL_RF_TECH_212F:
8826857bb96271cd40ffb38825d43897d716310e3dbMark A. Greer		trf->iso_ctrl_tech = TRF7970A_ISO_CTRL_FELICA_212;
8836857bb96271cd40ffb38825d43897d716310e3dbMark A. Greer		trf->modulator_sys_clk_ctrl = TRF7970A_MODULATOR_DEPTH_ASK10;
8846857bb96271cd40ffb38825d43897d716310e3dbMark A. Greer		break;
8856857bb96271cd40ffb38825d43897d716310e3dbMark A. Greer	case NFC_DIGITAL_RF_TECH_424F:
8866857bb96271cd40ffb38825d43897d716310e3dbMark A. Greer		trf->iso_ctrl_tech = TRF7970A_ISO_CTRL_FELICA_424;
8876857bb96271cd40ffb38825d43897d716310e3dbMark A. Greer		trf->modulator_sys_clk_ctrl = TRF7970A_MODULATOR_DEPTH_ASK10;
8886857bb96271cd40ffb38825d43897d716310e3dbMark A. Greer		break;
8899d9304b32154be5908a3abbb46215297b9ce0a4cMark A. Greer	case NFC_DIGITAL_RF_TECH_ISO15693:
89049d19cc794e73c3383283a5366ff31572d71a795Mark A. Greer		trf->iso_ctrl_tech = TRF7970A_ISO_CTRL_15693_SGL_1OF4_2648;
89112e9ade309db51e7ea26be3b4fd5bc6057ddc175Mark A. Greer		trf->modulator_sys_clk_ctrl = TRF7970A_MODULATOR_DEPTH_OOK;
8929d9304b32154be5908a3abbb46215297b9ce0a4cMark A. Greer		break;
893165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	default:
894165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		dev_dbg(trf->dev, "Unsupported rf technology: %d\n", tech);
895165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		return -EINVAL;
896165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	}
897165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
898165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	trf->technology = tech;
899165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
900165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	return ret;
901165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer}
902165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
903165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greerstatic int trf7970a_config_framing(struct trf7970a *trf, int framing)
904165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer{
90549d19cc794e73c3383283a5366ff31572d71a795Mark A. Greer	u8 iso_ctrl = trf->iso_ctrl_tech;
90649d19cc794e73c3383283a5366ff31572d71a795Mark A. Greer	int ret;
90749d19cc794e73c3383283a5366ff31572d71a795Mark A. Greer
908165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	dev_dbg(trf->dev, "framing: %d\n", framing);
909165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
910165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	switch (framing) {
911165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	case NFC_DIGITAL_FRAMING_NFCA_SHORT:
912165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	case NFC_DIGITAL_FRAMING_NFCA_STANDARD:
913165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		trf->tx_cmd = TRF7970A_CMD_TRANSMIT_NO_CRC;
91449d19cc794e73c3383283a5366ff31572d71a795Mark A. Greer		iso_ctrl |= TRF7970A_ISO_CTRL_RX_CRC_N;
915165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		break;
916165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	case NFC_DIGITAL_FRAMING_NFCA_STANDARD_WITH_CRC_A:
9178006289108fa9635d16a65d9db16da06d7dce201Mark A. Greer	case NFC_DIGITAL_FRAMING_NFCA_T4T:
918742b1f9fa292a1b8f5c8368464e114c9b71c2a81Mark A. Greer	case NFC_DIGITAL_FRAMING_NFCB:
919742b1f9fa292a1b8f5c8368464e114c9b71c2a81Mark A. Greer	case NFC_DIGITAL_FRAMING_NFCB_T4T:
9206857bb96271cd40ffb38825d43897d716310e3dbMark A. Greer	case NFC_DIGITAL_FRAMING_NFCF:
9216857bb96271cd40ffb38825d43897d716310e3dbMark A. Greer	case NFC_DIGITAL_FRAMING_NFCF_T3T:
9229d9304b32154be5908a3abbb46215297b9ce0a4cMark A. Greer	case NFC_DIGITAL_FRAMING_ISO15693_INVENTORY:
9239d9304b32154be5908a3abbb46215297b9ce0a4cMark A. Greer	case NFC_DIGITAL_FRAMING_ISO15693_T5T:
924165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		trf->tx_cmd = TRF7970A_CMD_TRANSMIT;
92549d19cc794e73c3383283a5366ff31572d71a795Mark A. Greer		iso_ctrl &= ~TRF7970A_ISO_CTRL_RX_CRC_N;
926165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		break;
927165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	case NFC_DIGITAL_FRAMING_NFCA_T2T:
928165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		trf->tx_cmd = TRF7970A_CMD_TRANSMIT;
92949d19cc794e73c3383283a5366ff31572d71a795Mark A. Greer		iso_ctrl |= TRF7970A_ISO_CTRL_RX_CRC_N;
930165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		break;
931165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	default:
932165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		dev_dbg(trf->dev, "Unsupported Framing: %d\n", framing);
933165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		return -EINVAL;
934165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	}
935165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
936165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	trf->framing = framing;
937165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
93849d19cc794e73c3383283a5366ff31572d71a795Mark A. Greer	if (iso_ctrl != trf->iso_ctrl) {
93949d19cc794e73c3383283a5366ff31572d71a795Mark A. Greer		ret = trf7970a_write(trf, TRF7970A_ISO_CTRL, iso_ctrl);
94049d19cc794e73c3383283a5366ff31572d71a795Mark A. Greer		if (ret)
94149d19cc794e73c3383283a5366ff31572d71a795Mark A. Greer			return ret;
94249d19cc794e73c3383283a5366ff31572d71a795Mark A. Greer
94349d19cc794e73c3383283a5366ff31572d71a795Mark A. Greer		trf->iso_ctrl = iso_ctrl;
944a0822a7e3b7333689b1c8cb92782e299791c2795Mark A. Greer
945a0822a7e3b7333689b1c8cb92782e299791c2795Mark A. Greer		ret = trf7970a_write(trf, TRF7970A_MODULATOR_SYS_CLK_CTRL,
94612e9ade309db51e7ea26be3b4fd5bc6057ddc175Mark A. Greer				trf->modulator_sys_clk_ctrl);
947a0822a7e3b7333689b1c8cb92782e299791c2795Mark A. Greer		if (ret)
948a0822a7e3b7333689b1c8cb92782e299791c2795Mark A. Greer			return ret;
94949d19cc794e73c3383283a5366ff31572d71a795Mark A. Greer	}
95049d19cc794e73c3383283a5366ff31572d71a795Mark A. Greer
951a1d2dc5b407ae18b59b7a129c93c8eb5ad7b1c80Mark A. Greer	if (!(trf->chip_status_ctrl & TRF7970A_CHIP_STATUS_RF_ON)) {
952a1d2dc5b407ae18b59b7a129c93c8eb5ad7b1c80Mark A. Greer		ret = trf7970a_write(trf, TRF7970A_CHIP_STATUS_CTRL,
953a1d2dc5b407ae18b59b7a129c93c8eb5ad7b1c80Mark A. Greer				trf->chip_status_ctrl |
954a1d2dc5b407ae18b59b7a129c93c8eb5ad7b1c80Mark A. Greer					TRF7970A_CHIP_STATUS_RF_ON);
955a1d2dc5b407ae18b59b7a129c93c8eb5ad7b1c80Mark A. Greer		if (ret)
956a1d2dc5b407ae18b59b7a129c93c8eb5ad7b1c80Mark A. Greer			return ret;
957a1d2dc5b407ae18b59b7a129c93c8eb5ad7b1c80Mark A. Greer
958a1d2dc5b407ae18b59b7a129c93c8eb5ad7b1c80Mark A. Greer		trf->chip_status_ctrl |= TRF7970A_CHIP_STATUS_RF_ON;
959a1d2dc5b407ae18b59b7a129c93c8eb5ad7b1c80Mark A. Greer
960a1d2dc5b407ae18b59b7a129c93c8eb5ad7b1c80Mark A. Greer		usleep_range(5000, 6000);
961a1d2dc5b407ae18b59b7a129c93c8eb5ad7b1c80Mark A. Greer	}
962a1d2dc5b407ae18b59b7a129c93c8eb5ad7b1c80Mark A. Greer
96349d19cc794e73c3383283a5366ff31572d71a795Mark A. Greer	return 0;
964165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer}
965165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
966165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greerstatic int trf7970a_in_configure_hw(struct nfc_digital_dev *ddev, int type,
967165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		int param)
968165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer{
969165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	struct trf7970a *trf = nfc_digital_get_drvdata(ddev);
97018422e686ef043b9abe004326ac9ffa1e38b81ecMark A. Greer	int ret;
971165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
972165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	dev_dbg(trf->dev, "Configure hw - type: %d, param: %d\n", type, param);
973165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
974165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	mutex_lock(&trf->lock);
975165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
97618422e686ef043b9abe004326ac9ffa1e38b81ecMark A. Greer	if (trf->state == TRF7970A_ST_OFF)
97718422e686ef043b9abe004326ac9ffa1e38b81ecMark A. Greer		trf7970a_switch_rf_on(trf);
978165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
979165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	switch (type) {
980165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	case NFC_DIGITAL_CONFIG_RF_TECH:
981165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		ret = trf7970a_config_rf_tech(trf, param);
982165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		break;
983165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	case NFC_DIGITAL_CONFIG_FRAMING:
984165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		ret = trf7970a_config_framing(trf, param);
985165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		break;
986165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	default:
987165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		dev_dbg(trf->dev, "Unknown type: %d\n", type);
988165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		ret = -EINVAL;
989165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	}
990165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
991165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	mutex_unlock(&trf->lock);
992165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	return ret;
993165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer}
994165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
9959d9304b32154be5908a3abbb46215297b9ce0a4cMark A. Greerstatic int trf7970a_is_iso15693_write_or_lock(u8 cmd)
9969d9304b32154be5908a3abbb46215297b9ce0a4cMark A. Greer{
9979d9304b32154be5908a3abbb46215297b9ce0a4cMark A. Greer	switch (cmd) {
9989d9304b32154be5908a3abbb46215297b9ce0a4cMark A. Greer	case ISO15693_CMD_WRITE_SINGLE_BLOCK:
9999d9304b32154be5908a3abbb46215297b9ce0a4cMark A. Greer	case ISO15693_CMD_LOCK_BLOCK:
10009d9304b32154be5908a3abbb46215297b9ce0a4cMark A. Greer	case ISO15693_CMD_WRITE_MULTIPLE_BLOCK:
10019d9304b32154be5908a3abbb46215297b9ce0a4cMark A. Greer	case ISO15693_CMD_WRITE_AFI:
10029d9304b32154be5908a3abbb46215297b9ce0a4cMark A. Greer	case ISO15693_CMD_LOCK_AFI:
10039d9304b32154be5908a3abbb46215297b9ce0a4cMark A. Greer	case ISO15693_CMD_WRITE_DSFID:
10049d9304b32154be5908a3abbb46215297b9ce0a4cMark A. Greer	case ISO15693_CMD_LOCK_DSFID:
10059d9304b32154be5908a3abbb46215297b9ce0a4cMark A. Greer		return 1;
10069d9304b32154be5908a3abbb46215297b9ce0a4cMark A. Greer		break;
10079d9304b32154be5908a3abbb46215297b9ce0a4cMark A. Greer	default:
10089d9304b32154be5908a3abbb46215297b9ce0a4cMark A. Greer		return 0;
10099d9304b32154be5908a3abbb46215297b9ce0a4cMark A. Greer	}
10109d9304b32154be5908a3abbb46215297b9ce0a4cMark A. Greer}
10119d9304b32154be5908a3abbb46215297b9ce0a4cMark A. Greer
1012165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greerstatic int trf7970a_per_cmd_config(struct trf7970a *trf, struct sk_buff *skb)
1013165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer{
1014165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	u8 *req = skb->data;
10159d9304b32154be5908a3abbb46215297b9ce0a4cMark A. Greer	u8 special_fcn_reg1, iso_ctrl;
1016165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	int ret;
1017165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
10189d9304b32154be5908a3abbb46215297b9ce0a4cMark A. Greer	trf->issue_eof = false;
10199d9304b32154be5908a3abbb46215297b9ce0a4cMark A. Greer
1020165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	/* When issuing Type 2 read command, make sure the '4_bit_RX' bit in
1021165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	 * special functions register 1 is cleared; otherwise, its a write or
1022165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	 * sector select command and '4_bit_RX' must be set.
10239d9304b32154be5908a3abbb46215297b9ce0a4cMark A. Greer	 *
10249d9304b32154be5908a3abbb46215297b9ce0a4cMark A. Greer	 * When issuing an ISO 15693 command, inspect the flags byte to see
10259d9304b32154be5908a3abbb46215297b9ce0a4cMark A. Greer	 * what speed to use.  Also, remember if the OPTION flag is set on
10269d9304b32154be5908a3abbb46215297b9ce0a4cMark A. Greer	 * a Type 5 write or lock command so the driver will know that it
10279d9304b32154be5908a3abbb46215297b9ce0a4cMark A. Greer	 * has to send an EOF in order to get a response.
1028165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	 */
1029165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	if ((trf->technology == NFC_DIGITAL_RF_TECH_106A) &&
1030165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer			(trf->framing == NFC_DIGITAL_FRAMING_NFCA_T2T)) {
1031165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		if (req[0] == NFC_T2T_CMD_READ)
1032165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer			special_fcn_reg1 = 0;
1033165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		else
1034165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer			special_fcn_reg1 = TRF7970A_SPECIAL_FCN_REG1_4_BIT_RX;
1035165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
1036165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		if (special_fcn_reg1 != trf->special_fcn_reg1) {
1037165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer			ret = trf7970a_write(trf, TRF7970A_SPECIAL_FCN_REG1,
1038165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer					special_fcn_reg1);
1039165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer			if (ret)
1040165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer				return ret;
1041165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
1042165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer			trf->special_fcn_reg1 = special_fcn_reg1;
1043165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		}
10449d9304b32154be5908a3abbb46215297b9ce0a4cMark A. Greer	} else if (trf->technology == NFC_DIGITAL_RF_TECH_ISO15693) {
10459d9304b32154be5908a3abbb46215297b9ce0a4cMark A. Greer		iso_ctrl = trf->iso_ctrl & ~TRF7970A_ISO_CTRL_RFID_SPEED_MASK;
10469d9304b32154be5908a3abbb46215297b9ce0a4cMark A. Greer
10479d9304b32154be5908a3abbb46215297b9ce0a4cMark A. Greer		switch (req[0] & ISO15693_REQ_FLAG_SPEED_MASK) {
10489d9304b32154be5908a3abbb46215297b9ce0a4cMark A. Greer		case 0x00:
10499d9304b32154be5908a3abbb46215297b9ce0a4cMark A. Greer			iso_ctrl |= TRF7970A_ISO_CTRL_15693_SGL_1OF4_662;
10509d9304b32154be5908a3abbb46215297b9ce0a4cMark A. Greer			break;
10519d9304b32154be5908a3abbb46215297b9ce0a4cMark A. Greer		case ISO15693_REQ_FLAG_SUB_CARRIER:
10529d9304b32154be5908a3abbb46215297b9ce0a4cMark A. Greer			iso_ctrl |= TRF7970A_ISO_CTRL_15693_DBL_1OF4_667a;
10539d9304b32154be5908a3abbb46215297b9ce0a4cMark A. Greer			break;
10549d9304b32154be5908a3abbb46215297b9ce0a4cMark A. Greer		case ISO15693_REQ_FLAG_DATA_RATE:
10559d9304b32154be5908a3abbb46215297b9ce0a4cMark A. Greer			iso_ctrl |= TRF7970A_ISO_CTRL_15693_SGL_1OF4_2648;
10569d9304b32154be5908a3abbb46215297b9ce0a4cMark A. Greer			break;
10579d9304b32154be5908a3abbb46215297b9ce0a4cMark A. Greer		case (ISO15693_REQ_FLAG_SUB_CARRIER |
10589d9304b32154be5908a3abbb46215297b9ce0a4cMark A. Greer				ISO15693_REQ_FLAG_DATA_RATE):
10599d9304b32154be5908a3abbb46215297b9ce0a4cMark A. Greer			iso_ctrl |= TRF7970A_ISO_CTRL_15693_DBL_1OF4_2669;
10609d9304b32154be5908a3abbb46215297b9ce0a4cMark A. Greer			break;
10619d9304b32154be5908a3abbb46215297b9ce0a4cMark A. Greer		}
10629d9304b32154be5908a3abbb46215297b9ce0a4cMark A. Greer
10639d9304b32154be5908a3abbb46215297b9ce0a4cMark A. Greer		if (iso_ctrl != trf->iso_ctrl) {
10649d9304b32154be5908a3abbb46215297b9ce0a4cMark A. Greer			ret = trf7970a_write(trf, TRF7970A_ISO_CTRL, iso_ctrl);
10659d9304b32154be5908a3abbb46215297b9ce0a4cMark A. Greer			if (ret)
10669d9304b32154be5908a3abbb46215297b9ce0a4cMark A. Greer				return ret;
10679d9304b32154be5908a3abbb46215297b9ce0a4cMark A. Greer
10689d9304b32154be5908a3abbb46215297b9ce0a4cMark A. Greer			trf->iso_ctrl = iso_ctrl;
10699d9304b32154be5908a3abbb46215297b9ce0a4cMark A. Greer		}
10709d9304b32154be5908a3abbb46215297b9ce0a4cMark A. Greer
10719d9304b32154be5908a3abbb46215297b9ce0a4cMark A. Greer		if ((trf->framing == NFC_DIGITAL_FRAMING_ISO15693_T5T) &&
10729d9304b32154be5908a3abbb46215297b9ce0a4cMark A. Greer				trf7970a_is_iso15693_write_or_lock(req[1]) &&
10739d9304b32154be5908a3abbb46215297b9ce0a4cMark A. Greer				(req[0] & ISO15693_REQ_FLAG_OPTION))
10749d9304b32154be5908a3abbb46215297b9ce0a4cMark A. Greer			trf->issue_eof = true;
1075165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	}
1076165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
1077165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	return 0;
1078165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer}
1079165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
1080165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greerstatic int trf7970a_in_send_cmd(struct nfc_digital_dev *ddev,
1081165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		struct sk_buff *skb, u16 timeout,
1082165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		nfc_digital_cmd_complete_t cb, void *arg)
1083165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer{
1084165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	struct trf7970a *trf = nfc_digital_get_drvdata(ddev);
1085165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	char *prefix;
1086165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	unsigned int len;
1087165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	int ret;
1088165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
1089165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	dev_dbg(trf->dev, "New request - state: %d, timeout: %d ms, len: %d\n",
1090165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer			trf->state, timeout, skb->len);
1091165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
1092165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	if (skb->len > TRF7970A_TX_MAX)
1093165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		return -EINVAL;
1094165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
1095165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	mutex_lock(&trf->lock);
1096165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
1097165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	if ((trf->state != TRF7970A_ST_IDLE) &&
1098165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer			(trf->state != TRF7970A_ST_IDLE_RX_BLOCKED)) {
1099165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		dev_err(trf->dev, "%s - Bogus state: %d\n", __func__,
1100165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer				trf->state);
1101165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		ret = -EIO;
1102165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		goto out_err;
1103165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	}
1104165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
1105165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	if (trf->aborting) {
1106165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		dev_dbg(trf->dev, "Abort process complete\n");
1107165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		trf->aborting = false;
1108165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		ret = -ECANCELED;
1109165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		goto out_err;
1110165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	}
1111165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
1112165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	trf->rx_skb = nfc_alloc_recv_skb(TRF7970A_RX_SKB_ALLOC_SIZE,
1113165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer			GFP_KERNEL);
1114165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	if (!trf->rx_skb) {
1115165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		dev_dbg(trf->dev, "Can't alloc rx_skb\n");
1116165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		ret = -ENOMEM;
1117165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		goto out_err;
1118165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	}
1119165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
1120165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	if (trf->state == TRF7970A_ST_IDLE_RX_BLOCKED) {
1121165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		ret = trf7970a_cmd(trf, TRF7970A_CMD_ENABLE_RX);
1122165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		if (ret)
1123165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer			goto out_err;
1124165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
1125165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		trf->state = TRF7970A_ST_IDLE;
1126165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	}
1127165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
1128165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	ret = trf7970a_per_cmd_config(trf, skb);
1129165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	if (ret)
1130165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		goto out_err;
1131165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
1132165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	trf->ddev = ddev;
1133165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	trf->tx_skb = skb;
1134165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	trf->cb = cb;
1135165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	trf->cb_arg = arg;
1136165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	trf->timeout = timeout;
1137165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	trf->ignore_timeout = false;
1138165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
1139165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	len = skb->len;
1140165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	prefix = skb_push(skb, TRF7970A_TX_SKB_HEADROOM);
1141165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
1142165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	/* TX data must be prefixed with a FIFO reset cmd, a cmd that depends
1143165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	 * on what the current framing is, the address of the TX length byte 1
1144165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	 * register (0x1d), and the 2 byte length of the data to be transmitted.
1145165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	 */
1146165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	prefix[0] = TRF7970A_CMD_BIT_CTRL |
1147165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer			TRF7970A_CMD_BIT_OPCODE(TRF7970A_CMD_FIFO_RESET);
1148165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	prefix[1] = TRF7970A_CMD_BIT_CTRL |
1149165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer			TRF7970A_CMD_BIT_OPCODE(trf->tx_cmd);
1150165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	prefix[2] = TRF7970A_CMD_BIT_CONTINUOUS | TRF7970A_TX_LENGTH_BYTE1;
1151165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
1152165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	if (trf->framing == NFC_DIGITAL_FRAMING_NFCA_SHORT) {
1153165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		prefix[3] = 0x00;
1154165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		prefix[4] = 0x0f; /* 7 bits */
1155165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	} else {
1156165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		prefix[3] = (len & 0xf00) >> 4;
1157165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		prefix[3] |= ((len & 0xf0) >> 4);
1158165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		prefix[4] = ((len & 0x0f) << 4);
1159165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	}
1160165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
1161165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	len = min_t(int, skb->len, TRF7970A_FIFO_SIZE);
1162165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
1163165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	usleep_range(1000, 2000);
1164165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
1165165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	ret = trf7970a_transmit(trf, skb, len);
1166165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	if (ret) {
1167165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		kfree_skb(trf->rx_skb);
1168165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		trf->rx_skb = NULL;
1169165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	}
1170165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
1171165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greerout_err:
1172165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	mutex_unlock(&trf->lock);
1173165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	return ret;
1174165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer}
1175165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
1176165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greerstatic int trf7970a_tg_configure_hw(struct nfc_digital_dev *ddev,
1177165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		int type, int param)
1178165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer{
1179165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	struct trf7970a *trf = nfc_digital_get_drvdata(ddev);
1180165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
1181165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	dev_dbg(trf->dev, "Unsupported interface\n");
1182165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
1183165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	return -EINVAL;
1184165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer}
1185165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
1186165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greerstatic int trf7970a_tg_send_cmd(struct nfc_digital_dev *ddev,
1187165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		struct sk_buff *skb, u16 timeout,
1188165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		nfc_digital_cmd_complete_t cb, void *arg)
1189165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer{
1190165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	struct trf7970a *trf = nfc_digital_get_drvdata(ddev);
1191165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
1192165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	dev_dbg(trf->dev, "Unsupported interface\n");
1193165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
1194165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	return -EINVAL;
1195165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer}
1196165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
1197165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greerstatic int trf7970a_tg_listen(struct nfc_digital_dev *ddev,
1198165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		u16 timeout, nfc_digital_cmd_complete_t cb, void *arg)
1199165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer{
1200165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	struct trf7970a *trf = nfc_digital_get_drvdata(ddev);
1201165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
1202165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	dev_dbg(trf->dev, "Unsupported interface\n");
1203165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
1204165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	return -EINVAL;
1205165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer}
1206165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
1207165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greerstatic void trf7970a_abort_cmd(struct nfc_digital_dev *ddev)
1208165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer{
1209165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	struct trf7970a *trf = nfc_digital_get_drvdata(ddev);
1210165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
1211165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	dev_dbg(trf->dev, "Abort process initiated\n");
1212165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
1213165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	mutex_lock(&trf->lock);
12145876bc75e2d3174cd1cd944ee33edc77cd1173caMark A. Greer
12155876bc75e2d3174cd1cd944ee33edc77cd1173caMark A. Greer	switch (trf->state) {
12165876bc75e2d3174cd1cd944ee33edc77cd1173caMark A. Greer	case TRF7970A_ST_WAIT_FOR_TX_FIFO:
12175876bc75e2d3174cd1cd944ee33edc77cd1173caMark A. Greer	case TRF7970A_ST_WAIT_FOR_RX_DATA:
12185876bc75e2d3174cd1cd944ee33edc77cd1173caMark A. Greer	case TRF7970A_ST_WAIT_FOR_RX_DATA_CONT:
12195876bc75e2d3174cd1cd944ee33edc77cd1173caMark A. Greer	case TRF7970A_ST_WAIT_TO_ISSUE_EOF:
12205876bc75e2d3174cd1cd944ee33edc77cd1173caMark A. Greer		trf->aborting = true;
12215876bc75e2d3174cd1cd944ee33edc77cd1173caMark A. Greer		break;
12225876bc75e2d3174cd1cd944ee33edc77cd1173caMark A. Greer	default:
12235876bc75e2d3174cd1cd944ee33edc77cd1173caMark A. Greer		break;
12245876bc75e2d3174cd1cd944ee33edc77cd1173caMark A. Greer	}
12255876bc75e2d3174cd1cd944ee33edc77cd1173caMark A. Greer
1226165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	mutex_unlock(&trf->lock);
1227165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer}
1228165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
1229165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greerstatic struct nfc_digital_ops trf7970a_nfc_ops = {
1230165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	.in_configure_hw	= trf7970a_in_configure_hw,
1231165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	.in_send_cmd		= trf7970a_in_send_cmd,
1232165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	.tg_configure_hw	= trf7970a_tg_configure_hw,
1233165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	.tg_send_cmd		= trf7970a_tg_send_cmd,
1234165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	.tg_listen		= trf7970a_tg_listen,
1235165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	.switch_rf		= trf7970a_switch_rf,
1236165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	.abort_cmd		= trf7970a_abort_cmd,
1237165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer};
1238165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
1239fd0c8280cf47104e87dc10828ded541b4e84dedaMark A. Greerstatic int trf7970a_get_autosuspend_delay(struct device_node *np)
1240fd0c8280cf47104e87dc10828ded541b4e84dedaMark A. Greer{
1241fd0c8280cf47104e87dc10828ded541b4e84dedaMark A. Greer	int autosuspend_delay, ret;
1242fd0c8280cf47104e87dc10828ded541b4e84dedaMark A. Greer
1243fd0c8280cf47104e87dc10828ded541b4e84dedaMark A. Greer	ret = of_property_read_u32(np, "autosuspend-delay", &autosuspend_delay);
1244fd0c8280cf47104e87dc10828ded541b4e84dedaMark A. Greer	if (ret)
1245fd0c8280cf47104e87dc10828ded541b4e84dedaMark A. Greer		autosuspend_delay = TRF7970A_AUTOSUSPEND_DELAY;
1246fd0c8280cf47104e87dc10828ded541b4e84dedaMark A. Greer
1247fd0c8280cf47104e87dc10828ded541b4e84dedaMark A. Greer	return autosuspend_delay;
1248fd0c8280cf47104e87dc10828ded541b4e84dedaMark A. Greer}
1249fd0c8280cf47104e87dc10828ded541b4e84dedaMark A. Greer
12503bd14233aa0733fbc6c3f75ec928f1a393522644Mark A. Greerstatic int trf7970a_get_vin_voltage_override(struct device_node *np,
12513bd14233aa0733fbc6c3f75ec928f1a393522644Mark A. Greer		u32 *vin_uvolts)
12523bd14233aa0733fbc6c3f75ec928f1a393522644Mark A. Greer{
12533bd14233aa0733fbc6c3f75ec928f1a393522644Mark A. Greer	return of_property_read_u32(np, "vin-voltage-override", vin_uvolts);
12543bd14233aa0733fbc6c3f75ec928f1a393522644Mark A. Greer}
12553bd14233aa0733fbc6c3f75ec928f1a393522644Mark A. Greer
1256165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greerstatic int trf7970a_probe(struct spi_device *spi)
1257165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer{
1258165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	struct device_node *np = spi->dev.of_node;
1259165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	struct trf7970a *trf;
1260fd0c8280cf47104e87dc10828ded541b4e84dedaMark A. Greer	int uvolts, autosuspend_delay, ret;
1261165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
1262165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	if (!np) {
1263165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		dev_err(&spi->dev, "No Device Tree entry\n");
1264165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		return -EINVAL;
1265165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	}
1266165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
1267165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	trf = devm_kzalloc(&spi->dev, sizeof(*trf), GFP_KERNEL);
1268165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	if (!trf)
1269165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		return -ENOMEM;
1270165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
1271165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	trf->state = TRF7970A_ST_OFF;
1272165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	trf->dev = &spi->dev;
1273165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	trf->spi = spi;
1274165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
1275165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	spi->mode = SPI_MODE_1;
1276165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	spi->bits_per_word = 8;
1277165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
127824707296c762d1828c4a51aa1872dc275dc3fcccMark A. Greer	ret = spi_setup(spi);
127924707296c762d1828c4a51aa1872dc275dc3fcccMark A. Greer	if (ret < 0) {
128024707296c762d1828c4a51aa1872dc275dc3fcccMark A. Greer		dev_err(trf->dev, "Can't set up SPI Communication\n");
128124707296c762d1828c4a51aa1872dc275dc3fcccMark A. Greer		return ret;
128224707296c762d1828c4a51aa1872dc275dc3fcccMark A. Greer	}
128324707296c762d1828c4a51aa1872dc275dc3fcccMark A. Greer
1284772079eb77587e0242752fa67685a8132d899f79Mark A. Greer	if (of_property_read_bool(np, "irq-status-read-quirk"))
1285772079eb77587e0242752fa67685a8132d899f79Mark A. Greer		trf->quirks |= TRF7970A_QUIRK_IRQ_STATUS_READ;
1286772079eb77587e0242752fa67685a8132d899f79Mark A. Greer
1287165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	/* There are two enable pins - both must be present */
1288165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	trf->en_gpio = of_get_named_gpio(np, "ti,enable-gpios", 0);
1289165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	if (!gpio_is_valid(trf->en_gpio)) {
1290165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		dev_err(trf->dev, "No EN GPIO property\n");
1291165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		return trf->en_gpio;
1292165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	}
1293165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
1294165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	ret = devm_gpio_request_one(trf->dev, trf->en_gpio,
1295f23b73526b82ca2ef333362e704a51d817c1ffc1Mark A. Greer			GPIOF_DIR_OUT | GPIOF_INIT_LOW, "trf7970a EN");
1296165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	if (ret) {
1297165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		dev_err(trf->dev, "Can't request EN GPIO: %d\n", ret);
1298165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		return ret;
1299165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	}
1300165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
1301165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	trf->en2_gpio = of_get_named_gpio(np, "ti,enable-gpios", 1);
1302165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	if (!gpio_is_valid(trf->en2_gpio)) {
1303165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		dev_err(trf->dev, "No EN2 GPIO property\n");
1304165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		return trf->en2_gpio;
1305165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	}
1306165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
1307165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	ret = devm_gpio_request_one(trf->dev, trf->en2_gpio,
1308f23b73526b82ca2ef333362e704a51d817c1ffc1Mark A. Greer			GPIOF_DIR_OUT | GPIOF_INIT_LOW, "trf7970a EN2");
1309165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	if (ret) {
1310165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		dev_err(trf->dev, "Can't request EN2 GPIO: %d\n", ret);
1311165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		return ret;
1312165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	}
1313165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
131495064bd95a822659f4a606b485aba5009d70fc88Mark A. Greer	if (of_property_read_bool(np, "en2-rf-quirk"))
131595064bd95a822659f4a606b485aba5009d70fc88Mark A. Greer		trf->quirks |= TRF7970A_QUIRK_EN2_MUST_STAY_LOW;
131695064bd95a822659f4a606b485aba5009d70fc88Mark A. Greer
1317165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	ret = devm_request_threaded_irq(trf->dev, spi->irq, NULL,
1318165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer			trf7970a_irq, IRQF_TRIGGER_RISING | IRQF_ONESHOT,
1319165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer			"trf7970a", trf);
1320165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	if (ret) {
1321165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		dev_err(trf->dev, "Can't request IRQ#%d: %d\n", spi->irq, ret);
1322165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		return ret;
1323165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	}
1324165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
1325165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	mutex_init(&trf->lock);
1326165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	INIT_DELAYED_WORK(&trf->timeout_work, trf7970a_timeout_work_handler);
1327165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
1328165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	trf->regulator = devm_regulator_get(&spi->dev, "vin");
1329165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	if (IS_ERR(trf->regulator)) {
1330165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		ret = PTR_ERR(trf->regulator);
1331165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		dev_err(trf->dev, "Can't get VIN regulator: %d\n", ret);
1332165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		goto err_destroy_lock;
1333165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	}
1334165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
1335165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	ret = regulator_enable(trf->regulator);
1336165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	if (ret) {
1337165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		dev_err(trf->dev, "Can't enable VIN: %d\n", ret);
1338165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		goto err_destroy_lock;
1339165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	}
1340165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
13413bd14233aa0733fbc6c3f75ec928f1a393522644Mark A. Greer	ret = trf7970a_get_vin_voltage_override(np, &uvolts);
13423bd14233aa0733fbc6c3f75ec928f1a393522644Mark A. Greer	if (ret)
13433bd14233aa0733fbc6c3f75ec928f1a393522644Mark A. Greer		uvolts = regulator_get_voltage(trf->regulator);
1344ebcc5a0d08e6a680558ed74f5dd724427ff5a29bMark A. Greer
1345ebcc5a0d08e6a680558ed74f5dd724427ff5a29bMark A. Greer	if (uvolts > 4000000)
1346ebcc5a0d08e6a680558ed74f5dd724427ff5a29bMark A. Greer		trf->chip_status_ctrl = TRF7970A_CHIP_STATUS_VRS5_3;
1347ebcc5a0d08e6a680558ed74f5dd724427ff5a29bMark A. Greer
1348165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	trf->ddev = nfc_digital_allocate_device(&trf7970a_nfc_ops,
1349165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer			TRF7970A_SUPPORTED_PROTOCOLS,
1350165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer			NFC_DIGITAL_DRV_CAPS_IN_CRC, TRF7970A_TX_SKB_HEADROOM,
1351165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer			0);
1352165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	if (!trf->ddev) {
1353165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		dev_err(trf->dev, "Can't allocate NFC digital device\n");
1354165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		ret = -ENOMEM;
1355165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		goto err_disable_regulator;
1356165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	}
1357165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
1358165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	nfc_digital_set_parent_dev(trf->ddev, trf->dev);
1359165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	nfc_digital_set_drvdata(trf->ddev, trf);
1360165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	spi_set_drvdata(spi, trf);
1361165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
1362fd0c8280cf47104e87dc10828ded541b4e84dedaMark A. Greer	autosuspend_delay = trf7970a_get_autosuspend_delay(np);
1363fd0c8280cf47104e87dc10828ded541b4e84dedaMark A. Greer
1364fd0c8280cf47104e87dc10828ded541b4e84dedaMark A. Greer	pm_runtime_set_autosuspend_delay(trf->dev, autosuspend_delay);
1365e6403b7c756f9d694332870ba0c2be7a4aa0b8c0Mark A. Greer	pm_runtime_use_autosuspend(trf->dev);
1366e6403b7c756f9d694332870ba0c2be7a4aa0b8c0Mark A. Greer	pm_runtime_enable(trf->dev);
1367e6403b7c756f9d694332870ba0c2be7a4aa0b8c0Mark A. Greer
1368165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	ret = nfc_digital_register_device(trf->ddev);
1369165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	if (ret) {
1370165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		dev_err(trf->dev, "Can't register NFC digital device: %d\n",
1371165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer				ret);
1372165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		goto err_free_ddev;
1373165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	}
1374165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
1375165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	return 0;
1376165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
1377165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greererr_free_ddev:
1378e6403b7c756f9d694332870ba0c2be7a4aa0b8c0Mark A. Greer	pm_runtime_disable(trf->dev);
1379165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	nfc_digital_free_device(trf->ddev);
1380165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greererr_disable_regulator:
1381165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	regulator_disable(trf->regulator);
1382165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greererr_destroy_lock:
1383165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	mutex_destroy(&trf->lock);
1384165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	return ret;
1385165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer}
1386165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
1387165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greerstatic int trf7970a_remove(struct spi_device *spi)
1388165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer{
1389165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	struct trf7970a *trf = spi_get_drvdata(spi);
1390165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
1391165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	mutex_lock(&trf->lock);
1392165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
1393165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	switch (trf->state) {
1394165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	case TRF7970A_ST_WAIT_FOR_TX_FIFO:
1395165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	case TRF7970A_ST_WAIT_FOR_RX_DATA:
1396165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	case TRF7970A_ST_WAIT_FOR_RX_DATA_CONT:
13979d9304b32154be5908a3abbb46215297b9ce0a4cMark A. Greer	case TRF7970A_ST_WAIT_TO_ISSUE_EOF:
1398165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		trf7970a_send_err_upstream(trf, -ECANCELED);
1399e6403b7c756f9d694332870ba0c2be7a4aa0b8c0Mark A. Greer		/* FALLTHROUGH */
1400e6403b7c756f9d694332870ba0c2be7a4aa0b8c0Mark A. Greer	case TRF7970A_ST_IDLE:
1401e6403b7c756f9d694332870ba0c2be7a4aa0b8c0Mark A. Greer	case TRF7970A_ST_IDLE_RX_BLOCKED:
1402e6403b7c756f9d694332870ba0c2be7a4aa0b8c0Mark A. Greer		pm_runtime_put_sync(trf->dev);
1403165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		break;
1404165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	default:
1405165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		break;
1406165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	}
1407165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
1408165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	mutex_unlock(&trf->lock);
1409165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
1410e6403b7c756f9d694332870ba0c2be7a4aa0b8c0Mark A. Greer	pm_runtime_disable(trf->dev);
1411e6403b7c756f9d694332870ba0c2be7a4aa0b8c0Mark A. Greer
1412165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	nfc_digital_unregister_device(trf->ddev);
1413165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	nfc_digital_free_device(trf->ddev);
1414165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
1415165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	regulator_disable(trf->regulator);
1416165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
1417165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	mutex_destroy(&trf->lock);
1418165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
1419165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	return 0;
1420165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer}
1421165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
1422e6403b7c756f9d694332870ba0c2be7a4aa0b8c0Mark A. Greer#ifdef CONFIG_PM_RUNTIME
1423e6403b7c756f9d694332870ba0c2be7a4aa0b8c0Mark A. Greerstatic int trf7970a_pm_runtime_suspend(struct device *dev)
1424e6403b7c756f9d694332870ba0c2be7a4aa0b8c0Mark A. Greer{
1425e6403b7c756f9d694332870ba0c2be7a4aa0b8c0Mark A. Greer	struct spi_device *spi = container_of(dev, struct spi_device, dev);
1426e6403b7c756f9d694332870ba0c2be7a4aa0b8c0Mark A. Greer	struct trf7970a *trf = spi_get_drvdata(spi);
1427e6403b7c756f9d694332870ba0c2be7a4aa0b8c0Mark A. Greer	int ret;
1428e6403b7c756f9d694332870ba0c2be7a4aa0b8c0Mark A. Greer
1429e6403b7c756f9d694332870ba0c2be7a4aa0b8c0Mark A. Greer	dev_dbg(dev, "Runtime suspend\n");
1430e6403b7c756f9d694332870ba0c2be7a4aa0b8c0Mark A. Greer
1431e6403b7c756f9d694332870ba0c2be7a4aa0b8c0Mark A. Greer	if (trf->state != TRF7970A_ST_OFF) {
1432e6403b7c756f9d694332870ba0c2be7a4aa0b8c0Mark A. Greer		dev_dbg(dev, "Can't suspend - not in OFF state (%d)\n",
1433e6403b7c756f9d694332870ba0c2be7a4aa0b8c0Mark A. Greer				trf->state);
1434e6403b7c756f9d694332870ba0c2be7a4aa0b8c0Mark A. Greer		return -EBUSY;
1435e6403b7c756f9d694332870ba0c2be7a4aa0b8c0Mark A. Greer	}
1436e6403b7c756f9d694332870ba0c2be7a4aa0b8c0Mark A. Greer
1437e6403b7c756f9d694332870ba0c2be7a4aa0b8c0Mark A. Greer	gpio_set_value(trf->en_gpio, 0);
1438e6403b7c756f9d694332870ba0c2be7a4aa0b8c0Mark A. Greer	gpio_set_value(trf->en2_gpio, 0);
1439e6403b7c756f9d694332870ba0c2be7a4aa0b8c0Mark A. Greer
1440e6403b7c756f9d694332870ba0c2be7a4aa0b8c0Mark A. Greer	ret = regulator_disable(trf->regulator);
1441e6403b7c756f9d694332870ba0c2be7a4aa0b8c0Mark A. Greer	if (ret)
1442e6403b7c756f9d694332870ba0c2be7a4aa0b8c0Mark A. Greer		dev_err(dev, "%s - Can't disable VIN: %d\n", __func__, ret);
1443e6403b7c756f9d694332870ba0c2be7a4aa0b8c0Mark A. Greer
1444e6403b7c756f9d694332870ba0c2be7a4aa0b8c0Mark A. Greer	return ret;
1445e6403b7c756f9d694332870ba0c2be7a4aa0b8c0Mark A. Greer}
1446e6403b7c756f9d694332870ba0c2be7a4aa0b8c0Mark A. Greer
1447e6403b7c756f9d694332870ba0c2be7a4aa0b8c0Mark A. Greerstatic int trf7970a_pm_runtime_resume(struct device *dev)
1448e6403b7c756f9d694332870ba0c2be7a4aa0b8c0Mark A. Greer{
1449e6403b7c756f9d694332870ba0c2be7a4aa0b8c0Mark A. Greer	struct spi_device *spi = container_of(dev, struct spi_device, dev);
1450e6403b7c756f9d694332870ba0c2be7a4aa0b8c0Mark A. Greer	struct trf7970a *trf = spi_get_drvdata(spi);
1451e6403b7c756f9d694332870ba0c2be7a4aa0b8c0Mark A. Greer	int ret;
1452e6403b7c756f9d694332870ba0c2be7a4aa0b8c0Mark A. Greer
1453e6403b7c756f9d694332870ba0c2be7a4aa0b8c0Mark A. Greer	dev_dbg(dev, "Runtime resume\n");
1454e6403b7c756f9d694332870ba0c2be7a4aa0b8c0Mark A. Greer
1455e6403b7c756f9d694332870ba0c2be7a4aa0b8c0Mark A. Greer	ret = regulator_enable(trf->regulator);
1456e6403b7c756f9d694332870ba0c2be7a4aa0b8c0Mark A. Greer	if (ret) {
1457e6403b7c756f9d694332870ba0c2be7a4aa0b8c0Mark A. Greer		dev_err(dev, "%s - Can't enable VIN: %d\n", __func__, ret);
1458e6403b7c756f9d694332870ba0c2be7a4aa0b8c0Mark A. Greer		return ret;
1459e6403b7c756f9d694332870ba0c2be7a4aa0b8c0Mark A. Greer	}
1460e6403b7c756f9d694332870ba0c2be7a4aa0b8c0Mark A. Greer
1461e6403b7c756f9d694332870ba0c2be7a4aa0b8c0Mark A. Greer	usleep_range(5000, 6000);
1462e6403b7c756f9d694332870ba0c2be7a4aa0b8c0Mark A. Greer
146395064bd95a822659f4a606b485aba5009d70fc88Mark A. Greer	if (!(trf->quirks & TRF7970A_QUIRK_EN2_MUST_STAY_LOW)) {
146495064bd95a822659f4a606b485aba5009d70fc88Mark A. Greer		gpio_set_value(trf->en2_gpio, 1);
146595064bd95a822659f4a606b485aba5009d70fc88Mark A. Greer		usleep_range(1000, 2000);
146695064bd95a822659f4a606b485aba5009d70fc88Mark A. Greer	}
146795064bd95a822659f4a606b485aba5009d70fc88Mark A. Greer
1468e6403b7c756f9d694332870ba0c2be7a4aa0b8c0Mark A. Greer	gpio_set_value(trf->en_gpio, 1);
1469e6403b7c756f9d694332870ba0c2be7a4aa0b8c0Mark A. Greer
1470e6403b7c756f9d694332870ba0c2be7a4aa0b8c0Mark A. Greer	usleep_range(20000, 21000);
1471e6403b7c756f9d694332870ba0c2be7a4aa0b8c0Mark A. Greer
1472e6403b7c756f9d694332870ba0c2be7a4aa0b8c0Mark A. Greer	ret = trf7970a_init(trf);
1473e6403b7c756f9d694332870ba0c2be7a4aa0b8c0Mark A. Greer	if (ret) {
1474e6403b7c756f9d694332870ba0c2be7a4aa0b8c0Mark A. Greer		dev_err(dev, "%s - Can't initialize: %d\n", __func__, ret);
1475e6403b7c756f9d694332870ba0c2be7a4aa0b8c0Mark A. Greer		return ret;
1476e6403b7c756f9d694332870ba0c2be7a4aa0b8c0Mark A. Greer	}
1477e6403b7c756f9d694332870ba0c2be7a4aa0b8c0Mark A. Greer
1478e6403b7c756f9d694332870ba0c2be7a4aa0b8c0Mark A. Greer	pm_runtime_mark_last_busy(dev);
1479e6403b7c756f9d694332870ba0c2be7a4aa0b8c0Mark A. Greer
1480e6403b7c756f9d694332870ba0c2be7a4aa0b8c0Mark A. Greer	return 0;
1481e6403b7c756f9d694332870ba0c2be7a4aa0b8c0Mark A. Greer}
1482e6403b7c756f9d694332870ba0c2be7a4aa0b8c0Mark A. Greer#endif
1483e6403b7c756f9d694332870ba0c2be7a4aa0b8c0Mark A. Greer
1484e6403b7c756f9d694332870ba0c2be7a4aa0b8c0Mark A. Greerstatic const struct dev_pm_ops trf7970a_pm_ops = {
1485e6403b7c756f9d694332870ba0c2be7a4aa0b8c0Mark A. Greer	SET_RUNTIME_PM_OPS(trf7970a_pm_runtime_suspend,
1486e6403b7c756f9d694332870ba0c2be7a4aa0b8c0Mark A. Greer			trf7970a_pm_runtime_resume, NULL)
1487e6403b7c756f9d694332870ba0c2be7a4aa0b8c0Mark A. Greer};
1488e6403b7c756f9d694332870ba0c2be7a4aa0b8c0Mark A. Greer
1489165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greerstatic const struct spi_device_id trf7970a_id_table[] = {
1490772079eb77587e0242752fa67685a8132d899f79Mark A. Greer	{ "trf7970a", 0 },
1491165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	{ }
1492165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer};
1493165063f1dac43e48ceb907490fff0a8413b9a32dMark A. GreerMODULE_DEVICE_TABLE(spi, trf7970a_id_table);
1494165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
1495165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greerstatic struct spi_driver trf7970a_spi_driver = {
1496165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	.probe		= trf7970a_probe,
1497165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	.remove		= trf7970a_remove,
1498165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	.id_table	= trf7970a_id_table,
1499165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	.driver		= {
1500165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		.name	= "trf7970a",
1501165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		.owner	= THIS_MODULE,
1502e6403b7c756f9d694332870ba0c2be7a4aa0b8c0Mark A. Greer		.pm	= &trf7970a_pm_ops,
1503165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	},
1504165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer};
1505165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
1506165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greermodule_spi_driver(trf7970a_spi_driver);
1507165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
1508165063f1dac43e48ceb907490fff0a8413b9a32dMark A. GreerMODULE_AUTHOR("Mark A. Greer <mgreer@animalcreek.com>");
1509165063f1dac43e48ceb907490fff0a8413b9a32dMark A. GreerMODULE_LICENSE("GPL v2");
1510165063f1dac43e48ceb907490fff0a8413b9a32dMark A. GreerMODULE_DESCRIPTION("TI trf7970a RFID/NFC Transceiver Driver");
1511