u8 gt[];
 } __packed;
 
+struct pn532_autopoll_resp {
+       u8 type;
+       u8 ln;
+       u8 tg;
+       u8 tgdata[];
+};
+
+/* PN532_CMD_IN_AUTOPOLL */
+#define PN532_AUTOPOLL_POLLNR_INFINITE 0xff
+#define PN532_AUTOPOLL_PERIOD          0x03 /* in units of 150 ms */
+
+#define PN532_AUTOPOLL_TYPE_GENERIC_106                0x00
+#define PN532_AUTOPOLL_TYPE_GENERIC_212                0x01
+#define PN532_AUTOPOLL_TYPE_GENERIC_424                0x02
+#define PN532_AUTOPOLL_TYPE_JEWEL              0x04
+#define PN532_AUTOPOLL_TYPE_MIFARE             0x10
+#define PN532_AUTOPOLL_TYPE_FELICA212          0x11
+#define PN532_AUTOPOLL_TYPE_FELICA424          0x12
+#define PN532_AUTOPOLL_TYPE_ISOA               0x20
+#define PN532_AUTOPOLL_TYPE_ISOB               0x23
+#define PN532_AUTOPOLL_TYPE_DEP_PASSIVE_106    0x40
+#define PN532_AUTOPOLL_TYPE_DEP_PASSIVE_212    0x41
+#define PN532_AUTOPOLL_TYPE_DEP_PASSIVE_424    0x42
+#define PN532_AUTOPOLL_TYPE_DEP_ACTIVE_106     0x80
+#define PN532_AUTOPOLL_TYPE_DEP_ACTIVE_212     0x81
+#define PN532_AUTOPOLL_TYPE_DEP_ACTIVE_424     0x82
 
 /* PN533_TG_INIT_AS_TARGET */
 #define PN533_INIT_TARGET_PASSIVE 0x1
        return rc;
 }
 
+static int pn533_autopoll_complete(struct pn533 *dev, void *arg,
+                              struct sk_buff *resp)
+{
+       struct pn532_autopoll_resp *apr;
+       struct nfc_target nfc_tgt;
+       u8 nbtg;
+       int rc;
+
+       if (IS_ERR(resp)) {
+               rc = PTR_ERR(resp);
+
+               nfc_err(dev->dev, "%s  autopoll complete error %d\n",
+                       __func__, rc);
+
+               if (rc == -ENOENT) {
+                       if (dev->poll_mod_count != 0)
+                               return rc;
+                       goto stop_poll;
+               } else if (rc < 0) {
+                       nfc_err(dev->dev,
+                               "Error %d when running autopoll\n", rc);
+                       goto stop_poll;
+               }
+       }
+
+       nbtg = resp->data[0];
+       if ((nbtg > 2) || (nbtg <= 0))
+               return -EAGAIN;
+
+       apr = (struct pn532_autopoll_resp *)&resp->data[1];
+       while (nbtg--) {
+               memset(&nfc_tgt, 0, sizeof(struct nfc_target));
+               switch (apr->type) {
+               case PN532_AUTOPOLL_TYPE_ISOA:
+                       dev_dbg(dev->dev, "ISOA\n");
+                       rc = pn533_target_found_type_a(&nfc_tgt, apr->tgdata,
+                                                      apr->ln - 1);
+                       break;
+               case PN532_AUTOPOLL_TYPE_FELICA212:
+               case PN532_AUTOPOLL_TYPE_FELICA424:
+                       dev_dbg(dev->dev, "FELICA\n");
+                       rc = pn533_target_found_felica(&nfc_tgt, apr->tgdata,
+                                                      apr->ln - 1);
+                       break;
+               case PN532_AUTOPOLL_TYPE_JEWEL:
+                       dev_dbg(dev->dev, "JEWEL\n");
+                       rc = pn533_target_found_jewel(&nfc_tgt, apr->tgdata,
+                                                     apr->ln - 1);
+                       break;
+               case PN532_AUTOPOLL_TYPE_ISOB:
+                       dev_dbg(dev->dev, "ISOB\n");
+                       rc = pn533_target_found_type_b(&nfc_tgt, apr->tgdata,
+                                                      apr->ln - 1);
+                       break;
+               case PN532_AUTOPOLL_TYPE_MIFARE:
+                       dev_dbg(dev->dev, "Mifare\n");
+                       rc = pn533_target_found_type_a(&nfc_tgt, apr->tgdata,
+                                                      apr->ln - 1);
+                       break;
+               default:
+                       nfc_err(dev->dev,
+                                   "Unknown current poll modulation\n");
+                       rc = -EPROTO;
+               }
+
+               if (rc)
+                       goto done;
+
+               if (!(nfc_tgt.supported_protocols & dev->poll_protocols)) {
+                       nfc_err(dev->dev,
+                                   "The Tg found doesn't have the desired protocol\n");
+                       rc = -EAGAIN;
+                       goto done;
+               }
+
+               dev->tgt_available_prots = nfc_tgt.supported_protocols;
+               apr = (struct pn532_autopoll_resp *)
+                       (apr->tgdata + (apr->ln - 1));
+       }
+
+       pn533_poll_reset_mod_list(dev);
+       nfc_targets_found(dev->nfc_dev, &nfc_tgt, 1);
+
+done:
+       dev_kfree_skb(resp);
+       return rc;
+
+stop_poll:
+       nfc_err(dev->dev, "autopoll operation has been stopped\n");
+
+       pn533_poll_reset_mod_list(dev);
+       dev->poll_protocols = 0;
+       return rc;
+}
+
 static int pn533_poll_complete(struct pn533 *dev, void *arg,
                               struct sk_buff *resp)
 {
 {
        struct pn533 *dev = nfc_get_drvdata(nfc_dev);
        struct pn533_poll_modulations *cur_mod;
+       struct sk_buff *skb;
        u8 rand_mod;
        int rc;
 
                        tm_protocols = 0;
        }
 
-       pn533_poll_create_mod_list(dev, im_protocols, tm_protocols);
        dev->poll_protocols = im_protocols;
        dev->listen_protocols = tm_protocols;
+       if (dev->device_type == PN533_DEVICE_PN532_AUTOPOLL) {
+               skb = pn533_alloc_skb(dev, 4 + 6);
+               if (!skb)
+                       return -ENOMEM;
+
+               *((u8 *)skb_put(skb, sizeof(u8))) =
+                       PN532_AUTOPOLL_POLLNR_INFINITE;
+               *((u8 *)skb_put(skb, sizeof(u8))) = PN532_AUTOPOLL_PERIOD;
+
+               if ((im_protocols & NFC_PROTO_MIFARE_MASK) &&
+                               (im_protocols & NFC_PROTO_ISO14443_MASK) &&
+                               (im_protocols & NFC_PROTO_NFC_DEP_MASK))
+                       *((u8 *)skb_put(skb, sizeof(u8))) =
+                               PN532_AUTOPOLL_TYPE_GENERIC_106;
+               else {
+                       if (im_protocols & NFC_PROTO_MIFARE_MASK)
+                               *((u8 *)skb_put(skb, sizeof(u8))) =
+                                       PN532_AUTOPOLL_TYPE_MIFARE;
+
+                       if (im_protocols & NFC_PROTO_ISO14443_MASK)
+                               *((u8 *)skb_put(skb, sizeof(u8))) =
+                                       PN532_AUTOPOLL_TYPE_ISOA;
+
+                       if (im_protocols & NFC_PROTO_NFC_DEP_MASK) {
+                               *((u8 *)skb_put(skb, sizeof(u8))) =
+                                       PN532_AUTOPOLL_TYPE_DEP_PASSIVE_106;
+                               *((u8 *)skb_put(skb, sizeof(u8))) =
+                                       PN532_AUTOPOLL_TYPE_DEP_PASSIVE_212;
+                               *((u8 *)skb_put(skb, sizeof(u8))) =
+                                       PN532_AUTOPOLL_TYPE_DEP_PASSIVE_424;
+                       }
+               }
+
+               if (im_protocols & NFC_PROTO_FELICA_MASK ||
+                               im_protocols & NFC_PROTO_NFC_DEP_MASK) {
+                       *((u8 *)skb_put(skb, sizeof(u8))) =
+                               PN532_AUTOPOLL_TYPE_FELICA212;
+                       *((u8 *)skb_put(skb, sizeof(u8))) =
+                               PN532_AUTOPOLL_TYPE_FELICA424;
+               }
+
+               if (im_protocols & NFC_PROTO_JEWEL_MASK)
+                       *((u8 *)skb_put(skb, sizeof(u8))) =
+                               PN532_AUTOPOLL_TYPE_JEWEL;
+
+               if (im_protocols & NFC_PROTO_ISO14443_B_MASK)
+                       *((u8 *)skb_put(skb, sizeof(u8))) =
+                               PN532_AUTOPOLL_TYPE_ISOB;
+
+               if (tm_protocols)
+                       *((u8 *)skb_put(skb, sizeof(u8))) =
+                               PN532_AUTOPOLL_TYPE_DEP_ACTIVE_106;
+
+               rc = pn533_send_cmd_async(dev, PN533_CMD_IN_AUTOPOLL, skb,
+                               pn533_autopoll_complete, NULL);
+
+               if (rc < 0)
+                       dev_kfree_skb(skb);
+               else
+                       dev->poll_mod_count++;
+
+               return rc;
+       }
+
+       pn533_poll_create_mod_list(dev, im_protocols, tm_protocols);
 
        /* Do not always start polling from the same modulation */
        get_random_bytes(&rand_mod, sizeof(rand_mod));
        if (dev->phy_ops->dev_up)
                dev->phy_ops->dev_up(dev);
 
-       if (dev->device_type == PN533_DEVICE_PN532) {
+       if ((dev->device_type == PN533_DEVICE_PN532) ||
+               (dev->device_type == PN533_DEVICE_PN532_AUTOPOLL)) {
                int rc = pn532_sam_configuration(nfc_dev);
 
                if (rc)
        case PN533_DEVICE_PASORI:
        case PN533_DEVICE_ACR122U:
        case PN533_DEVICE_PN532:
+       case PN533_DEVICE_PN532_AUTOPOLL:
                max_retries.mx_rty_atr = 0x2;
                max_retries.mx_rty_psl = 0x1;
                max_retries.mx_rty_passive_act =
        switch (dev->device_type) {
        case PN533_DEVICE_STD:
        case PN533_DEVICE_PN532:
+       case PN533_DEVICE_PN532_AUTOPOLL:
                break;
 
        case PN533_DEVICE_PASORI: