162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-only
262306a36Sopenharmony_ci/*
362306a36Sopenharmony_ci * TI TRF7970a RFID/NFC Transceiver Driver
462306a36Sopenharmony_ci *
562306a36Sopenharmony_ci * Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com
662306a36Sopenharmony_ci *
762306a36Sopenharmony_ci * Author: Erick Macias <emacias@ti.com>
862306a36Sopenharmony_ci * Author: Felipe Balbi <balbi@ti.com>
962306a36Sopenharmony_ci * Author: Mark A. Greer <mgreer@animalcreek.com>
1062306a36Sopenharmony_ci */
1162306a36Sopenharmony_ci
1262306a36Sopenharmony_ci#include <linux/module.h>
1362306a36Sopenharmony_ci#include <linux/device.h>
1462306a36Sopenharmony_ci#include <linux/netdevice.h>
1562306a36Sopenharmony_ci#include <linux/interrupt.h>
1662306a36Sopenharmony_ci#include <linux/pm_runtime.h>
1762306a36Sopenharmony_ci#include <linux/nfc.h>
1862306a36Sopenharmony_ci#include <linux/skbuff.h>
1962306a36Sopenharmony_ci#include <linux/delay.h>
2062306a36Sopenharmony_ci#include <linux/gpio/consumer.h>
2162306a36Sopenharmony_ci#include <linux/of.h>
2262306a36Sopenharmony_ci#include <linux/spi/spi.h>
2362306a36Sopenharmony_ci#include <linux/regulator/consumer.h>
2462306a36Sopenharmony_ci
2562306a36Sopenharmony_ci#include <net/nfc/nfc.h>
2662306a36Sopenharmony_ci#include <net/nfc/digital.h>
2762306a36Sopenharmony_ci
2862306a36Sopenharmony_ci/* There are 3 ways the host can communicate with the trf7970a:
2962306a36Sopenharmony_ci * parallel mode, SPI with Slave Select (SS) mode, and SPI without
3062306a36Sopenharmony_ci * SS mode.  The driver only supports the two SPI modes.
3162306a36Sopenharmony_ci *
3262306a36Sopenharmony_ci * The trf7970a is very timing sensitive and the VIN, EN2, and EN
3362306a36Sopenharmony_ci * pins must asserted in that order and with specific delays in between.
3462306a36Sopenharmony_ci * The delays used in the driver were provided by TI and have been
3562306a36Sopenharmony_ci * confirmed to work with this driver.  There is a bug with the current
3662306a36Sopenharmony_ci * version of the trf7970a that requires that EN2 remain low no matter
3762306a36Sopenharmony_ci * what.  If it goes high, it will generate an RF field even when in
3862306a36Sopenharmony_ci * passive target mode.  TI has indicated that the chip will work okay
3962306a36Sopenharmony_ci * when EN2 is left low.  The 'en2-rf-quirk' device tree property
4062306a36Sopenharmony_ci * indicates that trf7970a currently being used has the erratum and
4162306a36Sopenharmony_ci * that EN2 must be kept low.
4262306a36Sopenharmony_ci *
4362306a36Sopenharmony_ci * Timeouts are implemented using the delayed workqueue kernel facility.
4462306a36Sopenharmony_ci * Timeouts are required so things don't hang when there is no response
4562306a36Sopenharmony_ci * from the trf7970a (or tag).  Using this mechanism creates a race with
4662306a36Sopenharmony_ci * interrupts, however.  That is, an interrupt and a timeout could occur
4762306a36Sopenharmony_ci * closely enough together that one is blocked by the mutex while the other
4862306a36Sopenharmony_ci * executes.  When the timeout handler executes first and blocks the
4962306a36Sopenharmony_ci * interrupt handler, it will eventually set the state to IDLE so the
5062306a36Sopenharmony_ci * interrupt handler will check the state and exit with no harm done.
5162306a36Sopenharmony_ci * When the interrupt handler executes first and blocks the timeout handler,
5262306a36Sopenharmony_ci * the cancel_delayed_work() call will know that it didn't cancel the
5362306a36Sopenharmony_ci * work item (i.e., timeout) and will return zero.  That return code is
5462306a36Sopenharmony_ci * used by the timer handler to indicate that it should ignore the timeout
5562306a36Sopenharmony_ci * once its unblocked.
5662306a36Sopenharmony_ci *
5762306a36Sopenharmony_ci * Aborting an active command isn't as simple as it seems because the only
5862306a36Sopenharmony_ci * way to abort a command that's already been sent to the tag is so turn
5962306a36Sopenharmony_ci * off power to the tag.  If we do that, though, we'd have to go through
6062306a36Sopenharmony_ci * the entire anticollision procedure again but the digital layer doesn't
6162306a36Sopenharmony_ci * support that.  So, if an abort is received before trf7970a_send_cmd()
6262306a36Sopenharmony_ci * has sent the command to the tag, it simply returns -ECANCELED.  If the
6362306a36Sopenharmony_ci * command has already been sent to the tag, then the driver continues
6462306a36Sopenharmony_ci * normally and recieves the response data (or error) but just before
6562306a36Sopenharmony_ci * sending the data upstream, it frees the rx_skb and sends -ECANCELED
6662306a36Sopenharmony_ci * upstream instead.  If the command failed, that error will be sent
6762306a36Sopenharmony_ci * upstream.
6862306a36Sopenharmony_ci *
6962306a36Sopenharmony_ci * When recieving data from a tag and the interrupt status register has
7062306a36Sopenharmony_ci * only the SRX bit set, it means that all of the data has been received
7162306a36Sopenharmony_ci * (once what's in the fifo has been read).  However, depending on timing
7262306a36Sopenharmony_ci * an interrupt status with only the SRX bit set may not be recived.  In
7362306a36Sopenharmony_ci * those cases, the timeout mechanism is used to wait 20 ms in case more
7462306a36Sopenharmony_ci * data arrives.  After 20 ms, it is assumed that all of the data has been
7562306a36Sopenharmony_ci * received and the accumulated rx data is sent upstream.  The
7662306a36Sopenharmony_ci * 'TRF7970A_ST_WAIT_FOR_RX_DATA_CONT' state is used for this purpose
7762306a36Sopenharmony_ci * (i.e., it indicates that some data has been received but we're not sure
7862306a36Sopenharmony_ci * if there is more coming so a timeout in this state means all data has
7962306a36Sopenharmony_ci * been received and there isn't an error).  The delay is 20 ms since delays
8062306a36Sopenharmony_ci * of ~16 ms have been observed during testing.
8162306a36Sopenharmony_ci *
8262306a36Sopenharmony_ci * When transmitting a frame larger than the FIFO size (127 bytes), the
8362306a36Sopenharmony_ci * driver will wait 20 ms for the FIFO to drain past the low-watermark
8462306a36Sopenharmony_ci * and generate an interrupt.  The low-watermark set to 32 bytes so the
8562306a36Sopenharmony_ci * interrupt should fire after 127 - 32 = 95 bytes have been sent.  At
8662306a36Sopenharmony_ci * the lowest possible bit rate (6.62 kbps for 15693), it will take up
8762306a36Sopenharmony_ci * to ~14.35 ms so 20 ms is used for the timeout.
8862306a36Sopenharmony_ci *
8962306a36Sopenharmony_ci * Type 2 write and sector select commands respond with a 4-bit ACK or NACK.
9062306a36Sopenharmony_ci * Having only 4 bits in the FIFO won't normally generate an interrupt so
9162306a36Sopenharmony_ci * driver enables the '4_bit_RX' bit of the Special Functions register 1
9262306a36Sopenharmony_ci * to cause an interrupt in that case.  Leaving that bit for a read command
9362306a36Sopenharmony_ci * messes up the data returned so it is only enabled when the framing is
9462306a36Sopenharmony_ci * 'NFC_DIGITAL_FRAMING_NFCA_T2T' and the command is not a read command.
9562306a36Sopenharmony_ci * Unfortunately, that means that the driver has to peek into tx frames
9662306a36Sopenharmony_ci * when the framing is 'NFC_DIGITAL_FRAMING_NFCA_T2T'.  This is done by
9762306a36Sopenharmony_ci * the trf7970a_per_cmd_config() routine.
9862306a36Sopenharmony_ci *
9962306a36Sopenharmony_ci * ISO/IEC 15693 frames specify whether to use single or double sub-carrier
10062306a36Sopenharmony_ci * frequencies and whether to use low or high data rates in the flags byte
10162306a36Sopenharmony_ci * of the frame.  This means that the driver has to peek at all 15693 frames
10262306a36Sopenharmony_ci * to determine what speed to set the communication to.  In addition, write
10362306a36Sopenharmony_ci * and lock commands use the OPTION flag to indicate that an EOF must be
10462306a36Sopenharmony_ci * sent to the tag before it will send its response.  So the driver has to
10562306a36Sopenharmony_ci * examine all frames for that reason too.
10662306a36Sopenharmony_ci *
10762306a36Sopenharmony_ci * It is unclear how long to wait before sending the EOF.  According to the
10862306a36Sopenharmony_ci * Note under Table 1-1 in section 1.6 of
10962306a36Sopenharmony_ci * http://www.ti.com/lit/ug/scbu011/scbu011.pdf, that wait should be at least
11062306a36Sopenharmony_ci * 10 ms for TI Tag-it HF-I tags; however testing has shown that is not long
11162306a36Sopenharmony_ci * enough so 20 ms is used.  So the timer is set to 40 ms - 20 ms to drain
11262306a36Sopenharmony_ci * up to 127 bytes in the FIFO at the lowest bit rate plus another 20 ms to
11362306a36Sopenharmony_ci * ensure the wait is long enough before sending the EOF.  This seems to work
11462306a36Sopenharmony_ci * reliably.
11562306a36Sopenharmony_ci */
11662306a36Sopenharmony_ci
11762306a36Sopenharmony_ci#define TRF7970A_SUPPORTED_PROTOCOLS \
11862306a36Sopenharmony_ci		(NFC_PROTO_MIFARE_MASK | NFC_PROTO_ISO14443_MASK |	\
11962306a36Sopenharmony_ci		 NFC_PROTO_ISO14443_B_MASK | NFC_PROTO_FELICA_MASK | \
12062306a36Sopenharmony_ci		 NFC_PROTO_ISO15693_MASK | NFC_PROTO_NFC_DEP_MASK)
12162306a36Sopenharmony_ci
12262306a36Sopenharmony_ci#define TRF7970A_AUTOSUSPEND_DELAY		30000	/* 30 seconds */
12362306a36Sopenharmony_ci#define TRF7970A_13MHZ_CLOCK_FREQUENCY		13560000
12462306a36Sopenharmony_ci#define TRF7970A_27MHZ_CLOCK_FREQUENCY		27120000
12562306a36Sopenharmony_ci
12662306a36Sopenharmony_ci#define TRF7970A_RX_SKB_ALLOC_SIZE		256
12762306a36Sopenharmony_ci
12862306a36Sopenharmony_ci#define TRF7970A_FIFO_SIZE			127
12962306a36Sopenharmony_ci
13062306a36Sopenharmony_ci/* TX length is 3 nibbles long ==> 4KB - 1 bytes max */
13162306a36Sopenharmony_ci#define TRF7970A_TX_MAX				(4096 - 1)
13262306a36Sopenharmony_ci
13362306a36Sopenharmony_ci#define TRF7970A_WAIT_FOR_TX_IRQ		20
13462306a36Sopenharmony_ci#define TRF7970A_WAIT_FOR_RX_DATA_TIMEOUT	20
13562306a36Sopenharmony_ci#define TRF7970A_WAIT_FOR_FIFO_DRAIN_TIMEOUT	20
13662306a36Sopenharmony_ci#define TRF7970A_WAIT_TO_ISSUE_ISO15693_EOF	40
13762306a36Sopenharmony_ci
13862306a36Sopenharmony_ci/* Guard times for various RF technologies (in us) */
13962306a36Sopenharmony_ci#define TRF7970A_GUARD_TIME_NFCA		5000
14062306a36Sopenharmony_ci#define TRF7970A_GUARD_TIME_NFCB		5000
14162306a36Sopenharmony_ci#define TRF7970A_GUARD_TIME_NFCF		20000
14262306a36Sopenharmony_ci#define TRF7970A_GUARD_TIME_15693		1000
14362306a36Sopenharmony_ci
14462306a36Sopenharmony_ci/* Quirks */
14562306a36Sopenharmony_ci/* Erratum: When reading IRQ Status register on trf7970a, we must issue a
14662306a36Sopenharmony_ci * read continuous command for IRQ Status and Collision Position registers.
14762306a36Sopenharmony_ci */
14862306a36Sopenharmony_ci#define TRF7970A_QUIRK_IRQ_STATUS_READ		BIT(0)
14962306a36Sopenharmony_ci#define TRF7970A_QUIRK_EN2_MUST_STAY_LOW	BIT(1)
15062306a36Sopenharmony_ci
15162306a36Sopenharmony_ci/* Direct commands */
15262306a36Sopenharmony_ci#define TRF7970A_CMD_IDLE			0x00
15362306a36Sopenharmony_ci#define TRF7970A_CMD_SOFT_INIT			0x03
15462306a36Sopenharmony_ci#define TRF7970A_CMD_RF_COLLISION		0x04
15562306a36Sopenharmony_ci#define TRF7970A_CMD_RF_COLLISION_RESPONSE_N	0x05
15662306a36Sopenharmony_ci#define TRF7970A_CMD_RF_COLLISION_RESPONSE_0	0x06
15762306a36Sopenharmony_ci#define TRF7970A_CMD_FIFO_RESET			0x0f
15862306a36Sopenharmony_ci#define TRF7970A_CMD_TRANSMIT_NO_CRC		0x10
15962306a36Sopenharmony_ci#define TRF7970A_CMD_TRANSMIT			0x11
16062306a36Sopenharmony_ci#define TRF7970A_CMD_DELAY_TRANSMIT_NO_CRC	0x12
16162306a36Sopenharmony_ci#define TRF7970A_CMD_DELAY_TRANSMIT		0x13
16262306a36Sopenharmony_ci#define TRF7970A_CMD_EOF			0x14
16362306a36Sopenharmony_ci#define TRF7970A_CMD_CLOSE_SLOT			0x15
16462306a36Sopenharmony_ci#define TRF7970A_CMD_BLOCK_RX			0x16
16562306a36Sopenharmony_ci#define TRF7970A_CMD_ENABLE_RX			0x17
16662306a36Sopenharmony_ci#define TRF7970A_CMD_TEST_INT_RF		0x18
16762306a36Sopenharmony_ci#define TRF7970A_CMD_TEST_EXT_RF		0x19
16862306a36Sopenharmony_ci#define TRF7970A_CMD_RX_GAIN_ADJUST		0x1a
16962306a36Sopenharmony_ci
17062306a36Sopenharmony_ci/* Bits determining whether its a direct command or register R/W,
17162306a36Sopenharmony_ci * whether to use a continuous SPI transaction or not, and the actual
17262306a36Sopenharmony_ci * direct cmd opcode or register address.
17362306a36Sopenharmony_ci */
17462306a36Sopenharmony_ci#define TRF7970A_CMD_BIT_CTRL			BIT(7)
17562306a36Sopenharmony_ci#define TRF7970A_CMD_BIT_RW			BIT(6)
17662306a36Sopenharmony_ci#define TRF7970A_CMD_BIT_CONTINUOUS		BIT(5)
17762306a36Sopenharmony_ci#define TRF7970A_CMD_BIT_OPCODE(opcode)		((opcode) & 0x1f)
17862306a36Sopenharmony_ci
17962306a36Sopenharmony_ci/* Registers addresses */
18062306a36Sopenharmony_ci#define TRF7970A_CHIP_STATUS_CTRL		0x00
18162306a36Sopenharmony_ci#define TRF7970A_ISO_CTRL			0x01
18262306a36Sopenharmony_ci#define TRF7970A_ISO14443B_TX_OPTIONS		0x02
18362306a36Sopenharmony_ci#define TRF7970A_ISO14443A_HIGH_BITRATE_OPTIONS	0x03
18462306a36Sopenharmony_ci#define TRF7970A_TX_TIMER_SETTING_H_BYTE	0x04
18562306a36Sopenharmony_ci#define TRF7970A_TX_TIMER_SETTING_L_BYTE	0x05
18662306a36Sopenharmony_ci#define TRF7970A_TX_PULSE_LENGTH_CTRL		0x06
18762306a36Sopenharmony_ci#define TRF7970A_RX_NO_RESPONSE_WAIT		0x07
18862306a36Sopenharmony_ci#define TRF7970A_RX_WAIT_TIME			0x08
18962306a36Sopenharmony_ci#define TRF7970A_MODULATOR_SYS_CLK_CTRL		0x09
19062306a36Sopenharmony_ci#define TRF7970A_RX_SPECIAL_SETTINGS		0x0a
19162306a36Sopenharmony_ci#define TRF7970A_REG_IO_CTRL			0x0b
19262306a36Sopenharmony_ci#define TRF7970A_IRQ_STATUS			0x0c
19362306a36Sopenharmony_ci#define TRF7970A_COLLISION_IRQ_MASK		0x0d
19462306a36Sopenharmony_ci#define TRF7970A_COLLISION_POSITION		0x0e
19562306a36Sopenharmony_ci#define TRF7970A_RSSI_OSC_STATUS		0x0f
19662306a36Sopenharmony_ci#define TRF7970A_SPECIAL_FCN_REG1		0x10
19762306a36Sopenharmony_ci#define TRF7970A_SPECIAL_FCN_REG2		0x11
19862306a36Sopenharmony_ci#define TRF7970A_RAM1				0x12
19962306a36Sopenharmony_ci#define TRF7970A_RAM2				0x13
20062306a36Sopenharmony_ci#define TRF7970A_ADJUTABLE_FIFO_IRQ_LEVELS	0x14
20162306a36Sopenharmony_ci#define TRF7970A_NFC_LOW_FIELD_LEVEL		0x16
20262306a36Sopenharmony_ci#define TRF7970A_NFCID1				0x17
20362306a36Sopenharmony_ci#define TRF7970A_NFC_TARGET_LEVEL		0x18
20462306a36Sopenharmony_ci#define TRF79070A_NFC_TARGET_PROTOCOL		0x19
20562306a36Sopenharmony_ci#define TRF7970A_TEST_REGISTER1			0x1a
20662306a36Sopenharmony_ci#define TRF7970A_TEST_REGISTER2			0x1b
20762306a36Sopenharmony_ci#define TRF7970A_FIFO_STATUS			0x1c
20862306a36Sopenharmony_ci#define TRF7970A_TX_LENGTH_BYTE1		0x1d
20962306a36Sopenharmony_ci#define TRF7970A_TX_LENGTH_BYTE2		0x1e
21062306a36Sopenharmony_ci#define TRF7970A_FIFO_IO_REGISTER		0x1f
21162306a36Sopenharmony_ci
21262306a36Sopenharmony_ci/* Chip Status Control Register Bits */
21362306a36Sopenharmony_ci#define TRF7970A_CHIP_STATUS_VRS5_3		BIT(0)
21462306a36Sopenharmony_ci#define TRF7970A_CHIP_STATUS_REC_ON		BIT(1)
21562306a36Sopenharmony_ci#define TRF7970A_CHIP_STATUS_AGC_ON		BIT(2)
21662306a36Sopenharmony_ci#define TRF7970A_CHIP_STATUS_PM_ON		BIT(3)
21762306a36Sopenharmony_ci#define TRF7970A_CHIP_STATUS_RF_PWR		BIT(4)
21862306a36Sopenharmony_ci#define TRF7970A_CHIP_STATUS_RF_ON		BIT(5)
21962306a36Sopenharmony_ci#define TRF7970A_CHIP_STATUS_DIRECT		BIT(6)
22062306a36Sopenharmony_ci#define TRF7970A_CHIP_STATUS_STBY		BIT(7)
22162306a36Sopenharmony_ci
22262306a36Sopenharmony_ci/* ISO Control Register Bits */
22362306a36Sopenharmony_ci#define TRF7970A_ISO_CTRL_15693_SGL_1OF4_662	0x00
22462306a36Sopenharmony_ci#define TRF7970A_ISO_CTRL_15693_SGL_1OF256_662	0x01
22562306a36Sopenharmony_ci#define TRF7970A_ISO_CTRL_15693_SGL_1OF4_2648	0x02
22662306a36Sopenharmony_ci#define TRF7970A_ISO_CTRL_15693_SGL_1OF256_2648	0x03
22762306a36Sopenharmony_ci#define TRF7970A_ISO_CTRL_15693_DBL_1OF4_667a	0x04
22862306a36Sopenharmony_ci#define TRF7970A_ISO_CTRL_15693_DBL_1OF256_667	0x05
22962306a36Sopenharmony_ci#define TRF7970A_ISO_CTRL_15693_DBL_1OF4_2669	0x06
23062306a36Sopenharmony_ci#define TRF7970A_ISO_CTRL_15693_DBL_1OF256_2669	0x07
23162306a36Sopenharmony_ci#define TRF7970A_ISO_CTRL_14443A_106		0x08
23262306a36Sopenharmony_ci#define TRF7970A_ISO_CTRL_14443A_212		0x09
23362306a36Sopenharmony_ci#define TRF7970A_ISO_CTRL_14443A_424		0x0a
23462306a36Sopenharmony_ci#define TRF7970A_ISO_CTRL_14443A_848		0x0b
23562306a36Sopenharmony_ci#define TRF7970A_ISO_CTRL_14443B_106		0x0c
23662306a36Sopenharmony_ci#define TRF7970A_ISO_CTRL_14443B_212		0x0d
23762306a36Sopenharmony_ci#define TRF7970A_ISO_CTRL_14443B_424		0x0e
23862306a36Sopenharmony_ci#define TRF7970A_ISO_CTRL_14443B_848		0x0f
23962306a36Sopenharmony_ci#define TRF7970A_ISO_CTRL_FELICA_212		0x1a
24062306a36Sopenharmony_ci#define TRF7970A_ISO_CTRL_FELICA_424		0x1b
24162306a36Sopenharmony_ci#define TRF7970A_ISO_CTRL_NFC_NFCA_106		0x01
24262306a36Sopenharmony_ci#define TRF7970A_ISO_CTRL_NFC_NFCF_212		0x02
24362306a36Sopenharmony_ci#define TRF7970A_ISO_CTRL_NFC_NFCF_424		0x03
24462306a36Sopenharmony_ci#define TRF7970A_ISO_CTRL_NFC_CE_14443A		0x00
24562306a36Sopenharmony_ci#define TRF7970A_ISO_CTRL_NFC_CE_14443B		0x01
24662306a36Sopenharmony_ci#define TRF7970A_ISO_CTRL_NFC_CE		BIT(2)
24762306a36Sopenharmony_ci#define TRF7970A_ISO_CTRL_NFC_ACTIVE		BIT(3)
24862306a36Sopenharmony_ci#define TRF7970A_ISO_CTRL_NFC_INITIATOR		BIT(4)
24962306a36Sopenharmony_ci#define TRF7970A_ISO_CTRL_NFC_NFC_CE_MODE	BIT(5)
25062306a36Sopenharmony_ci#define TRF7970A_ISO_CTRL_RFID			BIT(5)
25162306a36Sopenharmony_ci#define TRF7970A_ISO_CTRL_DIR_MODE		BIT(6)
25262306a36Sopenharmony_ci#define TRF7970A_ISO_CTRL_RX_CRC_N		BIT(7)	/* true == No CRC */
25362306a36Sopenharmony_ci
25462306a36Sopenharmony_ci#define TRF7970A_ISO_CTRL_RFID_SPEED_MASK	0x1f
25562306a36Sopenharmony_ci
25662306a36Sopenharmony_ci/* Modulator and SYS_CLK Control Register Bits */
25762306a36Sopenharmony_ci#define TRF7970A_MODULATOR_DEPTH(n)		((n) & 0x7)
25862306a36Sopenharmony_ci#define TRF7970A_MODULATOR_DEPTH_ASK10		(TRF7970A_MODULATOR_DEPTH(0))
25962306a36Sopenharmony_ci#define TRF7970A_MODULATOR_DEPTH_OOK		(TRF7970A_MODULATOR_DEPTH(1))
26062306a36Sopenharmony_ci#define TRF7970A_MODULATOR_DEPTH_ASK7		(TRF7970A_MODULATOR_DEPTH(2))
26162306a36Sopenharmony_ci#define TRF7970A_MODULATOR_DEPTH_ASK8_5		(TRF7970A_MODULATOR_DEPTH(3))
26262306a36Sopenharmony_ci#define TRF7970A_MODULATOR_DEPTH_ASK13		(TRF7970A_MODULATOR_DEPTH(4))
26362306a36Sopenharmony_ci#define TRF7970A_MODULATOR_DEPTH_ASK16		(TRF7970A_MODULATOR_DEPTH(5))
26462306a36Sopenharmony_ci#define TRF7970A_MODULATOR_DEPTH_ASK22		(TRF7970A_MODULATOR_DEPTH(6))
26562306a36Sopenharmony_ci#define TRF7970A_MODULATOR_DEPTH_ASK30		(TRF7970A_MODULATOR_DEPTH(7))
26662306a36Sopenharmony_ci#define TRF7970A_MODULATOR_EN_ANA		BIT(3)
26762306a36Sopenharmony_ci#define TRF7970A_MODULATOR_CLK(n)		(((n) & 0x3) << 4)
26862306a36Sopenharmony_ci#define TRF7970A_MODULATOR_CLK_DISABLED		(TRF7970A_MODULATOR_CLK(0))
26962306a36Sopenharmony_ci#define TRF7970A_MODULATOR_CLK_3_6		(TRF7970A_MODULATOR_CLK(1))
27062306a36Sopenharmony_ci#define TRF7970A_MODULATOR_CLK_6_13		(TRF7970A_MODULATOR_CLK(2))
27162306a36Sopenharmony_ci#define TRF7970A_MODULATOR_CLK_13_27		(TRF7970A_MODULATOR_CLK(3))
27262306a36Sopenharmony_ci#define TRF7970A_MODULATOR_EN_OOK		BIT(6)
27362306a36Sopenharmony_ci#define TRF7970A_MODULATOR_27MHZ		BIT(7)
27462306a36Sopenharmony_ci
27562306a36Sopenharmony_ci#define TRF7970A_RX_SPECIAL_SETTINGS_NO_LIM	BIT(0)
27662306a36Sopenharmony_ci#define TRF7970A_RX_SPECIAL_SETTINGS_AGCR	BIT(1)
27762306a36Sopenharmony_ci#define TRF7970A_RX_SPECIAL_SETTINGS_GD_0DB	(0x0 << 2)
27862306a36Sopenharmony_ci#define TRF7970A_RX_SPECIAL_SETTINGS_GD_5DB	(0x1 << 2)
27962306a36Sopenharmony_ci#define TRF7970A_RX_SPECIAL_SETTINGS_GD_10DB	(0x2 << 2)
28062306a36Sopenharmony_ci#define TRF7970A_RX_SPECIAL_SETTINGS_GD_15DB	(0x3 << 2)
28162306a36Sopenharmony_ci#define TRF7970A_RX_SPECIAL_SETTINGS_HBT	BIT(4)
28262306a36Sopenharmony_ci#define TRF7970A_RX_SPECIAL_SETTINGS_M848	BIT(5)
28362306a36Sopenharmony_ci#define TRF7970A_RX_SPECIAL_SETTINGS_C424	BIT(6)
28462306a36Sopenharmony_ci#define TRF7970A_RX_SPECIAL_SETTINGS_C212	BIT(7)
28562306a36Sopenharmony_ci
28662306a36Sopenharmony_ci#define TRF7970A_REG_IO_CTRL_VRS(v)		((v) & 0x07)
28762306a36Sopenharmony_ci#define TRF7970A_REG_IO_CTRL_IO_LOW		BIT(5)
28862306a36Sopenharmony_ci#define TRF7970A_REG_IO_CTRL_EN_EXT_PA		BIT(6)
28962306a36Sopenharmony_ci#define TRF7970A_REG_IO_CTRL_AUTO_REG		BIT(7)
29062306a36Sopenharmony_ci
29162306a36Sopenharmony_ci/* IRQ Status Register Bits */
29262306a36Sopenharmony_ci#define TRF7970A_IRQ_STATUS_NORESP		BIT(0)	/* ISO15693 only */
29362306a36Sopenharmony_ci#define TRF7970A_IRQ_STATUS_NFC_COL_ERROR	BIT(0)
29462306a36Sopenharmony_ci#define TRF7970A_IRQ_STATUS_COL			BIT(1)
29562306a36Sopenharmony_ci#define TRF7970A_IRQ_STATUS_FRAMING_EOF_ERROR	BIT(2)
29662306a36Sopenharmony_ci#define TRF7970A_IRQ_STATUS_NFC_RF		BIT(2)
29762306a36Sopenharmony_ci#define TRF7970A_IRQ_STATUS_PARITY_ERROR	BIT(3)
29862306a36Sopenharmony_ci#define TRF7970A_IRQ_STATUS_NFC_SDD		BIT(3)
29962306a36Sopenharmony_ci#define TRF7970A_IRQ_STATUS_CRC_ERROR		BIT(4)
30062306a36Sopenharmony_ci#define TRF7970A_IRQ_STATUS_NFC_PROTO_ERROR	BIT(4)
30162306a36Sopenharmony_ci#define TRF7970A_IRQ_STATUS_FIFO		BIT(5)
30262306a36Sopenharmony_ci#define TRF7970A_IRQ_STATUS_SRX			BIT(6)
30362306a36Sopenharmony_ci#define TRF7970A_IRQ_STATUS_TX			BIT(7)
30462306a36Sopenharmony_ci
30562306a36Sopenharmony_ci#define TRF7970A_IRQ_STATUS_ERROR				\
30662306a36Sopenharmony_ci		(TRF7970A_IRQ_STATUS_COL |			\
30762306a36Sopenharmony_ci		 TRF7970A_IRQ_STATUS_FRAMING_EOF_ERROR |	\
30862306a36Sopenharmony_ci		 TRF7970A_IRQ_STATUS_PARITY_ERROR |		\
30962306a36Sopenharmony_ci		 TRF7970A_IRQ_STATUS_CRC_ERROR)
31062306a36Sopenharmony_ci
31162306a36Sopenharmony_ci#define TRF7970A_RSSI_OSC_STATUS_RSSI_MASK	(BIT(2) | BIT(1) | BIT(0))
31262306a36Sopenharmony_ci#define TRF7970A_RSSI_OSC_STATUS_RSSI_X_MASK	(BIT(5) | BIT(4) | BIT(3))
31362306a36Sopenharmony_ci#define TRF7970A_RSSI_OSC_STATUS_RSSI_OSC_OK	BIT(6)
31462306a36Sopenharmony_ci
31562306a36Sopenharmony_ci#define TRF7970A_SPECIAL_FCN_REG1_COL_7_6		BIT(0)
31662306a36Sopenharmony_ci#define TRF7970A_SPECIAL_FCN_REG1_14_ANTICOLL		BIT(1)
31762306a36Sopenharmony_ci#define TRF7970A_SPECIAL_FCN_REG1_4_BIT_RX		BIT(2)
31862306a36Sopenharmony_ci#define TRF7970A_SPECIAL_FCN_REG1_SP_DIR_MODE		BIT(3)
31962306a36Sopenharmony_ci#define TRF7970A_SPECIAL_FCN_REG1_NEXT_SLOT_37US	BIT(4)
32062306a36Sopenharmony_ci#define TRF7970A_SPECIAL_FCN_REG1_PAR43			BIT(5)
32162306a36Sopenharmony_ci
32262306a36Sopenharmony_ci#define TRF7970A_ADJUTABLE_FIFO_IRQ_LEVELS_WLH_124	(0x0 << 2)
32362306a36Sopenharmony_ci#define TRF7970A_ADJUTABLE_FIFO_IRQ_LEVELS_WLH_120	(0x1 << 2)
32462306a36Sopenharmony_ci#define TRF7970A_ADJUTABLE_FIFO_IRQ_LEVELS_WLH_112	(0x2 << 2)
32562306a36Sopenharmony_ci#define TRF7970A_ADJUTABLE_FIFO_IRQ_LEVELS_WLH_96	(0x3 << 2)
32662306a36Sopenharmony_ci#define TRF7970A_ADJUTABLE_FIFO_IRQ_LEVELS_WLL_4	0x0
32762306a36Sopenharmony_ci#define TRF7970A_ADJUTABLE_FIFO_IRQ_LEVELS_WLL_8	0x1
32862306a36Sopenharmony_ci#define TRF7970A_ADJUTABLE_FIFO_IRQ_LEVELS_WLL_16	0x2
32962306a36Sopenharmony_ci#define TRF7970A_ADJUTABLE_FIFO_IRQ_LEVELS_WLL_32	0x3
33062306a36Sopenharmony_ci
33162306a36Sopenharmony_ci#define TRF7970A_NFC_LOW_FIELD_LEVEL_RFDET(v)	((v) & 0x07)
33262306a36Sopenharmony_ci#define TRF7970A_NFC_LOW_FIELD_LEVEL_CLEX_DIS	BIT(7)
33362306a36Sopenharmony_ci
33462306a36Sopenharmony_ci#define TRF7970A_NFC_TARGET_LEVEL_RFDET(v)	((v) & 0x07)
33562306a36Sopenharmony_ci#define TRF7970A_NFC_TARGET_LEVEL_HI_RF		BIT(3)
33662306a36Sopenharmony_ci#define TRF7970A_NFC_TARGET_LEVEL_SDD_EN	BIT(5)
33762306a36Sopenharmony_ci#define TRF7970A_NFC_TARGET_LEVEL_LD_S_4BYTES	(0x0 << 6)
33862306a36Sopenharmony_ci#define TRF7970A_NFC_TARGET_LEVEL_LD_S_7BYTES	(0x1 << 6)
33962306a36Sopenharmony_ci#define TRF7970A_NFC_TARGET_LEVEL_LD_S_10BYTES	(0x2 << 6)
34062306a36Sopenharmony_ci
34162306a36Sopenharmony_ci#define TRF79070A_NFC_TARGET_PROTOCOL_NFCBR_106		BIT(0)
34262306a36Sopenharmony_ci#define TRF79070A_NFC_TARGET_PROTOCOL_NFCBR_212		BIT(1)
34362306a36Sopenharmony_ci#define TRF79070A_NFC_TARGET_PROTOCOL_NFCBR_424		(BIT(0) | BIT(1))
34462306a36Sopenharmony_ci#define TRF79070A_NFC_TARGET_PROTOCOL_PAS_14443B	BIT(2)
34562306a36Sopenharmony_ci#define TRF79070A_NFC_TARGET_PROTOCOL_PAS_106		BIT(3)
34662306a36Sopenharmony_ci#define TRF79070A_NFC_TARGET_PROTOCOL_FELICA		BIT(4)
34762306a36Sopenharmony_ci#define TRF79070A_NFC_TARGET_PROTOCOL_RF_L		BIT(6)
34862306a36Sopenharmony_ci#define TRF79070A_NFC_TARGET_PROTOCOL_RF_H		BIT(7)
34962306a36Sopenharmony_ci
35062306a36Sopenharmony_ci#define TRF79070A_NFC_TARGET_PROTOCOL_106A		\
35162306a36Sopenharmony_ci	 (TRF79070A_NFC_TARGET_PROTOCOL_RF_H |		\
35262306a36Sopenharmony_ci	  TRF79070A_NFC_TARGET_PROTOCOL_RF_L |		\
35362306a36Sopenharmony_ci	  TRF79070A_NFC_TARGET_PROTOCOL_PAS_106 |	\
35462306a36Sopenharmony_ci	  TRF79070A_NFC_TARGET_PROTOCOL_NFCBR_106)
35562306a36Sopenharmony_ci
35662306a36Sopenharmony_ci#define TRF79070A_NFC_TARGET_PROTOCOL_106B		\
35762306a36Sopenharmony_ci	 (TRF79070A_NFC_TARGET_PROTOCOL_RF_H |		\
35862306a36Sopenharmony_ci	  TRF79070A_NFC_TARGET_PROTOCOL_RF_L |		\
35962306a36Sopenharmony_ci	  TRF79070A_NFC_TARGET_PROTOCOL_PAS_14443B |	\
36062306a36Sopenharmony_ci	  TRF79070A_NFC_TARGET_PROTOCOL_NFCBR_106)
36162306a36Sopenharmony_ci
36262306a36Sopenharmony_ci#define TRF79070A_NFC_TARGET_PROTOCOL_212F		\
36362306a36Sopenharmony_ci	 (TRF79070A_NFC_TARGET_PROTOCOL_RF_H |		\
36462306a36Sopenharmony_ci	  TRF79070A_NFC_TARGET_PROTOCOL_RF_L |		\
36562306a36Sopenharmony_ci	  TRF79070A_NFC_TARGET_PROTOCOL_FELICA |	\
36662306a36Sopenharmony_ci	  TRF79070A_NFC_TARGET_PROTOCOL_NFCBR_212)
36762306a36Sopenharmony_ci
36862306a36Sopenharmony_ci#define TRF79070A_NFC_TARGET_PROTOCOL_424F		\
36962306a36Sopenharmony_ci	 (TRF79070A_NFC_TARGET_PROTOCOL_RF_H |		\
37062306a36Sopenharmony_ci	  TRF79070A_NFC_TARGET_PROTOCOL_RF_L |		\
37162306a36Sopenharmony_ci	  TRF79070A_NFC_TARGET_PROTOCOL_FELICA |	\
37262306a36Sopenharmony_ci	  TRF79070A_NFC_TARGET_PROTOCOL_NFCBR_424)
37362306a36Sopenharmony_ci
37462306a36Sopenharmony_ci#define TRF7970A_FIFO_STATUS_OVERFLOW		BIT(7)
37562306a36Sopenharmony_ci
37662306a36Sopenharmony_ci/* NFC (ISO/IEC 14443A) Type 2 Tag commands */
37762306a36Sopenharmony_ci#define NFC_T2T_CMD_READ			0x30
37862306a36Sopenharmony_ci
37962306a36Sopenharmony_ci/* ISO 15693 commands codes */
38062306a36Sopenharmony_ci#define ISO15693_CMD_INVENTORY			0x01
38162306a36Sopenharmony_ci#define ISO15693_CMD_READ_SINGLE_BLOCK		0x20
38262306a36Sopenharmony_ci#define ISO15693_CMD_WRITE_SINGLE_BLOCK		0x21
38362306a36Sopenharmony_ci#define ISO15693_CMD_LOCK_BLOCK			0x22
38462306a36Sopenharmony_ci#define ISO15693_CMD_READ_MULTIPLE_BLOCK	0x23
38562306a36Sopenharmony_ci#define ISO15693_CMD_WRITE_MULTIPLE_BLOCK	0x24
38662306a36Sopenharmony_ci#define ISO15693_CMD_SELECT			0x25
38762306a36Sopenharmony_ci#define ISO15693_CMD_RESET_TO_READY		0x26
38862306a36Sopenharmony_ci#define ISO15693_CMD_WRITE_AFI			0x27
38962306a36Sopenharmony_ci#define ISO15693_CMD_LOCK_AFI			0x28
39062306a36Sopenharmony_ci#define ISO15693_CMD_WRITE_DSFID		0x29
39162306a36Sopenharmony_ci#define ISO15693_CMD_LOCK_DSFID			0x2a
39262306a36Sopenharmony_ci#define ISO15693_CMD_GET_SYSTEM_INFO		0x2b
39362306a36Sopenharmony_ci#define ISO15693_CMD_GET_MULTIPLE_BLOCK_SECURITY_STATUS	0x2c
39462306a36Sopenharmony_ci
39562306a36Sopenharmony_ci/* ISO 15693 request and response flags */
39662306a36Sopenharmony_ci#define ISO15693_REQ_FLAG_SUB_CARRIER		BIT(0)
39762306a36Sopenharmony_ci#define ISO15693_REQ_FLAG_DATA_RATE		BIT(1)
39862306a36Sopenharmony_ci#define ISO15693_REQ_FLAG_INVENTORY		BIT(2)
39962306a36Sopenharmony_ci#define ISO15693_REQ_FLAG_PROTOCOL_EXT		BIT(3)
40062306a36Sopenharmony_ci#define ISO15693_REQ_FLAG_SELECT		BIT(4)
40162306a36Sopenharmony_ci#define ISO15693_REQ_FLAG_AFI			BIT(4)
40262306a36Sopenharmony_ci#define ISO15693_REQ_FLAG_ADDRESS		BIT(5)
40362306a36Sopenharmony_ci#define ISO15693_REQ_FLAG_NB_SLOTS		BIT(5)
40462306a36Sopenharmony_ci#define ISO15693_REQ_FLAG_OPTION		BIT(6)
40562306a36Sopenharmony_ci
40662306a36Sopenharmony_ci#define ISO15693_REQ_FLAG_SPEED_MASK \
40762306a36Sopenharmony_ci		(ISO15693_REQ_FLAG_SUB_CARRIER | ISO15693_REQ_FLAG_DATA_RATE)
40862306a36Sopenharmony_ci
40962306a36Sopenharmony_cienum trf7970a_state {
41062306a36Sopenharmony_ci	TRF7970A_ST_PWR_OFF,
41162306a36Sopenharmony_ci	TRF7970A_ST_RF_OFF,
41262306a36Sopenharmony_ci	TRF7970A_ST_IDLE,
41362306a36Sopenharmony_ci	TRF7970A_ST_IDLE_RX_BLOCKED,
41462306a36Sopenharmony_ci	TRF7970A_ST_WAIT_FOR_TX_FIFO,
41562306a36Sopenharmony_ci	TRF7970A_ST_WAIT_FOR_RX_DATA,
41662306a36Sopenharmony_ci	TRF7970A_ST_WAIT_FOR_RX_DATA_CONT,
41762306a36Sopenharmony_ci	TRF7970A_ST_WAIT_TO_ISSUE_EOF,
41862306a36Sopenharmony_ci	TRF7970A_ST_LISTENING,
41962306a36Sopenharmony_ci	TRF7970A_ST_LISTENING_MD,
42062306a36Sopenharmony_ci	TRF7970A_ST_MAX
42162306a36Sopenharmony_ci};
42262306a36Sopenharmony_ci
42362306a36Sopenharmony_cistruct trf7970a {
42462306a36Sopenharmony_ci	enum trf7970a_state		state;
42562306a36Sopenharmony_ci	struct device			*dev;
42662306a36Sopenharmony_ci	struct spi_device		*spi;
42762306a36Sopenharmony_ci	struct regulator		*regulator;
42862306a36Sopenharmony_ci	struct nfc_digital_dev		*ddev;
42962306a36Sopenharmony_ci	u32				quirks;
43062306a36Sopenharmony_ci	bool				is_initiator;
43162306a36Sopenharmony_ci	bool				aborting;
43262306a36Sopenharmony_ci	struct sk_buff			*tx_skb;
43362306a36Sopenharmony_ci	struct sk_buff			*rx_skb;
43462306a36Sopenharmony_ci	nfc_digital_cmd_complete_t	cb;
43562306a36Sopenharmony_ci	void				*cb_arg;
43662306a36Sopenharmony_ci	u8				chip_status_ctrl;
43762306a36Sopenharmony_ci	u8				iso_ctrl;
43862306a36Sopenharmony_ci	u8				iso_ctrl_tech;
43962306a36Sopenharmony_ci	u8				modulator_sys_clk_ctrl;
44062306a36Sopenharmony_ci	u8				special_fcn_reg1;
44162306a36Sopenharmony_ci	u8				io_ctrl;
44262306a36Sopenharmony_ci	unsigned int			guard_time;
44362306a36Sopenharmony_ci	int				technology;
44462306a36Sopenharmony_ci	int				framing;
44562306a36Sopenharmony_ci	u8				md_rf_tech;
44662306a36Sopenharmony_ci	u8				tx_cmd;
44762306a36Sopenharmony_ci	bool				issue_eof;
44862306a36Sopenharmony_ci	struct gpio_desc		*en_gpiod;
44962306a36Sopenharmony_ci	struct gpio_desc		*en2_gpiod;
45062306a36Sopenharmony_ci	struct mutex			lock;
45162306a36Sopenharmony_ci	unsigned int			timeout;
45262306a36Sopenharmony_ci	bool				ignore_timeout;
45362306a36Sopenharmony_ci	struct delayed_work		timeout_work;
45462306a36Sopenharmony_ci};
45562306a36Sopenharmony_ci
45662306a36Sopenharmony_cistatic int trf7970a_cmd(struct trf7970a *trf, u8 opcode)
45762306a36Sopenharmony_ci{
45862306a36Sopenharmony_ci	u8 cmd = TRF7970A_CMD_BIT_CTRL | TRF7970A_CMD_BIT_OPCODE(opcode);
45962306a36Sopenharmony_ci	int ret;
46062306a36Sopenharmony_ci
46162306a36Sopenharmony_ci	dev_dbg(trf->dev, "cmd: 0x%x\n", cmd);
46262306a36Sopenharmony_ci
46362306a36Sopenharmony_ci	ret = spi_write(trf->spi, &cmd, 1);
46462306a36Sopenharmony_ci	if (ret)
46562306a36Sopenharmony_ci		dev_err(trf->dev, "%s - cmd: 0x%x, ret: %d\n", __func__, cmd,
46662306a36Sopenharmony_ci			ret);
46762306a36Sopenharmony_ci	return ret;
46862306a36Sopenharmony_ci}
46962306a36Sopenharmony_ci
47062306a36Sopenharmony_cistatic int trf7970a_read(struct trf7970a *trf, u8 reg, u8 *val)
47162306a36Sopenharmony_ci{
47262306a36Sopenharmony_ci	u8 addr = TRF7970A_CMD_BIT_RW | reg;
47362306a36Sopenharmony_ci	int ret;
47462306a36Sopenharmony_ci
47562306a36Sopenharmony_ci	ret = spi_write_then_read(trf->spi, &addr, 1, val, 1);
47662306a36Sopenharmony_ci	if (ret)
47762306a36Sopenharmony_ci		dev_err(trf->dev, "%s - addr: 0x%x, ret: %d\n", __func__, addr,
47862306a36Sopenharmony_ci			ret);
47962306a36Sopenharmony_ci
48062306a36Sopenharmony_ci	dev_dbg(trf->dev, "read(0x%x): 0x%x\n", addr, *val);
48162306a36Sopenharmony_ci
48262306a36Sopenharmony_ci	return ret;
48362306a36Sopenharmony_ci}
48462306a36Sopenharmony_ci
48562306a36Sopenharmony_cistatic int trf7970a_read_cont(struct trf7970a *trf, u8 reg, u8 *buf,
48662306a36Sopenharmony_ci			      size_t len)
48762306a36Sopenharmony_ci{
48862306a36Sopenharmony_ci	u8 addr = reg | TRF7970A_CMD_BIT_RW | TRF7970A_CMD_BIT_CONTINUOUS;
48962306a36Sopenharmony_ci	struct spi_transfer t[2];
49062306a36Sopenharmony_ci	struct spi_message m;
49162306a36Sopenharmony_ci	int ret;
49262306a36Sopenharmony_ci
49362306a36Sopenharmony_ci	dev_dbg(trf->dev, "read_cont(0x%x, %zd)\n", addr, len);
49462306a36Sopenharmony_ci
49562306a36Sopenharmony_ci	spi_message_init(&m);
49662306a36Sopenharmony_ci
49762306a36Sopenharmony_ci	memset(&t, 0, sizeof(t));
49862306a36Sopenharmony_ci
49962306a36Sopenharmony_ci	t[0].tx_buf = &addr;
50062306a36Sopenharmony_ci	t[0].len = sizeof(addr);
50162306a36Sopenharmony_ci	spi_message_add_tail(&t[0], &m);
50262306a36Sopenharmony_ci
50362306a36Sopenharmony_ci	t[1].rx_buf = buf;
50462306a36Sopenharmony_ci	t[1].len = len;
50562306a36Sopenharmony_ci	spi_message_add_tail(&t[1], &m);
50662306a36Sopenharmony_ci
50762306a36Sopenharmony_ci	ret = spi_sync(trf->spi, &m);
50862306a36Sopenharmony_ci	if (ret)
50962306a36Sopenharmony_ci		dev_err(trf->dev, "%s - addr: 0x%x, ret: %d\n", __func__, addr,
51062306a36Sopenharmony_ci			ret);
51162306a36Sopenharmony_ci	return ret;
51262306a36Sopenharmony_ci}
51362306a36Sopenharmony_ci
51462306a36Sopenharmony_cistatic int trf7970a_write(struct trf7970a *trf, u8 reg, u8 val)
51562306a36Sopenharmony_ci{
51662306a36Sopenharmony_ci	u8 buf[2] = { reg, val };
51762306a36Sopenharmony_ci	int ret;
51862306a36Sopenharmony_ci
51962306a36Sopenharmony_ci	dev_dbg(trf->dev, "write(0x%x): 0x%x\n", reg, val);
52062306a36Sopenharmony_ci
52162306a36Sopenharmony_ci	ret = spi_write(trf->spi, buf, 2);
52262306a36Sopenharmony_ci	if (ret)
52362306a36Sopenharmony_ci		dev_err(trf->dev, "%s - write: 0x%x 0x%x, ret: %d\n", __func__,
52462306a36Sopenharmony_ci			buf[0], buf[1], ret);
52562306a36Sopenharmony_ci
52662306a36Sopenharmony_ci	return ret;
52762306a36Sopenharmony_ci}
52862306a36Sopenharmony_ci
52962306a36Sopenharmony_cistatic int trf7970a_read_irqstatus(struct trf7970a *trf, u8 *status)
53062306a36Sopenharmony_ci{
53162306a36Sopenharmony_ci	int ret;
53262306a36Sopenharmony_ci	u8 buf[2];
53362306a36Sopenharmony_ci	u8 addr;
53462306a36Sopenharmony_ci
53562306a36Sopenharmony_ci	addr = TRF7970A_IRQ_STATUS | TRF7970A_CMD_BIT_RW;
53662306a36Sopenharmony_ci
53762306a36Sopenharmony_ci	if (trf->quirks & TRF7970A_QUIRK_IRQ_STATUS_READ) {
53862306a36Sopenharmony_ci		addr |= TRF7970A_CMD_BIT_CONTINUOUS;
53962306a36Sopenharmony_ci		ret = spi_write_then_read(trf->spi, &addr, 1, buf, 2);
54062306a36Sopenharmony_ci	} else {
54162306a36Sopenharmony_ci		ret = spi_write_then_read(trf->spi, &addr, 1, buf, 1);
54262306a36Sopenharmony_ci	}
54362306a36Sopenharmony_ci
54462306a36Sopenharmony_ci	if (ret)
54562306a36Sopenharmony_ci		dev_err(trf->dev, "%s - irqstatus: Status read failed: %d\n",
54662306a36Sopenharmony_ci			__func__, ret);
54762306a36Sopenharmony_ci	else
54862306a36Sopenharmony_ci		*status = buf[0];
54962306a36Sopenharmony_ci
55062306a36Sopenharmony_ci	return ret;
55162306a36Sopenharmony_ci}
55262306a36Sopenharmony_ci
55362306a36Sopenharmony_cistatic int trf7970a_read_target_proto(struct trf7970a *trf, u8 *target_proto)
55462306a36Sopenharmony_ci{
55562306a36Sopenharmony_ci	int ret;
55662306a36Sopenharmony_ci	u8 buf[2];
55762306a36Sopenharmony_ci	u8 addr;
55862306a36Sopenharmony_ci
55962306a36Sopenharmony_ci	addr = TRF79070A_NFC_TARGET_PROTOCOL | TRF7970A_CMD_BIT_RW |
56062306a36Sopenharmony_ci	       TRF7970A_CMD_BIT_CONTINUOUS;
56162306a36Sopenharmony_ci
56262306a36Sopenharmony_ci	ret = spi_write_then_read(trf->spi, &addr, 1, buf, 2);
56362306a36Sopenharmony_ci	if (ret)
56462306a36Sopenharmony_ci		dev_err(trf->dev, "%s - target_proto: Read failed: %d\n",
56562306a36Sopenharmony_ci			__func__, ret);
56662306a36Sopenharmony_ci	else
56762306a36Sopenharmony_ci		*target_proto = buf[0];
56862306a36Sopenharmony_ci
56962306a36Sopenharmony_ci	return ret;
57062306a36Sopenharmony_ci}
57162306a36Sopenharmony_ci
57262306a36Sopenharmony_cistatic int trf7970a_mode_detect(struct trf7970a *trf, u8 *rf_tech)
57362306a36Sopenharmony_ci{
57462306a36Sopenharmony_ci	int ret;
57562306a36Sopenharmony_ci	u8 target_proto, tech;
57662306a36Sopenharmony_ci
57762306a36Sopenharmony_ci	ret = trf7970a_read_target_proto(trf, &target_proto);
57862306a36Sopenharmony_ci	if (ret)
57962306a36Sopenharmony_ci		return ret;
58062306a36Sopenharmony_ci
58162306a36Sopenharmony_ci	switch (target_proto) {
58262306a36Sopenharmony_ci	case TRF79070A_NFC_TARGET_PROTOCOL_106A:
58362306a36Sopenharmony_ci		tech = NFC_DIGITAL_RF_TECH_106A;
58462306a36Sopenharmony_ci		break;
58562306a36Sopenharmony_ci	case TRF79070A_NFC_TARGET_PROTOCOL_106B:
58662306a36Sopenharmony_ci		tech = NFC_DIGITAL_RF_TECH_106B;
58762306a36Sopenharmony_ci		break;
58862306a36Sopenharmony_ci	case TRF79070A_NFC_TARGET_PROTOCOL_212F:
58962306a36Sopenharmony_ci		tech = NFC_DIGITAL_RF_TECH_212F;
59062306a36Sopenharmony_ci		break;
59162306a36Sopenharmony_ci	case TRF79070A_NFC_TARGET_PROTOCOL_424F:
59262306a36Sopenharmony_ci		tech = NFC_DIGITAL_RF_TECH_424F;
59362306a36Sopenharmony_ci		break;
59462306a36Sopenharmony_ci	default:
59562306a36Sopenharmony_ci		dev_dbg(trf->dev, "%s - mode_detect: target_proto: 0x%x\n",
59662306a36Sopenharmony_ci			__func__, target_proto);
59762306a36Sopenharmony_ci		return -EIO;
59862306a36Sopenharmony_ci	}
59962306a36Sopenharmony_ci
60062306a36Sopenharmony_ci	*rf_tech = tech;
60162306a36Sopenharmony_ci
60262306a36Sopenharmony_ci	return ret;
60362306a36Sopenharmony_ci}
60462306a36Sopenharmony_ci
60562306a36Sopenharmony_cistatic void trf7970a_send_upstream(struct trf7970a *trf)
60662306a36Sopenharmony_ci{
60762306a36Sopenharmony_ci	dev_kfree_skb_any(trf->tx_skb);
60862306a36Sopenharmony_ci	trf->tx_skb = NULL;
60962306a36Sopenharmony_ci
61062306a36Sopenharmony_ci	if (trf->rx_skb && !IS_ERR(trf->rx_skb) && !trf->aborting)
61162306a36Sopenharmony_ci		print_hex_dump_debug("trf7970a rx data: ", DUMP_PREFIX_NONE,
61262306a36Sopenharmony_ci				     16, 1, trf->rx_skb->data, trf->rx_skb->len,
61362306a36Sopenharmony_ci				     false);
61462306a36Sopenharmony_ci
61562306a36Sopenharmony_ci	trf->state = TRF7970A_ST_IDLE;
61662306a36Sopenharmony_ci
61762306a36Sopenharmony_ci	if (trf->aborting) {
61862306a36Sopenharmony_ci		dev_dbg(trf->dev, "Abort process complete\n");
61962306a36Sopenharmony_ci
62062306a36Sopenharmony_ci		if (!IS_ERR(trf->rx_skb)) {
62162306a36Sopenharmony_ci			kfree_skb(trf->rx_skb);
62262306a36Sopenharmony_ci			trf->rx_skb = ERR_PTR(-ECANCELED);
62362306a36Sopenharmony_ci		}
62462306a36Sopenharmony_ci
62562306a36Sopenharmony_ci		trf->aborting = false;
62662306a36Sopenharmony_ci	}
62762306a36Sopenharmony_ci
62862306a36Sopenharmony_ci	trf->cb(trf->ddev, trf->cb_arg, trf->rx_skb);
62962306a36Sopenharmony_ci
63062306a36Sopenharmony_ci	trf->rx_skb = NULL;
63162306a36Sopenharmony_ci}
63262306a36Sopenharmony_ci
63362306a36Sopenharmony_cistatic void trf7970a_send_err_upstream(struct trf7970a *trf, int errno)
63462306a36Sopenharmony_ci{
63562306a36Sopenharmony_ci	dev_dbg(trf->dev, "Error - state: %d, errno: %d\n", trf->state, errno);
63662306a36Sopenharmony_ci
63762306a36Sopenharmony_ci	cancel_delayed_work(&trf->timeout_work);
63862306a36Sopenharmony_ci
63962306a36Sopenharmony_ci	kfree_skb(trf->rx_skb);
64062306a36Sopenharmony_ci	trf->rx_skb = ERR_PTR(errno);
64162306a36Sopenharmony_ci
64262306a36Sopenharmony_ci	trf7970a_send_upstream(trf);
64362306a36Sopenharmony_ci}
64462306a36Sopenharmony_ci
64562306a36Sopenharmony_cistatic int trf7970a_transmit(struct trf7970a *trf, struct sk_buff *skb,
64662306a36Sopenharmony_ci			     unsigned int len, const u8 *prefix,
64762306a36Sopenharmony_ci			     unsigned int prefix_len)
64862306a36Sopenharmony_ci{
64962306a36Sopenharmony_ci	struct spi_transfer t[2];
65062306a36Sopenharmony_ci	struct spi_message m;
65162306a36Sopenharmony_ci	unsigned int timeout;
65262306a36Sopenharmony_ci	int ret;
65362306a36Sopenharmony_ci
65462306a36Sopenharmony_ci	print_hex_dump_debug("trf7970a tx data: ", DUMP_PREFIX_NONE,
65562306a36Sopenharmony_ci			     16, 1, skb->data, len, false);
65662306a36Sopenharmony_ci
65762306a36Sopenharmony_ci	spi_message_init(&m);
65862306a36Sopenharmony_ci
65962306a36Sopenharmony_ci	memset(&t, 0, sizeof(t));
66062306a36Sopenharmony_ci
66162306a36Sopenharmony_ci	t[0].tx_buf = prefix;
66262306a36Sopenharmony_ci	t[0].len = prefix_len;
66362306a36Sopenharmony_ci	spi_message_add_tail(&t[0], &m);
66462306a36Sopenharmony_ci
66562306a36Sopenharmony_ci	t[1].tx_buf = skb->data;
66662306a36Sopenharmony_ci	t[1].len = len;
66762306a36Sopenharmony_ci	spi_message_add_tail(&t[1], &m);
66862306a36Sopenharmony_ci
66962306a36Sopenharmony_ci	ret = spi_sync(trf->spi, &m);
67062306a36Sopenharmony_ci	if (ret) {
67162306a36Sopenharmony_ci		dev_err(trf->dev, "%s - Can't send tx data: %d\n", __func__,
67262306a36Sopenharmony_ci			ret);
67362306a36Sopenharmony_ci		return ret;
67462306a36Sopenharmony_ci	}
67562306a36Sopenharmony_ci
67662306a36Sopenharmony_ci	skb_pull(skb, len);
67762306a36Sopenharmony_ci
67862306a36Sopenharmony_ci	if (skb->len > 0) {
67962306a36Sopenharmony_ci		trf->state = TRF7970A_ST_WAIT_FOR_TX_FIFO;
68062306a36Sopenharmony_ci		timeout = TRF7970A_WAIT_FOR_FIFO_DRAIN_TIMEOUT;
68162306a36Sopenharmony_ci	} else {
68262306a36Sopenharmony_ci		if (trf->issue_eof) {
68362306a36Sopenharmony_ci			trf->state = TRF7970A_ST_WAIT_TO_ISSUE_EOF;
68462306a36Sopenharmony_ci			timeout = TRF7970A_WAIT_TO_ISSUE_ISO15693_EOF;
68562306a36Sopenharmony_ci		} else {
68662306a36Sopenharmony_ci			trf->state = TRF7970A_ST_WAIT_FOR_RX_DATA;
68762306a36Sopenharmony_ci
68862306a36Sopenharmony_ci			if (!trf->timeout)
68962306a36Sopenharmony_ci				timeout = TRF7970A_WAIT_FOR_TX_IRQ;
69062306a36Sopenharmony_ci			else
69162306a36Sopenharmony_ci				timeout = trf->timeout;
69262306a36Sopenharmony_ci		}
69362306a36Sopenharmony_ci	}
69462306a36Sopenharmony_ci
69562306a36Sopenharmony_ci	dev_dbg(trf->dev, "Setting timeout for %d ms, state: %d\n", timeout,
69662306a36Sopenharmony_ci		trf->state);
69762306a36Sopenharmony_ci
69862306a36Sopenharmony_ci	schedule_delayed_work(&trf->timeout_work, msecs_to_jiffies(timeout));
69962306a36Sopenharmony_ci
70062306a36Sopenharmony_ci	return 0;
70162306a36Sopenharmony_ci}
70262306a36Sopenharmony_ci
70362306a36Sopenharmony_cistatic void trf7970a_fill_fifo(struct trf7970a *trf)
70462306a36Sopenharmony_ci{
70562306a36Sopenharmony_ci	struct sk_buff *skb = trf->tx_skb;
70662306a36Sopenharmony_ci	unsigned int len;
70762306a36Sopenharmony_ci	int ret;
70862306a36Sopenharmony_ci	u8 fifo_bytes;
70962306a36Sopenharmony_ci	u8 prefix;
71062306a36Sopenharmony_ci
71162306a36Sopenharmony_ci	ret = trf7970a_read(trf, TRF7970A_FIFO_STATUS, &fifo_bytes);
71262306a36Sopenharmony_ci	if (ret) {
71362306a36Sopenharmony_ci		trf7970a_send_err_upstream(trf, ret);
71462306a36Sopenharmony_ci		return;
71562306a36Sopenharmony_ci	}
71662306a36Sopenharmony_ci
71762306a36Sopenharmony_ci	dev_dbg(trf->dev, "Filling FIFO - fifo_bytes: 0x%x\n", fifo_bytes);
71862306a36Sopenharmony_ci
71962306a36Sopenharmony_ci	fifo_bytes &= ~TRF7970A_FIFO_STATUS_OVERFLOW;
72062306a36Sopenharmony_ci
72162306a36Sopenharmony_ci	/* Calculate how much more data can be written to the fifo */
72262306a36Sopenharmony_ci	len = TRF7970A_FIFO_SIZE - fifo_bytes;
72362306a36Sopenharmony_ci	if (!len) {
72462306a36Sopenharmony_ci		schedule_delayed_work(&trf->timeout_work,
72562306a36Sopenharmony_ci			msecs_to_jiffies(TRF7970A_WAIT_FOR_FIFO_DRAIN_TIMEOUT));
72662306a36Sopenharmony_ci		return;
72762306a36Sopenharmony_ci	}
72862306a36Sopenharmony_ci
72962306a36Sopenharmony_ci	len = min(skb->len, len);
73062306a36Sopenharmony_ci
73162306a36Sopenharmony_ci	prefix = TRF7970A_CMD_BIT_CONTINUOUS | TRF7970A_FIFO_IO_REGISTER;
73262306a36Sopenharmony_ci
73362306a36Sopenharmony_ci	ret = trf7970a_transmit(trf, skb, len, &prefix, sizeof(prefix));
73462306a36Sopenharmony_ci	if (ret)
73562306a36Sopenharmony_ci		trf7970a_send_err_upstream(trf, ret);
73662306a36Sopenharmony_ci}
73762306a36Sopenharmony_ci
73862306a36Sopenharmony_cistatic void trf7970a_drain_fifo(struct trf7970a *trf, u8 status)
73962306a36Sopenharmony_ci{
74062306a36Sopenharmony_ci	struct sk_buff *skb = trf->rx_skb;
74162306a36Sopenharmony_ci	int ret;
74262306a36Sopenharmony_ci	u8 fifo_bytes;
74362306a36Sopenharmony_ci
74462306a36Sopenharmony_ci	if (status & TRF7970A_IRQ_STATUS_ERROR) {
74562306a36Sopenharmony_ci		trf7970a_send_err_upstream(trf, -EIO);
74662306a36Sopenharmony_ci		return;
74762306a36Sopenharmony_ci	}
74862306a36Sopenharmony_ci
74962306a36Sopenharmony_ci	ret = trf7970a_read(trf, TRF7970A_FIFO_STATUS, &fifo_bytes);
75062306a36Sopenharmony_ci	if (ret) {
75162306a36Sopenharmony_ci		trf7970a_send_err_upstream(trf, ret);
75262306a36Sopenharmony_ci		return;
75362306a36Sopenharmony_ci	}
75462306a36Sopenharmony_ci
75562306a36Sopenharmony_ci	dev_dbg(trf->dev, "Draining FIFO - fifo_bytes: 0x%x\n", fifo_bytes);
75662306a36Sopenharmony_ci
75762306a36Sopenharmony_ci	fifo_bytes &= ~TRF7970A_FIFO_STATUS_OVERFLOW;
75862306a36Sopenharmony_ci
75962306a36Sopenharmony_ci	if (!fifo_bytes)
76062306a36Sopenharmony_ci		goto no_rx_data;
76162306a36Sopenharmony_ci
76262306a36Sopenharmony_ci	if (fifo_bytes > skb_tailroom(skb)) {
76362306a36Sopenharmony_ci		skb = skb_copy_expand(skb, skb_headroom(skb),
76462306a36Sopenharmony_ci				      max_t(int, fifo_bytes,
76562306a36Sopenharmony_ci					    TRF7970A_RX_SKB_ALLOC_SIZE),
76662306a36Sopenharmony_ci				      GFP_KERNEL);
76762306a36Sopenharmony_ci		if (!skb) {
76862306a36Sopenharmony_ci			trf7970a_send_err_upstream(trf, -ENOMEM);
76962306a36Sopenharmony_ci			return;
77062306a36Sopenharmony_ci		}
77162306a36Sopenharmony_ci
77262306a36Sopenharmony_ci		kfree_skb(trf->rx_skb);
77362306a36Sopenharmony_ci		trf->rx_skb = skb;
77462306a36Sopenharmony_ci	}
77562306a36Sopenharmony_ci
77662306a36Sopenharmony_ci	ret = trf7970a_read_cont(trf, TRF7970A_FIFO_IO_REGISTER,
77762306a36Sopenharmony_ci				 skb_put(skb, fifo_bytes), fifo_bytes);
77862306a36Sopenharmony_ci	if (ret) {
77962306a36Sopenharmony_ci		trf7970a_send_err_upstream(trf, ret);
78062306a36Sopenharmony_ci		return;
78162306a36Sopenharmony_ci	}
78262306a36Sopenharmony_ci
78362306a36Sopenharmony_ci	/* If received Type 2 ACK/NACK, shift right 4 bits and pass up */
78462306a36Sopenharmony_ci	if ((trf->framing == NFC_DIGITAL_FRAMING_NFCA_T2T) && (skb->len == 1) &&
78562306a36Sopenharmony_ci	    (trf->special_fcn_reg1 == TRF7970A_SPECIAL_FCN_REG1_4_BIT_RX)) {
78662306a36Sopenharmony_ci		skb->data[0] >>= 4;
78762306a36Sopenharmony_ci		status = TRF7970A_IRQ_STATUS_SRX;
78862306a36Sopenharmony_ci	} else {
78962306a36Sopenharmony_ci		trf->state = TRF7970A_ST_WAIT_FOR_RX_DATA_CONT;
79062306a36Sopenharmony_ci
79162306a36Sopenharmony_ci		ret = trf7970a_read(trf, TRF7970A_FIFO_STATUS, &fifo_bytes);
79262306a36Sopenharmony_ci		if (ret) {
79362306a36Sopenharmony_ci			trf7970a_send_err_upstream(trf, ret);
79462306a36Sopenharmony_ci			return;
79562306a36Sopenharmony_ci		}
79662306a36Sopenharmony_ci
79762306a36Sopenharmony_ci		fifo_bytes &= ~TRF7970A_FIFO_STATUS_OVERFLOW;
79862306a36Sopenharmony_ci
79962306a36Sopenharmony_ci		/* If there are bytes in the FIFO, set status to '0' so
80062306a36Sopenharmony_ci		 * the if stmt below doesn't fire and the driver will wait
80162306a36Sopenharmony_ci		 * for the trf7970a to generate another RX interrupt.
80262306a36Sopenharmony_ci		 */
80362306a36Sopenharmony_ci		if (fifo_bytes)
80462306a36Sopenharmony_ci			status = 0;
80562306a36Sopenharmony_ci	}
80662306a36Sopenharmony_ci
80762306a36Sopenharmony_cino_rx_data:
80862306a36Sopenharmony_ci	if (status == TRF7970A_IRQ_STATUS_SRX) {	/* Receive complete */
80962306a36Sopenharmony_ci		trf7970a_send_upstream(trf);
81062306a36Sopenharmony_ci		return;
81162306a36Sopenharmony_ci	}
81262306a36Sopenharmony_ci
81362306a36Sopenharmony_ci	dev_dbg(trf->dev, "Setting timeout for %d ms\n",
81462306a36Sopenharmony_ci		TRF7970A_WAIT_FOR_RX_DATA_TIMEOUT);
81562306a36Sopenharmony_ci
81662306a36Sopenharmony_ci	schedule_delayed_work(&trf->timeout_work,
81762306a36Sopenharmony_ci			   msecs_to_jiffies(TRF7970A_WAIT_FOR_RX_DATA_TIMEOUT));
81862306a36Sopenharmony_ci}
81962306a36Sopenharmony_ci
82062306a36Sopenharmony_cistatic irqreturn_t trf7970a_irq(int irq, void *dev_id)
82162306a36Sopenharmony_ci{
82262306a36Sopenharmony_ci	struct trf7970a *trf = dev_id;
82362306a36Sopenharmony_ci	int ret;
82462306a36Sopenharmony_ci	u8 status, fifo_bytes, iso_ctrl;
82562306a36Sopenharmony_ci
82662306a36Sopenharmony_ci	mutex_lock(&trf->lock);
82762306a36Sopenharmony_ci
82862306a36Sopenharmony_ci	if (trf->state == TRF7970A_ST_RF_OFF) {
82962306a36Sopenharmony_ci		mutex_unlock(&trf->lock);
83062306a36Sopenharmony_ci		return IRQ_NONE;
83162306a36Sopenharmony_ci	}
83262306a36Sopenharmony_ci
83362306a36Sopenharmony_ci	ret = trf7970a_read_irqstatus(trf, &status);
83462306a36Sopenharmony_ci	if (ret) {
83562306a36Sopenharmony_ci		mutex_unlock(&trf->lock);
83662306a36Sopenharmony_ci		return IRQ_NONE;
83762306a36Sopenharmony_ci	}
83862306a36Sopenharmony_ci
83962306a36Sopenharmony_ci	dev_dbg(trf->dev, "IRQ - state: %d, status: 0x%x\n", trf->state,
84062306a36Sopenharmony_ci		status);
84162306a36Sopenharmony_ci
84262306a36Sopenharmony_ci	if (!status) {
84362306a36Sopenharmony_ci		mutex_unlock(&trf->lock);
84462306a36Sopenharmony_ci		return IRQ_NONE;
84562306a36Sopenharmony_ci	}
84662306a36Sopenharmony_ci
84762306a36Sopenharmony_ci	switch (trf->state) {
84862306a36Sopenharmony_ci	case TRF7970A_ST_IDLE:
84962306a36Sopenharmony_ci	case TRF7970A_ST_IDLE_RX_BLOCKED:
85062306a36Sopenharmony_ci		/* If initiator and getting interrupts caused by RF noise,
85162306a36Sopenharmony_ci		 * turn off the receiver to avoid unnecessary interrupts.
85262306a36Sopenharmony_ci		 * It will be turned back on in trf7970a_send_cmd() when
85362306a36Sopenharmony_ci		 * the next command is issued.
85462306a36Sopenharmony_ci		 */
85562306a36Sopenharmony_ci		if (trf->is_initiator && (status & TRF7970A_IRQ_STATUS_ERROR)) {
85662306a36Sopenharmony_ci			trf7970a_cmd(trf, TRF7970A_CMD_BLOCK_RX);
85762306a36Sopenharmony_ci			trf->state = TRF7970A_ST_IDLE_RX_BLOCKED;
85862306a36Sopenharmony_ci		}
85962306a36Sopenharmony_ci
86062306a36Sopenharmony_ci		trf7970a_cmd(trf, TRF7970A_CMD_FIFO_RESET);
86162306a36Sopenharmony_ci		break;
86262306a36Sopenharmony_ci	case TRF7970A_ST_WAIT_FOR_TX_FIFO:
86362306a36Sopenharmony_ci		if (status & TRF7970A_IRQ_STATUS_TX) {
86462306a36Sopenharmony_ci			trf->ignore_timeout =
86562306a36Sopenharmony_ci			    !cancel_delayed_work(&trf->timeout_work);
86662306a36Sopenharmony_ci			trf7970a_fill_fifo(trf);
86762306a36Sopenharmony_ci		} else {
86862306a36Sopenharmony_ci			trf7970a_send_err_upstream(trf, -EIO);
86962306a36Sopenharmony_ci		}
87062306a36Sopenharmony_ci		break;
87162306a36Sopenharmony_ci	case TRF7970A_ST_WAIT_FOR_RX_DATA:
87262306a36Sopenharmony_ci	case TRF7970A_ST_WAIT_FOR_RX_DATA_CONT:
87362306a36Sopenharmony_ci		if (status & TRF7970A_IRQ_STATUS_SRX) {
87462306a36Sopenharmony_ci			trf->ignore_timeout =
87562306a36Sopenharmony_ci			    !cancel_delayed_work(&trf->timeout_work);
87662306a36Sopenharmony_ci			trf7970a_drain_fifo(trf, status);
87762306a36Sopenharmony_ci		} else if (status & TRF7970A_IRQ_STATUS_FIFO) {
87862306a36Sopenharmony_ci			ret = trf7970a_read(trf, TRF7970A_FIFO_STATUS,
87962306a36Sopenharmony_ci					    &fifo_bytes);
88062306a36Sopenharmony_ci
88162306a36Sopenharmony_ci			fifo_bytes &= ~TRF7970A_FIFO_STATUS_OVERFLOW;
88262306a36Sopenharmony_ci
88362306a36Sopenharmony_ci			if (ret)
88462306a36Sopenharmony_ci				trf7970a_send_err_upstream(trf, ret);
88562306a36Sopenharmony_ci			else if (!fifo_bytes)
88662306a36Sopenharmony_ci				trf7970a_cmd(trf, TRF7970A_CMD_FIFO_RESET);
88762306a36Sopenharmony_ci		} else if ((status == TRF7970A_IRQ_STATUS_TX) ||
88862306a36Sopenharmony_ci			   (!trf->is_initiator &&
88962306a36Sopenharmony_ci			    (status == (TRF7970A_IRQ_STATUS_TX |
89062306a36Sopenharmony_ci					TRF7970A_IRQ_STATUS_NFC_RF)))) {
89162306a36Sopenharmony_ci			trf7970a_cmd(trf, TRF7970A_CMD_FIFO_RESET);
89262306a36Sopenharmony_ci
89362306a36Sopenharmony_ci			if (!trf->timeout) {
89462306a36Sopenharmony_ci				trf->ignore_timeout =
89562306a36Sopenharmony_ci				    !cancel_delayed_work(&trf->timeout_work);
89662306a36Sopenharmony_ci				trf->rx_skb = ERR_PTR(0);
89762306a36Sopenharmony_ci				trf7970a_send_upstream(trf);
89862306a36Sopenharmony_ci				break;
89962306a36Sopenharmony_ci			}
90062306a36Sopenharmony_ci
90162306a36Sopenharmony_ci			if (trf->is_initiator)
90262306a36Sopenharmony_ci				break;
90362306a36Sopenharmony_ci
90462306a36Sopenharmony_ci			iso_ctrl = trf->iso_ctrl;
90562306a36Sopenharmony_ci
90662306a36Sopenharmony_ci			switch (trf->framing) {
90762306a36Sopenharmony_ci			case NFC_DIGITAL_FRAMING_NFCA_STANDARD:
90862306a36Sopenharmony_ci				trf->tx_cmd = TRF7970A_CMD_TRANSMIT_NO_CRC;
90962306a36Sopenharmony_ci				iso_ctrl |= TRF7970A_ISO_CTRL_RX_CRC_N;
91062306a36Sopenharmony_ci				trf->iso_ctrl = 0xff; /* Force ISO_CTRL write */
91162306a36Sopenharmony_ci				break;
91262306a36Sopenharmony_ci			case NFC_DIGITAL_FRAMING_NFCA_STANDARD_WITH_CRC_A:
91362306a36Sopenharmony_ci				trf->tx_cmd = TRF7970A_CMD_TRANSMIT;
91462306a36Sopenharmony_ci				iso_ctrl &= ~TRF7970A_ISO_CTRL_RX_CRC_N;
91562306a36Sopenharmony_ci				trf->iso_ctrl = 0xff; /* Force ISO_CTRL write */
91662306a36Sopenharmony_ci				break;
91762306a36Sopenharmony_ci			case NFC_DIGITAL_FRAMING_NFCA_ANTICOL_COMPLETE:
91862306a36Sopenharmony_ci				ret = trf7970a_write(trf,
91962306a36Sopenharmony_ci					 TRF7970A_SPECIAL_FCN_REG1,
92062306a36Sopenharmony_ci					 TRF7970A_SPECIAL_FCN_REG1_14_ANTICOLL);
92162306a36Sopenharmony_ci				if (ret)
92262306a36Sopenharmony_ci					goto err_unlock_exit;
92362306a36Sopenharmony_ci
92462306a36Sopenharmony_ci				trf->special_fcn_reg1 =
92562306a36Sopenharmony_ci				    TRF7970A_SPECIAL_FCN_REG1_14_ANTICOLL;
92662306a36Sopenharmony_ci				break;
92762306a36Sopenharmony_ci			default:
92862306a36Sopenharmony_ci				break;
92962306a36Sopenharmony_ci			}
93062306a36Sopenharmony_ci
93162306a36Sopenharmony_ci			if (iso_ctrl != trf->iso_ctrl) {
93262306a36Sopenharmony_ci				ret = trf7970a_write(trf, TRF7970A_ISO_CTRL,
93362306a36Sopenharmony_ci						     iso_ctrl);
93462306a36Sopenharmony_ci				if (ret)
93562306a36Sopenharmony_ci					goto err_unlock_exit;
93662306a36Sopenharmony_ci
93762306a36Sopenharmony_ci				trf->iso_ctrl = iso_ctrl;
93862306a36Sopenharmony_ci			}
93962306a36Sopenharmony_ci		} else {
94062306a36Sopenharmony_ci			trf7970a_send_err_upstream(trf, -EIO);
94162306a36Sopenharmony_ci		}
94262306a36Sopenharmony_ci		break;
94362306a36Sopenharmony_ci	case TRF7970A_ST_WAIT_TO_ISSUE_EOF:
94462306a36Sopenharmony_ci		if (status != TRF7970A_IRQ_STATUS_TX)
94562306a36Sopenharmony_ci			trf7970a_send_err_upstream(trf, -EIO);
94662306a36Sopenharmony_ci		break;
94762306a36Sopenharmony_ci	case TRF7970A_ST_LISTENING:
94862306a36Sopenharmony_ci		if (status & TRF7970A_IRQ_STATUS_SRX) {
94962306a36Sopenharmony_ci			trf->ignore_timeout =
95062306a36Sopenharmony_ci			    !cancel_delayed_work(&trf->timeout_work);
95162306a36Sopenharmony_ci			trf7970a_drain_fifo(trf, status);
95262306a36Sopenharmony_ci		} else if (!(status & TRF7970A_IRQ_STATUS_NFC_RF)) {
95362306a36Sopenharmony_ci			trf7970a_send_err_upstream(trf, -EIO);
95462306a36Sopenharmony_ci		}
95562306a36Sopenharmony_ci		break;
95662306a36Sopenharmony_ci	case TRF7970A_ST_LISTENING_MD:
95762306a36Sopenharmony_ci		if (status & TRF7970A_IRQ_STATUS_SRX) {
95862306a36Sopenharmony_ci			trf->ignore_timeout =
95962306a36Sopenharmony_ci			    !cancel_delayed_work(&trf->timeout_work);
96062306a36Sopenharmony_ci
96162306a36Sopenharmony_ci			ret = trf7970a_mode_detect(trf, &trf->md_rf_tech);
96262306a36Sopenharmony_ci			if (ret) {
96362306a36Sopenharmony_ci				trf7970a_send_err_upstream(trf, ret);
96462306a36Sopenharmony_ci			} else {
96562306a36Sopenharmony_ci				trf->state = TRF7970A_ST_LISTENING;
96662306a36Sopenharmony_ci				trf7970a_drain_fifo(trf, status);
96762306a36Sopenharmony_ci			}
96862306a36Sopenharmony_ci		} else if (!(status & TRF7970A_IRQ_STATUS_NFC_RF)) {
96962306a36Sopenharmony_ci			trf7970a_send_err_upstream(trf, -EIO);
97062306a36Sopenharmony_ci		}
97162306a36Sopenharmony_ci		break;
97262306a36Sopenharmony_ci	default:
97362306a36Sopenharmony_ci		dev_err(trf->dev, "%s - Driver in invalid state: %d\n",
97462306a36Sopenharmony_ci			__func__, trf->state);
97562306a36Sopenharmony_ci	}
97662306a36Sopenharmony_ci
97762306a36Sopenharmony_cierr_unlock_exit:
97862306a36Sopenharmony_ci	mutex_unlock(&trf->lock);
97962306a36Sopenharmony_ci	return IRQ_HANDLED;
98062306a36Sopenharmony_ci}
98162306a36Sopenharmony_ci
98262306a36Sopenharmony_cistatic void trf7970a_issue_eof(struct trf7970a *trf)
98362306a36Sopenharmony_ci{
98462306a36Sopenharmony_ci	int ret;
98562306a36Sopenharmony_ci
98662306a36Sopenharmony_ci	dev_dbg(trf->dev, "Issuing EOF\n");
98762306a36Sopenharmony_ci
98862306a36Sopenharmony_ci	ret = trf7970a_cmd(trf, TRF7970A_CMD_FIFO_RESET);
98962306a36Sopenharmony_ci	if (ret)
99062306a36Sopenharmony_ci		trf7970a_send_err_upstream(trf, ret);
99162306a36Sopenharmony_ci
99262306a36Sopenharmony_ci	ret = trf7970a_cmd(trf, TRF7970A_CMD_EOF);
99362306a36Sopenharmony_ci	if (ret)
99462306a36Sopenharmony_ci		trf7970a_send_err_upstream(trf, ret);
99562306a36Sopenharmony_ci
99662306a36Sopenharmony_ci	trf->state = TRF7970A_ST_WAIT_FOR_RX_DATA;
99762306a36Sopenharmony_ci
99862306a36Sopenharmony_ci	dev_dbg(trf->dev, "Setting timeout for %d ms, state: %d\n",
99962306a36Sopenharmony_ci		trf->timeout, trf->state);
100062306a36Sopenharmony_ci
100162306a36Sopenharmony_ci	schedule_delayed_work(&trf->timeout_work,
100262306a36Sopenharmony_ci			      msecs_to_jiffies(trf->timeout));
100362306a36Sopenharmony_ci}
100462306a36Sopenharmony_ci
100562306a36Sopenharmony_cistatic void trf7970a_timeout_work_handler(struct work_struct *work)
100662306a36Sopenharmony_ci{
100762306a36Sopenharmony_ci	struct trf7970a *trf = container_of(work, struct trf7970a,
100862306a36Sopenharmony_ci					    timeout_work.work);
100962306a36Sopenharmony_ci
101062306a36Sopenharmony_ci	dev_dbg(trf->dev, "Timeout - state: %d, ignore_timeout: %d\n",
101162306a36Sopenharmony_ci		trf->state, trf->ignore_timeout);
101262306a36Sopenharmony_ci
101362306a36Sopenharmony_ci	mutex_lock(&trf->lock);
101462306a36Sopenharmony_ci
101562306a36Sopenharmony_ci	if (trf->ignore_timeout)
101662306a36Sopenharmony_ci		trf->ignore_timeout = false;
101762306a36Sopenharmony_ci	else if (trf->state == TRF7970A_ST_WAIT_FOR_RX_DATA_CONT)
101862306a36Sopenharmony_ci		trf7970a_drain_fifo(trf, TRF7970A_IRQ_STATUS_SRX);
101962306a36Sopenharmony_ci	else if (trf->state == TRF7970A_ST_WAIT_TO_ISSUE_EOF)
102062306a36Sopenharmony_ci		trf7970a_issue_eof(trf);
102162306a36Sopenharmony_ci	else
102262306a36Sopenharmony_ci		trf7970a_send_err_upstream(trf, -ETIMEDOUT);
102362306a36Sopenharmony_ci
102462306a36Sopenharmony_ci	mutex_unlock(&trf->lock);
102562306a36Sopenharmony_ci}
102662306a36Sopenharmony_ci
102762306a36Sopenharmony_cistatic int trf7970a_init(struct trf7970a *trf)
102862306a36Sopenharmony_ci{
102962306a36Sopenharmony_ci	int ret;
103062306a36Sopenharmony_ci
103162306a36Sopenharmony_ci	dev_dbg(trf->dev, "Initializing device - state: %d\n", trf->state);
103262306a36Sopenharmony_ci
103362306a36Sopenharmony_ci	ret = trf7970a_cmd(trf, TRF7970A_CMD_SOFT_INIT);
103462306a36Sopenharmony_ci	if (ret)
103562306a36Sopenharmony_ci		goto err_out;
103662306a36Sopenharmony_ci
103762306a36Sopenharmony_ci	ret = trf7970a_cmd(trf, TRF7970A_CMD_IDLE);
103862306a36Sopenharmony_ci	if (ret)
103962306a36Sopenharmony_ci		goto err_out;
104062306a36Sopenharmony_ci
104162306a36Sopenharmony_ci	ret = trf7970a_write(trf, TRF7970A_REG_IO_CTRL,
104262306a36Sopenharmony_ci			     trf->io_ctrl | TRF7970A_REG_IO_CTRL_VRS(0x1));
104362306a36Sopenharmony_ci	if (ret)
104462306a36Sopenharmony_ci		goto err_out;
104562306a36Sopenharmony_ci
104662306a36Sopenharmony_ci	ret = trf7970a_write(trf, TRF7970A_NFC_TARGET_LEVEL, 0);
104762306a36Sopenharmony_ci	if (ret)
104862306a36Sopenharmony_ci		goto err_out;
104962306a36Sopenharmony_ci
105062306a36Sopenharmony_ci	usleep_range(1000, 2000);
105162306a36Sopenharmony_ci
105262306a36Sopenharmony_ci	trf->chip_status_ctrl &= ~TRF7970A_CHIP_STATUS_RF_ON;
105362306a36Sopenharmony_ci
105462306a36Sopenharmony_ci	ret = trf7970a_write(trf, TRF7970A_MODULATOR_SYS_CLK_CTRL,
105562306a36Sopenharmony_ci			     trf->modulator_sys_clk_ctrl);
105662306a36Sopenharmony_ci	if (ret)
105762306a36Sopenharmony_ci		goto err_out;
105862306a36Sopenharmony_ci
105962306a36Sopenharmony_ci	ret = trf7970a_write(trf, TRF7970A_ADJUTABLE_FIFO_IRQ_LEVELS,
106062306a36Sopenharmony_ci			     TRF7970A_ADJUTABLE_FIFO_IRQ_LEVELS_WLH_96 |
106162306a36Sopenharmony_ci			     TRF7970A_ADJUTABLE_FIFO_IRQ_LEVELS_WLL_32);
106262306a36Sopenharmony_ci	if (ret)
106362306a36Sopenharmony_ci		goto err_out;
106462306a36Sopenharmony_ci
106562306a36Sopenharmony_ci	ret = trf7970a_write(trf, TRF7970A_SPECIAL_FCN_REG1, 0);
106662306a36Sopenharmony_ci	if (ret)
106762306a36Sopenharmony_ci		goto err_out;
106862306a36Sopenharmony_ci
106962306a36Sopenharmony_ci	trf->special_fcn_reg1 = 0;
107062306a36Sopenharmony_ci
107162306a36Sopenharmony_ci	trf->iso_ctrl = 0xff;
107262306a36Sopenharmony_ci	return 0;
107362306a36Sopenharmony_ci
107462306a36Sopenharmony_cierr_out:
107562306a36Sopenharmony_ci	dev_dbg(trf->dev, "Couldn't init device: %d\n", ret);
107662306a36Sopenharmony_ci	return ret;
107762306a36Sopenharmony_ci}
107862306a36Sopenharmony_ci
107962306a36Sopenharmony_cistatic void trf7970a_switch_rf_off(struct trf7970a *trf)
108062306a36Sopenharmony_ci{
108162306a36Sopenharmony_ci	if ((trf->state == TRF7970A_ST_PWR_OFF) ||
108262306a36Sopenharmony_ci	    (trf->state == TRF7970A_ST_RF_OFF))
108362306a36Sopenharmony_ci		return;
108462306a36Sopenharmony_ci
108562306a36Sopenharmony_ci	dev_dbg(trf->dev, "Switching rf off\n");
108662306a36Sopenharmony_ci
108762306a36Sopenharmony_ci	trf->chip_status_ctrl &= ~TRF7970A_CHIP_STATUS_RF_ON;
108862306a36Sopenharmony_ci
108962306a36Sopenharmony_ci	trf7970a_write(trf, TRF7970A_CHIP_STATUS_CTRL, trf->chip_status_ctrl);
109062306a36Sopenharmony_ci
109162306a36Sopenharmony_ci	trf->aborting = false;
109262306a36Sopenharmony_ci	trf->state = TRF7970A_ST_RF_OFF;
109362306a36Sopenharmony_ci
109462306a36Sopenharmony_ci	pm_runtime_mark_last_busy(trf->dev);
109562306a36Sopenharmony_ci	pm_runtime_put_autosuspend(trf->dev);
109662306a36Sopenharmony_ci}
109762306a36Sopenharmony_ci
109862306a36Sopenharmony_cistatic int trf7970a_switch_rf_on(struct trf7970a *trf)
109962306a36Sopenharmony_ci{
110062306a36Sopenharmony_ci	int ret;
110162306a36Sopenharmony_ci
110262306a36Sopenharmony_ci	dev_dbg(trf->dev, "Switching rf on\n");
110362306a36Sopenharmony_ci
110462306a36Sopenharmony_ci	pm_runtime_get_sync(trf->dev);
110562306a36Sopenharmony_ci
110662306a36Sopenharmony_ci	if (trf->state != TRF7970A_ST_RF_OFF) {	/* Power on, RF off */
110762306a36Sopenharmony_ci		dev_err(trf->dev, "%s - Incorrect state: %d\n", __func__,
110862306a36Sopenharmony_ci			trf->state);
110962306a36Sopenharmony_ci		return -EINVAL;
111062306a36Sopenharmony_ci	}
111162306a36Sopenharmony_ci
111262306a36Sopenharmony_ci	ret = trf7970a_init(trf);
111362306a36Sopenharmony_ci	if (ret) {
111462306a36Sopenharmony_ci		dev_err(trf->dev, "%s - Can't initialize: %d\n", __func__, ret);
111562306a36Sopenharmony_ci		return ret;
111662306a36Sopenharmony_ci	}
111762306a36Sopenharmony_ci
111862306a36Sopenharmony_ci	trf->state = TRF7970A_ST_IDLE;
111962306a36Sopenharmony_ci
112062306a36Sopenharmony_ci	return 0;
112162306a36Sopenharmony_ci}
112262306a36Sopenharmony_ci
112362306a36Sopenharmony_cistatic int trf7970a_switch_rf(struct nfc_digital_dev *ddev, bool on)
112462306a36Sopenharmony_ci{
112562306a36Sopenharmony_ci	struct trf7970a *trf = nfc_digital_get_drvdata(ddev);
112662306a36Sopenharmony_ci	int ret = 0;
112762306a36Sopenharmony_ci
112862306a36Sopenharmony_ci	dev_dbg(trf->dev, "Switching RF - state: %d, on: %d\n", trf->state, on);
112962306a36Sopenharmony_ci
113062306a36Sopenharmony_ci	mutex_lock(&trf->lock);
113162306a36Sopenharmony_ci
113262306a36Sopenharmony_ci	if (on) {
113362306a36Sopenharmony_ci		switch (trf->state) {
113462306a36Sopenharmony_ci		case TRF7970A_ST_PWR_OFF:
113562306a36Sopenharmony_ci		case TRF7970A_ST_RF_OFF:
113662306a36Sopenharmony_ci			ret = trf7970a_switch_rf_on(trf);
113762306a36Sopenharmony_ci			break;
113862306a36Sopenharmony_ci		case TRF7970A_ST_IDLE:
113962306a36Sopenharmony_ci		case TRF7970A_ST_IDLE_RX_BLOCKED:
114062306a36Sopenharmony_ci			break;
114162306a36Sopenharmony_ci		default:
114262306a36Sopenharmony_ci			dev_err(trf->dev, "%s - Invalid request: %d %d\n",
114362306a36Sopenharmony_ci				__func__, trf->state, on);
114462306a36Sopenharmony_ci			trf7970a_switch_rf_off(trf);
114562306a36Sopenharmony_ci			ret = -EINVAL;
114662306a36Sopenharmony_ci		}
114762306a36Sopenharmony_ci	} else {
114862306a36Sopenharmony_ci		switch (trf->state) {
114962306a36Sopenharmony_ci		case TRF7970A_ST_PWR_OFF:
115062306a36Sopenharmony_ci		case TRF7970A_ST_RF_OFF:
115162306a36Sopenharmony_ci			break;
115262306a36Sopenharmony_ci		default:
115362306a36Sopenharmony_ci			dev_err(trf->dev, "%s - Invalid request: %d %d\n",
115462306a36Sopenharmony_ci				__func__, trf->state, on);
115562306a36Sopenharmony_ci			ret = -EINVAL;
115662306a36Sopenharmony_ci			fallthrough;
115762306a36Sopenharmony_ci		case TRF7970A_ST_IDLE:
115862306a36Sopenharmony_ci		case TRF7970A_ST_IDLE_RX_BLOCKED:
115962306a36Sopenharmony_ci		case TRF7970A_ST_WAIT_FOR_RX_DATA:
116062306a36Sopenharmony_ci		case TRF7970A_ST_WAIT_FOR_RX_DATA_CONT:
116162306a36Sopenharmony_ci			trf7970a_switch_rf_off(trf);
116262306a36Sopenharmony_ci		}
116362306a36Sopenharmony_ci	}
116462306a36Sopenharmony_ci
116562306a36Sopenharmony_ci	mutex_unlock(&trf->lock);
116662306a36Sopenharmony_ci	return ret;
116762306a36Sopenharmony_ci}
116862306a36Sopenharmony_ci
116962306a36Sopenharmony_cistatic int trf7970a_in_config_rf_tech(struct trf7970a *trf, int tech)
117062306a36Sopenharmony_ci{
117162306a36Sopenharmony_ci	int ret = 0;
117262306a36Sopenharmony_ci
117362306a36Sopenharmony_ci	dev_dbg(trf->dev, "rf technology: %d\n", tech);
117462306a36Sopenharmony_ci
117562306a36Sopenharmony_ci	switch (tech) {
117662306a36Sopenharmony_ci	case NFC_DIGITAL_RF_TECH_106A:
117762306a36Sopenharmony_ci		trf->iso_ctrl_tech = TRF7970A_ISO_CTRL_14443A_106;
117862306a36Sopenharmony_ci		trf->modulator_sys_clk_ctrl =
117962306a36Sopenharmony_ci		    (trf->modulator_sys_clk_ctrl & 0xf8) |
118062306a36Sopenharmony_ci		    TRF7970A_MODULATOR_DEPTH_OOK;
118162306a36Sopenharmony_ci		trf->guard_time = TRF7970A_GUARD_TIME_NFCA;
118262306a36Sopenharmony_ci		break;
118362306a36Sopenharmony_ci	case NFC_DIGITAL_RF_TECH_106B:
118462306a36Sopenharmony_ci		trf->iso_ctrl_tech = TRF7970A_ISO_CTRL_14443B_106;
118562306a36Sopenharmony_ci		trf->modulator_sys_clk_ctrl =
118662306a36Sopenharmony_ci		    (trf->modulator_sys_clk_ctrl & 0xf8) |
118762306a36Sopenharmony_ci		    TRF7970A_MODULATOR_DEPTH_ASK10;
118862306a36Sopenharmony_ci		trf->guard_time = TRF7970A_GUARD_TIME_NFCB;
118962306a36Sopenharmony_ci		break;
119062306a36Sopenharmony_ci	case NFC_DIGITAL_RF_TECH_212F:
119162306a36Sopenharmony_ci		trf->iso_ctrl_tech = TRF7970A_ISO_CTRL_FELICA_212;
119262306a36Sopenharmony_ci		trf->modulator_sys_clk_ctrl =
119362306a36Sopenharmony_ci		    (trf->modulator_sys_clk_ctrl & 0xf8) |
119462306a36Sopenharmony_ci		    TRF7970A_MODULATOR_DEPTH_ASK10;
119562306a36Sopenharmony_ci		trf->guard_time = TRF7970A_GUARD_TIME_NFCF;
119662306a36Sopenharmony_ci		break;
119762306a36Sopenharmony_ci	case NFC_DIGITAL_RF_TECH_424F:
119862306a36Sopenharmony_ci		trf->iso_ctrl_tech = TRF7970A_ISO_CTRL_FELICA_424;
119962306a36Sopenharmony_ci		trf->modulator_sys_clk_ctrl =
120062306a36Sopenharmony_ci		    (trf->modulator_sys_clk_ctrl & 0xf8) |
120162306a36Sopenharmony_ci		    TRF7970A_MODULATOR_DEPTH_ASK10;
120262306a36Sopenharmony_ci		trf->guard_time = TRF7970A_GUARD_TIME_NFCF;
120362306a36Sopenharmony_ci		break;
120462306a36Sopenharmony_ci	case NFC_DIGITAL_RF_TECH_ISO15693:
120562306a36Sopenharmony_ci		trf->iso_ctrl_tech = TRF7970A_ISO_CTRL_15693_SGL_1OF4_2648;
120662306a36Sopenharmony_ci		trf->modulator_sys_clk_ctrl =
120762306a36Sopenharmony_ci		    (trf->modulator_sys_clk_ctrl & 0xf8) |
120862306a36Sopenharmony_ci		    TRF7970A_MODULATOR_DEPTH_OOK;
120962306a36Sopenharmony_ci		trf->guard_time = TRF7970A_GUARD_TIME_15693;
121062306a36Sopenharmony_ci		break;
121162306a36Sopenharmony_ci	default:
121262306a36Sopenharmony_ci		dev_dbg(trf->dev, "Unsupported rf technology: %d\n", tech);
121362306a36Sopenharmony_ci		return -EINVAL;
121462306a36Sopenharmony_ci	}
121562306a36Sopenharmony_ci
121662306a36Sopenharmony_ci	trf->technology = tech;
121762306a36Sopenharmony_ci
121862306a36Sopenharmony_ci	/* If in initiator mode and not changing the RF tech due to a
121962306a36Sopenharmony_ci	 * PSL sequence (indicated by 'trf->iso_ctrl == 0xff' from
122062306a36Sopenharmony_ci	 * trf7970a_init()), clear the NFC Target Detection Level register
122162306a36Sopenharmony_ci	 * due to erratum.
122262306a36Sopenharmony_ci	 */
122362306a36Sopenharmony_ci	if (trf->iso_ctrl == 0xff)
122462306a36Sopenharmony_ci		ret = trf7970a_write(trf, TRF7970A_NFC_TARGET_LEVEL, 0);
122562306a36Sopenharmony_ci
122662306a36Sopenharmony_ci	return ret;
122762306a36Sopenharmony_ci}
122862306a36Sopenharmony_ci
122962306a36Sopenharmony_cistatic int trf7970a_is_rf_field(struct trf7970a *trf, bool *is_rf_field)
123062306a36Sopenharmony_ci{
123162306a36Sopenharmony_ci	int ret;
123262306a36Sopenharmony_ci	u8 rssi;
123362306a36Sopenharmony_ci
123462306a36Sopenharmony_ci	ret = trf7970a_write(trf, TRF7970A_CHIP_STATUS_CTRL,
123562306a36Sopenharmony_ci			     trf->chip_status_ctrl |
123662306a36Sopenharmony_ci			     TRF7970A_CHIP_STATUS_REC_ON);
123762306a36Sopenharmony_ci	if (ret)
123862306a36Sopenharmony_ci		return ret;
123962306a36Sopenharmony_ci
124062306a36Sopenharmony_ci	ret = trf7970a_cmd(trf, TRF7970A_CMD_TEST_EXT_RF);
124162306a36Sopenharmony_ci	if (ret)
124262306a36Sopenharmony_ci		return ret;
124362306a36Sopenharmony_ci
124462306a36Sopenharmony_ci	usleep_range(50, 60);
124562306a36Sopenharmony_ci
124662306a36Sopenharmony_ci	ret = trf7970a_read(trf, TRF7970A_RSSI_OSC_STATUS, &rssi);
124762306a36Sopenharmony_ci	if (ret)
124862306a36Sopenharmony_ci		return ret;
124962306a36Sopenharmony_ci
125062306a36Sopenharmony_ci	ret = trf7970a_write(trf, TRF7970A_CHIP_STATUS_CTRL,
125162306a36Sopenharmony_ci			     trf->chip_status_ctrl);
125262306a36Sopenharmony_ci	if (ret)
125362306a36Sopenharmony_ci		return ret;
125462306a36Sopenharmony_ci
125562306a36Sopenharmony_ci	if (rssi & TRF7970A_RSSI_OSC_STATUS_RSSI_MASK)
125662306a36Sopenharmony_ci		*is_rf_field = true;
125762306a36Sopenharmony_ci	else
125862306a36Sopenharmony_ci		*is_rf_field = false;
125962306a36Sopenharmony_ci
126062306a36Sopenharmony_ci	return 0;
126162306a36Sopenharmony_ci}
126262306a36Sopenharmony_ci
126362306a36Sopenharmony_cistatic int trf7970a_in_config_framing(struct trf7970a *trf, int framing)
126462306a36Sopenharmony_ci{
126562306a36Sopenharmony_ci	u8 iso_ctrl = trf->iso_ctrl_tech;
126662306a36Sopenharmony_ci	bool is_rf_field = false;
126762306a36Sopenharmony_ci	int ret;
126862306a36Sopenharmony_ci
126962306a36Sopenharmony_ci	dev_dbg(trf->dev, "framing: %d\n", framing);
127062306a36Sopenharmony_ci
127162306a36Sopenharmony_ci	switch (framing) {
127262306a36Sopenharmony_ci	case NFC_DIGITAL_FRAMING_NFCA_SHORT:
127362306a36Sopenharmony_ci	case NFC_DIGITAL_FRAMING_NFCA_STANDARD:
127462306a36Sopenharmony_ci		trf->tx_cmd = TRF7970A_CMD_TRANSMIT_NO_CRC;
127562306a36Sopenharmony_ci		iso_ctrl |= TRF7970A_ISO_CTRL_RX_CRC_N;
127662306a36Sopenharmony_ci		break;
127762306a36Sopenharmony_ci	case NFC_DIGITAL_FRAMING_NFCA_STANDARD_WITH_CRC_A:
127862306a36Sopenharmony_ci	case NFC_DIGITAL_FRAMING_NFCA_T4T:
127962306a36Sopenharmony_ci	case NFC_DIGITAL_FRAMING_NFCB:
128062306a36Sopenharmony_ci	case NFC_DIGITAL_FRAMING_NFCB_T4T:
128162306a36Sopenharmony_ci	case NFC_DIGITAL_FRAMING_NFCF:
128262306a36Sopenharmony_ci	case NFC_DIGITAL_FRAMING_NFCF_T3T:
128362306a36Sopenharmony_ci	case NFC_DIGITAL_FRAMING_ISO15693_INVENTORY:
128462306a36Sopenharmony_ci	case NFC_DIGITAL_FRAMING_ISO15693_T5T:
128562306a36Sopenharmony_ci	case NFC_DIGITAL_FRAMING_NFCA_NFC_DEP:
128662306a36Sopenharmony_ci	case NFC_DIGITAL_FRAMING_NFCF_NFC_DEP:
128762306a36Sopenharmony_ci		trf->tx_cmd = TRF7970A_CMD_TRANSMIT;
128862306a36Sopenharmony_ci		iso_ctrl &= ~TRF7970A_ISO_CTRL_RX_CRC_N;
128962306a36Sopenharmony_ci		break;
129062306a36Sopenharmony_ci	case NFC_DIGITAL_FRAMING_NFCA_T2T:
129162306a36Sopenharmony_ci		trf->tx_cmd = TRF7970A_CMD_TRANSMIT;
129262306a36Sopenharmony_ci		iso_ctrl |= TRF7970A_ISO_CTRL_RX_CRC_N;
129362306a36Sopenharmony_ci		break;
129462306a36Sopenharmony_ci	default:
129562306a36Sopenharmony_ci		dev_dbg(trf->dev, "Unsupported Framing: %d\n", framing);
129662306a36Sopenharmony_ci		return -EINVAL;
129762306a36Sopenharmony_ci	}
129862306a36Sopenharmony_ci
129962306a36Sopenharmony_ci	trf->framing = framing;
130062306a36Sopenharmony_ci
130162306a36Sopenharmony_ci	if (!(trf->chip_status_ctrl & TRF7970A_CHIP_STATUS_RF_ON)) {
130262306a36Sopenharmony_ci		ret = trf7970a_is_rf_field(trf, &is_rf_field);
130362306a36Sopenharmony_ci		if (ret)
130462306a36Sopenharmony_ci			return ret;
130562306a36Sopenharmony_ci
130662306a36Sopenharmony_ci		if (is_rf_field)
130762306a36Sopenharmony_ci			return -EBUSY;
130862306a36Sopenharmony_ci	}
130962306a36Sopenharmony_ci
131062306a36Sopenharmony_ci	if (iso_ctrl != trf->iso_ctrl) {
131162306a36Sopenharmony_ci		ret = trf7970a_write(trf, TRF7970A_ISO_CTRL, iso_ctrl);
131262306a36Sopenharmony_ci		if (ret)
131362306a36Sopenharmony_ci			return ret;
131462306a36Sopenharmony_ci
131562306a36Sopenharmony_ci		trf->iso_ctrl = iso_ctrl;
131662306a36Sopenharmony_ci
131762306a36Sopenharmony_ci		ret = trf7970a_write(trf, TRF7970A_MODULATOR_SYS_CLK_CTRL,
131862306a36Sopenharmony_ci				     trf->modulator_sys_clk_ctrl);
131962306a36Sopenharmony_ci		if (ret)
132062306a36Sopenharmony_ci			return ret;
132162306a36Sopenharmony_ci	}
132262306a36Sopenharmony_ci
132362306a36Sopenharmony_ci	if (!(trf->chip_status_ctrl & TRF7970A_CHIP_STATUS_RF_ON)) {
132462306a36Sopenharmony_ci		ret = trf7970a_write(trf, TRF7970A_CHIP_STATUS_CTRL,
132562306a36Sopenharmony_ci				     trf->chip_status_ctrl |
132662306a36Sopenharmony_ci				     TRF7970A_CHIP_STATUS_RF_ON);
132762306a36Sopenharmony_ci		if (ret)
132862306a36Sopenharmony_ci			return ret;
132962306a36Sopenharmony_ci
133062306a36Sopenharmony_ci		trf->chip_status_ctrl |= TRF7970A_CHIP_STATUS_RF_ON;
133162306a36Sopenharmony_ci
133262306a36Sopenharmony_ci		usleep_range(trf->guard_time, trf->guard_time + 1000);
133362306a36Sopenharmony_ci	}
133462306a36Sopenharmony_ci
133562306a36Sopenharmony_ci	return 0;
133662306a36Sopenharmony_ci}
133762306a36Sopenharmony_ci
133862306a36Sopenharmony_cistatic int trf7970a_in_configure_hw(struct nfc_digital_dev *ddev, int type,
133962306a36Sopenharmony_ci				    int param)
134062306a36Sopenharmony_ci{
134162306a36Sopenharmony_ci	struct trf7970a *trf = nfc_digital_get_drvdata(ddev);
134262306a36Sopenharmony_ci	int ret;
134362306a36Sopenharmony_ci
134462306a36Sopenharmony_ci	dev_dbg(trf->dev, "Configure hw - type: %d, param: %d\n", type, param);
134562306a36Sopenharmony_ci
134662306a36Sopenharmony_ci	mutex_lock(&trf->lock);
134762306a36Sopenharmony_ci
134862306a36Sopenharmony_ci	trf->is_initiator = true;
134962306a36Sopenharmony_ci
135062306a36Sopenharmony_ci	if ((trf->state == TRF7970A_ST_PWR_OFF) ||
135162306a36Sopenharmony_ci	    (trf->state == TRF7970A_ST_RF_OFF)) {
135262306a36Sopenharmony_ci		ret = trf7970a_switch_rf_on(trf);
135362306a36Sopenharmony_ci		if (ret)
135462306a36Sopenharmony_ci			goto err_unlock;
135562306a36Sopenharmony_ci	}
135662306a36Sopenharmony_ci
135762306a36Sopenharmony_ci	switch (type) {
135862306a36Sopenharmony_ci	case NFC_DIGITAL_CONFIG_RF_TECH:
135962306a36Sopenharmony_ci		ret = trf7970a_in_config_rf_tech(trf, param);
136062306a36Sopenharmony_ci		break;
136162306a36Sopenharmony_ci	case NFC_DIGITAL_CONFIG_FRAMING:
136262306a36Sopenharmony_ci		ret = trf7970a_in_config_framing(trf, param);
136362306a36Sopenharmony_ci		break;
136462306a36Sopenharmony_ci	default:
136562306a36Sopenharmony_ci		dev_dbg(trf->dev, "Unknown type: %d\n", type);
136662306a36Sopenharmony_ci		ret = -EINVAL;
136762306a36Sopenharmony_ci	}
136862306a36Sopenharmony_ci
136962306a36Sopenharmony_cierr_unlock:
137062306a36Sopenharmony_ci	mutex_unlock(&trf->lock);
137162306a36Sopenharmony_ci	return ret;
137262306a36Sopenharmony_ci}
137362306a36Sopenharmony_ci
137462306a36Sopenharmony_cistatic int trf7970a_is_iso15693_write_or_lock(u8 cmd)
137562306a36Sopenharmony_ci{
137662306a36Sopenharmony_ci	switch (cmd) {
137762306a36Sopenharmony_ci	case ISO15693_CMD_WRITE_SINGLE_BLOCK:
137862306a36Sopenharmony_ci	case ISO15693_CMD_LOCK_BLOCK:
137962306a36Sopenharmony_ci	case ISO15693_CMD_WRITE_MULTIPLE_BLOCK:
138062306a36Sopenharmony_ci	case ISO15693_CMD_WRITE_AFI:
138162306a36Sopenharmony_ci	case ISO15693_CMD_LOCK_AFI:
138262306a36Sopenharmony_ci	case ISO15693_CMD_WRITE_DSFID:
138362306a36Sopenharmony_ci	case ISO15693_CMD_LOCK_DSFID:
138462306a36Sopenharmony_ci		return 1;
138562306a36Sopenharmony_ci	default:
138662306a36Sopenharmony_ci		return 0;
138762306a36Sopenharmony_ci	}
138862306a36Sopenharmony_ci}
138962306a36Sopenharmony_ci
139062306a36Sopenharmony_cistatic int trf7970a_per_cmd_config(struct trf7970a *trf,
139162306a36Sopenharmony_ci				   const struct sk_buff *skb)
139262306a36Sopenharmony_ci{
139362306a36Sopenharmony_ci	const u8 *req = skb->data;
139462306a36Sopenharmony_ci	u8 special_fcn_reg1, iso_ctrl;
139562306a36Sopenharmony_ci	int ret;
139662306a36Sopenharmony_ci
139762306a36Sopenharmony_ci	trf->issue_eof = false;
139862306a36Sopenharmony_ci
139962306a36Sopenharmony_ci	/* When issuing Type 2 read command, make sure the '4_bit_RX' bit in
140062306a36Sopenharmony_ci	 * special functions register 1 is cleared; otherwise, its a write or
140162306a36Sopenharmony_ci	 * sector select command and '4_bit_RX' must be set.
140262306a36Sopenharmony_ci	 *
140362306a36Sopenharmony_ci	 * When issuing an ISO 15693 command, inspect the flags byte to see
140462306a36Sopenharmony_ci	 * what speed to use.  Also, remember if the OPTION flag is set on
140562306a36Sopenharmony_ci	 * a Type 5 write or lock command so the driver will know that it
140662306a36Sopenharmony_ci	 * has to send an EOF in order to get a response.
140762306a36Sopenharmony_ci	 */
140862306a36Sopenharmony_ci	if ((trf->technology == NFC_DIGITAL_RF_TECH_106A) &&
140962306a36Sopenharmony_ci	    (trf->framing == NFC_DIGITAL_FRAMING_NFCA_T2T)) {
141062306a36Sopenharmony_ci		if (req[0] == NFC_T2T_CMD_READ)
141162306a36Sopenharmony_ci			special_fcn_reg1 = 0;
141262306a36Sopenharmony_ci		else
141362306a36Sopenharmony_ci			special_fcn_reg1 = TRF7970A_SPECIAL_FCN_REG1_4_BIT_RX;
141462306a36Sopenharmony_ci
141562306a36Sopenharmony_ci		if (special_fcn_reg1 != trf->special_fcn_reg1) {
141662306a36Sopenharmony_ci			ret = trf7970a_write(trf, TRF7970A_SPECIAL_FCN_REG1,
141762306a36Sopenharmony_ci					     special_fcn_reg1);
141862306a36Sopenharmony_ci			if (ret)
141962306a36Sopenharmony_ci				return ret;
142062306a36Sopenharmony_ci
142162306a36Sopenharmony_ci			trf->special_fcn_reg1 = special_fcn_reg1;
142262306a36Sopenharmony_ci		}
142362306a36Sopenharmony_ci	} else if (trf->technology == NFC_DIGITAL_RF_TECH_ISO15693) {
142462306a36Sopenharmony_ci		iso_ctrl = trf->iso_ctrl & ~TRF7970A_ISO_CTRL_RFID_SPEED_MASK;
142562306a36Sopenharmony_ci
142662306a36Sopenharmony_ci		switch (req[0] & ISO15693_REQ_FLAG_SPEED_MASK) {
142762306a36Sopenharmony_ci		case 0x00:
142862306a36Sopenharmony_ci			iso_ctrl |= TRF7970A_ISO_CTRL_15693_SGL_1OF4_662;
142962306a36Sopenharmony_ci			break;
143062306a36Sopenharmony_ci		case ISO15693_REQ_FLAG_SUB_CARRIER:
143162306a36Sopenharmony_ci			iso_ctrl |= TRF7970A_ISO_CTRL_15693_DBL_1OF4_667a;
143262306a36Sopenharmony_ci			break;
143362306a36Sopenharmony_ci		case ISO15693_REQ_FLAG_DATA_RATE:
143462306a36Sopenharmony_ci			iso_ctrl |= TRF7970A_ISO_CTRL_15693_SGL_1OF4_2648;
143562306a36Sopenharmony_ci			break;
143662306a36Sopenharmony_ci		case (ISO15693_REQ_FLAG_SUB_CARRIER |
143762306a36Sopenharmony_ci		      ISO15693_REQ_FLAG_DATA_RATE):
143862306a36Sopenharmony_ci			iso_ctrl |= TRF7970A_ISO_CTRL_15693_DBL_1OF4_2669;
143962306a36Sopenharmony_ci			break;
144062306a36Sopenharmony_ci		}
144162306a36Sopenharmony_ci
144262306a36Sopenharmony_ci		if (iso_ctrl != trf->iso_ctrl) {
144362306a36Sopenharmony_ci			ret = trf7970a_write(trf, TRF7970A_ISO_CTRL, iso_ctrl);
144462306a36Sopenharmony_ci			if (ret)
144562306a36Sopenharmony_ci				return ret;
144662306a36Sopenharmony_ci
144762306a36Sopenharmony_ci			trf->iso_ctrl = iso_ctrl;
144862306a36Sopenharmony_ci		}
144962306a36Sopenharmony_ci
145062306a36Sopenharmony_ci		if ((trf->framing == NFC_DIGITAL_FRAMING_ISO15693_T5T) &&
145162306a36Sopenharmony_ci		    trf7970a_is_iso15693_write_or_lock(req[1]) &&
145262306a36Sopenharmony_ci		    (req[0] & ISO15693_REQ_FLAG_OPTION))
145362306a36Sopenharmony_ci			trf->issue_eof = true;
145462306a36Sopenharmony_ci	}
145562306a36Sopenharmony_ci
145662306a36Sopenharmony_ci	return 0;
145762306a36Sopenharmony_ci}
145862306a36Sopenharmony_ci
145962306a36Sopenharmony_cistatic int trf7970a_send_cmd(struct nfc_digital_dev *ddev,
146062306a36Sopenharmony_ci			     struct sk_buff *skb, u16 timeout,
146162306a36Sopenharmony_ci			     nfc_digital_cmd_complete_t cb, void *arg)
146262306a36Sopenharmony_ci{
146362306a36Sopenharmony_ci	struct trf7970a *trf = nfc_digital_get_drvdata(ddev);
146462306a36Sopenharmony_ci	u8 prefix[5];
146562306a36Sopenharmony_ci	unsigned int len;
146662306a36Sopenharmony_ci	int ret;
146762306a36Sopenharmony_ci	u8 status;
146862306a36Sopenharmony_ci
146962306a36Sopenharmony_ci	dev_dbg(trf->dev, "New request - state: %d, timeout: %d ms, len: %d\n",
147062306a36Sopenharmony_ci		trf->state, timeout, skb->len);
147162306a36Sopenharmony_ci
147262306a36Sopenharmony_ci	if (skb->len > TRF7970A_TX_MAX)
147362306a36Sopenharmony_ci		return -EINVAL;
147462306a36Sopenharmony_ci
147562306a36Sopenharmony_ci	mutex_lock(&trf->lock);
147662306a36Sopenharmony_ci
147762306a36Sopenharmony_ci	if ((trf->state != TRF7970A_ST_IDLE) &&
147862306a36Sopenharmony_ci	    (trf->state != TRF7970A_ST_IDLE_RX_BLOCKED)) {
147962306a36Sopenharmony_ci		dev_err(trf->dev, "%s - Bogus state: %d\n", __func__,
148062306a36Sopenharmony_ci			trf->state);
148162306a36Sopenharmony_ci		ret = -EIO;
148262306a36Sopenharmony_ci		goto out_err;
148362306a36Sopenharmony_ci	}
148462306a36Sopenharmony_ci
148562306a36Sopenharmony_ci	if (trf->aborting) {
148662306a36Sopenharmony_ci		dev_dbg(trf->dev, "Abort process complete\n");
148762306a36Sopenharmony_ci		trf->aborting = false;
148862306a36Sopenharmony_ci		ret = -ECANCELED;
148962306a36Sopenharmony_ci		goto out_err;
149062306a36Sopenharmony_ci	}
149162306a36Sopenharmony_ci
149262306a36Sopenharmony_ci	if (timeout) {
149362306a36Sopenharmony_ci		trf->rx_skb = nfc_alloc_recv_skb(TRF7970A_RX_SKB_ALLOC_SIZE,
149462306a36Sopenharmony_ci						 GFP_KERNEL);
149562306a36Sopenharmony_ci		if (!trf->rx_skb) {
149662306a36Sopenharmony_ci			dev_dbg(trf->dev, "Can't alloc rx_skb\n");
149762306a36Sopenharmony_ci			ret = -ENOMEM;
149862306a36Sopenharmony_ci			goto out_err;
149962306a36Sopenharmony_ci		}
150062306a36Sopenharmony_ci	}
150162306a36Sopenharmony_ci
150262306a36Sopenharmony_ci	if (trf->state == TRF7970A_ST_IDLE_RX_BLOCKED) {
150362306a36Sopenharmony_ci		ret = trf7970a_cmd(trf, TRF7970A_CMD_ENABLE_RX);
150462306a36Sopenharmony_ci		if (ret)
150562306a36Sopenharmony_ci			goto out_err;
150662306a36Sopenharmony_ci
150762306a36Sopenharmony_ci		trf->state = TRF7970A_ST_IDLE;
150862306a36Sopenharmony_ci	}
150962306a36Sopenharmony_ci
151062306a36Sopenharmony_ci	if (trf->is_initiator) {
151162306a36Sopenharmony_ci		ret = trf7970a_per_cmd_config(trf, skb);
151262306a36Sopenharmony_ci		if (ret)
151362306a36Sopenharmony_ci			goto out_err;
151462306a36Sopenharmony_ci	}
151562306a36Sopenharmony_ci
151662306a36Sopenharmony_ci	trf->ddev = ddev;
151762306a36Sopenharmony_ci	trf->tx_skb = skb;
151862306a36Sopenharmony_ci	trf->cb = cb;
151962306a36Sopenharmony_ci	trf->cb_arg = arg;
152062306a36Sopenharmony_ci	trf->timeout = timeout;
152162306a36Sopenharmony_ci	trf->ignore_timeout = false;
152262306a36Sopenharmony_ci
152362306a36Sopenharmony_ci	len = skb->len;
152462306a36Sopenharmony_ci
152562306a36Sopenharmony_ci	/* TX data must be prefixed with a FIFO reset cmd, a cmd that depends
152662306a36Sopenharmony_ci	 * on what the current framing is, the address of the TX length byte 1
152762306a36Sopenharmony_ci	 * register (0x1d), and the 2 byte length of the data to be transmitted.
152862306a36Sopenharmony_ci	 * That totals 5 bytes.
152962306a36Sopenharmony_ci	 */
153062306a36Sopenharmony_ci	prefix[0] = TRF7970A_CMD_BIT_CTRL |
153162306a36Sopenharmony_ci	    TRF7970A_CMD_BIT_OPCODE(TRF7970A_CMD_FIFO_RESET);
153262306a36Sopenharmony_ci	prefix[1] = TRF7970A_CMD_BIT_CTRL |
153362306a36Sopenharmony_ci	    TRF7970A_CMD_BIT_OPCODE(trf->tx_cmd);
153462306a36Sopenharmony_ci	prefix[2] = TRF7970A_CMD_BIT_CONTINUOUS | TRF7970A_TX_LENGTH_BYTE1;
153562306a36Sopenharmony_ci
153662306a36Sopenharmony_ci	if (trf->framing == NFC_DIGITAL_FRAMING_NFCA_SHORT) {
153762306a36Sopenharmony_ci		prefix[3] = 0x00;
153862306a36Sopenharmony_ci		prefix[4] = 0x0f;	/* 7 bits */
153962306a36Sopenharmony_ci	} else {
154062306a36Sopenharmony_ci		prefix[3] = (len & 0xf00) >> 4;
154162306a36Sopenharmony_ci		prefix[3] |= ((len & 0xf0) >> 4);
154262306a36Sopenharmony_ci		prefix[4] = ((len & 0x0f) << 4);
154362306a36Sopenharmony_ci	}
154462306a36Sopenharmony_ci
154562306a36Sopenharmony_ci	len = min_t(int, skb->len, TRF7970A_FIFO_SIZE);
154662306a36Sopenharmony_ci
154762306a36Sopenharmony_ci	/* Clear possible spurious interrupt */
154862306a36Sopenharmony_ci	ret = trf7970a_read_irqstatus(trf, &status);
154962306a36Sopenharmony_ci	if (ret)
155062306a36Sopenharmony_ci		goto out_err;
155162306a36Sopenharmony_ci
155262306a36Sopenharmony_ci	ret = trf7970a_transmit(trf, skb, len, prefix, sizeof(prefix));
155362306a36Sopenharmony_ci	if (ret) {
155462306a36Sopenharmony_ci		kfree_skb(trf->rx_skb);
155562306a36Sopenharmony_ci		trf->rx_skb = NULL;
155662306a36Sopenharmony_ci	}
155762306a36Sopenharmony_ci
155862306a36Sopenharmony_ciout_err:
155962306a36Sopenharmony_ci	mutex_unlock(&trf->lock);
156062306a36Sopenharmony_ci	return ret;
156162306a36Sopenharmony_ci}
156262306a36Sopenharmony_ci
156362306a36Sopenharmony_cistatic int trf7970a_tg_config_rf_tech(struct trf7970a *trf, int tech)
156462306a36Sopenharmony_ci{
156562306a36Sopenharmony_ci	int ret = 0;
156662306a36Sopenharmony_ci
156762306a36Sopenharmony_ci	dev_dbg(trf->dev, "rf technology: %d\n", tech);
156862306a36Sopenharmony_ci
156962306a36Sopenharmony_ci	switch (tech) {
157062306a36Sopenharmony_ci	case NFC_DIGITAL_RF_TECH_106A:
157162306a36Sopenharmony_ci		trf->iso_ctrl_tech = TRF7970A_ISO_CTRL_NFC_NFC_CE_MODE |
157262306a36Sopenharmony_ci		    TRF7970A_ISO_CTRL_NFC_CE | TRF7970A_ISO_CTRL_NFC_CE_14443A;
157362306a36Sopenharmony_ci		trf->modulator_sys_clk_ctrl =
157462306a36Sopenharmony_ci		    (trf->modulator_sys_clk_ctrl & 0xf8) |
157562306a36Sopenharmony_ci		    TRF7970A_MODULATOR_DEPTH_OOK;
157662306a36Sopenharmony_ci		break;
157762306a36Sopenharmony_ci	case NFC_DIGITAL_RF_TECH_212F:
157862306a36Sopenharmony_ci		trf->iso_ctrl_tech = TRF7970A_ISO_CTRL_NFC_NFC_CE_MODE |
157962306a36Sopenharmony_ci		    TRF7970A_ISO_CTRL_NFC_NFCF_212;
158062306a36Sopenharmony_ci		trf->modulator_sys_clk_ctrl =
158162306a36Sopenharmony_ci		    (trf->modulator_sys_clk_ctrl & 0xf8) |
158262306a36Sopenharmony_ci		    TRF7970A_MODULATOR_DEPTH_ASK10;
158362306a36Sopenharmony_ci		break;
158462306a36Sopenharmony_ci	case NFC_DIGITAL_RF_TECH_424F:
158562306a36Sopenharmony_ci		trf->iso_ctrl_tech = TRF7970A_ISO_CTRL_NFC_NFC_CE_MODE |
158662306a36Sopenharmony_ci		    TRF7970A_ISO_CTRL_NFC_NFCF_424;
158762306a36Sopenharmony_ci		trf->modulator_sys_clk_ctrl =
158862306a36Sopenharmony_ci		    (trf->modulator_sys_clk_ctrl & 0xf8) |
158962306a36Sopenharmony_ci		    TRF7970A_MODULATOR_DEPTH_ASK10;
159062306a36Sopenharmony_ci		break;
159162306a36Sopenharmony_ci	default:
159262306a36Sopenharmony_ci		dev_dbg(trf->dev, "Unsupported rf technology: %d\n", tech);
159362306a36Sopenharmony_ci		return -EINVAL;
159462306a36Sopenharmony_ci	}
159562306a36Sopenharmony_ci
159662306a36Sopenharmony_ci	trf->technology = tech;
159762306a36Sopenharmony_ci
159862306a36Sopenharmony_ci	/* Normally we write the ISO_CTRL register in
159962306a36Sopenharmony_ci	 * trf7970a_tg_config_framing() because the framing can change
160062306a36Sopenharmony_ci	 * the value written.  However, when sending a PSL RES,
160162306a36Sopenharmony_ci	 * digital_tg_send_psl_res_complete() doesn't call
160262306a36Sopenharmony_ci	 * trf7970a_tg_config_framing() so we must write the register
160362306a36Sopenharmony_ci	 * here.
160462306a36Sopenharmony_ci	 */
160562306a36Sopenharmony_ci	if ((trf->framing == NFC_DIGITAL_FRAMING_NFC_DEP_ACTIVATED) &&
160662306a36Sopenharmony_ci	    (trf->iso_ctrl_tech != trf->iso_ctrl)) {
160762306a36Sopenharmony_ci		ret = trf7970a_write(trf, TRF7970A_ISO_CTRL,
160862306a36Sopenharmony_ci				     trf->iso_ctrl_tech);
160962306a36Sopenharmony_ci
161062306a36Sopenharmony_ci		trf->iso_ctrl = trf->iso_ctrl_tech;
161162306a36Sopenharmony_ci	}
161262306a36Sopenharmony_ci
161362306a36Sopenharmony_ci	return ret;
161462306a36Sopenharmony_ci}
161562306a36Sopenharmony_ci
161662306a36Sopenharmony_ci/* Since this is a target routine, several of the framing calls are
161762306a36Sopenharmony_ci * made between receiving the request and sending the response so they
161862306a36Sopenharmony_ci * should take effect until after the response is sent.  This is accomplished
161962306a36Sopenharmony_ci * by skipping the ISO_CTRL register write here and doing it in the interrupt
162062306a36Sopenharmony_ci * handler.
162162306a36Sopenharmony_ci */
162262306a36Sopenharmony_cistatic int trf7970a_tg_config_framing(struct trf7970a *trf, int framing)
162362306a36Sopenharmony_ci{
162462306a36Sopenharmony_ci	u8 iso_ctrl = trf->iso_ctrl_tech;
162562306a36Sopenharmony_ci	int ret;
162662306a36Sopenharmony_ci
162762306a36Sopenharmony_ci	dev_dbg(trf->dev, "framing: %d\n", framing);
162862306a36Sopenharmony_ci
162962306a36Sopenharmony_ci	switch (framing) {
163062306a36Sopenharmony_ci	case NFC_DIGITAL_FRAMING_NFCA_NFC_DEP:
163162306a36Sopenharmony_ci		trf->tx_cmd = TRF7970A_CMD_TRANSMIT_NO_CRC;
163262306a36Sopenharmony_ci		iso_ctrl |= TRF7970A_ISO_CTRL_RX_CRC_N;
163362306a36Sopenharmony_ci		break;
163462306a36Sopenharmony_ci	case NFC_DIGITAL_FRAMING_NFCA_STANDARD:
163562306a36Sopenharmony_ci	case NFC_DIGITAL_FRAMING_NFCA_STANDARD_WITH_CRC_A:
163662306a36Sopenharmony_ci	case NFC_DIGITAL_FRAMING_NFCA_ANTICOL_COMPLETE:
163762306a36Sopenharmony_ci		/* These ones are applied in the interrupt handler */
163862306a36Sopenharmony_ci		iso_ctrl = trf->iso_ctrl; /* Don't write to ISO_CTRL yet */
163962306a36Sopenharmony_ci		break;
164062306a36Sopenharmony_ci	case NFC_DIGITAL_FRAMING_NFCF_NFC_DEP:
164162306a36Sopenharmony_ci		trf->tx_cmd = TRF7970A_CMD_TRANSMIT;
164262306a36Sopenharmony_ci		iso_ctrl &= ~TRF7970A_ISO_CTRL_RX_CRC_N;
164362306a36Sopenharmony_ci		break;
164462306a36Sopenharmony_ci	case NFC_DIGITAL_FRAMING_NFC_DEP_ACTIVATED:
164562306a36Sopenharmony_ci		trf->tx_cmd = TRF7970A_CMD_TRANSMIT;
164662306a36Sopenharmony_ci		iso_ctrl &= ~TRF7970A_ISO_CTRL_RX_CRC_N;
164762306a36Sopenharmony_ci		break;
164862306a36Sopenharmony_ci	default:
164962306a36Sopenharmony_ci		dev_dbg(trf->dev, "Unsupported Framing: %d\n", framing);
165062306a36Sopenharmony_ci		return -EINVAL;
165162306a36Sopenharmony_ci	}
165262306a36Sopenharmony_ci
165362306a36Sopenharmony_ci	trf->framing = framing;
165462306a36Sopenharmony_ci
165562306a36Sopenharmony_ci	if (iso_ctrl != trf->iso_ctrl) {
165662306a36Sopenharmony_ci		ret = trf7970a_write(trf, TRF7970A_ISO_CTRL, iso_ctrl);
165762306a36Sopenharmony_ci		if (ret)
165862306a36Sopenharmony_ci			return ret;
165962306a36Sopenharmony_ci
166062306a36Sopenharmony_ci		trf->iso_ctrl = iso_ctrl;
166162306a36Sopenharmony_ci
166262306a36Sopenharmony_ci		ret = trf7970a_write(trf, TRF7970A_MODULATOR_SYS_CLK_CTRL,
166362306a36Sopenharmony_ci				     trf->modulator_sys_clk_ctrl);
166462306a36Sopenharmony_ci		if (ret)
166562306a36Sopenharmony_ci			return ret;
166662306a36Sopenharmony_ci	}
166762306a36Sopenharmony_ci
166862306a36Sopenharmony_ci	if (!(trf->chip_status_ctrl & TRF7970A_CHIP_STATUS_RF_ON)) {
166962306a36Sopenharmony_ci		ret = trf7970a_write(trf, TRF7970A_CHIP_STATUS_CTRL,
167062306a36Sopenharmony_ci				     trf->chip_status_ctrl |
167162306a36Sopenharmony_ci				     TRF7970A_CHIP_STATUS_RF_ON);
167262306a36Sopenharmony_ci		if (ret)
167362306a36Sopenharmony_ci			return ret;
167462306a36Sopenharmony_ci
167562306a36Sopenharmony_ci		trf->chip_status_ctrl |= TRF7970A_CHIP_STATUS_RF_ON;
167662306a36Sopenharmony_ci	}
167762306a36Sopenharmony_ci
167862306a36Sopenharmony_ci	return 0;
167962306a36Sopenharmony_ci}
168062306a36Sopenharmony_ci
168162306a36Sopenharmony_cistatic int trf7970a_tg_configure_hw(struct nfc_digital_dev *ddev, int type,
168262306a36Sopenharmony_ci				    int param)
168362306a36Sopenharmony_ci{
168462306a36Sopenharmony_ci	struct trf7970a *trf = nfc_digital_get_drvdata(ddev);
168562306a36Sopenharmony_ci	int ret;
168662306a36Sopenharmony_ci
168762306a36Sopenharmony_ci	dev_dbg(trf->dev, "Configure hw - type: %d, param: %d\n", type, param);
168862306a36Sopenharmony_ci
168962306a36Sopenharmony_ci	mutex_lock(&trf->lock);
169062306a36Sopenharmony_ci
169162306a36Sopenharmony_ci	trf->is_initiator = false;
169262306a36Sopenharmony_ci
169362306a36Sopenharmony_ci	if ((trf->state == TRF7970A_ST_PWR_OFF) ||
169462306a36Sopenharmony_ci	    (trf->state == TRF7970A_ST_RF_OFF)) {
169562306a36Sopenharmony_ci		ret = trf7970a_switch_rf_on(trf);
169662306a36Sopenharmony_ci		if (ret)
169762306a36Sopenharmony_ci			goto err_unlock;
169862306a36Sopenharmony_ci	}
169962306a36Sopenharmony_ci
170062306a36Sopenharmony_ci	switch (type) {
170162306a36Sopenharmony_ci	case NFC_DIGITAL_CONFIG_RF_TECH:
170262306a36Sopenharmony_ci		ret = trf7970a_tg_config_rf_tech(trf, param);
170362306a36Sopenharmony_ci		break;
170462306a36Sopenharmony_ci	case NFC_DIGITAL_CONFIG_FRAMING:
170562306a36Sopenharmony_ci		ret = trf7970a_tg_config_framing(trf, param);
170662306a36Sopenharmony_ci		break;
170762306a36Sopenharmony_ci	default:
170862306a36Sopenharmony_ci		dev_dbg(trf->dev, "Unknown type: %d\n", type);
170962306a36Sopenharmony_ci		ret = -EINVAL;
171062306a36Sopenharmony_ci	}
171162306a36Sopenharmony_ci
171262306a36Sopenharmony_cierr_unlock:
171362306a36Sopenharmony_ci	mutex_unlock(&trf->lock);
171462306a36Sopenharmony_ci	return ret;
171562306a36Sopenharmony_ci}
171662306a36Sopenharmony_ci
171762306a36Sopenharmony_cistatic int _trf7970a_tg_listen(struct nfc_digital_dev *ddev, u16 timeout,
171862306a36Sopenharmony_ci			       nfc_digital_cmd_complete_t cb, void *arg,
171962306a36Sopenharmony_ci			       bool mode_detect)
172062306a36Sopenharmony_ci{
172162306a36Sopenharmony_ci	struct trf7970a *trf = nfc_digital_get_drvdata(ddev);
172262306a36Sopenharmony_ci	int ret;
172362306a36Sopenharmony_ci
172462306a36Sopenharmony_ci	mutex_lock(&trf->lock);
172562306a36Sopenharmony_ci
172662306a36Sopenharmony_ci	if ((trf->state != TRF7970A_ST_IDLE) &&
172762306a36Sopenharmony_ci	    (trf->state != TRF7970A_ST_IDLE_RX_BLOCKED)) {
172862306a36Sopenharmony_ci		dev_err(trf->dev, "%s - Bogus state: %d\n", __func__,
172962306a36Sopenharmony_ci			trf->state);
173062306a36Sopenharmony_ci		ret = -EIO;
173162306a36Sopenharmony_ci		goto out_err;
173262306a36Sopenharmony_ci	}
173362306a36Sopenharmony_ci
173462306a36Sopenharmony_ci	if (trf->aborting) {
173562306a36Sopenharmony_ci		dev_dbg(trf->dev, "Abort process complete\n");
173662306a36Sopenharmony_ci		trf->aborting = false;
173762306a36Sopenharmony_ci		ret = -ECANCELED;
173862306a36Sopenharmony_ci		goto out_err;
173962306a36Sopenharmony_ci	}
174062306a36Sopenharmony_ci
174162306a36Sopenharmony_ci	trf->rx_skb = nfc_alloc_recv_skb(TRF7970A_RX_SKB_ALLOC_SIZE,
174262306a36Sopenharmony_ci					 GFP_KERNEL);
174362306a36Sopenharmony_ci	if (!trf->rx_skb) {
174462306a36Sopenharmony_ci		dev_dbg(trf->dev, "Can't alloc rx_skb\n");
174562306a36Sopenharmony_ci		ret = -ENOMEM;
174662306a36Sopenharmony_ci		goto out_err;
174762306a36Sopenharmony_ci	}
174862306a36Sopenharmony_ci
174962306a36Sopenharmony_ci	ret = trf7970a_write(trf, TRF7970A_RX_SPECIAL_SETTINGS,
175062306a36Sopenharmony_ci			     TRF7970A_RX_SPECIAL_SETTINGS_HBT |
175162306a36Sopenharmony_ci			     TRF7970A_RX_SPECIAL_SETTINGS_M848 |
175262306a36Sopenharmony_ci			     TRF7970A_RX_SPECIAL_SETTINGS_C424 |
175362306a36Sopenharmony_ci			     TRF7970A_RX_SPECIAL_SETTINGS_C212);
175462306a36Sopenharmony_ci	if (ret)
175562306a36Sopenharmony_ci		goto out_err;
175662306a36Sopenharmony_ci
175762306a36Sopenharmony_ci	ret = trf7970a_write(trf, TRF7970A_REG_IO_CTRL,
175862306a36Sopenharmony_ci			     trf->io_ctrl | TRF7970A_REG_IO_CTRL_VRS(0x1));
175962306a36Sopenharmony_ci	if (ret)
176062306a36Sopenharmony_ci		goto out_err;
176162306a36Sopenharmony_ci
176262306a36Sopenharmony_ci	ret = trf7970a_write(trf, TRF7970A_NFC_LOW_FIELD_LEVEL,
176362306a36Sopenharmony_ci			     TRF7970A_NFC_LOW_FIELD_LEVEL_RFDET(0x3));
176462306a36Sopenharmony_ci	if (ret)
176562306a36Sopenharmony_ci		goto out_err;
176662306a36Sopenharmony_ci
176762306a36Sopenharmony_ci	ret = trf7970a_write(trf, TRF7970A_NFC_TARGET_LEVEL,
176862306a36Sopenharmony_ci			     TRF7970A_NFC_TARGET_LEVEL_RFDET(0x7));
176962306a36Sopenharmony_ci	if (ret)
177062306a36Sopenharmony_ci		goto out_err;
177162306a36Sopenharmony_ci
177262306a36Sopenharmony_ci	trf->ddev = ddev;
177362306a36Sopenharmony_ci	trf->cb = cb;
177462306a36Sopenharmony_ci	trf->cb_arg = arg;
177562306a36Sopenharmony_ci	trf->timeout = timeout;
177662306a36Sopenharmony_ci	trf->ignore_timeout = false;
177762306a36Sopenharmony_ci
177862306a36Sopenharmony_ci	ret = trf7970a_cmd(trf, TRF7970A_CMD_ENABLE_RX);
177962306a36Sopenharmony_ci	if (ret)
178062306a36Sopenharmony_ci		goto out_err;
178162306a36Sopenharmony_ci
178262306a36Sopenharmony_ci	trf->state = mode_detect ? TRF7970A_ST_LISTENING_MD :
178362306a36Sopenharmony_ci				   TRF7970A_ST_LISTENING;
178462306a36Sopenharmony_ci
178562306a36Sopenharmony_ci	schedule_delayed_work(&trf->timeout_work, msecs_to_jiffies(timeout));
178662306a36Sopenharmony_ci
178762306a36Sopenharmony_ciout_err:
178862306a36Sopenharmony_ci	mutex_unlock(&trf->lock);
178962306a36Sopenharmony_ci	return ret;
179062306a36Sopenharmony_ci}
179162306a36Sopenharmony_ci
179262306a36Sopenharmony_cistatic int trf7970a_tg_listen(struct nfc_digital_dev *ddev, u16 timeout,
179362306a36Sopenharmony_ci			      nfc_digital_cmd_complete_t cb, void *arg)
179462306a36Sopenharmony_ci{
179562306a36Sopenharmony_ci	const struct trf7970a *trf = nfc_digital_get_drvdata(ddev);
179662306a36Sopenharmony_ci
179762306a36Sopenharmony_ci	dev_dbg(trf->dev, "Listen - state: %d, timeout: %d ms\n",
179862306a36Sopenharmony_ci		trf->state, timeout);
179962306a36Sopenharmony_ci
180062306a36Sopenharmony_ci	return _trf7970a_tg_listen(ddev, timeout, cb, arg, false);
180162306a36Sopenharmony_ci}
180262306a36Sopenharmony_ci
180362306a36Sopenharmony_cistatic int trf7970a_tg_listen_md(struct nfc_digital_dev *ddev,
180462306a36Sopenharmony_ci				 u16 timeout, nfc_digital_cmd_complete_t cb,
180562306a36Sopenharmony_ci				 void *arg)
180662306a36Sopenharmony_ci{
180762306a36Sopenharmony_ci	const struct trf7970a *trf = nfc_digital_get_drvdata(ddev);
180862306a36Sopenharmony_ci	int ret;
180962306a36Sopenharmony_ci
181062306a36Sopenharmony_ci	dev_dbg(trf->dev, "Listen MD - state: %d, timeout: %d ms\n",
181162306a36Sopenharmony_ci		trf->state, timeout);
181262306a36Sopenharmony_ci
181362306a36Sopenharmony_ci	ret = trf7970a_tg_configure_hw(ddev, NFC_DIGITAL_CONFIG_RF_TECH,
181462306a36Sopenharmony_ci				       NFC_DIGITAL_RF_TECH_106A);
181562306a36Sopenharmony_ci	if (ret)
181662306a36Sopenharmony_ci		return ret;
181762306a36Sopenharmony_ci
181862306a36Sopenharmony_ci	ret = trf7970a_tg_configure_hw(ddev, NFC_DIGITAL_CONFIG_FRAMING,
181962306a36Sopenharmony_ci				       NFC_DIGITAL_FRAMING_NFCA_NFC_DEP);
182062306a36Sopenharmony_ci	if (ret)
182162306a36Sopenharmony_ci		return ret;
182262306a36Sopenharmony_ci
182362306a36Sopenharmony_ci	return _trf7970a_tg_listen(ddev, timeout, cb, arg, true);
182462306a36Sopenharmony_ci}
182562306a36Sopenharmony_ci
182662306a36Sopenharmony_cistatic int trf7970a_tg_get_rf_tech(struct nfc_digital_dev *ddev, u8 *rf_tech)
182762306a36Sopenharmony_ci{
182862306a36Sopenharmony_ci	const struct trf7970a *trf = nfc_digital_get_drvdata(ddev);
182962306a36Sopenharmony_ci
183062306a36Sopenharmony_ci	dev_dbg(trf->dev, "Get RF Tech - state: %d, rf_tech: %d\n",
183162306a36Sopenharmony_ci		trf->state, trf->md_rf_tech);
183262306a36Sopenharmony_ci
183362306a36Sopenharmony_ci	*rf_tech = trf->md_rf_tech;
183462306a36Sopenharmony_ci
183562306a36Sopenharmony_ci	return 0;
183662306a36Sopenharmony_ci}
183762306a36Sopenharmony_ci
183862306a36Sopenharmony_cistatic void trf7970a_abort_cmd(struct nfc_digital_dev *ddev)
183962306a36Sopenharmony_ci{
184062306a36Sopenharmony_ci	struct trf7970a *trf = nfc_digital_get_drvdata(ddev);
184162306a36Sopenharmony_ci
184262306a36Sopenharmony_ci	dev_dbg(trf->dev, "Abort process initiated\n");
184362306a36Sopenharmony_ci
184462306a36Sopenharmony_ci	mutex_lock(&trf->lock);
184562306a36Sopenharmony_ci
184662306a36Sopenharmony_ci	switch (trf->state) {
184762306a36Sopenharmony_ci	case TRF7970A_ST_WAIT_FOR_TX_FIFO:
184862306a36Sopenharmony_ci	case TRF7970A_ST_WAIT_FOR_RX_DATA:
184962306a36Sopenharmony_ci	case TRF7970A_ST_WAIT_FOR_RX_DATA_CONT:
185062306a36Sopenharmony_ci	case TRF7970A_ST_WAIT_TO_ISSUE_EOF:
185162306a36Sopenharmony_ci		trf->aborting = true;
185262306a36Sopenharmony_ci		break;
185362306a36Sopenharmony_ci	case TRF7970A_ST_LISTENING:
185462306a36Sopenharmony_ci		trf->ignore_timeout = !cancel_delayed_work(&trf->timeout_work);
185562306a36Sopenharmony_ci		trf7970a_send_err_upstream(trf, -ECANCELED);
185662306a36Sopenharmony_ci		dev_dbg(trf->dev, "Abort process complete\n");
185762306a36Sopenharmony_ci		break;
185862306a36Sopenharmony_ci	default:
185962306a36Sopenharmony_ci		break;
186062306a36Sopenharmony_ci	}
186162306a36Sopenharmony_ci
186262306a36Sopenharmony_ci	mutex_unlock(&trf->lock);
186362306a36Sopenharmony_ci}
186462306a36Sopenharmony_ci
186562306a36Sopenharmony_cistatic const struct nfc_digital_ops trf7970a_nfc_ops = {
186662306a36Sopenharmony_ci	.in_configure_hw	= trf7970a_in_configure_hw,
186762306a36Sopenharmony_ci	.in_send_cmd		= trf7970a_send_cmd,
186862306a36Sopenharmony_ci	.tg_configure_hw	= trf7970a_tg_configure_hw,
186962306a36Sopenharmony_ci	.tg_send_cmd		= trf7970a_send_cmd,
187062306a36Sopenharmony_ci	.tg_listen		= trf7970a_tg_listen,
187162306a36Sopenharmony_ci	.tg_listen_md		= trf7970a_tg_listen_md,
187262306a36Sopenharmony_ci	.tg_get_rf_tech		= trf7970a_tg_get_rf_tech,
187362306a36Sopenharmony_ci	.switch_rf		= trf7970a_switch_rf,
187462306a36Sopenharmony_ci	.abort_cmd		= trf7970a_abort_cmd,
187562306a36Sopenharmony_ci};
187662306a36Sopenharmony_ci
187762306a36Sopenharmony_cistatic int trf7970a_power_up(struct trf7970a *trf)
187862306a36Sopenharmony_ci{
187962306a36Sopenharmony_ci	int ret;
188062306a36Sopenharmony_ci
188162306a36Sopenharmony_ci	dev_dbg(trf->dev, "Powering up - state: %d\n", trf->state);
188262306a36Sopenharmony_ci
188362306a36Sopenharmony_ci	if (trf->state != TRF7970A_ST_PWR_OFF)
188462306a36Sopenharmony_ci		return 0;
188562306a36Sopenharmony_ci
188662306a36Sopenharmony_ci	ret = regulator_enable(trf->regulator);
188762306a36Sopenharmony_ci	if (ret) {
188862306a36Sopenharmony_ci		dev_err(trf->dev, "%s - Can't enable VIN: %d\n", __func__, ret);
188962306a36Sopenharmony_ci		return ret;
189062306a36Sopenharmony_ci	}
189162306a36Sopenharmony_ci
189262306a36Sopenharmony_ci	usleep_range(5000, 6000);
189362306a36Sopenharmony_ci
189462306a36Sopenharmony_ci	if (trf->en2_gpiod &&
189562306a36Sopenharmony_ci	    !(trf->quirks & TRF7970A_QUIRK_EN2_MUST_STAY_LOW)) {
189662306a36Sopenharmony_ci		gpiod_set_value_cansleep(trf->en2_gpiod, 1);
189762306a36Sopenharmony_ci		usleep_range(1000, 2000);
189862306a36Sopenharmony_ci	}
189962306a36Sopenharmony_ci
190062306a36Sopenharmony_ci	gpiod_set_value_cansleep(trf->en_gpiod, 1);
190162306a36Sopenharmony_ci
190262306a36Sopenharmony_ci	usleep_range(20000, 21000);
190362306a36Sopenharmony_ci
190462306a36Sopenharmony_ci	trf->state = TRF7970A_ST_RF_OFF;
190562306a36Sopenharmony_ci
190662306a36Sopenharmony_ci	return 0;
190762306a36Sopenharmony_ci}
190862306a36Sopenharmony_ci
190962306a36Sopenharmony_cistatic int trf7970a_power_down(struct trf7970a *trf)
191062306a36Sopenharmony_ci{
191162306a36Sopenharmony_ci	int ret;
191262306a36Sopenharmony_ci
191362306a36Sopenharmony_ci	dev_dbg(trf->dev, "Powering down - state: %d\n", trf->state);
191462306a36Sopenharmony_ci
191562306a36Sopenharmony_ci	if (trf->state == TRF7970A_ST_PWR_OFF)
191662306a36Sopenharmony_ci		return 0;
191762306a36Sopenharmony_ci
191862306a36Sopenharmony_ci	if (trf->state != TRF7970A_ST_RF_OFF) {
191962306a36Sopenharmony_ci		dev_dbg(trf->dev, "Can't power down - not RF_OFF state (%d)\n",
192062306a36Sopenharmony_ci			trf->state);
192162306a36Sopenharmony_ci		return -EBUSY;
192262306a36Sopenharmony_ci	}
192362306a36Sopenharmony_ci
192462306a36Sopenharmony_ci	gpiod_set_value_cansleep(trf->en_gpiod, 0);
192562306a36Sopenharmony_ci
192662306a36Sopenharmony_ci	if (trf->en2_gpiod && !(trf->quirks & TRF7970A_QUIRK_EN2_MUST_STAY_LOW))
192762306a36Sopenharmony_ci		gpiod_set_value_cansleep(trf->en2_gpiod, 0);
192862306a36Sopenharmony_ci
192962306a36Sopenharmony_ci	ret = regulator_disable(trf->regulator);
193062306a36Sopenharmony_ci	if (ret)
193162306a36Sopenharmony_ci		dev_err(trf->dev, "%s - Can't disable VIN: %d\n", __func__,
193262306a36Sopenharmony_ci			ret);
193362306a36Sopenharmony_ci
193462306a36Sopenharmony_ci	trf->state = TRF7970A_ST_PWR_OFF;
193562306a36Sopenharmony_ci
193662306a36Sopenharmony_ci	return ret;
193762306a36Sopenharmony_ci}
193862306a36Sopenharmony_ci
193962306a36Sopenharmony_cistatic int trf7970a_startup(struct trf7970a *trf)
194062306a36Sopenharmony_ci{
194162306a36Sopenharmony_ci	int ret;
194262306a36Sopenharmony_ci
194362306a36Sopenharmony_ci	ret = trf7970a_power_up(trf);
194462306a36Sopenharmony_ci	if (ret)
194562306a36Sopenharmony_ci		return ret;
194662306a36Sopenharmony_ci
194762306a36Sopenharmony_ci	pm_runtime_set_active(trf->dev);
194862306a36Sopenharmony_ci	pm_runtime_enable(trf->dev);
194962306a36Sopenharmony_ci	pm_runtime_mark_last_busy(trf->dev);
195062306a36Sopenharmony_ci
195162306a36Sopenharmony_ci	return 0;
195262306a36Sopenharmony_ci}
195362306a36Sopenharmony_ci
195462306a36Sopenharmony_cistatic void trf7970a_shutdown(struct trf7970a *trf)
195562306a36Sopenharmony_ci{
195662306a36Sopenharmony_ci	switch (trf->state) {
195762306a36Sopenharmony_ci	case TRF7970A_ST_WAIT_FOR_TX_FIFO:
195862306a36Sopenharmony_ci	case TRF7970A_ST_WAIT_FOR_RX_DATA:
195962306a36Sopenharmony_ci	case TRF7970A_ST_WAIT_FOR_RX_DATA_CONT:
196062306a36Sopenharmony_ci	case TRF7970A_ST_WAIT_TO_ISSUE_EOF:
196162306a36Sopenharmony_ci	case TRF7970A_ST_LISTENING:
196262306a36Sopenharmony_ci		trf7970a_send_err_upstream(trf, -ECANCELED);
196362306a36Sopenharmony_ci		fallthrough;
196462306a36Sopenharmony_ci	case TRF7970A_ST_IDLE:
196562306a36Sopenharmony_ci	case TRF7970A_ST_IDLE_RX_BLOCKED:
196662306a36Sopenharmony_ci		trf7970a_switch_rf_off(trf);
196762306a36Sopenharmony_ci		break;
196862306a36Sopenharmony_ci	default:
196962306a36Sopenharmony_ci		break;
197062306a36Sopenharmony_ci	}
197162306a36Sopenharmony_ci
197262306a36Sopenharmony_ci	pm_runtime_disable(trf->dev);
197362306a36Sopenharmony_ci	pm_runtime_set_suspended(trf->dev);
197462306a36Sopenharmony_ci
197562306a36Sopenharmony_ci	trf7970a_power_down(trf);
197662306a36Sopenharmony_ci}
197762306a36Sopenharmony_ci
197862306a36Sopenharmony_cistatic int trf7970a_get_autosuspend_delay(const struct device_node *np)
197962306a36Sopenharmony_ci{
198062306a36Sopenharmony_ci	int autosuspend_delay, ret;
198162306a36Sopenharmony_ci
198262306a36Sopenharmony_ci	ret = of_property_read_u32(np, "autosuspend-delay", &autosuspend_delay);
198362306a36Sopenharmony_ci	if (ret)
198462306a36Sopenharmony_ci		autosuspend_delay = TRF7970A_AUTOSUSPEND_DELAY;
198562306a36Sopenharmony_ci
198662306a36Sopenharmony_ci	return autosuspend_delay;
198762306a36Sopenharmony_ci}
198862306a36Sopenharmony_ci
198962306a36Sopenharmony_cistatic int trf7970a_probe(struct spi_device *spi)
199062306a36Sopenharmony_ci{
199162306a36Sopenharmony_ci	const struct device_node *np = spi->dev.of_node;
199262306a36Sopenharmony_ci	struct trf7970a *trf;
199362306a36Sopenharmony_ci	int uvolts, autosuspend_delay, ret;
199462306a36Sopenharmony_ci	u32 clk_freq = TRF7970A_13MHZ_CLOCK_FREQUENCY;
199562306a36Sopenharmony_ci
199662306a36Sopenharmony_ci	if (!np) {
199762306a36Sopenharmony_ci		dev_err(&spi->dev, "No Device Tree entry\n");
199862306a36Sopenharmony_ci		return -EINVAL;
199962306a36Sopenharmony_ci	}
200062306a36Sopenharmony_ci
200162306a36Sopenharmony_ci	trf = devm_kzalloc(&spi->dev, sizeof(*trf), GFP_KERNEL);
200262306a36Sopenharmony_ci	if (!trf)
200362306a36Sopenharmony_ci		return -ENOMEM;
200462306a36Sopenharmony_ci
200562306a36Sopenharmony_ci	trf->state = TRF7970A_ST_PWR_OFF;
200662306a36Sopenharmony_ci	trf->dev = &spi->dev;
200762306a36Sopenharmony_ci	trf->spi = spi;
200862306a36Sopenharmony_ci
200962306a36Sopenharmony_ci	spi->mode = SPI_MODE_1;
201062306a36Sopenharmony_ci	spi->bits_per_word = 8;
201162306a36Sopenharmony_ci
201262306a36Sopenharmony_ci	ret = spi_setup(spi);
201362306a36Sopenharmony_ci	if (ret < 0) {
201462306a36Sopenharmony_ci		dev_err(trf->dev, "Can't set up SPI Communication\n");
201562306a36Sopenharmony_ci		return ret;
201662306a36Sopenharmony_ci	}
201762306a36Sopenharmony_ci
201862306a36Sopenharmony_ci	if (of_property_read_bool(np, "irq-status-read-quirk"))
201962306a36Sopenharmony_ci		trf->quirks |= TRF7970A_QUIRK_IRQ_STATUS_READ;
202062306a36Sopenharmony_ci
202162306a36Sopenharmony_ci	/* There are two enable pins - only EN must be present in the DT */
202262306a36Sopenharmony_ci	trf->en_gpiod = devm_gpiod_get_index(trf->dev, "ti,enable", 0,
202362306a36Sopenharmony_ci					     GPIOD_OUT_LOW);
202462306a36Sopenharmony_ci	if (IS_ERR(trf->en_gpiod)) {
202562306a36Sopenharmony_ci		dev_err(trf->dev, "No EN GPIO property\n");
202662306a36Sopenharmony_ci		return PTR_ERR(trf->en_gpiod);
202762306a36Sopenharmony_ci	}
202862306a36Sopenharmony_ci
202962306a36Sopenharmony_ci	trf->en2_gpiod = devm_gpiod_get_index_optional(trf->dev, "ti,enable", 1,
203062306a36Sopenharmony_ci						       GPIOD_OUT_LOW);
203162306a36Sopenharmony_ci	if (!trf->en2_gpiod) {
203262306a36Sopenharmony_ci		dev_info(trf->dev, "No EN2 GPIO property\n");
203362306a36Sopenharmony_ci	} else if (IS_ERR(trf->en2_gpiod)) {
203462306a36Sopenharmony_ci		dev_err(trf->dev, "Error getting EN2 GPIO property: %ld\n",
203562306a36Sopenharmony_ci			PTR_ERR(trf->en2_gpiod));
203662306a36Sopenharmony_ci		return PTR_ERR(trf->en2_gpiod);
203762306a36Sopenharmony_ci	} else if (of_property_read_bool(np, "en2-rf-quirk")) {
203862306a36Sopenharmony_ci		trf->quirks |= TRF7970A_QUIRK_EN2_MUST_STAY_LOW;
203962306a36Sopenharmony_ci	}
204062306a36Sopenharmony_ci
204162306a36Sopenharmony_ci	of_property_read_u32(np, "clock-frequency", &clk_freq);
204262306a36Sopenharmony_ci	if ((clk_freq != TRF7970A_27MHZ_CLOCK_FREQUENCY) &&
204362306a36Sopenharmony_ci	    (clk_freq != TRF7970A_13MHZ_CLOCK_FREQUENCY)) {
204462306a36Sopenharmony_ci		dev_err(trf->dev,
204562306a36Sopenharmony_ci			"clock-frequency (%u Hz) unsupported\n", clk_freq);
204662306a36Sopenharmony_ci		return -EINVAL;
204762306a36Sopenharmony_ci	}
204862306a36Sopenharmony_ci
204962306a36Sopenharmony_ci	if (clk_freq == TRF7970A_27MHZ_CLOCK_FREQUENCY) {
205062306a36Sopenharmony_ci		trf->modulator_sys_clk_ctrl = TRF7970A_MODULATOR_27MHZ;
205162306a36Sopenharmony_ci		dev_dbg(trf->dev, "trf7970a configured for 27MHz crystal\n");
205262306a36Sopenharmony_ci	} else {
205362306a36Sopenharmony_ci		trf->modulator_sys_clk_ctrl = 0;
205462306a36Sopenharmony_ci	}
205562306a36Sopenharmony_ci
205662306a36Sopenharmony_ci	ret = devm_request_threaded_irq(trf->dev, spi->irq, NULL,
205762306a36Sopenharmony_ci					trf7970a_irq,
205862306a36Sopenharmony_ci					IRQF_TRIGGER_RISING | IRQF_ONESHOT,
205962306a36Sopenharmony_ci					"trf7970a", trf);
206062306a36Sopenharmony_ci	if (ret) {
206162306a36Sopenharmony_ci		dev_err(trf->dev, "Can't request IRQ#%d: %d\n", spi->irq, ret);
206262306a36Sopenharmony_ci		return ret;
206362306a36Sopenharmony_ci	}
206462306a36Sopenharmony_ci
206562306a36Sopenharmony_ci	mutex_init(&trf->lock);
206662306a36Sopenharmony_ci	INIT_DELAYED_WORK(&trf->timeout_work, trf7970a_timeout_work_handler);
206762306a36Sopenharmony_ci
206862306a36Sopenharmony_ci	trf->regulator = devm_regulator_get(&spi->dev, "vin");
206962306a36Sopenharmony_ci	if (IS_ERR(trf->regulator)) {
207062306a36Sopenharmony_ci		ret = PTR_ERR(trf->regulator);
207162306a36Sopenharmony_ci		dev_err(trf->dev, "Can't get VIN regulator: %d\n", ret);
207262306a36Sopenharmony_ci		goto err_destroy_lock;
207362306a36Sopenharmony_ci	}
207462306a36Sopenharmony_ci
207562306a36Sopenharmony_ci	ret = regulator_enable(trf->regulator);
207662306a36Sopenharmony_ci	if (ret) {
207762306a36Sopenharmony_ci		dev_err(trf->dev, "Can't enable VIN: %d\n", ret);
207862306a36Sopenharmony_ci		goto err_destroy_lock;
207962306a36Sopenharmony_ci	}
208062306a36Sopenharmony_ci
208162306a36Sopenharmony_ci	uvolts = regulator_get_voltage(trf->regulator);
208262306a36Sopenharmony_ci	if (uvolts > 4000000)
208362306a36Sopenharmony_ci		trf->chip_status_ctrl = TRF7970A_CHIP_STATUS_VRS5_3;
208462306a36Sopenharmony_ci
208562306a36Sopenharmony_ci	trf->regulator = devm_regulator_get(&spi->dev, "vdd-io");
208662306a36Sopenharmony_ci	if (IS_ERR(trf->regulator)) {
208762306a36Sopenharmony_ci		ret = PTR_ERR(trf->regulator);
208862306a36Sopenharmony_ci		dev_err(trf->dev, "Can't get VDD_IO regulator: %d\n", ret);
208962306a36Sopenharmony_ci		goto err_destroy_lock;
209062306a36Sopenharmony_ci	}
209162306a36Sopenharmony_ci
209262306a36Sopenharmony_ci	ret = regulator_enable(trf->regulator);
209362306a36Sopenharmony_ci	if (ret) {
209462306a36Sopenharmony_ci		dev_err(trf->dev, "Can't enable VDD_IO: %d\n", ret);
209562306a36Sopenharmony_ci		goto err_destroy_lock;
209662306a36Sopenharmony_ci	}
209762306a36Sopenharmony_ci
209862306a36Sopenharmony_ci	if (regulator_get_voltage(trf->regulator) == 1800000) {
209962306a36Sopenharmony_ci		trf->io_ctrl = TRF7970A_REG_IO_CTRL_IO_LOW;
210062306a36Sopenharmony_ci		dev_dbg(trf->dev, "trf7970a config vdd_io to 1.8V\n");
210162306a36Sopenharmony_ci	}
210262306a36Sopenharmony_ci
210362306a36Sopenharmony_ci	trf->ddev = nfc_digital_allocate_device(&trf7970a_nfc_ops,
210462306a36Sopenharmony_ci						TRF7970A_SUPPORTED_PROTOCOLS,
210562306a36Sopenharmony_ci						NFC_DIGITAL_DRV_CAPS_IN_CRC |
210662306a36Sopenharmony_ci						NFC_DIGITAL_DRV_CAPS_TG_CRC, 0,
210762306a36Sopenharmony_ci						0);
210862306a36Sopenharmony_ci	if (!trf->ddev) {
210962306a36Sopenharmony_ci		dev_err(trf->dev, "Can't allocate NFC digital device\n");
211062306a36Sopenharmony_ci		ret = -ENOMEM;
211162306a36Sopenharmony_ci		goto err_disable_regulator;
211262306a36Sopenharmony_ci	}
211362306a36Sopenharmony_ci
211462306a36Sopenharmony_ci	nfc_digital_set_parent_dev(trf->ddev, trf->dev);
211562306a36Sopenharmony_ci	nfc_digital_set_drvdata(trf->ddev, trf);
211662306a36Sopenharmony_ci	spi_set_drvdata(spi, trf);
211762306a36Sopenharmony_ci
211862306a36Sopenharmony_ci	autosuspend_delay = trf7970a_get_autosuspend_delay(np);
211962306a36Sopenharmony_ci
212062306a36Sopenharmony_ci	pm_runtime_set_autosuspend_delay(trf->dev, autosuspend_delay);
212162306a36Sopenharmony_ci	pm_runtime_use_autosuspend(trf->dev);
212262306a36Sopenharmony_ci
212362306a36Sopenharmony_ci	ret = trf7970a_startup(trf);
212462306a36Sopenharmony_ci	if (ret)
212562306a36Sopenharmony_ci		goto err_free_ddev;
212662306a36Sopenharmony_ci
212762306a36Sopenharmony_ci	ret = nfc_digital_register_device(trf->ddev);
212862306a36Sopenharmony_ci	if (ret) {
212962306a36Sopenharmony_ci		dev_err(trf->dev, "Can't register NFC digital device: %d\n",
213062306a36Sopenharmony_ci			ret);
213162306a36Sopenharmony_ci		goto err_shutdown;
213262306a36Sopenharmony_ci	}
213362306a36Sopenharmony_ci
213462306a36Sopenharmony_ci	return 0;
213562306a36Sopenharmony_ci
213662306a36Sopenharmony_cierr_shutdown:
213762306a36Sopenharmony_ci	trf7970a_shutdown(trf);
213862306a36Sopenharmony_cierr_free_ddev:
213962306a36Sopenharmony_ci	nfc_digital_free_device(trf->ddev);
214062306a36Sopenharmony_cierr_disable_regulator:
214162306a36Sopenharmony_ci	regulator_disable(trf->regulator);
214262306a36Sopenharmony_cierr_destroy_lock:
214362306a36Sopenharmony_ci	mutex_destroy(&trf->lock);
214462306a36Sopenharmony_ci	return ret;
214562306a36Sopenharmony_ci}
214662306a36Sopenharmony_ci
214762306a36Sopenharmony_cistatic void trf7970a_remove(struct spi_device *spi)
214862306a36Sopenharmony_ci{
214962306a36Sopenharmony_ci	struct trf7970a *trf = spi_get_drvdata(spi);
215062306a36Sopenharmony_ci
215162306a36Sopenharmony_ci	mutex_lock(&trf->lock);
215262306a36Sopenharmony_ci
215362306a36Sopenharmony_ci	trf7970a_shutdown(trf);
215462306a36Sopenharmony_ci
215562306a36Sopenharmony_ci	mutex_unlock(&trf->lock);
215662306a36Sopenharmony_ci
215762306a36Sopenharmony_ci	nfc_digital_unregister_device(trf->ddev);
215862306a36Sopenharmony_ci	nfc_digital_free_device(trf->ddev);
215962306a36Sopenharmony_ci
216062306a36Sopenharmony_ci	regulator_disable(trf->regulator);
216162306a36Sopenharmony_ci
216262306a36Sopenharmony_ci	mutex_destroy(&trf->lock);
216362306a36Sopenharmony_ci}
216462306a36Sopenharmony_ci
216562306a36Sopenharmony_ci#ifdef CONFIG_PM_SLEEP
216662306a36Sopenharmony_cistatic int trf7970a_suspend(struct device *dev)
216762306a36Sopenharmony_ci{
216862306a36Sopenharmony_ci	struct spi_device *spi = to_spi_device(dev);
216962306a36Sopenharmony_ci	struct trf7970a *trf = spi_get_drvdata(spi);
217062306a36Sopenharmony_ci
217162306a36Sopenharmony_ci	mutex_lock(&trf->lock);
217262306a36Sopenharmony_ci
217362306a36Sopenharmony_ci	trf7970a_shutdown(trf);
217462306a36Sopenharmony_ci
217562306a36Sopenharmony_ci	mutex_unlock(&trf->lock);
217662306a36Sopenharmony_ci
217762306a36Sopenharmony_ci	return 0;
217862306a36Sopenharmony_ci}
217962306a36Sopenharmony_ci
218062306a36Sopenharmony_cistatic int trf7970a_resume(struct device *dev)
218162306a36Sopenharmony_ci{
218262306a36Sopenharmony_ci	struct spi_device *spi = to_spi_device(dev);
218362306a36Sopenharmony_ci	struct trf7970a *trf = spi_get_drvdata(spi);
218462306a36Sopenharmony_ci	int ret;
218562306a36Sopenharmony_ci
218662306a36Sopenharmony_ci	mutex_lock(&trf->lock);
218762306a36Sopenharmony_ci
218862306a36Sopenharmony_ci	ret = trf7970a_startup(trf);
218962306a36Sopenharmony_ci
219062306a36Sopenharmony_ci	mutex_unlock(&trf->lock);
219162306a36Sopenharmony_ci
219262306a36Sopenharmony_ci	return ret;
219362306a36Sopenharmony_ci}
219462306a36Sopenharmony_ci#endif
219562306a36Sopenharmony_ci
219662306a36Sopenharmony_ci#ifdef CONFIG_PM
219762306a36Sopenharmony_cistatic int trf7970a_pm_runtime_suspend(struct device *dev)
219862306a36Sopenharmony_ci{
219962306a36Sopenharmony_ci	struct spi_device *spi = to_spi_device(dev);
220062306a36Sopenharmony_ci	struct trf7970a *trf = spi_get_drvdata(spi);
220162306a36Sopenharmony_ci	int ret;
220262306a36Sopenharmony_ci
220362306a36Sopenharmony_ci	mutex_lock(&trf->lock);
220462306a36Sopenharmony_ci
220562306a36Sopenharmony_ci	ret = trf7970a_power_down(trf);
220662306a36Sopenharmony_ci
220762306a36Sopenharmony_ci	mutex_unlock(&trf->lock);
220862306a36Sopenharmony_ci
220962306a36Sopenharmony_ci	return ret;
221062306a36Sopenharmony_ci}
221162306a36Sopenharmony_ci
221262306a36Sopenharmony_cistatic int trf7970a_pm_runtime_resume(struct device *dev)
221362306a36Sopenharmony_ci{
221462306a36Sopenharmony_ci	struct spi_device *spi = to_spi_device(dev);
221562306a36Sopenharmony_ci	struct trf7970a *trf = spi_get_drvdata(spi);
221662306a36Sopenharmony_ci	int ret;
221762306a36Sopenharmony_ci
221862306a36Sopenharmony_ci	ret = trf7970a_power_up(trf);
221962306a36Sopenharmony_ci	if (!ret)
222062306a36Sopenharmony_ci		pm_runtime_mark_last_busy(dev);
222162306a36Sopenharmony_ci
222262306a36Sopenharmony_ci	return ret;
222362306a36Sopenharmony_ci}
222462306a36Sopenharmony_ci#endif
222562306a36Sopenharmony_ci
222662306a36Sopenharmony_cistatic const struct dev_pm_ops trf7970a_pm_ops = {
222762306a36Sopenharmony_ci	SET_SYSTEM_SLEEP_PM_OPS(trf7970a_suspend, trf7970a_resume)
222862306a36Sopenharmony_ci	SET_RUNTIME_PM_OPS(trf7970a_pm_runtime_suspend,
222962306a36Sopenharmony_ci			   trf7970a_pm_runtime_resume, NULL)
223062306a36Sopenharmony_ci};
223162306a36Sopenharmony_ci
223262306a36Sopenharmony_cistatic const struct of_device_id trf7970a_of_match[] __maybe_unused = {
223362306a36Sopenharmony_ci	{.compatible = "ti,trf7970a",},
223462306a36Sopenharmony_ci	{},
223562306a36Sopenharmony_ci};
223662306a36Sopenharmony_ci
223762306a36Sopenharmony_ciMODULE_DEVICE_TABLE(of, trf7970a_of_match);
223862306a36Sopenharmony_ci
223962306a36Sopenharmony_cistatic const struct spi_device_id trf7970a_id_table[] = {
224062306a36Sopenharmony_ci	{"trf7970a", 0},
224162306a36Sopenharmony_ci	{}
224262306a36Sopenharmony_ci};
224362306a36Sopenharmony_ci
224462306a36Sopenharmony_ciMODULE_DEVICE_TABLE(spi, trf7970a_id_table);
224562306a36Sopenharmony_ci
224662306a36Sopenharmony_cistatic struct spi_driver trf7970a_spi_driver = {
224762306a36Sopenharmony_ci	.probe		= trf7970a_probe,
224862306a36Sopenharmony_ci	.remove		= trf7970a_remove,
224962306a36Sopenharmony_ci	.id_table	= trf7970a_id_table,
225062306a36Sopenharmony_ci	.driver	= {
225162306a36Sopenharmony_ci		.name		= "trf7970a",
225262306a36Sopenharmony_ci		.of_match_table	= of_match_ptr(trf7970a_of_match),
225362306a36Sopenharmony_ci		.pm		= &trf7970a_pm_ops,
225462306a36Sopenharmony_ci	},
225562306a36Sopenharmony_ci};
225662306a36Sopenharmony_ci
225762306a36Sopenharmony_cimodule_spi_driver(trf7970a_spi_driver);
225862306a36Sopenharmony_ci
225962306a36Sopenharmony_ciMODULE_AUTHOR("Mark A. Greer <mgreer@animalcreek.com>");
226062306a36Sopenharmony_ciMODULE_LICENSE("GPL v2");
226162306a36Sopenharmony_ciMODULE_DESCRIPTION("TI trf7970a RFID/NFC Transceiver Driver");
2262