trf7970a.c revision 4e64eff837fb682dfb2a1188fb036d75ec57375c
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
1281568bfef18a9150d83b0f91aa254cef7ebead4cdMark A. Greer#define TRF7970A_FIFO_SIZE			127
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
1374e64eff837fb682dfb2a1188fb036d75ec57375cMark A. Greer/* Guard times for various RF technologies (in us) */
1384e64eff837fb682dfb2a1188fb036d75ec57375cMark A. Greer#define TRF7970A_GUARD_TIME_NFCA		5000
1394e64eff837fb682dfb2a1188fb036d75ec57375cMark A. Greer#define TRF7970A_GUARD_TIME_NFCB		5000
1404e64eff837fb682dfb2a1188fb036d75ec57375cMark A. Greer#define TRF7970A_GUARD_TIME_NFCF		20000
1414e64eff837fb682dfb2a1188fb036d75ec57375cMark A. Greer#define TRF7970A_GUARD_TIME_15693		1000
1424e64eff837fb682dfb2a1188fb036d75ec57375cMark A. Greer
143165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer/* Quirks */
144165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer/* Erratum: When reading IRQ Status register on trf7970a, we must issue a
145165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer * read continuous command for IRQ Status and Collision Position registers.
146165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer */
147772079eb77587e0242752fa67685a8132d899f79Mark A. Greer#define TRF7970A_QUIRK_IRQ_STATUS_READ		BIT(0)
14895064bd95a822659f4a606b485aba5009d70fc88Mark A. Greer#define TRF7970A_QUIRK_EN2_MUST_STAY_LOW	BIT(1)
149165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
150165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer/* Direct commands */
151165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer#define TRF7970A_CMD_IDLE			0x00
152165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer#define TRF7970A_CMD_SOFT_INIT			0x03
153165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer#define TRF7970A_CMD_RF_COLLISION		0x04
154165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer#define TRF7970A_CMD_RF_COLLISION_RESPONSE_N	0x05
155165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer#define TRF7970A_CMD_RF_COLLISION_RESPONSE_0	0x06
156165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer#define TRF7970A_CMD_FIFO_RESET			0x0f
157165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer#define TRF7970A_CMD_TRANSMIT_NO_CRC		0x10
158165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer#define TRF7970A_CMD_TRANSMIT			0x11
159165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer#define TRF7970A_CMD_DELAY_TRANSMIT_NO_CRC	0x12
160165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer#define TRF7970A_CMD_DELAY_TRANSMIT		0x13
161165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer#define TRF7970A_CMD_EOF			0x14
162165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer#define TRF7970A_CMD_CLOSE_SLOT			0x15
163165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer#define TRF7970A_CMD_BLOCK_RX			0x16
164165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer#define TRF7970A_CMD_ENABLE_RX			0x17
165165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer#define TRF7970A_CMD_TEST_EXT_RF		0x18
166165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer#define TRF7970A_CMD_TEST_INT_RF		0x19
167165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer#define TRF7970A_CMD_RX_GAIN_ADJUST		0x1a
168165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
169165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer/* Bits determining whether its a direct command or register R/W,
170165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer * whether to use a continuous SPI transaction or not, and the actual
171165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer * direct cmd opcode or regster address.
172165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer */
173165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer#define TRF7970A_CMD_BIT_CTRL			BIT(7)
174165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer#define TRF7970A_CMD_BIT_RW			BIT(6)
175165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer#define TRF7970A_CMD_BIT_CONTINUOUS		BIT(5)
176165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer#define TRF7970A_CMD_BIT_OPCODE(opcode)		((opcode) & 0x1f)
177165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
178165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer/* Registers addresses */
179165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer#define TRF7970A_CHIP_STATUS_CTRL		0x00
180165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer#define TRF7970A_ISO_CTRL			0x01
181165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer#define TRF7970A_ISO14443B_TX_OPTIONS		0x02
182165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer#define TRF7970A_ISO14443A_HIGH_BITRATE_OPTIONS	0x03
183165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer#define TRF7970A_TX_TIMER_SETTING_H_BYTE	0x04
184165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer#define TRF7970A_TX_TIMER_SETTING_L_BYTE	0x05
185165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer#define TRF7970A_TX_PULSE_LENGTH_CTRL		0x06
186165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer#define TRF7970A_RX_NO_RESPONSE_WAIT		0x07
187165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer#define TRF7970A_RX_WAIT_TIME			0x08
188165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer#define TRF7970A_MODULATOR_SYS_CLK_CTRL		0x09
189165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer#define TRF7970A_RX_SPECIAL_SETTINGS		0x0a
190165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer#define TRF7970A_REG_IO_CTRL			0x0b
191165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer#define TRF7970A_IRQ_STATUS			0x0c
192165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer#define TRF7970A_COLLISION_IRQ_MASK		0x0d
193165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer#define TRF7970A_COLLISION_POSITION		0x0e
194165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer#define TRF7970A_RSSI_OSC_STATUS		0x0f
195165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer#define TRF7970A_SPECIAL_FCN_REG1		0x10
196165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer#define TRF7970A_SPECIAL_FCN_REG2		0x11
197165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer#define TRF7970A_RAM1				0x12
198165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer#define TRF7970A_RAM2				0x13
199165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer#define TRF7970A_ADJUTABLE_FIFO_IRQ_LEVELS	0x14
200165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer#define TRF7970A_NFC_LOW_FIELD_LEVEL		0x16
201165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer#define TRF7970A_NFCID1				0x17
202165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer#define TRF7970A_NFC_TARGET_LEVEL		0x18
203165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer#define TRF79070A_NFC_TARGET_PROTOCOL		0x19
204165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer#define TRF7970A_TEST_REGISTER1			0x1a
205165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer#define TRF7970A_TEST_REGISTER2			0x1b
206165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer#define TRF7970A_FIFO_STATUS			0x1c
207165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer#define TRF7970A_TX_LENGTH_BYTE1		0x1d
208165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer#define TRF7970A_TX_LENGTH_BYTE2		0x1e
209165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer#define TRF7970A_FIFO_IO_REGISTER		0x1f
210165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
211165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer/* Chip Status Control Register Bits */
212165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer#define TRF7970A_CHIP_STATUS_VRS5_3		BIT(0)
213165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer#define TRF7970A_CHIP_STATUS_REC_ON		BIT(1)
214165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer#define TRF7970A_CHIP_STATUS_AGC_ON		BIT(2)
215165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer#define TRF7970A_CHIP_STATUS_PM_ON		BIT(3)
216165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer#define TRF7970A_CHIP_STATUS_RF_PWR		BIT(4)
217165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer#define TRF7970A_CHIP_STATUS_RF_ON		BIT(5)
218165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer#define TRF7970A_CHIP_STATUS_DIRECT		BIT(6)
219165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer#define TRF7970A_CHIP_STATUS_STBY		BIT(7)
220165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
221165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer/* ISO Control Register Bits */
222165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer#define TRF7970A_ISO_CTRL_15693_SGL_1OF4_662	0x00
223165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer#define TRF7970A_ISO_CTRL_15693_SGL_1OF256_662	0x01
224165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer#define TRF7970A_ISO_CTRL_15693_SGL_1OF4_2648	0x02
225165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer#define TRF7970A_ISO_CTRL_15693_SGL_1OF256_2648	0x03
226165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer#define TRF7970A_ISO_CTRL_15693_DBL_1OF4_667a	0x04
227165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer#define TRF7970A_ISO_CTRL_15693_DBL_1OF256_667	0x05
228165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer#define TRF7970A_ISO_CTRL_15693_DBL_1OF4_2669	0x06
229165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer#define TRF7970A_ISO_CTRL_15693_DBL_1OF256_2669	0x07
230165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer#define TRF7970A_ISO_CTRL_14443A_106		0x08
231165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer#define TRF7970A_ISO_CTRL_14443A_212		0x09
232165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer#define TRF7970A_ISO_CTRL_14443A_424		0x0a
233165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer#define TRF7970A_ISO_CTRL_14443A_848		0x0b
234165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer#define TRF7970A_ISO_CTRL_14443B_106		0x0c
235165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer#define TRF7970A_ISO_CTRL_14443B_212		0x0d
236165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer#define TRF7970A_ISO_CTRL_14443B_424		0x0e
237165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer#define TRF7970A_ISO_CTRL_14443B_848		0x0f
238165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer#define TRF7970A_ISO_CTRL_FELICA_212		0x1a
239165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer#define TRF7970A_ISO_CTRL_FELICA_424		0x1b
240165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer#define TRF7970A_ISO_CTRL_RFID			BIT(5)
241165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer#define TRF7970A_ISO_CTRL_DIR_MODE		BIT(6)
242165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer#define TRF7970A_ISO_CTRL_RX_CRC_N		BIT(7)	/* true == No CRC */
243165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
244165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer#define TRF7970A_ISO_CTRL_RFID_SPEED_MASK	0x1f
245165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
246165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer/* Modulator and SYS_CLK Control Register Bits */
247165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer#define TRF7970A_MODULATOR_DEPTH(n)		((n) & 0x7)
248165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer#define TRF7970A_MODULATOR_DEPTH_ASK10		(TRF7970A_MODULATOR_DEPTH(0))
249165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer#define TRF7970A_MODULATOR_DEPTH_OOK		(TRF7970A_MODULATOR_DEPTH(1))
250165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer#define TRF7970A_MODULATOR_DEPTH_ASK7		(TRF7970A_MODULATOR_DEPTH(2))
251165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer#define TRF7970A_MODULATOR_DEPTH_ASK8_5		(TRF7970A_MODULATOR_DEPTH(3))
252165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer#define TRF7970A_MODULATOR_DEPTH_ASK13		(TRF7970A_MODULATOR_DEPTH(4))
253165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer#define TRF7970A_MODULATOR_DEPTH_ASK16		(TRF7970A_MODULATOR_DEPTH(5))
254165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer#define TRF7970A_MODULATOR_DEPTH_ASK22		(TRF7970A_MODULATOR_DEPTH(6))
255165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer#define TRF7970A_MODULATOR_DEPTH_ASK30		(TRF7970A_MODULATOR_DEPTH(7))
256165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer#define TRF7970A_MODULATOR_EN_ANA		BIT(3)
257165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer#define TRF7970A_MODULATOR_CLK(n)		(((n) & 0x3) << 4)
258165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer#define TRF7970A_MODULATOR_CLK_DISABLED		(TRF7970A_MODULATOR_CLK(0))
259165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer#define TRF7970A_MODULATOR_CLK_3_6		(TRF7970A_MODULATOR_CLK(1))
260165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer#define TRF7970A_MODULATOR_CLK_6_13		(TRF7970A_MODULATOR_CLK(2))
261165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer#define TRF7970A_MODULATOR_CLK_13_27		(TRF7970A_MODULATOR_CLK(3))
262165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer#define TRF7970A_MODULATOR_EN_OOK		BIT(6)
263165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer#define TRF7970A_MODULATOR_27MHZ		BIT(7)
264165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
265165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer/* IRQ Status Register Bits */
266165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer#define TRF7970A_IRQ_STATUS_NORESP		BIT(0) /* ISO15693 only */
267165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer#define TRF7970A_IRQ_STATUS_COL			BIT(1)
268165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer#define TRF7970A_IRQ_STATUS_FRAMING_EOF_ERROR	BIT(2)
269165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer#define TRF7970A_IRQ_STATUS_PARITY_ERROR	BIT(3)
270165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer#define TRF7970A_IRQ_STATUS_CRC_ERROR		BIT(4)
271165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer#define TRF7970A_IRQ_STATUS_FIFO		BIT(5)
272165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer#define TRF7970A_IRQ_STATUS_SRX			BIT(6)
273165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer#define TRF7970A_IRQ_STATUS_TX			BIT(7)
274165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
275165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer#define TRF7970A_IRQ_STATUS_ERROR				\
276165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		(TRF7970A_IRQ_STATUS_COL |			\
277165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		 TRF7970A_IRQ_STATUS_FRAMING_EOF_ERROR |	\
278165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		 TRF7970A_IRQ_STATUS_PARITY_ERROR |		\
279165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		 TRF7970A_IRQ_STATUS_CRC_ERROR)
280165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
281165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer#define TRF7970A_SPECIAL_FCN_REG1_COL_7_6		BIT(0)
282165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer#define TRF7970A_SPECIAL_FCN_REG1_14_ANTICOLL		BIT(1)
283165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer#define TRF7970A_SPECIAL_FCN_REG1_4_BIT_RX		BIT(2)
284165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer#define TRF7970A_SPECIAL_FCN_REG1_SP_DIR_MODE		BIT(3)
285165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer#define TRF7970A_SPECIAL_FCN_REG1_NEXT_SLOT_37US	BIT(4)
286165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer#define TRF7970A_SPECIAL_FCN_REG1_PAR43			BIT(5)
287165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
288165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer#define TRF7970A_ADJUTABLE_FIFO_IRQ_LEVELS_WLH_124	(0x0 << 2)
289165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer#define TRF7970A_ADJUTABLE_FIFO_IRQ_LEVELS_WLH_120	(0x1 << 2)
290165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer#define TRF7970A_ADJUTABLE_FIFO_IRQ_LEVELS_WLH_112	(0x2 << 2)
291165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer#define TRF7970A_ADJUTABLE_FIFO_IRQ_LEVELS_WLH_96	(0x3 << 2)
292165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer#define TRF7970A_ADJUTABLE_FIFO_IRQ_LEVELS_WLL_4	0x0
293165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer#define TRF7970A_ADJUTABLE_FIFO_IRQ_LEVELS_WLL_8	0x1
294165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer#define TRF7970A_ADJUTABLE_FIFO_IRQ_LEVELS_WLL_16	0x2
295165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer#define TRF7970A_ADJUTABLE_FIFO_IRQ_LEVELS_WLL_32	0x3
296165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
297165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer#define TRF7970A_FIFO_STATUS_OVERFLOW		BIT(7)
298165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
299165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer/* NFC (ISO/IEC 14443A) Type 2 Tag commands */
300165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer#define NFC_T2T_CMD_READ			0x30
301165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
3029d9304b32154be5908a3abbb46215297b9ce0a4cMark A. Greer/* ISO 15693 commands codes */
3039d9304b32154be5908a3abbb46215297b9ce0a4cMark A. Greer#define ISO15693_CMD_INVENTORY			0x01
3049d9304b32154be5908a3abbb46215297b9ce0a4cMark A. Greer#define ISO15693_CMD_READ_SINGLE_BLOCK		0x20
3059d9304b32154be5908a3abbb46215297b9ce0a4cMark A. Greer#define ISO15693_CMD_WRITE_SINGLE_BLOCK		0x21
3069d9304b32154be5908a3abbb46215297b9ce0a4cMark A. Greer#define ISO15693_CMD_LOCK_BLOCK			0x22
3079d9304b32154be5908a3abbb46215297b9ce0a4cMark A. Greer#define ISO15693_CMD_READ_MULTIPLE_BLOCK	0x23
3089d9304b32154be5908a3abbb46215297b9ce0a4cMark A. Greer#define ISO15693_CMD_WRITE_MULTIPLE_BLOCK	0x24
3099d9304b32154be5908a3abbb46215297b9ce0a4cMark A. Greer#define ISO15693_CMD_SELECT			0x25
3109d9304b32154be5908a3abbb46215297b9ce0a4cMark A. Greer#define ISO15693_CMD_RESET_TO_READY		0x26
3119d9304b32154be5908a3abbb46215297b9ce0a4cMark A. Greer#define ISO15693_CMD_WRITE_AFI			0x27
3129d9304b32154be5908a3abbb46215297b9ce0a4cMark A. Greer#define ISO15693_CMD_LOCK_AFI			0x28
3139d9304b32154be5908a3abbb46215297b9ce0a4cMark A. Greer#define ISO15693_CMD_WRITE_DSFID		0x29
3149d9304b32154be5908a3abbb46215297b9ce0a4cMark A. Greer#define ISO15693_CMD_LOCK_DSFID			0x2a
3159d9304b32154be5908a3abbb46215297b9ce0a4cMark A. Greer#define ISO15693_CMD_GET_SYSTEM_INFO		0x2b
3169d9304b32154be5908a3abbb46215297b9ce0a4cMark A. Greer#define ISO15693_CMD_GET_MULTIPLE_BLOCK_SECURITY_STATUS	0x2c
3179d9304b32154be5908a3abbb46215297b9ce0a4cMark A. Greer
3189d9304b32154be5908a3abbb46215297b9ce0a4cMark A. Greer/* ISO 15693 request and response flags */
3199d9304b32154be5908a3abbb46215297b9ce0a4cMark A. Greer#define ISO15693_REQ_FLAG_SUB_CARRIER		BIT(0)
3209d9304b32154be5908a3abbb46215297b9ce0a4cMark A. Greer#define ISO15693_REQ_FLAG_DATA_RATE		BIT(1)
3219d9304b32154be5908a3abbb46215297b9ce0a4cMark A. Greer#define ISO15693_REQ_FLAG_INVENTORY		BIT(2)
3229d9304b32154be5908a3abbb46215297b9ce0a4cMark A. Greer#define ISO15693_REQ_FLAG_PROTOCOL_EXT		BIT(3)
3239d9304b32154be5908a3abbb46215297b9ce0a4cMark A. Greer#define ISO15693_REQ_FLAG_SELECT		BIT(4)
3249d9304b32154be5908a3abbb46215297b9ce0a4cMark A. Greer#define ISO15693_REQ_FLAG_AFI			BIT(4)
3259d9304b32154be5908a3abbb46215297b9ce0a4cMark A. Greer#define ISO15693_REQ_FLAG_ADDRESS		BIT(5)
3269d9304b32154be5908a3abbb46215297b9ce0a4cMark A. Greer#define ISO15693_REQ_FLAG_NB_SLOTS		BIT(5)
3279d9304b32154be5908a3abbb46215297b9ce0a4cMark A. Greer#define ISO15693_REQ_FLAG_OPTION		BIT(6)
3289d9304b32154be5908a3abbb46215297b9ce0a4cMark A. Greer
3299d9304b32154be5908a3abbb46215297b9ce0a4cMark A. Greer#define ISO15693_REQ_FLAG_SPEED_MASK \
3309d9304b32154be5908a3abbb46215297b9ce0a4cMark A. Greer		(ISO15693_REQ_FLAG_SUB_CARRIER | ISO15693_REQ_FLAG_DATA_RATE)
3319d9304b32154be5908a3abbb46215297b9ce0a4cMark A. Greer
332165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greerenum trf7970a_state {
333165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	TRF7970A_ST_OFF,
334165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	TRF7970A_ST_IDLE,
335165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	TRF7970A_ST_IDLE_RX_BLOCKED,
336165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	TRF7970A_ST_WAIT_FOR_TX_FIFO,
337165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	TRF7970A_ST_WAIT_FOR_RX_DATA,
338165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	TRF7970A_ST_WAIT_FOR_RX_DATA_CONT,
3399d9304b32154be5908a3abbb46215297b9ce0a4cMark A. Greer	TRF7970A_ST_WAIT_TO_ISSUE_EOF,
340165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	TRF7970A_ST_MAX
341165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer};
342165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
343165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greerstruct trf7970a {
344165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	enum trf7970a_state		state;
345165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	struct device			*dev;
346165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	struct spi_device		*spi;
347165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	struct regulator		*regulator;
348165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	struct nfc_digital_dev		*ddev;
349165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	u32				quirks;
350165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	bool				aborting;
351165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	struct sk_buff			*tx_skb;
352165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	struct sk_buff			*rx_skb;
353165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	nfc_digital_cmd_complete_t	cb;
354165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	void				*cb_arg;
355ebcc5a0d08e6a680558ed74f5dd724427ff5a29bMark A. Greer	u8				chip_status_ctrl;
356165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	u8				iso_ctrl;
35749d19cc794e73c3383283a5366ff31572d71a795Mark A. Greer	u8				iso_ctrl_tech;
35812e9ade309db51e7ea26be3b4fd5bc6057ddc175Mark A. Greer	u8				modulator_sys_clk_ctrl;
359165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	u8				special_fcn_reg1;
3604e64eff837fb682dfb2a1188fb036d75ec57375cMark A. Greer	unsigned int			guard_time;
361165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	int				technology;
362165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	int				framing;
363165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	u8				tx_cmd;
3649d9304b32154be5908a3abbb46215297b9ce0a4cMark A. Greer	bool				issue_eof;
365165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	int				en2_gpio;
366165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	int				en_gpio;
367165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	struct mutex			lock;
368165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	unsigned int			timeout;
369165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	bool				ignore_timeout;
370165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	struct delayed_work		timeout_work;
371165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer};
372165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
373165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
374165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greerstatic int trf7970a_cmd(struct trf7970a *trf, u8 opcode)
375165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer{
376165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	u8 cmd = TRF7970A_CMD_BIT_CTRL | TRF7970A_CMD_BIT_OPCODE(opcode);
377165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	int ret;
378165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
379165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	dev_dbg(trf->dev, "cmd: 0x%x\n", cmd);
380165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
381165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	ret = spi_write(trf->spi, &cmd, 1);
382165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	if (ret)
383165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		dev_err(trf->dev, "%s - cmd: 0x%x, ret: %d\n", __func__, cmd,
384165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer				ret);
385165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	return ret;
386165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer}
387165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
388165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greerstatic int trf7970a_read(struct trf7970a *trf, u8 reg, u8 *val)
389165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer{
390165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	u8 addr = TRF7970A_CMD_BIT_RW | reg;
391165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	int ret;
392165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
393165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	ret = spi_write_then_read(trf->spi, &addr, 1, val, 1);
394165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	if (ret)
395165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		dev_err(trf->dev, "%s - addr: 0x%x, ret: %d\n", __func__, addr,
396165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer				ret);
397165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
398165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	dev_dbg(trf->dev, "read(0x%x): 0x%x\n", addr, *val);
399165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
400165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	return ret;
401165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer}
402165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
4033e7f335689ebfa0a68814dfe9f0588076fb9ad01Mark A. Greerstatic int trf7970a_read_cont(struct trf7970a *trf, u8 reg, u8 *buf, size_t len)
404165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer{
405165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	u8 addr = reg | TRF7970A_CMD_BIT_RW | TRF7970A_CMD_BIT_CONTINUOUS;
4063e7f335689ebfa0a68814dfe9f0588076fb9ad01Mark A. Greer	struct spi_transfer t[2];
4073e7f335689ebfa0a68814dfe9f0588076fb9ad01Mark A. Greer	struct spi_message m;
408165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	int ret;
409165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
410165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	dev_dbg(trf->dev, "read_cont(0x%x, %zd)\n", addr, len);
411165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
4123e7f335689ebfa0a68814dfe9f0588076fb9ad01Mark A. Greer	spi_message_init(&m);
4133e7f335689ebfa0a68814dfe9f0588076fb9ad01Mark A. Greer
4143e7f335689ebfa0a68814dfe9f0588076fb9ad01Mark A. Greer	memset(&t, 0, sizeof(t));
4153e7f335689ebfa0a68814dfe9f0588076fb9ad01Mark A. Greer
4163e7f335689ebfa0a68814dfe9f0588076fb9ad01Mark A. Greer	t[0].tx_buf = &addr;
4173e7f335689ebfa0a68814dfe9f0588076fb9ad01Mark A. Greer	t[0].len = sizeof(addr);
4183e7f335689ebfa0a68814dfe9f0588076fb9ad01Mark A. Greer	spi_message_add_tail(&t[0], &m);
4193e7f335689ebfa0a68814dfe9f0588076fb9ad01Mark A. Greer
4203e7f335689ebfa0a68814dfe9f0588076fb9ad01Mark A. Greer	t[1].rx_buf = buf;
4213e7f335689ebfa0a68814dfe9f0588076fb9ad01Mark A. Greer	t[1].len = len;
4223e7f335689ebfa0a68814dfe9f0588076fb9ad01Mark A. Greer	spi_message_add_tail(&t[1], &m);
4233e7f335689ebfa0a68814dfe9f0588076fb9ad01Mark A. Greer
4243e7f335689ebfa0a68814dfe9f0588076fb9ad01Mark A. Greer	ret = spi_sync(trf->spi, &m);
425165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	if (ret)
426165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		dev_err(trf->dev, "%s - addr: 0x%x, ret: %d\n", __func__, addr,
427165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer				ret);
428165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	return ret;
429165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer}
430165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
431165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greerstatic int trf7970a_write(struct trf7970a *trf, u8 reg, u8 val)
432165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer{
433165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	u8 buf[2] = { reg, val };
434165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	int ret;
435165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
436165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	dev_dbg(trf->dev, "write(0x%x): 0x%x\n", reg, val);
437165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
438165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	ret = spi_write(trf->spi, buf, 2);
439165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	if (ret)
440165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		dev_err(trf->dev, "%s - write: 0x%x 0x%x, ret: %d\n", __func__,
441165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer				buf[0], buf[1], ret);
442165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
443165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	return ret;
444165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer}
445165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
446165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greerstatic int trf7970a_read_irqstatus(struct trf7970a *trf, u8 *status)
447165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer{
448165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	int ret;
449165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	u8 buf[2];
450165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	u8 addr;
451165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
452165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	addr = TRF7970A_IRQ_STATUS | TRF7970A_CMD_BIT_RW;
453165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
454772079eb77587e0242752fa67685a8132d899f79Mark A. Greer	if (trf->quirks & TRF7970A_QUIRK_IRQ_STATUS_READ) {
455165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		addr |= TRF7970A_CMD_BIT_CONTINUOUS;
456165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		ret = spi_write_then_read(trf->spi, &addr, 1, buf, 2);
457165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	} else {
458165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		ret = spi_write_then_read(trf->spi, &addr, 1, buf, 1);
459165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	}
460165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
461165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	if (ret)
462165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		dev_err(trf->dev, "%s - irqstatus: Status read failed: %d\n",
463165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer				__func__, ret);
464165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	else
465165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		*status = buf[0];
466165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
467165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	return ret;
468165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer}
469165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
470165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greerstatic void trf7970a_send_upstream(struct trf7970a *trf)
471165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer{
472165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	u8 rssi;
473165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
474165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	dev_kfree_skb_any(trf->tx_skb);
475165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	trf->tx_skb = NULL;
476165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
477165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	if (trf->rx_skb && !IS_ERR(trf->rx_skb) && !trf->aborting)
478165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		print_hex_dump_debug("trf7970a rx data: ", DUMP_PREFIX_NONE,
479165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer				16, 1, trf->rx_skb->data, trf->rx_skb->len,
480165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer				false);
481165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
482165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	/* According to the manual it is "good form" to reset the fifo and
483165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	 * read the RSSI levels & oscillator status register here.  It doesn't
484165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	 * explain why.
485165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	 */
486165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	trf7970a_cmd(trf, TRF7970A_CMD_FIFO_RESET);
487165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	trf7970a_read(trf, TRF7970A_RSSI_OSC_STATUS, &rssi);
488165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
489165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	trf->state = TRF7970A_ST_IDLE;
490165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
491165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	if (trf->aborting) {
492165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		dev_dbg(trf->dev, "Abort process complete\n");
493165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
494165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		if (!IS_ERR(trf->rx_skb)) {
495165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer			kfree_skb(trf->rx_skb);
496165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer			trf->rx_skb = ERR_PTR(-ECANCELED);
497165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		}
498165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
499165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		trf->aborting = false;
500165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	}
501165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
502165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	trf->cb(trf->ddev, trf->cb_arg, trf->rx_skb);
503165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
504165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	trf->rx_skb = NULL;
505165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer}
506165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
507165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greerstatic void trf7970a_send_err_upstream(struct trf7970a *trf, int errno)
508165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer{
509165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	dev_dbg(trf->dev, "Error - state: %d, errno: %d\n", trf->state, errno);
510165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
511165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	kfree_skb(trf->rx_skb);
512165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	trf->rx_skb = ERR_PTR(errno);
513165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
514165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	trf7970a_send_upstream(trf);
515165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer}
516165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
517165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greerstatic int trf7970a_transmit(struct trf7970a *trf, struct sk_buff *skb,
518165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		unsigned int len)
519165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer{
520165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	unsigned int timeout;
521165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	int ret;
522165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
523165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	print_hex_dump_debug("trf7970a tx data: ", DUMP_PREFIX_NONE,
524165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer			16, 1, skb->data, len, false);
525165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
526165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	ret = spi_write(trf->spi, skb->data, len);
527165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	if (ret) {
528165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		dev_err(trf->dev, "%s - Can't send tx data: %d\n", __func__,
529165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer				ret);
530165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		return ret;
531165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	}
532165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
533165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	skb_pull(skb, len);
534165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
535165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	if (skb->len > 0) {
536165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		trf->state = TRF7970A_ST_WAIT_FOR_TX_FIFO;
537165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		timeout = TRF7970A_WAIT_FOR_FIFO_DRAIN_TIMEOUT;
538165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	} else {
5399d9304b32154be5908a3abbb46215297b9ce0a4cMark A. Greer		if (trf->issue_eof) {
5409d9304b32154be5908a3abbb46215297b9ce0a4cMark A. Greer			trf->state = TRF7970A_ST_WAIT_TO_ISSUE_EOF;
5419d9304b32154be5908a3abbb46215297b9ce0a4cMark A. Greer			timeout = TRF7970A_WAIT_TO_ISSUE_ISO15693_EOF;
5429d9304b32154be5908a3abbb46215297b9ce0a4cMark A. Greer		} else {
5439d9304b32154be5908a3abbb46215297b9ce0a4cMark A. Greer			trf->state = TRF7970A_ST_WAIT_FOR_RX_DATA;
5449d9304b32154be5908a3abbb46215297b9ce0a4cMark A. Greer			timeout = trf->timeout;
5459d9304b32154be5908a3abbb46215297b9ce0a4cMark A. Greer		}
546165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	}
547165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
548165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	dev_dbg(trf->dev, "Setting timeout for %d ms, state: %d\n", timeout,
549165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer			trf->state);
550165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
551165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	schedule_delayed_work(&trf->timeout_work, msecs_to_jiffies(timeout));
552165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
553165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	return 0;
554165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer}
555165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
556165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greerstatic void trf7970a_fill_fifo(struct trf7970a *trf)
557165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer{
558165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	struct sk_buff *skb = trf->tx_skb;
559165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	unsigned int len;
560165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	int ret;
561165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	u8 fifo_bytes;
562165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
563165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	ret = trf7970a_read(trf, TRF7970A_FIFO_STATUS, &fifo_bytes);
564165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	if (ret) {
565165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		trf7970a_send_err_upstream(trf, ret);
566165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		return;
567165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	}
568165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
569165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	dev_dbg(trf->dev, "Filling FIFO - fifo_bytes: 0x%x\n", fifo_bytes);
570165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
5714542e8345af6076c87d036c7bd3f9dfa30768b1eMark A. Greer	fifo_bytes &= ~TRF7970A_FIFO_STATUS_OVERFLOW;
572165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
573165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	/* Calculate how much more data can be written to the fifo */
574165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	len = TRF7970A_FIFO_SIZE - fifo_bytes;
575165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	len = min(skb->len, len);
576165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
577165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	ret = trf7970a_transmit(trf, skb, len);
578165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	if (ret)
579165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		trf7970a_send_err_upstream(trf, ret);
580165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer}
581165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
582165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greerstatic void trf7970a_drain_fifo(struct trf7970a *trf, u8 status)
583165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer{
584165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	struct sk_buff *skb = trf->rx_skb;
585165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	int ret;
586165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	u8 fifo_bytes;
587165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
588165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	if (status & TRF7970A_IRQ_STATUS_ERROR) {
589165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		trf7970a_send_err_upstream(trf, -EIO);
590165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		return;
591165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	}
592165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
593165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	ret = trf7970a_read(trf, TRF7970A_FIFO_STATUS, &fifo_bytes);
594165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	if (ret) {
595165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		trf7970a_send_err_upstream(trf, ret);
596165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		return;
597165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	}
598165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
599165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	dev_dbg(trf->dev, "Draining FIFO - fifo_bytes: 0x%x\n", fifo_bytes);
600165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
6014542e8345af6076c87d036c7bd3f9dfa30768b1eMark A. Greer	fifo_bytes &= ~TRF7970A_FIFO_STATUS_OVERFLOW;
6024542e8345af6076c87d036c7bd3f9dfa30768b1eMark A. Greer
603165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	if (!fifo_bytes)
604165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		goto no_rx_data;
605165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
606165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	if (fifo_bytes > skb_tailroom(skb)) {
607165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		skb = skb_copy_expand(skb, skb_headroom(skb),
608165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer				max_t(int, fifo_bytes,
609165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer					TRF7970A_RX_SKB_ALLOC_SIZE),
610165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer				GFP_KERNEL);
611165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		if (!skb) {
612165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer			trf7970a_send_err_upstream(trf, -ENOMEM);
613165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer			return;
614165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		}
615165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
616165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		kfree_skb(trf->rx_skb);
617165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		trf->rx_skb = skb;
618165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	}
619165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
620165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	ret = trf7970a_read_cont(trf, TRF7970A_FIFO_IO_REGISTER,
621165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer			skb_put(skb, fifo_bytes), fifo_bytes);
622165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	if (ret) {
623165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		trf7970a_send_err_upstream(trf, ret);
624165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		return;
625165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	}
626165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
627165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	/* If received Type 2 ACK/NACK, shift right 4 bits and pass up */
628165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	if ((trf->framing == NFC_DIGITAL_FRAMING_NFCA_T2T) && (skb->len == 1) &&
629165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer			(trf->special_fcn_reg1 ==
630165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer				 TRF7970A_SPECIAL_FCN_REG1_4_BIT_RX)) {
631165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		skb->data[0] >>= 4;
632165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		status = TRF7970A_IRQ_STATUS_SRX;
633165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	} else {
634165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		trf->state = TRF7970A_ST_WAIT_FOR_RX_DATA_CONT;
635165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	}
636165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
637165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greerno_rx_data:
638165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	if (status == TRF7970A_IRQ_STATUS_SRX) { /* Receive complete */
639165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		trf7970a_send_upstream(trf);
640165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		return;
641165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	}
642165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
643165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	dev_dbg(trf->dev, "Setting timeout for %d ms\n",
644165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer			TRF7970A_WAIT_FOR_RX_DATA_TIMEOUT);
645165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
646165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	schedule_delayed_work(&trf->timeout_work,
647165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer			msecs_to_jiffies(TRF7970A_WAIT_FOR_RX_DATA_TIMEOUT));
648165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer}
649165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
650165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greerstatic irqreturn_t trf7970a_irq(int irq, void *dev_id)
651165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer{
652165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	struct trf7970a *trf = dev_id;
653165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	int ret;
654165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	u8 status;
655165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
656165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	mutex_lock(&trf->lock);
657165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
658165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	if (trf->state == TRF7970A_ST_OFF) {
659165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		mutex_unlock(&trf->lock);
660165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		return IRQ_NONE;
661165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	}
662165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
663165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	ret = trf7970a_read_irqstatus(trf, &status);
664165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	if (ret) {
665165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		mutex_unlock(&trf->lock);
666165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		return IRQ_NONE;
667165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	}
668165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
669165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	dev_dbg(trf->dev, "IRQ - state: %d, status: 0x%x\n", trf->state,
670165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer			status);
671165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
672165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	if (!status) {
673165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		mutex_unlock(&trf->lock);
674165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		return IRQ_NONE;
675165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	}
676165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
677165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	switch (trf->state) {
678165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	case TRF7970A_ST_IDLE:
679165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	case TRF7970A_ST_IDLE_RX_BLOCKED:
680165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		/* If getting interrupts caused by RF noise, turn off the
681165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		 * receiver to avoid unnecessary interrupts.  It will be
682165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		 * turned back on in trf7970a_in_send_cmd() when the next
683165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		 * command is issued.
684165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		 */
685165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		if (status & TRF7970A_IRQ_STATUS_ERROR) {
686165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer			trf7970a_cmd(trf, TRF7970A_CMD_BLOCK_RX);
687165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer			trf->state = TRF7970A_ST_IDLE_RX_BLOCKED;
688165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		}
689165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
690165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		trf7970a_cmd(trf, TRF7970A_CMD_FIFO_RESET);
691165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		break;
692165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	case TRF7970A_ST_WAIT_FOR_TX_FIFO:
693165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		if (status & TRF7970A_IRQ_STATUS_TX) {
694165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer			trf->ignore_timeout =
695165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer				!cancel_delayed_work(&trf->timeout_work);
696165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer			trf7970a_fill_fifo(trf);
697165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		} else {
698165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer			trf7970a_send_err_upstream(trf, -EIO);
699165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		}
700165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		break;
701165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	case TRF7970A_ST_WAIT_FOR_RX_DATA:
702165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	case TRF7970A_ST_WAIT_FOR_RX_DATA_CONT:
703165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		if (status & TRF7970A_IRQ_STATUS_SRX) {
704165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer			trf->ignore_timeout =
705165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer				!cancel_delayed_work(&trf->timeout_work);
706165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer			trf7970a_drain_fifo(trf, status);
7074dd836e46c3ddcb2020646c867be589658440be0Mark A. Greer		} else if (status == TRF7970A_IRQ_STATUS_TX) {
7084dd836e46c3ddcb2020646c867be589658440be0Mark A. Greer			trf7970a_cmd(trf, TRF7970A_CMD_FIFO_RESET);
7094dd836e46c3ddcb2020646c867be589658440be0Mark A. Greer		} else {
710165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer			trf7970a_send_err_upstream(trf, -EIO);
711165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		}
712165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		break;
7139d9304b32154be5908a3abbb46215297b9ce0a4cMark A. Greer	case TRF7970A_ST_WAIT_TO_ISSUE_EOF:
7149d9304b32154be5908a3abbb46215297b9ce0a4cMark A. Greer		if (status != TRF7970A_IRQ_STATUS_TX)
7159d9304b32154be5908a3abbb46215297b9ce0a4cMark A. Greer			trf7970a_send_err_upstream(trf, -EIO);
7169d9304b32154be5908a3abbb46215297b9ce0a4cMark A. Greer		break;
717165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	default:
718165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		dev_err(trf->dev, "%s - Driver in invalid state: %d\n",
719165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer				__func__, trf->state);
720165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	}
721165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
722165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	mutex_unlock(&trf->lock);
723165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	return IRQ_HANDLED;
724165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer}
725165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
7269d9304b32154be5908a3abbb46215297b9ce0a4cMark A. Greerstatic void trf7970a_issue_eof(struct trf7970a *trf)
7279d9304b32154be5908a3abbb46215297b9ce0a4cMark A. Greer{
7289d9304b32154be5908a3abbb46215297b9ce0a4cMark A. Greer	int ret;
7299d9304b32154be5908a3abbb46215297b9ce0a4cMark A. Greer
7309d9304b32154be5908a3abbb46215297b9ce0a4cMark A. Greer	dev_dbg(trf->dev, "Issuing EOF\n");
7319d9304b32154be5908a3abbb46215297b9ce0a4cMark A. Greer
7329d9304b32154be5908a3abbb46215297b9ce0a4cMark A. Greer	ret = trf7970a_cmd(trf, TRF7970A_CMD_FIFO_RESET);
7339d9304b32154be5908a3abbb46215297b9ce0a4cMark A. Greer	if (ret)
7349d9304b32154be5908a3abbb46215297b9ce0a4cMark A. Greer		trf7970a_send_err_upstream(trf, ret);
7359d9304b32154be5908a3abbb46215297b9ce0a4cMark A. Greer
7369d9304b32154be5908a3abbb46215297b9ce0a4cMark A. Greer	ret = trf7970a_cmd(trf, TRF7970A_CMD_EOF);
7379d9304b32154be5908a3abbb46215297b9ce0a4cMark A. Greer	if (ret)
7389d9304b32154be5908a3abbb46215297b9ce0a4cMark A. Greer		trf7970a_send_err_upstream(trf, ret);
7399d9304b32154be5908a3abbb46215297b9ce0a4cMark A. Greer
7409d9304b32154be5908a3abbb46215297b9ce0a4cMark A. Greer	trf->state = TRF7970A_ST_WAIT_FOR_RX_DATA;
7419d9304b32154be5908a3abbb46215297b9ce0a4cMark A. Greer
7429d9304b32154be5908a3abbb46215297b9ce0a4cMark A. Greer	dev_dbg(trf->dev, "Setting timeout for %d ms, state: %d\n",
7439d9304b32154be5908a3abbb46215297b9ce0a4cMark A. Greer			trf->timeout, trf->state);
7449d9304b32154be5908a3abbb46215297b9ce0a4cMark A. Greer
7459d9304b32154be5908a3abbb46215297b9ce0a4cMark A. Greer	schedule_delayed_work(&trf->timeout_work,
7469d9304b32154be5908a3abbb46215297b9ce0a4cMark A. Greer			msecs_to_jiffies(trf->timeout));
7479d9304b32154be5908a3abbb46215297b9ce0a4cMark A. Greer}
7489d9304b32154be5908a3abbb46215297b9ce0a4cMark A. Greer
749165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greerstatic void trf7970a_timeout_work_handler(struct work_struct *work)
750165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer{
751165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	struct trf7970a *trf = container_of(work, struct trf7970a,
752165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer			timeout_work.work);
753165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
754165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	dev_dbg(trf->dev, "Timeout - state: %d, ignore_timeout: %d\n",
755165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer			trf->state, trf->ignore_timeout);
756165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
757165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	mutex_lock(&trf->lock);
758165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
759165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	if (trf->ignore_timeout)
760165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		trf->ignore_timeout = false;
761165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	else if (trf->state == TRF7970A_ST_WAIT_FOR_RX_DATA_CONT)
762165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		trf7970a_send_upstream(trf); /* No more rx data so send up */
7639d9304b32154be5908a3abbb46215297b9ce0a4cMark A. Greer	else if (trf->state == TRF7970A_ST_WAIT_TO_ISSUE_EOF)
7649d9304b32154be5908a3abbb46215297b9ce0a4cMark A. Greer		trf7970a_issue_eof(trf);
765165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	else
766165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		trf7970a_send_err_upstream(trf, -ETIMEDOUT);
767165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
768165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	mutex_unlock(&trf->lock);
769165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer}
770165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
771165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greerstatic int trf7970a_init(struct trf7970a *trf)
772165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer{
773165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	int ret;
774165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
775165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	dev_dbg(trf->dev, "Initializing device - state: %d\n", trf->state);
776165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
777165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	ret = trf7970a_cmd(trf, TRF7970A_CMD_SOFT_INIT);
778165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	if (ret)
779165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		goto err_out;
780165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
781165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	ret = trf7970a_cmd(trf, TRF7970A_CMD_IDLE);
782165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	if (ret)
783165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		goto err_out;
784165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
7856c08df422ede7db94776b8099a5f43597629234cMark A. Greer	ret = trf7970a_write(trf, TRF7970A_MODULATOR_SYS_CLK_CTRL, 0);
7866c08df422ede7db94776b8099a5f43597629234cMark A. Greer	if (ret)
7876c08df422ede7db94776b8099a5f43597629234cMark A. Greer		goto err_out;
7886c08df422ede7db94776b8099a5f43597629234cMark A. Greer
7896c08df422ede7db94776b8099a5f43597629234cMark A. Greer	trf->modulator_sys_clk_ctrl = 0;
7906c08df422ede7db94776b8099a5f43597629234cMark A. Greer
791b887eb09d3cbda145d9fff4b9a56c384edd07ed7Mark A. Greer	/* Must clear NFC Target Detection Level reg due to erratum */
792b887eb09d3cbda145d9fff4b9a56c384edd07ed7Mark A. Greer	ret = trf7970a_write(trf, TRF7970A_NFC_TARGET_LEVEL, 0);
793b887eb09d3cbda145d9fff4b9a56c384edd07ed7Mark A. Greer	if (ret)
794b887eb09d3cbda145d9fff4b9a56c384edd07ed7Mark A. Greer		goto err_out;
795b887eb09d3cbda145d9fff4b9a56c384edd07ed7Mark A. Greer
796165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	ret = trf7970a_write(trf, TRF7970A_ADJUTABLE_FIFO_IRQ_LEVELS,
797165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer			TRF7970A_ADJUTABLE_FIFO_IRQ_LEVELS_WLH_96 |
798165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer			TRF7970A_ADJUTABLE_FIFO_IRQ_LEVELS_WLL_32);
799165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	if (ret)
800165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		goto err_out;
801165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
802165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	ret = trf7970a_write(trf, TRF7970A_SPECIAL_FCN_REG1, 0);
803165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	if (ret)
804165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		goto err_out;
805165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
806165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	trf->special_fcn_reg1 = 0;
807165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
80849d19cc794e73c3383283a5366ff31572d71a795Mark A. Greer	trf->iso_ctrl = 0xff;
809165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	return 0;
810165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
811165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greererr_out:
812165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	dev_dbg(trf->dev, "Couldn't init device: %d\n", ret);
813165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	return ret;
814165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer}
815165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
816165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greerstatic void trf7970a_switch_rf_off(struct trf7970a *trf)
817165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer{
818165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	dev_dbg(trf->dev, "Switching rf off\n");
819165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
820a1d2dc5b407ae18b59b7a129c93c8eb5ad7b1c80Mark A. Greer	trf->chip_status_ctrl &= ~TRF7970A_CHIP_STATUS_RF_ON;
821a1d2dc5b407ae18b59b7a129c93c8eb5ad7b1c80Mark A. Greer
822a1d2dc5b407ae18b59b7a129c93c8eb5ad7b1c80Mark A. Greer	trf7970a_write(trf, TRF7970A_CHIP_STATUS_CTRL, trf->chip_status_ctrl);
823a1d2dc5b407ae18b59b7a129c93c8eb5ad7b1c80Mark A. Greer
824165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	trf->aborting = false;
825165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	trf->state = TRF7970A_ST_OFF;
826e6403b7c756f9d694332870ba0c2be7a4aa0b8c0Mark A. Greer
827e6403b7c756f9d694332870ba0c2be7a4aa0b8c0Mark A. Greer	pm_runtime_mark_last_busy(trf->dev);
828e6403b7c756f9d694332870ba0c2be7a4aa0b8c0Mark A. Greer	pm_runtime_put_autosuspend(trf->dev);
829165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer}
830165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
83118422e686ef043b9abe004326ac9ffa1e38b81ecMark A. Greerstatic void trf7970a_switch_rf_on(struct trf7970a *trf)
832165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer{
833a08e54549e743ea3704da939f92caf3eaa8471d3Mark A. Greer	int ret;
834a08e54549e743ea3704da939f92caf3eaa8471d3Mark A. Greer
835165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	dev_dbg(trf->dev, "Switching rf on\n");
836165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
837e6403b7c756f9d694332870ba0c2be7a4aa0b8c0Mark A. Greer	pm_runtime_get_sync(trf->dev);
838165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
839a08e54549e743ea3704da939f92caf3eaa8471d3Mark A. Greer	ret = trf7970a_init(trf);
840a08e54549e743ea3704da939f92caf3eaa8471d3Mark A. Greer	if (ret) {
841a08e54549e743ea3704da939f92caf3eaa8471d3Mark A. Greer		dev_err(trf->dev, "%s - Can't initialize: %d\n", __func__, ret);
842a08e54549e743ea3704da939f92caf3eaa8471d3Mark A. Greer		return;
843a08e54549e743ea3704da939f92caf3eaa8471d3Mark A. Greer	}
844a08e54549e743ea3704da939f92caf3eaa8471d3Mark A. Greer
845e6403b7c756f9d694332870ba0c2be7a4aa0b8c0Mark A. Greer	trf->state = TRF7970A_ST_IDLE;
846165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer}
847165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
848165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greerstatic int trf7970a_switch_rf(struct nfc_digital_dev *ddev, bool on)
849165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer{
850165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	struct trf7970a *trf = nfc_digital_get_drvdata(ddev);
851165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
852165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	dev_dbg(trf->dev, "Switching RF - state: %d, on: %d\n", trf->state, on);
853165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
854165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	mutex_lock(&trf->lock);
855165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
856165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	if (on) {
857165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		switch (trf->state) {
858165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		case TRF7970A_ST_OFF:
85918422e686ef043b9abe004326ac9ffa1e38b81ecMark A. Greer			trf7970a_switch_rf_on(trf);
860165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer			break;
861165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		case TRF7970A_ST_IDLE:
862165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		case TRF7970A_ST_IDLE_RX_BLOCKED:
863165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer			break;
864165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		default:
865165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer			dev_err(trf->dev, "%s - Invalid request: %d %d\n",
866165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer					__func__, trf->state, on);
867165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer			trf7970a_switch_rf_off(trf);
868165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		}
869165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	} else {
870165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		switch (trf->state) {
871165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		case TRF7970A_ST_OFF:
872165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer			break;
873165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		default:
874165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer			dev_err(trf->dev, "%s - Invalid request: %d %d\n",
875165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer					__func__, trf->state, on);
876165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer			/* FALLTHROUGH */
877165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		case TRF7970A_ST_IDLE:
878165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		case TRF7970A_ST_IDLE_RX_BLOCKED:
879165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer			trf7970a_switch_rf_off(trf);
880165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		}
881165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	}
882165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
883165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	mutex_unlock(&trf->lock);
88418422e686ef043b9abe004326ac9ffa1e38b81ecMark A. Greer	return 0;
885165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer}
886165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
887165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greerstatic int trf7970a_config_rf_tech(struct trf7970a *trf, int tech)
888165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer{
889165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	int ret = 0;
890165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
891165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	dev_dbg(trf->dev, "rf technology: %d\n", tech);
892165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
893165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	switch (tech) {
894165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	case NFC_DIGITAL_RF_TECH_106A:
89549d19cc794e73c3383283a5366ff31572d71a795Mark A. Greer		trf->iso_ctrl_tech = TRF7970A_ISO_CTRL_14443A_106;
89612e9ade309db51e7ea26be3b4fd5bc6057ddc175Mark A. Greer		trf->modulator_sys_clk_ctrl = TRF7970A_MODULATOR_DEPTH_OOK;
8974e64eff837fb682dfb2a1188fb036d75ec57375cMark A. Greer		trf->guard_time = TRF7970A_GUARD_TIME_NFCA;
898165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		break;
899742b1f9fa292a1b8f5c8368464e114c9b71c2a81Mark A. Greer	case NFC_DIGITAL_RF_TECH_106B:
900742b1f9fa292a1b8f5c8368464e114c9b71c2a81Mark A. Greer		trf->iso_ctrl_tech = TRF7970A_ISO_CTRL_14443B_106;
901742b1f9fa292a1b8f5c8368464e114c9b71c2a81Mark A. Greer		trf->modulator_sys_clk_ctrl = TRF7970A_MODULATOR_DEPTH_ASK10;
9024e64eff837fb682dfb2a1188fb036d75ec57375cMark A. Greer		trf->guard_time = TRF7970A_GUARD_TIME_NFCB;
903742b1f9fa292a1b8f5c8368464e114c9b71c2a81Mark A. Greer		break;
9046857bb96271cd40ffb38825d43897d716310e3dbMark A. Greer	case NFC_DIGITAL_RF_TECH_212F:
9056857bb96271cd40ffb38825d43897d716310e3dbMark A. Greer		trf->iso_ctrl_tech = TRF7970A_ISO_CTRL_FELICA_212;
9066857bb96271cd40ffb38825d43897d716310e3dbMark A. Greer		trf->modulator_sys_clk_ctrl = TRF7970A_MODULATOR_DEPTH_ASK10;
9074e64eff837fb682dfb2a1188fb036d75ec57375cMark A. Greer		trf->guard_time = TRF7970A_GUARD_TIME_NFCF;
9086857bb96271cd40ffb38825d43897d716310e3dbMark A. Greer		break;
9096857bb96271cd40ffb38825d43897d716310e3dbMark A. Greer	case NFC_DIGITAL_RF_TECH_424F:
9106857bb96271cd40ffb38825d43897d716310e3dbMark A. Greer		trf->iso_ctrl_tech = TRF7970A_ISO_CTRL_FELICA_424;
9116857bb96271cd40ffb38825d43897d716310e3dbMark A. Greer		trf->modulator_sys_clk_ctrl = TRF7970A_MODULATOR_DEPTH_ASK10;
9124e64eff837fb682dfb2a1188fb036d75ec57375cMark A. Greer		trf->guard_time = TRF7970A_GUARD_TIME_NFCF;
9136857bb96271cd40ffb38825d43897d716310e3dbMark A. Greer		break;
9149d9304b32154be5908a3abbb46215297b9ce0a4cMark A. Greer	case NFC_DIGITAL_RF_TECH_ISO15693:
91549d19cc794e73c3383283a5366ff31572d71a795Mark A. Greer		trf->iso_ctrl_tech = TRF7970A_ISO_CTRL_15693_SGL_1OF4_2648;
91612e9ade309db51e7ea26be3b4fd5bc6057ddc175Mark A. Greer		trf->modulator_sys_clk_ctrl = TRF7970A_MODULATOR_DEPTH_OOK;
9174e64eff837fb682dfb2a1188fb036d75ec57375cMark A. Greer		trf->guard_time = TRF7970A_GUARD_TIME_15693;
9189d9304b32154be5908a3abbb46215297b9ce0a4cMark A. Greer		break;
919165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	default:
920165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		dev_dbg(trf->dev, "Unsupported rf technology: %d\n", tech);
921165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		return -EINVAL;
922165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	}
923165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
924165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	trf->technology = tech;
925165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
926165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	return ret;
927165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer}
928165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
929165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greerstatic int trf7970a_config_framing(struct trf7970a *trf, int framing)
930165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer{
93149d19cc794e73c3383283a5366ff31572d71a795Mark A. Greer	u8 iso_ctrl = trf->iso_ctrl_tech;
93249d19cc794e73c3383283a5366ff31572d71a795Mark A. Greer	int ret;
93349d19cc794e73c3383283a5366ff31572d71a795Mark A. Greer
934165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	dev_dbg(trf->dev, "framing: %d\n", framing);
935165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
936165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	switch (framing) {
937165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	case NFC_DIGITAL_FRAMING_NFCA_SHORT:
938165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	case NFC_DIGITAL_FRAMING_NFCA_STANDARD:
939165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		trf->tx_cmd = TRF7970A_CMD_TRANSMIT_NO_CRC;
94049d19cc794e73c3383283a5366ff31572d71a795Mark A. Greer		iso_ctrl |= TRF7970A_ISO_CTRL_RX_CRC_N;
941165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		break;
942165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	case NFC_DIGITAL_FRAMING_NFCA_STANDARD_WITH_CRC_A:
9438006289108fa9635d16a65d9db16da06d7dce201Mark A. Greer	case NFC_DIGITAL_FRAMING_NFCA_T4T:
944742b1f9fa292a1b8f5c8368464e114c9b71c2a81Mark A. Greer	case NFC_DIGITAL_FRAMING_NFCB:
945742b1f9fa292a1b8f5c8368464e114c9b71c2a81Mark A. Greer	case NFC_DIGITAL_FRAMING_NFCB_T4T:
9466857bb96271cd40ffb38825d43897d716310e3dbMark A. Greer	case NFC_DIGITAL_FRAMING_NFCF:
9476857bb96271cd40ffb38825d43897d716310e3dbMark A. Greer	case NFC_DIGITAL_FRAMING_NFCF_T3T:
9489d9304b32154be5908a3abbb46215297b9ce0a4cMark A. Greer	case NFC_DIGITAL_FRAMING_ISO15693_INVENTORY:
9499d9304b32154be5908a3abbb46215297b9ce0a4cMark A. Greer	case NFC_DIGITAL_FRAMING_ISO15693_T5T:
950165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		trf->tx_cmd = TRF7970A_CMD_TRANSMIT;
95149d19cc794e73c3383283a5366ff31572d71a795Mark A. Greer		iso_ctrl &= ~TRF7970A_ISO_CTRL_RX_CRC_N;
952165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		break;
953165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	case NFC_DIGITAL_FRAMING_NFCA_T2T:
954165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		trf->tx_cmd = TRF7970A_CMD_TRANSMIT;
95549d19cc794e73c3383283a5366ff31572d71a795Mark A. Greer		iso_ctrl |= TRF7970A_ISO_CTRL_RX_CRC_N;
956165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		break;
957165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	default:
958165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		dev_dbg(trf->dev, "Unsupported Framing: %d\n", framing);
959165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		return -EINVAL;
960165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	}
961165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
962165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	trf->framing = framing;
963165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
96449d19cc794e73c3383283a5366ff31572d71a795Mark A. Greer	if (iso_ctrl != trf->iso_ctrl) {
96549d19cc794e73c3383283a5366ff31572d71a795Mark A. Greer		ret = trf7970a_write(trf, TRF7970A_ISO_CTRL, iso_ctrl);
96649d19cc794e73c3383283a5366ff31572d71a795Mark A. Greer		if (ret)
96749d19cc794e73c3383283a5366ff31572d71a795Mark A. Greer			return ret;
96849d19cc794e73c3383283a5366ff31572d71a795Mark A. Greer
96949d19cc794e73c3383283a5366ff31572d71a795Mark A. Greer		trf->iso_ctrl = iso_ctrl;
970a0822a7e3b7333689b1c8cb92782e299791c2795Mark A. Greer
971a0822a7e3b7333689b1c8cb92782e299791c2795Mark A. Greer		ret = trf7970a_write(trf, TRF7970A_MODULATOR_SYS_CLK_CTRL,
97212e9ade309db51e7ea26be3b4fd5bc6057ddc175Mark A. Greer				trf->modulator_sys_clk_ctrl);
973a0822a7e3b7333689b1c8cb92782e299791c2795Mark A. Greer		if (ret)
974a0822a7e3b7333689b1c8cb92782e299791c2795Mark A. Greer			return ret;
97549d19cc794e73c3383283a5366ff31572d71a795Mark A. Greer	}
97649d19cc794e73c3383283a5366ff31572d71a795Mark A. Greer
977a1d2dc5b407ae18b59b7a129c93c8eb5ad7b1c80Mark A. Greer	if (!(trf->chip_status_ctrl & TRF7970A_CHIP_STATUS_RF_ON)) {
978a1d2dc5b407ae18b59b7a129c93c8eb5ad7b1c80Mark A. Greer		ret = trf7970a_write(trf, TRF7970A_CHIP_STATUS_CTRL,
979a1d2dc5b407ae18b59b7a129c93c8eb5ad7b1c80Mark A. Greer				trf->chip_status_ctrl |
980a1d2dc5b407ae18b59b7a129c93c8eb5ad7b1c80Mark A. Greer					TRF7970A_CHIP_STATUS_RF_ON);
981a1d2dc5b407ae18b59b7a129c93c8eb5ad7b1c80Mark A. Greer		if (ret)
982a1d2dc5b407ae18b59b7a129c93c8eb5ad7b1c80Mark A. Greer			return ret;
983a1d2dc5b407ae18b59b7a129c93c8eb5ad7b1c80Mark A. Greer
984a1d2dc5b407ae18b59b7a129c93c8eb5ad7b1c80Mark A. Greer		trf->chip_status_ctrl |= TRF7970A_CHIP_STATUS_RF_ON;
985a1d2dc5b407ae18b59b7a129c93c8eb5ad7b1c80Mark A. Greer
9864e64eff837fb682dfb2a1188fb036d75ec57375cMark A. Greer		usleep_range(trf->guard_time, trf->guard_time + 1000);
987a1d2dc5b407ae18b59b7a129c93c8eb5ad7b1c80Mark A. Greer	}
988a1d2dc5b407ae18b59b7a129c93c8eb5ad7b1c80Mark A. Greer
98949d19cc794e73c3383283a5366ff31572d71a795Mark A. Greer	return 0;
990165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer}
991165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
992165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greerstatic int trf7970a_in_configure_hw(struct nfc_digital_dev *ddev, int type,
993165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		int param)
994165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer{
995165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	struct trf7970a *trf = nfc_digital_get_drvdata(ddev);
99618422e686ef043b9abe004326ac9ffa1e38b81ecMark A. Greer	int ret;
997165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
998165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	dev_dbg(trf->dev, "Configure hw - type: %d, param: %d\n", type, param);
999165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
1000165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	mutex_lock(&trf->lock);
1001165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
100218422e686ef043b9abe004326ac9ffa1e38b81ecMark A. Greer	if (trf->state == TRF7970A_ST_OFF)
100318422e686ef043b9abe004326ac9ffa1e38b81ecMark A. Greer		trf7970a_switch_rf_on(trf);
1004165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
1005165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	switch (type) {
1006165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	case NFC_DIGITAL_CONFIG_RF_TECH:
1007165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		ret = trf7970a_config_rf_tech(trf, param);
1008165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		break;
1009165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	case NFC_DIGITAL_CONFIG_FRAMING:
1010165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		ret = trf7970a_config_framing(trf, param);
1011165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		break;
1012165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	default:
1013165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		dev_dbg(trf->dev, "Unknown type: %d\n", type);
1014165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		ret = -EINVAL;
1015165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	}
1016165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
1017165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	mutex_unlock(&trf->lock);
1018165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	return ret;
1019165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer}
1020165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
10219d9304b32154be5908a3abbb46215297b9ce0a4cMark A. Greerstatic int trf7970a_is_iso15693_write_or_lock(u8 cmd)
10229d9304b32154be5908a3abbb46215297b9ce0a4cMark A. Greer{
10239d9304b32154be5908a3abbb46215297b9ce0a4cMark A. Greer	switch (cmd) {
10249d9304b32154be5908a3abbb46215297b9ce0a4cMark A. Greer	case ISO15693_CMD_WRITE_SINGLE_BLOCK:
10259d9304b32154be5908a3abbb46215297b9ce0a4cMark A. Greer	case ISO15693_CMD_LOCK_BLOCK:
10269d9304b32154be5908a3abbb46215297b9ce0a4cMark A. Greer	case ISO15693_CMD_WRITE_MULTIPLE_BLOCK:
10279d9304b32154be5908a3abbb46215297b9ce0a4cMark A. Greer	case ISO15693_CMD_WRITE_AFI:
10289d9304b32154be5908a3abbb46215297b9ce0a4cMark A. Greer	case ISO15693_CMD_LOCK_AFI:
10299d9304b32154be5908a3abbb46215297b9ce0a4cMark A. Greer	case ISO15693_CMD_WRITE_DSFID:
10309d9304b32154be5908a3abbb46215297b9ce0a4cMark A. Greer	case ISO15693_CMD_LOCK_DSFID:
10319d9304b32154be5908a3abbb46215297b9ce0a4cMark A. Greer		return 1;
10329d9304b32154be5908a3abbb46215297b9ce0a4cMark A. Greer		break;
10339d9304b32154be5908a3abbb46215297b9ce0a4cMark A. Greer	default:
10349d9304b32154be5908a3abbb46215297b9ce0a4cMark A. Greer		return 0;
10359d9304b32154be5908a3abbb46215297b9ce0a4cMark A. Greer	}
10369d9304b32154be5908a3abbb46215297b9ce0a4cMark A. Greer}
10379d9304b32154be5908a3abbb46215297b9ce0a4cMark A. Greer
1038165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greerstatic int trf7970a_per_cmd_config(struct trf7970a *trf, struct sk_buff *skb)
1039165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer{
1040165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	u8 *req = skb->data;
10419d9304b32154be5908a3abbb46215297b9ce0a4cMark A. Greer	u8 special_fcn_reg1, iso_ctrl;
1042165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	int ret;
1043165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
10449d9304b32154be5908a3abbb46215297b9ce0a4cMark A. Greer	trf->issue_eof = false;
10459d9304b32154be5908a3abbb46215297b9ce0a4cMark A. Greer
1046165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	/* When issuing Type 2 read command, make sure the '4_bit_RX' bit in
1047165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	 * special functions register 1 is cleared; otherwise, its a write or
1048165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	 * sector select command and '4_bit_RX' must be set.
10499d9304b32154be5908a3abbb46215297b9ce0a4cMark A. Greer	 *
10509d9304b32154be5908a3abbb46215297b9ce0a4cMark A. Greer	 * When issuing an ISO 15693 command, inspect the flags byte to see
10519d9304b32154be5908a3abbb46215297b9ce0a4cMark A. Greer	 * what speed to use.  Also, remember if the OPTION flag is set on
10529d9304b32154be5908a3abbb46215297b9ce0a4cMark A. Greer	 * a Type 5 write or lock command so the driver will know that it
10539d9304b32154be5908a3abbb46215297b9ce0a4cMark A. Greer	 * has to send an EOF in order to get a response.
1054165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	 */
1055165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	if ((trf->technology == NFC_DIGITAL_RF_TECH_106A) &&
1056165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer			(trf->framing == NFC_DIGITAL_FRAMING_NFCA_T2T)) {
1057165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		if (req[0] == NFC_T2T_CMD_READ)
1058165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer			special_fcn_reg1 = 0;
1059165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		else
1060165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer			special_fcn_reg1 = TRF7970A_SPECIAL_FCN_REG1_4_BIT_RX;
1061165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
1062165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		if (special_fcn_reg1 != trf->special_fcn_reg1) {
1063165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer			ret = trf7970a_write(trf, TRF7970A_SPECIAL_FCN_REG1,
1064165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer					special_fcn_reg1);
1065165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer			if (ret)
1066165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer				return ret;
1067165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
1068165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer			trf->special_fcn_reg1 = special_fcn_reg1;
1069165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		}
10709d9304b32154be5908a3abbb46215297b9ce0a4cMark A. Greer	} else if (trf->technology == NFC_DIGITAL_RF_TECH_ISO15693) {
10719d9304b32154be5908a3abbb46215297b9ce0a4cMark A. Greer		iso_ctrl = trf->iso_ctrl & ~TRF7970A_ISO_CTRL_RFID_SPEED_MASK;
10729d9304b32154be5908a3abbb46215297b9ce0a4cMark A. Greer
10739d9304b32154be5908a3abbb46215297b9ce0a4cMark A. Greer		switch (req[0] & ISO15693_REQ_FLAG_SPEED_MASK) {
10749d9304b32154be5908a3abbb46215297b9ce0a4cMark A. Greer		case 0x00:
10759d9304b32154be5908a3abbb46215297b9ce0a4cMark A. Greer			iso_ctrl |= TRF7970A_ISO_CTRL_15693_SGL_1OF4_662;
10769d9304b32154be5908a3abbb46215297b9ce0a4cMark A. Greer			break;
10779d9304b32154be5908a3abbb46215297b9ce0a4cMark A. Greer		case ISO15693_REQ_FLAG_SUB_CARRIER:
10789d9304b32154be5908a3abbb46215297b9ce0a4cMark A. Greer			iso_ctrl |= TRF7970A_ISO_CTRL_15693_DBL_1OF4_667a;
10799d9304b32154be5908a3abbb46215297b9ce0a4cMark A. Greer			break;
10809d9304b32154be5908a3abbb46215297b9ce0a4cMark A. Greer		case ISO15693_REQ_FLAG_DATA_RATE:
10819d9304b32154be5908a3abbb46215297b9ce0a4cMark A. Greer			iso_ctrl |= TRF7970A_ISO_CTRL_15693_SGL_1OF4_2648;
10829d9304b32154be5908a3abbb46215297b9ce0a4cMark A. Greer			break;
10839d9304b32154be5908a3abbb46215297b9ce0a4cMark A. Greer		case (ISO15693_REQ_FLAG_SUB_CARRIER |
10849d9304b32154be5908a3abbb46215297b9ce0a4cMark A. Greer				ISO15693_REQ_FLAG_DATA_RATE):
10859d9304b32154be5908a3abbb46215297b9ce0a4cMark A. Greer			iso_ctrl |= TRF7970A_ISO_CTRL_15693_DBL_1OF4_2669;
10869d9304b32154be5908a3abbb46215297b9ce0a4cMark A. Greer			break;
10879d9304b32154be5908a3abbb46215297b9ce0a4cMark A. Greer		}
10889d9304b32154be5908a3abbb46215297b9ce0a4cMark A. Greer
10899d9304b32154be5908a3abbb46215297b9ce0a4cMark A. Greer		if (iso_ctrl != trf->iso_ctrl) {
10909d9304b32154be5908a3abbb46215297b9ce0a4cMark A. Greer			ret = trf7970a_write(trf, TRF7970A_ISO_CTRL, iso_ctrl);
10919d9304b32154be5908a3abbb46215297b9ce0a4cMark A. Greer			if (ret)
10929d9304b32154be5908a3abbb46215297b9ce0a4cMark A. Greer				return ret;
10939d9304b32154be5908a3abbb46215297b9ce0a4cMark A. Greer
10949d9304b32154be5908a3abbb46215297b9ce0a4cMark A. Greer			trf->iso_ctrl = iso_ctrl;
10959d9304b32154be5908a3abbb46215297b9ce0a4cMark A. Greer		}
10969d9304b32154be5908a3abbb46215297b9ce0a4cMark A. Greer
10979d9304b32154be5908a3abbb46215297b9ce0a4cMark A. Greer		if ((trf->framing == NFC_DIGITAL_FRAMING_ISO15693_T5T) &&
10989d9304b32154be5908a3abbb46215297b9ce0a4cMark A. Greer				trf7970a_is_iso15693_write_or_lock(req[1]) &&
10999d9304b32154be5908a3abbb46215297b9ce0a4cMark A. Greer				(req[0] & ISO15693_REQ_FLAG_OPTION))
11009d9304b32154be5908a3abbb46215297b9ce0a4cMark A. Greer			trf->issue_eof = true;
1101165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	}
1102165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
1103165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	return 0;
1104165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer}
1105165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
1106165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greerstatic int trf7970a_in_send_cmd(struct nfc_digital_dev *ddev,
1107165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		struct sk_buff *skb, u16 timeout,
1108165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		nfc_digital_cmd_complete_t cb, void *arg)
1109165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer{
1110165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	struct trf7970a *trf = nfc_digital_get_drvdata(ddev);
1111165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	char *prefix;
1112165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	unsigned int len;
1113165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	int ret;
1114165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
1115165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	dev_dbg(trf->dev, "New request - state: %d, timeout: %d ms, len: %d\n",
1116165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer			trf->state, timeout, skb->len);
1117165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
1118165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	if (skb->len > TRF7970A_TX_MAX)
1119165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		return -EINVAL;
1120165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
1121165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	mutex_lock(&trf->lock);
1122165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
1123165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	if ((trf->state != TRF7970A_ST_IDLE) &&
1124165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer			(trf->state != TRF7970A_ST_IDLE_RX_BLOCKED)) {
1125165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		dev_err(trf->dev, "%s - Bogus state: %d\n", __func__,
1126165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer				trf->state);
1127165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		ret = -EIO;
1128165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		goto out_err;
1129165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	}
1130165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
1131165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	if (trf->aborting) {
1132165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		dev_dbg(trf->dev, "Abort process complete\n");
1133165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		trf->aborting = false;
1134165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		ret = -ECANCELED;
1135165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		goto out_err;
1136165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	}
1137165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
1138165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	trf->rx_skb = nfc_alloc_recv_skb(TRF7970A_RX_SKB_ALLOC_SIZE,
1139165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer			GFP_KERNEL);
1140165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	if (!trf->rx_skb) {
1141165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		dev_dbg(trf->dev, "Can't alloc rx_skb\n");
1142165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		ret = -ENOMEM;
1143165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		goto out_err;
1144165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	}
1145165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
1146165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	if (trf->state == TRF7970A_ST_IDLE_RX_BLOCKED) {
1147165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		ret = trf7970a_cmd(trf, TRF7970A_CMD_ENABLE_RX);
1148165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		if (ret)
1149165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer			goto out_err;
1150165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
1151165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		trf->state = TRF7970A_ST_IDLE;
1152165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	}
1153165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
1154165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	ret = trf7970a_per_cmd_config(trf, skb);
1155165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	if (ret)
1156165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		goto out_err;
1157165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
1158165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	trf->ddev = ddev;
1159165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	trf->tx_skb = skb;
1160165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	trf->cb = cb;
1161165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	trf->cb_arg = arg;
1162165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	trf->timeout = timeout;
1163165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	trf->ignore_timeout = false;
1164165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
1165165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	len = skb->len;
1166165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	prefix = skb_push(skb, TRF7970A_TX_SKB_HEADROOM);
1167165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
1168165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	/* TX data must be prefixed with a FIFO reset cmd, a cmd that depends
1169165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	 * on what the current framing is, the address of the TX length byte 1
1170165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	 * register (0x1d), and the 2 byte length of the data to be transmitted.
1171165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	 */
1172165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	prefix[0] = TRF7970A_CMD_BIT_CTRL |
1173165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer			TRF7970A_CMD_BIT_OPCODE(TRF7970A_CMD_FIFO_RESET);
1174165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	prefix[1] = TRF7970A_CMD_BIT_CTRL |
1175165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer			TRF7970A_CMD_BIT_OPCODE(trf->tx_cmd);
1176165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	prefix[2] = TRF7970A_CMD_BIT_CONTINUOUS | TRF7970A_TX_LENGTH_BYTE1;
1177165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
1178165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	if (trf->framing == NFC_DIGITAL_FRAMING_NFCA_SHORT) {
1179165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		prefix[3] = 0x00;
1180165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		prefix[4] = 0x0f; /* 7 bits */
1181165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	} else {
1182165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		prefix[3] = (len & 0xf00) >> 4;
1183165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		prefix[3] |= ((len & 0xf0) >> 4);
1184165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		prefix[4] = ((len & 0x0f) << 4);
1185165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	}
1186165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
1187165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	len = min_t(int, skb->len, TRF7970A_FIFO_SIZE);
1188165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
1189165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	ret = trf7970a_transmit(trf, skb, len);
1190165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	if (ret) {
1191165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		kfree_skb(trf->rx_skb);
1192165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		trf->rx_skb = NULL;
1193165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	}
1194165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
1195165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greerout_err:
1196165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	mutex_unlock(&trf->lock);
1197165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	return ret;
1198165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer}
1199165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
1200165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greerstatic int trf7970a_tg_configure_hw(struct nfc_digital_dev *ddev,
1201165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		int type, int param)
1202165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer{
1203165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	struct trf7970a *trf = nfc_digital_get_drvdata(ddev);
1204165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
1205165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	dev_dbg(trf->dev, "Unsupported interface\n");
1206165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
1207165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	return -EINVAL;
1208165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer}
1209165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
1210165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greerstatic int trf7970a_tg_send_cmd(struct nfc_digital_dev *ddev,
1211165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		struct sk_buff *skb, u16 timeout,
1212165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		nfc_digital_cmd_complete_t cb, void *arg)
1213165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer{
1214165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	struct trf7970a *trf = nfc_digital_get_drvdata(ddev);
1215165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
1216165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	dev_dbg(trf->dev, "Unsupported interface\n");
1217165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
1218165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	return -EINVAL;
1219165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer}
1220165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
1221165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greerstatic int trf7970a_tg_listen(struct nfc_digital_dev *ddev,
1222165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		u16 timeout, nfc_digital_cmd_complete_t cb, void *arg)
1223165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer{
1224165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	struct trf7970a *trf = nfc_digital_get_drvdata(ddev);
1225165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
1226165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	dev_dbg(trf->dev, "Unsupported interface\n");
1227165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
1228165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	return -EINVAL;
1229165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer}
1230165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
1231165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greerstatic void trf7970a_abort_cmd(struct nfc_digital_dev *ddev)
1232165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer{
1233165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	struct trf7970a *trf = nfc_digital_get_drvdata(ddev);
1234165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
1235165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	dev_dbg(trf->dev, "Abort process initiated\n");
1236165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
1237165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	mutex_lock(&trf->lock);
12385876bc75e2d3174cd1cd944ee33edc77cd1173caMark A. Greer
12395876bc75e2d3174cd1cd944ee33edc77cd1173caMark A. Greer	switch (trf->state) {
12405876bc75e2d3174cd1cd944ee33edc77cd1173caMark A. Greer	case TRF7970A_ST_WAIT_FOR_TX_FIFO:
12415876bc75e2d3174cd1cd944ee33edc77cd1173caMark A. Greer	case TRF7970A_ST_WAIT_FOR_RX_DATA:
12425876bc75e2d3174cd1cd944ee33edc77cd1173caMark A. Greer	case TRF7970A_ST_WAIT_FOR_RX_DATA_CONT:
12435876bc75e2d3174cd1cd944ee33edc77cd1173caMark A. Greer	case TRF7970A_ST_WAIT_TO_ISSUE_EOF:
12445876bc75e2d3174cd1cd944ee33edc77cd1173caMark A. Greer		trf->aborting = true;
12455876bc75e2d3174cd1cd944ee33edc77cd1173caMark A. Greer		break;
12465876bc75e2d3174cd1cd944ee33edc77cd1173caMark A. Greer	default:
12475876bc75e2d3174cd1cd944ee33edc77cd1173caMark A. Greer		break;
12485876bc75e2d3174cd1cd944ee33edc77cd1173caMark A. Greer	}
12495876bc75e2d3174cd1cd944ee33edc77cd1173caMark A. Greer
1250165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	mutex_unlock(&trf->lock);
1251165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer}
1252165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
1253165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greerstatic struct nfc_digital_ops trf7970a_nfc_ops = {
1254165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	.in_configure_hw	= trf7970a_in_configure_hw,
1255165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	.in_send_cmd		= trf7970a_in_send_cmd,
1256165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	.tg_configure_hw	= trf7970a_tg_configure_hw,
1257165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	.tg_send_cmd		= trf7970a_tg_send_cmd,
1258165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	.tg_listen		= trf7970a_tg_listen,
1259165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	.switch_rf		= trf7970a_switch_rf,
1260165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	.abort_cmd		= trf7970a_abort_cmd,
1261165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer};
1262165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
1263fd0c8280cf47104e87dc10828ded541b4e84dedaMark A. Greerstatic int trf7970a_get_autosuspend_delay(struct device_node *np)
1264fd0c8280cf47104e87dc10828ded541b4e84dedaMark A. Greer{
1265fd0c8280cf47104e87dc10828ded541b4e84dedaMark A. Greer	int autosuspend_delay, ret;
1266fd0c8280cf47104e87dc10828ded541b4e84dedaMark A. Greer
1267fd0c8280cf47104e87dc10828ded541b4e84dedaMark A. Greer	ret = of_property_read_u32(np, "autosuspend-delay", &autosuspend_delay);
1268fd0c8280cf47104e87dc10828ded541b4e84dedaMark A. Greer	if (ret)
1269fd0c8280cf47104e87dc10828ded541b4e84dedaMark A. Greer		autosuspend_delay = TRF7970A_AUTOSUSPEND_DELAY;
1270fd0c8280cf47104e87dc10828ded541b4e84dedaMark A. Greer
1271fd0c8280cf47104e87dc10828ded541b4e84dedaMark A. Greer	return autosuspend_delay;
1272fd0c8280cf47104e87dc10828ded541b4e84dedaMark A. Greer}
1273fd0c8280cf47104e87dc10828ded541b4e84dedaMark A. Greer
12743bd14233aa0733fbc6c3f75ec928f1a393522644Mark A. Greerstatic int trf7970a_get_vin_voltage_override(struct device_node *np,
12753bd14233aa0733fbc6c3f75ec928f1a393522644Mark A. Greer		u32 *vin_uvolts)
12763bd14233aa0733fbc6c3f75ec928f1a393522644Mark A. Greer{
12773bd14233aa0733fbc6c3f75ec928f1a393522644Mark A. Greer	return of_property_read_u32(np, "vin-voltage-override", vin_uvolts);
12783bd14233aa0733fbc6c3f75ec928f1a393522644Mark A. Greer}
12793bd14233aa0733fbc6c3f75ec928f1a393522644Mark A. Greer
1280165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greerstatic int trf7970a_probe(struct spi_device *spi)
1281165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer{
1282165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	struct device_node *np = spi->dev.of_node;
1283165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	struct trf7970a *trf;
1284fd0c8280cf47104e87dc10828ded541b4e84dedaMark A. Greer	int uvolts, autosuspend_delay, ret;
1285165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
1286165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	if (!np) {
1287165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		dev_err(&spi->dev, "No Device Tree entry\n");
1288165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		return -EINVAL;
1289165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	}
1290165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
1291165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	trf = devm_kzalloc(&spi->dev, sizeof(*trf), GFP_KERNEL);
1292165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	if (!trf)
1293165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		return -ENOMEM;
1294165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
1295165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	trf->state = TRF7970A_ST_OFF;
1296165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	trf->dev = &spi->dev;
1297165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	trf->spi = spi;
1298165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
1299165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	spi->mode = SPI_MODE_1;
1300165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	spi->bits_per_word = 8;
1301165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
130224707296c762d1828c4a51aa1872dc275dc3fcccMark A. Greer	ret = spi_setup(spi);
130324707296c762d1828c4a51aa1872dc275dc3fcccMark A. Greer	if (ret < 0) {
130424707296c762d1828c4a51aa1872dc275dc3fcccMark A. Greer		dev_err(trf->dev, "Can't set up SPI Communication\n");
130524707296c762d1828c4a51aa1872dc275dc3fcccMark A. Greer		return ret;
130624707296c762d1828c4a51aa1872dc275dc3fcccMark A. Greer	}
130724707296c762d1828c4a51aa1872dc275dc3fcccMark A. Greer
1308772079eb77587e0242752fa67685a8132d899f79Mark A. Greer	if (of_property_read_bool(np, "irq-status-read-quirk"))
1309772079eb77587e0242752fa67685a8132d899f79Mark A. Greer		trf->quirks |= TRF7970A_QUIRK_IRQ_STATUS_READ;
1310772079eb77587e0242752fa67685a8132d899f79Mark A. Greer
1311165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	/* There are two enable pins - both must be present */
1312165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	trf->en_gpio = of_get_named_gpio(np, "ti,enable-gpios", 0);
1313165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	if (!gpio_is_valid(trf->en_gpio)) {
1314165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		dev_err(trf->dev, "No EN GPIO property\n");
1315165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		return trf->en_gpio;
1316165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	}
1317165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
1318165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	ret = devm_gpio_request_one(trf->dev, trf->en_gpio,
1319f23b73526b82ca2ef333362e704a51d817c1ffc1Mark A. Greer			GPIOF_DIR_OUT | GPIOF_INIT_LOW, "trf7970a EN");
1320165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	if (ret) {
1321165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		dev_err(trf->dev, "Can't request EN GPIO: %d\n", ret);
1322165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		return ret;
1323165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	}
1324165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
1325165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	trf->en2_gpio = of_get_named_gpio(np, "ti,enable-gpios", 1);
1326165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	if (!gpio_is_valid(trf->en2_gpio)) {
1327165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		dev_err(trf->dev, "No EN2 GPIO property\n");
1328165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		return trf->en2_gpio;
1329165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	}
1330165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
1331165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	ret = devm_gpio_request_one(trf->dev, trf->en2_gpio,
1332f23b73526b82ca2ef333362e704a51d817c1ffc1Mark A. Greer			GPIOF_DIR_OUT | GPIOF_INIT_LOW, "trf7970a EN2");
1333165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	if (ret) {
1334165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		dev_err(trf->dev, "Can't request EN2 GPIO: %d\n", ret);
1335165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		return ret;
1336165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	}
1337165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
133895064bd95a822659f4a606b485aba5009d70fc88Mark A. Greer	if (of_property_read_bool(np, "en2-rf-quirk"))
133995064bd95a822659f4a606b485aba5009d70fc88Mark A. Greer		trf->quirks |= TRF7970A_QUIRK_EN2_MUST_STAY_LOW;
134095064bd95a822659f4a606b485aba5009d70fc88Mark A. Greer
1341165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	ret = devm_request_threaded_irq(trf->dev, spi->irq, NULL,
1342165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer			trf7970a_irq, IRQF_TRIGGER_RISING | IRQF_ONESHOT,
1343165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer			"trf7970a", trf);
1344165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	if (ret) {
1345165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		dev_err(trf->dev, "Can't request IRQ#%d: %d\n", spi->irq, ret);
1346165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		return ret;
1347165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	}
1348165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
1349165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	mutex_init(&trf->lock);
1350165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	INIT_DELAYED_WORK(&trf->timeout_work, trf7970a_timeout_work_handler);
1351165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
1352165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	trf->regulator = devm_regulator_get(&spi->dev, "vin");
1353165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	if (IS_ERR(trf->regulator)) {
1354165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		ret = PTR_ERR(trf->regulator);
1355165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		dev_err(trf->dev, "Can't get VIN regulator: %d\n", ret);
1356165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		goto err_destroy_lock;
1357165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	}
1358165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
1359165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	ret = regulator_enable(trf->regulator);
1360165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	if (ret) {
1361165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		dev_err(trf->dev, "Can't enable VIN: %d\n", ret);
1362165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		goto err_destroy_lock;
1363165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	}
1364165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
13653bd14233aa0733fbc6c3f75ec928f1a393522644Mark A. Greer	ret = trf7970a_get_vin_voltage_override(np, &uvolts);
13663bd14233aa0733fbc6c3f75ec928f1a393522644Mark A. Greer	if (ret)
13673bd14233aa0733fbc6c3f75ec928f1a393522644Mark A. Greer		uvolts = regulator_get_voltage(trf->regulator);
1368ebcc5a0d08e6a680558ed74f5dd724427ff5a29bMark A. Greer
1369ebcc5a0d08e6a680558ed74f5dd724427ff5a29bMark A. Greer	if (uvolts > 4000000)
1370ebcc5a0d08e6a680558ed74f5dd724427ff5a29bMark A. Greer		trf->chip_status_ctrl = TRF7970A_CHIP_STATUS_VRS5_3;
1371ebcc5a0d08e6a680558ed74f5dd724427ff5a29bMark A. Greer
1372165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	trf->ddev = nfc_digital_allocate_device(&trf7970a_nfc_ops,
1373165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer			TRF7970A_SUPPORTED_PROTOCOLS,
1374165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer			NFC_DIGITAL_DRV_CAPS_IN_CRC, TRF7970A_TX_SKB_HEADROOM,
1375165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer			0);
1376165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	if (!trf->ddev) {
1377165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		dev_err(trf->dev, "Can't allocate NFC digital device\n");
1378165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		ret = -ENOMEM;
1379165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		goto err_disable_regulator;
1380165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	}
1381165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
1382165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	nfc_digital_set_parent_dev(trf->ddev, trf->dev);
1383165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	nfc_digital_set_drvdata(trf->ddev, trf);
1384165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	spi_set_drvdata(spi, trf);
1385165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
1386fd0c8280cf47104e87dc10828ded541b4e84dedaMark A. Greer	autosuspend_delay = trf7970a_get_autosuspend_delay(np);
1387fd0c8280cf47104e87dc10828ded541b4e84dedaMark A. Greer
1388fd0c8280cf47104e87dc10828ded541b4e84dedaMark A. Greer	pm_runtime_set_autosuspend_delay(trf->dev, autosuspend_delay);
1389e6403b7c756f9d694332870ba0c2be7a4aa0b8c0Mark A. Greer	pm_runtime_use_autosuspend(trf->dev);
1390e6403b7c756f9d694332870ba0c2be7a4aa0b8c0Mark A. Greer	pm_runtime_enable(trf->dev);
1391e6403b7c756f9d694332870ba0c2be7a4aa0b8c0Mark A. Greer
1392165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	ret = nfc_digital_register_device(trf->ddev);
1393165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	if (ret) {
1394165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		dev_err(trf->dev, "Can't register NFC digital device: %d\n",
1395165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer				ret);
1396165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		goto err_free_ddev;
1397165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	}
1398165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
1399165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	return 0;
1400165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
1401165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greererr_free_ddev:
1402e6403b7c756f9d694332870ba0c2be7a4aa0b8c0Mark A. Greer	pm_runtime_disable(trf->dev);
1403165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	nfc_digital_free_device(trf->ddev);
1404165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greererr_disable_regulator:
1405165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	regulator_disable(trf->regulator);
1406165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greererr_destroy_lock:
1407165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	mutex_destroy(&trf->lock);
1408165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	return ret;
1409165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer}
1410165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
1411165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greerstatic int trf7970a_remove(struct spi_device *spi)
1412165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer{
1413165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	struct trf7970a *trf = spi_get_drvdata(spi);
1414165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
1415165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	mutex_lock(&trf->lock);
1416165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
1417165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	switch (trf->state) {
1418165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	case TRF7970A_ST_WAIT_FOR_TX_FIFO:
1419165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	case TRF7970A_ST_WAIT_FOR_RX_DATA:
1420165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	case TRF7970A_ST_WAIT_FOR_RX_DATA_CONT:
14219d9304b32154be5908a3abbb46215297b9ce0a4cMark A. Greer	case TRF7970A_ST_WAIT_TO_ISSUE_EOF:
1422165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		trf7970a_send_err_upstream(trf, -ECANCELED);
1423e6403b7c756f9d694332870ba0c2be7a4aa0b8c0Mark A. Greer		/* FALLTHROUGH */
1424e6403b7c756f9d694332870ba0c2be7a4aa0b8c0Mark A. Greer	case TRF7970A_ST_IDLE:
1425e6403b7c756f9d694332870ba0c2be7a4aa0b8c0Mark A. Greer	case TRF7970A_ST_IDLE_RX_BLOCKED:
1426e6403b7c756f9d694332870ba0c2be7a4aa0b8c0Mark A. Greer		pm_runtime_put_sync(trf->dev);
1427165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		break;
1428165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	default:
1429165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		break;
1430165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	}
1431165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
1432165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	mutex_unlock(&trf->lock);
1433165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
1434e6403b7c756f9d694332870ba0c2be7a4aa0b8c0Mark A. Greer	pm_runtime_disable(trf->dev);
1435e6403b7c756f9d694332870ba0c2be7a4aa0b8c0Mark A. Greer
1436165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	nfc_digital_unregister_device(trf->ddev);
1437165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	nfc_digital_free_device(trf->ddev);
1438165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
1439165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	regulator_disable(trf->regulator);
1440165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
1441165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	mutex_destroy(&trf->lock);
1442165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
1443165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	return 0;
1444165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer}
1445165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
1446e6403b7c756f9d694332870ba0c2be7a4aa0b8c0Mark A. Greer#ifdef CONFIG_PM_RUNTIME
1447e6403b7c756f9d694332870ba0c2be7a4aa0b8c0Mark A. Greerstatic int trf7970a_pm_runtime_suspend(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 suspend\n");
1454e6403b7c756f9d694332870ba0c2be7a4aa0b8c0Mark A. Greer
1455e6403b7c756f9d694332870ba0c2be7a4aa0b8c0Mark A. Greer	if (trf->state != TRF7970A_ST_OFF) {
1456e6403b7c756f9d694332870ba0c2be7a4aa0b8c0Mark A. Greer		dev_dbg(dev, "Can't suspend - not in OFF state (%d)\n",
1457e6403b7c756f9d694332870ba0c2be7a4aa0b8c0Mark A. Greer				trf->state);
1458e6403b7c756f9d694332870ba0c2be7a4aa0b8c0Mark A. Greer		return -EBUSY;
1459e6403b7c756f9d694332870ba0c2be7a4aa0b8c0Mark A. Greer	}
1460e6403b7c756f9d694332870ba0c2be7a4aa0b8c0Mark A. Greer
1461e6403b7c756f9d694332870ba0c2be7a4aa0b8c0Mark A. Greer	gpio_set_value(trf->en_gpio, 0);
1462e6403b7c756f9d694332870ba0c2be7a4aa0b8c0Mark A. Greer	gpio_set_value(trf->en2_gpio, 0);
1463e6403b7c756f9d694332870ba0c2be7a4aa0b8c0Mark A. Greer
1464e6403b7c756f9d694332870ba0c2be7a4aa0b8c0Mark A. Greer	ret = regulator_disable(trf->regulator);
1465e6403b7c756f9d694332870ba0c2be7a4aa0b8c0Mark A. Greer	if (ret)
1466e6403b7c756f9d694332870ba0c2be7a4aa0b8c0Mark A. Greer		dev_err(dev, "%s - Can't disable VIN: %d\n", __func__, ret);
1467e6403b7c756f9d694332870ba0c2be7a4aa0b8c0Mark A. Greer
1468e6403b7c756f9d694332870ba0c2be7a4aa0b8c0Mark A. Greer	return ret;
1469e6403b7c756f9d694332870ba0c2be7a4aa0b8c0Mark A. Greer}
1470e6403b7c756f9d694332870ba0c2be7a4aa0b8c0Mark A. Greer
1471e6403b7c756f9d694332870ba0c2be7a4aa0b8c0Mark A. Greerstatic int trf7970a_pm_runtime_resume(struct device *dev)
1472e6403b7c756f9d694332870ba0c2be7a4aa0b8c0Mark A. Greer{
1473e6403b7c756f9d694332870ba0c2be7a4aa0b8c0Mark A. Greer	struct spi_device *spi = container_of(dev, struct spi_device, dev);
1474e6403b7c756f9d694332870ba0c2be7a4aa0b8c0Mark A. Greer	struct trf7970a *trf = spi_get_drvdata(spi);
1475e6403b7c756f9d694332870ba0c2be7a4aa0b8c0Mark A. Greer	int ret;
1476e6403b7c756f9d694332870ba0c2be7a4aa0b8c0Mark A. Greer
1477e6403b7c756f9d694332870ba0c2be7a4aa0b8c0Mark A. Greer	dev_dbg(dev, "Runtime resume\n");
1478e6403b7c756f9d694332870ba0c2be7a4aa0b8c0Mark A. Greer
1479e6403b7c756f9d694332870ba0c2be7a4aa0b8c0Mark A. Greer	ret = regulator_enable(trf->regulator);
1480e6403b7c756f9d694332870ba0c2be7a4aa0b8c0Mark A. Greer	if (ret) {
1481e6403b7c756f9d694332870ba0c2be7a4aa0b8c0Mark A. Greer		dev_err(dev, "%s - Can't enable VIN: %d\n", __func__, ret);
1482e6403b7c756f9d694332870ba0c2be7a4aa0b8c0Mark A. Greer		return ret;
1483e6403b7c756f9d694332870ba0c2be7a4aa0b8c0Mark A. Greer	}
1484e6403b7c756f9d694332870ba0c2be7a4aa0b8c0Mark A. Greer
1485e6403b7c756f9d694332870ba0c2be7a4aa0b8c0Mark A. Greer	usleep_range(5000, 6000);
1486e6403b7c756f9d694332870ba0c2be7a4aa0b8c0Mark A. Greer
148795064bd95a822659f4a606b485aba5009d70fc88Mark A. Greer	if (!(trf->quirks & TRF7970A_QUIRK_EN2_MUST_STAY_LOW)) {
148895064bd95a822659f4a606b485aba5009d70fc88Mark A. Greer		gpio_set_value(trf->en2_gpio, 1);
148995064bd95a822659f4a606b485aba5009d70fc88Mark A. Greer		usleep_range(1000, 2000);
149095064bd95a822659f4a606b485aba5009d70fc88Mark A. Greer	}
149195064bd95a822659f4a606b485aba5009d70fc88Mark A. Greer
1492e6403b7c756f9d694332870ba0c2be7a4aa0b8c0Mark A. Greer	gpio_set_value(trf->en_gpio, 1);
1493e6403b7c756f9d694332870ba0c2be7a4aa0b8c0Mark A. Greer
1494e6403b7c756f9d694332870ba0c2be7a4aa0b8c0Mark A. Greer	usleep_range(20000, 21000);
1495e6403b7c756f9d694332870ba0c2be7a4aa0b8c0Mark A. Greer
1496e6403b7c756f9d694332870ba0c2be7a4aa0b8c0Mark A. Greer	pm_runtime_mark_last_busy(dev);
1497e6403b7c756f9d694332870ba0c2be7a4aa0b8c0Mark A. Greer
1498e6403b7c756f9d694332870ba0c2be7a4aa0b8c0Mark A. Greer	return 0;
1499e6403b7c756f9d694332870ba0c2be7a4aa0b8c0Mark A. Greer}
1500e6403b7c756f9d694332870ba0c2be7a4aa0b8c0Mark A. Greer#endif
1501e6403b7c756f9d694332870ba0c2be7a4aa0b8c0Mark A. Greer
1502e6403b7c756f9d694332870ba0c2be7a4aa0b8c0Mark A. Greerstatic const struct dev_pm_ops trf7970a_pm_ops = {
1503e6403b7c756f9d694332870ba0c2be7a4aa0b8c0Mark A. Greer	SET_RUNTIME_PM_OPS(trf7970a_pm_runtime_suspend,
1504e6403b7c756f9d694332870ba0c2be7a4aa0b8c0Mark A. Greer			trf7970a_pm_runtime_resume, NULL)
1505e6403b7c756f9d694332870ba0c2be7a4aa0b8c0Mark A. Greer};
1506e6403b7c756f9d694332870ba0c2be7a4aa0b8c0Mark A. Greer
1507165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greerstatic const struct spi_device_id trf7970a_id_table[] = {
1508772079eb77587e0242752fa67685a8132d899f79Mark A. Greer	{ "trf7970a", 0 },
1509165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	{ }
1510165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer};
1511165063f1dac43e48ceb907490fff0a8413b9a32dMark A. GreerMODULE_DEVICE_TABLE(spi, trf7970a_id_table);
1512165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
1513165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greerstatic struct spi_driver trf7970a_spi_driver = {
1514165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	.probe		= trf7970a_probe,
1515165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	.remove		= trf7970a_remove,
1516165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	.id_table	= trf7970a_id_table,
1517165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	.driver		= {
1518165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		.name	= "trf7970a",
1519165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer		.owner	= THIS_MODULE,
1520e6403b7c756f9d694332870ba0c2be7a4aa0b8c0Mark A. Greer		.pm	= &trf7970a_pm_ops,
1521165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer	},
1522165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer};
1523165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
1524165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greermodule_spi_driver(trf7970a_spi_driver);
1525165063f1dac43e48ceb907490fff0a8413b9a32dMark A. Greer
1526165063f1dac43e48ceb907490fff0a8413b9a32dMark A. GreerMODULE_AUTHOR("Mark A. Greer <mgreer@animalcreek.com>");
1527165063f1dac43e48ceb907490fff0a8413b9a32dMark A. GreerMODULE_LICENSE("GPL v2");
1528165063f1dac43e48ceb907490fff0a8413b9a32dMark A. GreerMODULE_DESCRIPTION("TI trf7970a RFID/NFC Transceiver Driver");
1529