NFC: trf7970a: Handle extra byte in response to Type 5 RMB commands
authorMark A. Greer <mgreer@animalcreek.com>
Fri, 24 Apr 2015 17:37:22 +0000 (10:37 -0700)
committerSamuel Ortiz <sameo@linux.intel.com>
Mon, 8 Jun 2015 21:16:31 +0000 (23:16 +0200)
The current versions of the trf7970a has an erratum where it returns
an extra byte in the response to 'Read Multiple Block' (RMB) commands.
This command is issued to Type 5 tags (i.e., ISO/IEC 15693 tags) by
the neard daemon.

To handle this, define a new Device Tree property,
't5t-rmb-extra-byte-quirk', which indicates that the associated
trf7970a device has this erratum.  The trf7970a device driver
will then ensure that the response length to RMB commands is
reduced by one byte (for devices with the erratum).

Signed-off-by: Mark A. Greer <mgreer@animalcreek.com>
Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
Documentation/devicetree/bindings/net/nfc/trf7970a.txt
drivers/nfc/trf7970a.c

index 7c89ca290ced74c05600d59fa6abe7abaf7f8f58..32b35a07abe4224c298e601eb09ad50f1c0c0b2f 100644 (file)
@@ -18,6 +18,9 @@ Optional SoC Specific Properties:
   "IRQ Status Read" erratum.
 - en2-rf-quirk: Specify that the trf7970a being used has the "EN2 RF"
   erratum.
+- t5t-rmb-extra-byte-quirk: Specify that the trf7970a has the erratum
+  where an extra byte is returned by Read Multiple Block commands issued
+  to Type 5 tags.
 
 Example (for ARM-based BeagleBone with TRF7970A on SPI1):
 
@@ -39,6 +42,7 @@ Example (for ARM-based BeagleBone with TRF7970A on SPI1):
                autosuspend-delay = <30000>;
                irq-status-read-quirk;
                en2-rf-quirk;
+               t5t-rmb-extra-byte-quirk;
                status = "okay";
        };
 };
index aa6a333b2ead9e4f4c0ad7eef5659681f96eec49..85b4d86772d8b37e05f83b07377b2af6cd2d0d75 100644 (file)
  */
 #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
@@ -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,11 @@ static void trf7970a_send_upstream(struct trf7970a *trf)
                trf->aborting = false;
        }
 
+       if (trf->adjust_resp_len) {
+               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 +1436,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 +2004,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;
 
This page took 0.027826 seconds and 5 git commands to generate.