summaryrefslogtreecommitdiffstats
path: root/kernel/drivers/nfc/trf7970a.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/drivers/nfc/trf7970a.c')
-rw-r--r--kernel/drivers/nfc/trf7970a.c35
1 files changed, 29 insertions, 6 deletions
diff --git a/kernel/drivers/nfc/trf7970a.c b/kernel/drivers/nfc/trf7970a.c
index aa6a333b2..f857feb2b 100644
--- a/kernel/drivers/nfc/trf7970a.c
+++ b/kernel/drivers/nfc/trf7970a.c
@@ -149,6 +149,7 @@
*/
#define TRF7970A_QUIRK_IRQ_STATUS_READ BIT(0)
#define TRF7970A_QUIRK_EN2_MUST_STAY_LOW BIT(1)
+#define TRF7970A_QUIRK_T5T_RMB_EXTRA_BYTE BIT(2)
/* Direct commands */
#define TRF7970A_CMD_IDLE 0x00
@@ -335,7 +336,7 @@
#define TRF7970A_NFC_TARGET_LEVEL_RFDET(v) ((v) & 0x07)
#define TRF7970A_NFC_TARGET_LEVEL_HI_RF BIT(3)
-#define TRF7970A_NFC_TARGET_LEVEL_SDD_EN BIT(3)
+#define TRF7970A_NFC_TARGET_LEVEL_SDD_EN BIT(5)
#define TRF7970A_NFC_TARGET_LEVEL_LD_S_4BYTES (0x0 << 6)
#define TRF7970A_NFC_TARGET_LEVEL_LD_S_7BYTES (0x1 << 6)
#define TRF7970A_NFC_TARGET_LEVEL_LD_S_10BYTES (0x2 << 6)
@@ -446,6 +447,7 @@ struct trf7970a {
u8 md_rf_tech;
u8 tx_cmd;
bool issue_eof;
+ bool adjust_resp_len;
int en2_gpio;
int en_gpio;
struct mutex lock;
@@ -626,6 +628,13 @@ static void trf7970a_send_upstream(struct trf7970a *trf)
trf->aborting = false;
}
+ if (trf->adjust_resp_len) {
+ if (trf->rx_skb)
+ skb_trim(trf->rx_skb, trf->rx_skb->len - 1);
+
+ trf->adjust_resp_len = false;
+ }
+
trf->cb(trf->ddev, trf->cb_arg, trf->rx_skb);
trf->rx_skb = NULL;
@@ -1429,10 +1438,15 @@ static int trf7970a_per_cmd_config(struct trf7970a *trf, struct sk_buff *skb)
trf->iso_ctrl = iso_ctrl;
}
- if ((trf->framing == NFC_DIGITAL_FRAMING_ISO15693_T5T) &&
- trf7970a_is_iso15693_write_or_lock(req[1]) &&
- (req[0] & ISO15693_REQ_FLAG_OPTION))
- trf->issue_eof = true;
+ if (trf->framing == NFC_DIGITAL_FRAMING_ISO15693_T5T) {
+ if (trf7970a_is_iso15693_write_or_lock(req[1]) &&
+ (req[0] & ISO15693_REQ_FLAG_OPTION))
+ trf->issue_eof = true;
+ else if ((trf->quirks &
+ TRF7970A_QUIRK_T5T_RMB_EXTRA_BYTE) &&
+ (req[1] == ISO15693_CMD_READ_MULTIPLE_BLOCK))
+ trf->adjust_resp_len = true;
+ }
}
return 0;
@@ -1992,6 +2006,9 @@ static int trf7970a_probe(struct spi_device *spi)
return ret;
}
+ if (of_property_read_bool(np, "t5t-rmb-extra-byte-quirk"))
+ trf->quirks |= TRF7970A_QUIRK_T5T_RMB_EXTRA_BYTE;
+
if (of_property_read_bool(np, "irq-status-read-quirk"))
trf->quirks |= TRF7970A_QUIRK_IRQ_STATUS_READ;
@@ -2194,6 +2211,12 @@ static const struct dev_pm_ops trf7970a_pm_ops = {
trf7970a_pm_runtime_resume, NULL)
};
+static const struct of_device_id trf7970a_of_match[] = {
+ { .compatible = "ti,trf7970a", },
+ { /* sentinel */ },
+};
+MODULE_DEVICE_TABLE(of, trf7970a_of_match);
+
static const struct spi_device_id trf7970a_id_table[] = {
{ "trf7970a", 0 },
{ }
@@ -2206,7 +2229,7 @@ static struct spi_driver trf7970a_spi_driver = {
.id_table = trf7970a_id_table,
.driver = {
.name = "trf7970a",
- .owner = THIS_MODULE,
+ .of_match_table = of_match_ptr(trf7970a_of_match),
.pm = &trf7970a_pm_ops,
},
};