/* There are 3 ways the host can communicate with the trf7970a: * parallel mode, SPI with Slave Select (SS) mode, and SPI without * SS mode. The driver only supports the two SPI modes. * * The trf7970a is very timing sensitive and the VIN, EN2, and EN * pins must asserted in that order and with specific delays in between. * The delays used in the driver were provided by TI and have been * confirmed to work with this driver. There is a bug with the current * version of the trf7970a that requires that EN2 remain low no matter * what. If it goes high, it will generate an RF field even when in * passive target mode. TI has indicated that the chip will work okay * when EN2 is left low. The 'en2-rf-quirk' device tree property * indicates that trf7970a currently being used has the erratum and * that EN2 must be kept low. * * Timeouts are implemented using the delayed workqueue kernel facility. * Timeouts are required so things don't hang when there is no response * from the trf7970a (or tag). Using this mechanism creates a race with * interrupts, however. That is, an interrupt and a timeout could occur * closely enough together that one is blocked by the mutex while the other * executes. When the timeout handler executes first and blocks the * interrupt handler, it will eventually set the state to IDLE so the * interrupt handler will check the state and exit with no harm done. * When the interrupt handler executes first and blocks the timeout handler, * the cancel_delayed_work() call will know that it didn't cancel the * work item (i.e., timeout) and will return zero. That return code is * used by the timer handler to indicate that it should ignore the timeout * once its unblocked. * * Aborting an active command isn't as simple as it seems because the only * way to abort a command that's already been sent to the tag is so turn * off power to the tag. If we do that, though, we'd have to go through * the entire anticollision procedure again but the digital layer doesn't * support that. So, if an abort is received before trf7970a_send_cmd() * has sent the command to the tag, it simply returns -ECANCELED. If the * command has already been sent to the tag, then the driver continues * normally and recieves the response data (or error) but just before * sending the data upstream, it frees the rx_skb and sends -ECANCELED * upstream instead. If the command failed, that error will be sent * upstream. * * When recieving data from a tag and the interrupt status register has * only the SRX bit set, it means that all of the data has been received * (once what's in the fifo has been read). However, depending on timing * an interrupt status with only the SRX bit set may not be recived. In * those cases, the timeout mechanism is used to wait 20 ms in case more * data arrives. After 20 ms, it is assumed that all of the data has been * received and the accumulated rx data is sent upstream. The * 'TRF7970A_ST_WAIT_FOR_RX_DATA_CONT' state is used for this purpose * (i.e., it indicates that some data has been received but we're not sure * if there is more coming so a timeout in this state means all data has * been received and there isn't an error). The delay is 20 ms since delays * of ~16 ms have been observed during testing. * * When transmitting a frame larger than the FIFO size (127 bytes), the * driver will wait 20 ms for the FIFO to drain past the low-watermark * and generate an interrupt. The low-watermark set to 32 bytes so the * interrupt should fire after 127 - 32 = 95 bytes have been sent. At * the lowest possible bit rate (6.62 kbps for 15693), it will take up * to ~14.35 ms so 20 ms is used for the timeout. * * Type 2 write and sector select commands respond with a 4-bit ACK or NACK. * Having only 4 bits in the FIFO won't normally generate an interrupt so * driver enables the '4_bit_RX' bit of the Special Functions register 1 * to cause an interrupt in that case. Leaving that bit for a read command * messes up the data returned so it is only enabled when the framing is * 'NFC_DIGITAL_FRAMING_NFCA_T2T' and the command is not a read command. * Unfortunately, that means that the driver has to peek into tx frames * when the framing is 'NFC_DIGITAL_FRAMING_NFCA_T2T'. This is done by * the trf7970a_per_cmd_config() routine. * * ISO/IEC 15693 frames specify whether to use single or double sub-carrier * frequencies and whether to use low or high data rates in the flags byte * of the frame. This means that the driver has to peek at all 15693 frames * to determine what speed to set the communication to. In addition, write * and lock commands use the OPTION flag to indicate that an EOF must be * sent to the tag before it will send its response. So the driver has to * examine all frames for that reason too. * * It is unclear how long to wait before sending the EOF. According to the * Note under Table 1-1 in section 1.6 of * http://www.ti.com/lit/ug/scbu011/scbu011.pdf, that wait should be at least * 10 ms for TI Tag-it HF-I tags; however testing has shown that is not long * enough so 20 ms is used. So the timer is set to 40 ms - 20 ms to drain * up to 127 bytes in the FIFO at the lowest bit rate plus another 20 ms to * ensure the wait is long enough before sending the EOF. This seems to work * reliably.
*/
/* Guard times for various RF technologies (in us) */ #define TRF7970A_GUARD_TIME_NFCA 5000 #define TRF7970A_GUARD_TIME_NFCB 5000 #define TRF7970A_GUARD_TIME_NFCF 20000 #define TRF7970A_GUARD_TIME_15693 1000
/* Quirks */ /* Erratum: When reading IRQ Status register on trf7970a, we must issue a * read continuous command for IRQ Status and Collision Position registers.
*/ #define TRF7970A_QUIRK_IRQ_STATUS_READ BIT(0) #define TRF7970A_QUIRK_EN2_MUST_STAY_LOW BIT(1)
/* Bits determining whether its a direct command or register R/W, * whether to use a continuous SPI transaction or not, and the actual * direct cmd opcode or register address.
*/ #define TRF7970A_CMD_BIT_CTRL BIT(7) #define TRF7970A_CMD_BIT_RW BIT(6) #define TRF7970A_CMD_BIT_CONTINUOUS BIT(5) #define TRF7970A_CMD_BIT_OPCODE(opcode) ((opcode) & 0x1f)
if (trf->quirks & TRF7970A_QUIRK_IRQ_STATUS_READ) {
addr |= TRF7970A_CMD_BIT_CONTINUOUS;
ret = spi_write_then_read(trf->spi, &addr, 1, buf, 2);
} else {
ret = spi_write_then_read(trf->spi, &addr, 1, buf, 1);
}
if (ret)
dev_err(trf->dev, "%s - irqstatus: Status read failed: %d\n",
__func__, ret); else
*status = buf[0];
return ret;
}
staticint trf7970a_update_rx_gain_reduction(struct trf7970a *trf)
{ int ret = 0;
u8 reg;
if (!trf->custom_rx_gain_reduction) return 0;
ret = trf7970a_read(trf, TRF7970A_RX_SPECIAL_SETTINGS, ®); if (ret) return ret;
reg &= ~(TRF7970A_RX_SPECIAL_SETTINGS_GD_MASK);
reg |= trf->rx_gain_reduction;
ret = trf7970a_write(trf, TRF7970A_RX_SPECIAL_SETTINGS, reg);
return ret;
}
staticint trf7970a_update_iso_ctrl_register(struct trf7970a *trf, u8 iso_ctrl)
{ int ret;
ret = trf7970a_write(trf, TRF7970A_ISO_CTRL, iso_ctrl); if (ret) return ret; /* * Every time the ISO_CTRL register is written, the RX special setting register is reset by * the chip. When a custom gain reguduction is required, it should be rewritten now.
*/
ret = trf7970a_update_rx_gain_reduction(trf);
/* Calculate how much more data can be written to the fifo */
len = TRF7970A_FIFO_SIZE - fifo_bytes; if (!len) {
schedule_delayed_work(&trf->timeout_work,
msecs_to_jiffies(TRF7970A_WAIT_FOR_FIFO_DRAIN_TIMEOUT)); return;
}
if (fifo_bytes > skb_tailroom(skb)) {
skb = skb_copy_expand(skb, skb_headroom(skb),
max_t(int, fifo_bytes,
TRF7970A_RX_SKB_ALLOC_SIZE),
GFP_KERNEL); if (!skb) {
trf7970a_send_err_upstream(trf, -ENOMEM); return;
}
kfree_skb(trf->rx_skb);
trf->rx_skb = skb;
}
ret = trf7970a_read_cont(trf, TRF7970A_FIFO_IO_REGISTER,
skb_put(skb, fifo_bytes), fifo_bytes); if (ret) {
trf7970a_send_err_upstream(trf, ret); return;
}
/* If received Type 2 ACK/NACK, shift right 4 bits and pass up */ if ((trf->framing == NFC_DIGITAL_FRAMING_NFCA_T2T) && (skb->len == 1) &&
(trf->special_fcn_reg1 == TRF7970A_SPECIAL_FCN_REG1_4_BIT_RX)) {
skb->data[0] >>= 4;
status = TRF7970A_IRQ_STATUS_SRX;
} else {
trf->state = TRF7970A_ST_WAIT_FOR_RX_DATA_CONT;
ret = trf7970a_read(trf, TRF7970A_FIFO_STATUS, &fifo_bytes); if (ret) {
trf7970a_send_err_upstream(trf, ret); return;
}
fifo_bytes &= ~TRF7970A_FIFO_STATUS_OVERFLOW;
/* If there are bytes in the FIFO, set status to '0' so * the if stmt below doesn't fire and the driver will wait * for the trf7970a to generate another RX interrupt.
*/ if (fifo_bytes)
status = 0;
}
if (!status) {
mutex_unlock(&trf->lock); return IRQ_NONE;
}
switch (trf->state) { case TRF7970A_ST_IDLE: case TRF7970A_ST_IDLE_RX_BLOCKED: /* If initiator and getting interrupts caused by RF noise, * turn off the receiver to avoid unnecessary interrupts. * It will be turned back on in trf7970a_send_cmd() when * the next command is issued.
*/ if (trf->is_initiator && (status & TRF7970A_IRQ_STATUS_ERROR)) {
trf7970a_cmd(trf, TRF7970A_CMD_BLOCK_RX);
trf->state = TRF7970A_ST_IDLE_RX_BLOCKED;
}
trf7970a_cmd(trf, TRF7970A_CMD_FIFO_RESET); break; case TRF7970A_ST_WAIT_FOR_TX_FIFO: if (status & TRF7970A_IRQ_STATUS_TX) {
trf->ignore_timeout =
!cancel_delayed_work(&trf->timeout_work);
trf7970a_fill_fifo(trf);
} else {
trf7970a_send_err_upstream(trf, -EIO);
} break; case TRF7970A_ST_WAIT_FOR_RX_DATA: case TRF7970A_ST_WAIT_FOR_RX_DATA_CONT: if (status & TRF7970A_IRQ_STATUS_SRX) {
trf->ignore_timeout =
!cancel_delayed_work(&trf->timeout_work);
trf7970a_drain_fifo(trf, status);
} elseif (status & TRF7970A_IRQ_STATUS_FIFO) {
ret = trf7970a_read(trf, TRF7970A_FIFO_STATUS,
&fifo_bytes);
/* If in initiator mode and not changing the RF tech due to a * PSL sequence (indicated by 'trf->iso_ctrl == 0xff' from * trf7970a_init()), clear the NFC Target Detection Level register * due to erratum.
*/ if (trf->iso_ctrl == 0xff)
ret = trf7970a_write(trf, TRF7970A_NFC_TARGET_LEVEL, 0);
staticint trf7970a_in_config_framing(struct trf7970a *trf, int framing)
{
u8 iso_ctrl = trf->iso_ctrl_tech; bool is_rf_field = false; int ret;
dev_dbg(trf->dev, "framing: %d\n", framing);
switch (framing) { case NFC_DIGITAL_FRAMING_NFCA_SHORT: case NFC_DIGITAL_FRAMING_NFCA_STANDARD:
trf->tx_cmd = TRF7970A_CMD_TRANSMIT_NO_CRC;
iso_ctrl |= TRF7970A_ISO_CTRL_RX_CRC_N; break; case NFC_DIGITAL_FRAMING_NFCA_STANDARD_WITH_CRC_A: case NFC_DIGITAL_FRAMING_NFCA_T4T: case NFC_DIGITAL_FRAMING_NFCB: case NFC_DIGITAL_FRAMING_NFCB_T4T: case NFC_DIGITAL_FRAMING_NFCF: case NFC_DIGITAL_FRAMING_NFCF_T3T: case NFC_DIGITAL_FRAMING_ISO15693_INVENTORY: case NFC_DIGITAL_FRAMING_ISO15693_T5T: case NFC_DIGITAL_FRAMING_NFCA_NFC_DEP: case NFC_DIGITAL_FRAMING_NFCF_NFC_DEP:
trf->tx_cmd = TRF7970A_CMD_TRANSMIT;
iso_ctrl &= ~TRF7970A_ISO_CTRL_RX_CRC_N; break; case NFC_DIGITAL_FRAMING_NFCA_T2T:
trf->tx_cmd = TRF7970A_CMD_TRANSMIT;
iso_ctrl |= TRF7970A_ISO_CTRL_RX_CRC_N; break; default:
dev_dbg(trf->dev, "Unsupported Framing: %d\n", framing); return -EINVAL;
}
trf->framing = framing;
if (!(trf->chip_status_ctrl & TRF7970A_CHIP_STATUS_RF_ON)) {
ret = trf7970a_is_rf_field(trf, &is_rf_field); if (ret) return ret;
if (is_rf_field) return -EBUSY;
}
if (iso_ctrl != trf->iso_ctrl) {
ret = trf7970a_update_iso_ctrl_register(trf, iso_ctrl); if (ret) return ret;
trf->iso_ctrl = iso_ctrl;
ret = trf7970a_write(trf, TRF7970A_MODULATOR_SYS_CLK_CTRL,
trf->modulator_sys_clk_ctrl); if (ret) return ret;
}
if (!(trf->chip_status_ctrl & TRF7970A_CHIP_STATUS_RF_ON)) {
ret = trf7970a_write(trf, TRF7970A_CHIP_STATUS_CTRL,
trf->chip_status_ctrl |
TRF7970A_CHIP_STATUS_RF_ON); if (ret) return ret;
staticint trf7970a_is_iso15693_write_or_lock(u8 cmd)
{ switch (cmd) { case ISO15693_CMD_WRITE_SINGLE_BLOCK: case ISO15693_CMD_LOCK_BLOCK: case ISO15693_CMD_WRITE_MULTIPLE_BLOCK: case ISO15693_CMD_WRITE_AFI: case ISO15693_CMD_LOCK_AFI: case ISO15693_CMD_WRITE_DSFID: case ISO15693_CMD_LOCK_DSFID: return 1; default: return 0;
}
}
/* When issuing Type 2 read command, make sure the '4_bit_RX' bit in * special functions register 1 is cleared; otherwise, its a write or * sector select command and '4_bit_RX' must be set. * * When issuing an ISO 15693 command, inspect the flags byte to see * what speed to use. Also, remember if the OPTION flag is set on * a Type 5 write or lock command so the driver will know that it * has to send an EOF in order to get a response.
*/ if ((trf->technology == NFC_DIGITAL_RF_TECH_106A) &&
(trf->framing == NFC_DIGITAL_FRAMING_NFCA_T2T)) { if (req[0] == NFC_T2T_CMD_READ)
special_fcn_reg1 = 0; else
special_fcn_reg1 = TRF7970A_SPECIAL_FCN_REG1_4_BIT_RX;
if (special_fcn_reg1 != trf->special_fcn_reg1) {
ret = trf7970a_write(trf, TRF7970A_SPECIAL_FCN_REG1,
special_fcn_reg1); if (ret) return ret;
/* TX data must be prefixed with a FIFO reset cmd, a cmd that depends * on what the current framing is, the address of the TX length byte 1 * register (0x1d), and the 2 byte length of the data to be transmitted. * That totals 5 bytes.
*/
prefix[0] = TRF7970A_CMD_BIT_CTRL |
TRF7970A_CMD_BIT_OPCODE(TRF7970A_CMD_FIFO_RESET);
prefix[1] = TRF7970A_CMD_BIT_CTRL |
TRF7970A_CMD_BIT_OPCODE(trf->tx_cmd);
prefix[2] = TRF7970A_CMD_BIT_CONTINUOUS | TRF7970A_TX_LENGTH_BYTE1;
/* Normally we write the ISO_CTRL register in * trf7970a_tg_config_framing() because the framing can change * the value written. However, when sending a PSL RES, * digital_tg_send_psl_res_complete() doesn't call * trf7970a_tg_config_framing() so we must write the register * here.
*/ if ((trf->framing == NFC_DIGITAL_FRAMING_NFC_DEP_ACTIVATED) &&
(trf->iso_ctrl_tech != trf->iso_ctrl)) {
ret = trf7970a_update_iso_ctrl_register(trf, trf->iso_ctrl_tech);
trf->iso_ctrl = trf->iso_ctrl_tech;
}
return ret;
}
/* Since this is a target routine, several of the framing calls are * made between receiving the request and sending the response so they * should take effect until after the response is sent. This is accomplished * by skipping the ISO_CTRL register write here and doing it in the interrupt * handler.
*/ staticint trf7970a_tg_config_framing(struct trf7970a *trf, int framing)
{
u8 iso_ctrl = trf->iso_ctrl_tech; int ret;
dev_dbg(trf->dev, "framing: %d\n", framing);
switch (framing) { case NFC_DIGITAL_FRAMING_NFCA_NFC_DEP:
trf->tx_cmd = TRF7970A_CMD_TRANSMIT_NO_CRC;
iso_ctrl |= TRF7970A_ISO_CTRL_RX_CRC_N; break; case NFC_DIGITAL_FRAMING_NFCA_STANDARD: case NFC_DIGITAL_FRAMING_NFCA_STANDARD_WITH_CRC_A: case NFC_DIGITAL_FRAMING_NFCA_ANTICOL_COMPLETE: /* These ones are applied in the interrupt handler */
iso_ctrl = trf->iso_ctrl; /* Don't write to ISO_CTRL yet */ break; case NFC_DIGITAL_FRAMING_NFCF_NFC_DEP:
trf->tx_cmd = TRF7970A_CMD_TRANSMIT;
iso_ctrl &= ~TRF7970A_ISO_CTRL_RX_CRC_N; break; case NFC_DIGITAL_FRAMING_NFC_DEP_ACTIVATED:
trf->tx_cmd = TRF7970A_CMD_TRANSMIT;
iso_ctrl &= ~TRF7970A_ISO_CTRL_RX_CRC_N; break; default:
dev_dbg(trf->dev, "Unsupported Framing: %d\n", framing); return -EINVAL;
}
trf->framing = framing;
if (iso_ctrl != trf->iso_ctrl) {
ret = trf7970a_update_iso_ctrl_register(trf, iso_ctrl); if (ret) return ret;
trf->iso_ctrl = iso_ctrl;
ret = trf7970a_write(trf, TRF7970A_MODULATOR_SYS_CLK_CTRL,
trf->modulator_sys_clk_ctrl); if (ret) return ret;
}
if (!(trf->chip_status_ctrl & TRF7970A_CHIP_STATUS_RF_ON)) {
ret = trf7970a_write(trf, TRF7970A_CHIP_STATUS_CTRL,
trf->chip_status_ctrl |
TRF7970A_CHIP_STATUS_RF_ON); if (ret) return ret;
switch (trf->state) { case TRF7970A_ST_WAIT_FOR_TX_FIFO: case TRF7970A_ST_WAIT_FOR_RX_DATA: case TRF7970A_ST_WAIT_FOR_RX_DATA_CONT: case TRF7970A_ST_WAIT_TO_ISSUE_EOF:
trf->aborting = true; break; case TRF7970A_ST_LISTENING:
trf->ignore_timeout = !cancel_delayed_work(&trf->timeout_work);
trf7970a_send_err_upstream(trf, -ECANCELED);
dev_dbg(trf->dev, "Abort process complete\n"); break; default: break;
}
staticvoid trf7970a_shutdown(struct trf7970a *trf)
{ switch (trf->state) { case TRF7970A_ST_WAIT_FOR_TX_FIFO: case TRF7970A_ST_WAIT_FOR_RX_DATA: case TRF7970A_ST_WAIT_FOR_RX_DATA_CONT: case TRF7970A_ST_WAIT_TO_ISSUE_EOF: case TRF7970A_ST_LISTENING:
trf7970a_send_err_upstream(trf, -ECANCELED);
fallthrough; case TRF7970A_ST_IDLE: case TRF7970A_ST_IDLE_RX_BLOCKED:
trf7970a_switch_rf_off(trf); break; default: break;
}
ret = spi_setup(spi); if (ret < 0) {
dev_err(trf->dev, "Can't set up SPI Communication\n"); return ret;
}
if (of_property_read_bool(np, "irq-status-read-quirk"))
trf->quirks |= TRF7970A_QUIRK_IRQ_STATUS_READ;
/* There are two enable pins - only EN must be present in the DT */
trf->en_gpiod = devm_gpiod_get_index(trf->dev, "ti,enable", 0,
GPIOD_OUT_LOW); if (IS_ERR(trf->en_gpiod)) {
dev_err(trf->dev, "No EN GPIO property\n"); return PTR_ERR(trf->en_gpiod);
}
if (of_property_read_u32(np, "ti,rx-gain-reduction-db", &rx_gain_reduction_db) == 0) { if (rx_gain_reduction_db > TRF7970A_RX_GAIN_REDUCTION_MAX_DB) {
dev_warn(trf->dev, "RX Gain reduction too high. Ignored\n");
} elseif ((rx_gain_reduction_db % TRF7970A_RX_GAIN_REDUCTION_DB_PER_LSB)) {
dev_warn(trf->dev, "RX Gain must be set in 5 dB increments. Ignored\n");
} else {
dev_dbg(trf->dev, "RX gain set to -%udB\n", rx_gain_reduction_db);
trf->rx_gain_reduction = ((rx_gain_reduction_db /
TRF7970A_RX_GAIN_REDUCTION_DB_PER_LSB) <<
TRF7970A_RX_SPECIAL_SETTINGS_GD_SHIFT);
trf->custom_rx_gain_reduction = true;
}
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.