| .. | .. |
|---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-or-later |
|---|
| 1 | 2 | /* |
|---|
| 2 | 3 | * Driver for NXP PN533 NFC Chip - core functions |
|---|
| 3 | 4 | * |
|---|
| 4 | 5 | * Copyright (C) 2011 Instituto Nokia de Tecnologia |
|---|
| 5 | 6 | * Copyright (C) 2012-2013 Tieto Poland |
|---|
| 6 | | - * |
|---|
| 7 | | - * This program is free software; you can redistribute it and/or modify |
|---|
| 8 | | - * it under the terms of the GNU General Public License as published by |
|---|
| 9 | | - * the Free Software Foundation; either version 2 of the License, or |
|---|
| 10 | | - * (at your option) any later version. |
|---|
| 11 | | - * |
|---|
| 12 | | - * This program is distributed in the hope that it will be useful, |
|---|
| 13 | | - * but WITHOUT ANY WARRANTY; without even the implied warranty of |
|---|
| 14 | | - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|---|
| 15 | | - * GNU General Public License for more details. |
|---|
| 16 | | - * |
|---|
| 17 | | - * You should have received a copy of the GNU General Public License |
|---|
| 18 | | - * along with this program; if not, see <http://www.gnu.org/licenses/>. |
|---|
| 19 | 7 | */ |
|---|
| 20 | 8 | |
|---|
| 21 | 9 | #include <linux/device.h> |
|---|
| .. | .. |
|---|
| 197 | 185 | u8 gt[]; |
|---|
| 198 | 186 | } __packed; |
|---|
| 199 | 187 | |
|---|
| 188 | +struct pn532_autopoll_resp { |
|---|
| 189 | + u8 type; |
|---|
| 190 | + u8 ln; |
|---|
| 191 | + u8 tg; |
|---|
| 192 | + u8 tgdata[]; |
|---|
| 193 | +}; |
|---|
| 194 | + |
|---|
| 195 | +/* PN532_CMD_IN_AUTOPOLL */ |
|---|
| 196 | +#define PN532_AUTOPOLL_POLLNR_INFINITE 0xff |
|---|
| 197 | +#define PN532_AUTOPOLL_PERIOD 0x03 /* in units of 150 ms */ |
|---|
| 198 | + |
|---|
| 199 | +#define PN532_AUTOPOLL_TYPE_GENERIC_106 0x00 |
|---|
| 200 | +#define PN532_AUTOPOLL_TYPE_GENERIC_212 0x01 |
|---|
| 201 | +#define PN532_AUTOPOLL_TYPE_GENERIC_424 0x02 |
|---|
| 202 | +#define PN532_AUTOPOLL_TYPE_JEWEL 0x04 |
|---|
| 203 | +#define PN532_AUTOPOLL_TYPE_MIFARE 0x10 |
|---|
| 204 | +#define PN532_AUTOPOLL_TYPE_FELICA212 0x11 |
|---|
| 205 | +#define PN532_AUTOPOLL_TYPE_FELICA424 0x12 |
|---|
| 206 | +#define PN532_AUTOPOLL_TYPE_ISOA 0x20 |
|---|
| 207 | +#define PN532_AUTOPOLL_TYPE_ISOB 0x23 |
|---|
| 208 | +#define PN532_AUTOPOLL_TYPE_DEP_PASSIVE_106 0x40 |
|---|
| 209 | +#define PN532_AUTOPOLL_TYPE_DEP_PASSIVE_212 0x41 |
|---|
| 210 | +#define PN532_AUTOPOLL_TYPE_DEP_PASSIVE_424 0x42 |
|---|
| 211 | +#define PN532_AUTOPOLL_TYPE_DEP_ACTIVE_106 0x80 |
|---|
| 212 | +#define PN532_AUTOPOLL_TYPE_DEP_ACTIVE_212 0x81 |
|---|
| 213 | +#define PN532_AUTOPOLL_TYPE_DEP_ACTIVE_424 0x82 |
|---|
| 200 | 214 | |
|---|
| 201 | 215 | /* PN533_TG_INIT_AS_TARGET */ |
|---|
| 202 | 216 | #define PN533_INIT_TARGET_PASSIVE 0x1 |
|---|
| .. | .. |
|---|
| 1404 | 1418 | return rc; |
|---|
| 1405 | 1419 | } |
|---|
| 1406 | 1420 | |
|---|
| 1421 | +static int pn533_autopoll_complete(struct pn533 *dev, void *arg, |
|---|
| 1422 | + struct sk_buff *resp) |
|---|
| 1423 | +{ |
|---|
| 1424 | + struct pn532_autopoll_resp *apr; |
|---|
| 1425 | + struct nfc_target nfc_tgt; |
|---|
| 1426 | + u8 nbtg; |
|---|
| 1427 | + int rc; |
|---|
| 1428 | + |
|---|
| 1429 | + if (IS_ERR(resp)) { |
|---|
| 1430 | + rc = PTR_ERR(resp); |
|---|
| 1431 | + |
|---|
| 1432 | + nfc_err(dev->dev, "%s autopoll complete error %d\n", |
|---|
| 1433 | + __func__, rc); |
|---|
| 1434 | + |
|---|
| 1435 | + if (rc == -ENOENT) { |
|---|
| 1436 | + if (dev->poll_mod_count != 0) |
|---|
| 1437 | + return rc; |
|---|
| 1438 | + goto stop_poll; |
|---|
| 1439 | + } else if (rc < 0) { |
|---|
| 1440 | + nfc_err(dev->dev, |
|---|
| 1441 | + "Error %d when running autopoll\n", rc); |
|---|
| 1442 | + goto stop_poll; |
|---|
| 1443 | + } |
|---|
| 1444 | + } |
|---|
| 1445 | + |
|---|
| 1446 | + nbtg = resp->data[0]; |
|---|
| 1447 | + if ((nbtg > 2) || (nbtg <= 0)) |
|---|
| 1448 | + return -EAGAIN; |
|---|
| 1449 | + |
|---|
| 1450 | + apr = (struct pn532_autopoll_resp *)&resp->data[1]; |
|---|
| 1451 | + while (nbtg--) { |
|---|
| 1452 | + memset(&nfc_tgt, 0, sizeof(struct nfc_target)); |
|---|
| 1453 | + switch (apr->type) { |
|---|
| 1454 | + case PN532_AUTOPOLL_TYPE_ISOA: |
|---|
| 1455 | + dev_dbg(dev->dev, "ISOA\n"); |
|---|
| 1456 | + rc = pn533_target_found_type_a(&nfc_tgt, apr->tgdata, |
|---|
| 1457 | + apr->ln - 1); |
|---|
| 1458 | + break; |
|---|
| 1459 | + case PN532_AUTOPOLL_TYPE_FELICA212: |
|---|
| 1460 | + case PN532_AUTOPOLL_TYPE_FELICA424: |
|---|
| 1461 | + dev_dbg(dev->dev, "FELICA\n"); |
|---|
| 1462 | + rc = pn533_target_found_felica(&nfc_tgt, apr->tgdata, |
|---|
| 1463 | + apr->ln - 1); |
|---|
| 1464 | + break; |
|---|
| 1465 | + case PN532_AUTOPOLL_TYPE_JEWEL: |
|---|
| 1466 | + dev_dbg(dev->dev, "JEWEL\n"); |
|---|
| 1467 | + rc = pn533_target_found_jewel(&nfc_tgt, apr->tgdata, |
|---|
| 1468 | + apr->ln - 1); |
|---|
| 1469 | + break; |
|---|
| 1470 | + case PN532_AUTOPOLL_TYPE_ISOB: |
|---|
| 1471 | + dev_dbg(dev->dev, "ISOB\n"); |
|---|
| 1472 | + rc = pn533_target_found_type_b(&nfc_tgt, apr->tgdata, |
|---|
| 1473 | + apr->ln - 1); |
|---|
| 1474 | + break; |
|---|
| 1475 | + case PN532_AUTOPOLL_TYPE_MIFARE: |
|---|
| 1476 | + dev_dbg(dev->dev, "Mifare\n"); |
|---|
| 1477 | + rc = pn533_target_found_type_a(&nfc_tgt, apr->tgdata, |
|---|
| 1478 | + apr->ln - 1); |
|---|
| 1479 | + break; |
|---|
| 1480 | + default: |
|---|
| 1481 | + nfc_err(dev->dev, |
|---|
| 1482 | + "Unknown current poll modulation\n"); |
|---|
| 1483 | + rc = -EPROTO; |
|---|
| 1484 | + } |
|---|
| 1485 | + |
|---|
| 1486 | + if (rc) |
|---|
| 1487 | + goto done; |
|---|
| 1488 | + |
|---|
| 1489 | + if (!(nfc_tgt.supported_protocols & dev->poll_protocols)) { |
|---|
| 1490 | + nfc_err(dev->dev, |
|---|
| 1491 | + "The Tg found doesn't have the desired protocol\n"); |
|---|
| 1492 | + rc = -EAGAIN; |
|---|
| 1493 | + goto done; |
|---|
| 1494 | + } |
|---|
| 1495 | + |
|---|
| 1496 | + dev->tgt_available_prots = nfc_tgt.supported_protocols; |
|---|
| 1497 | + apr = (struct pn532_autopoll_resp *) |
|---|
| 1498 | + (apr->tgdata + (apr->ln - 1)); |
|---|
| 1499 | + } |
|---|
| 1500 | + |
|---|
| 1501 | + pn533_poll_reset_mod_list(dev); |
|---|
| 1502 | + nfc_targets_found(dev->nfc_dev, &nfc_tgt, 1); |
|---|
| 1503 | + |
|---|
| 1504 | +done: |
|---|
| 1505 | + dev_kfree_skb(resp); |
|---|
| 1506 | + return rc; |
|---|
| 1507 | + |
|---|
| 1508 | +stop_poll: |
|---|
| 1509 | + nfc_err(dev->dev, "autopoll operation has been stopped\n"); |
|---|
| 1510 | + |
|---|
| 1511 | + pn533_poll_reset_mod_list(dev); |
|---|
| 1512 | + dev->poll_protocols = 0; |
|---|
| 1513 | + return rc; |
|---|
| 1514 | +} |
|---|
| 1515 | + |
|---|
| 1407 | 1516 | static int pn533_poll_complete(struct pn533 *dev, void *arg, |
|---|
| 1408 | 1517 | struct sk_buff *resp) |
|---|
| 1409 | 1518 | { |
|---|
| .. | .. |
|---|
| 1547 | 1656 | { |
|---|
| 1548 | 1657 | struct pn533 *dev = nfc_get_drvdata(nfc_dev); |
|---|
| 1549 | 1658 | struct pn533_poll_modulations *cur_mod; |
|---|
| 1659 | + struct sk_buff *skb; |
|---|
| 1550 | 1660 | u8 rand_mod; |
|---|
| 1551 | 1661 | int rc; |
|---|
| 1552 | 1662 | |
|---|
| .. | .. |
|---|
| 1572 | 1682 | tm_protocols = 0; |
|---|
| 1573 | 1683 | } |
|---|
| 1574 | 1684 | |
|---|
| 1575 | | - pn533_poll_create_mod_list(dev, im_protocols, tm_protocols); |
|---|
| 1576 | 1685 | dev->poll_protocols = im_protocols; |
|---|
| 1577 | 1686 | dev->listen_protocols = tm_protocols; |
|---|
| 1687 | + if (dev->device_type == PN533_DEVICE_PN532_AUTOPOLL) { |
|---|
| 1688 | + skb = pn533_alloc_skb(dev, 4 + 6); |
|---|
| 1689 | + if (!skb) |
|---|
| 1690 | + return -ENOMEM; |
|---|
| 1691 | + |
|---|
| 1692 | + *((u8 *)skb_put(skb, sizeof(u8))) = |
|---|
| 1693 | + PN532_AUTOPOLL_POLLNR_INFINITE; |
|---|
| 1694 | + *((u8 *)skb_put(skb, sizeof(u8))) = PN532_AUTOPOLL_PERIOD; |
|---|
| 1695 | + |
|---|
| 1696 | + if ((im_protocols & NFC_PROTO_MIFARE_MASK) && |
|---|
| 1697 | + (im_protocols & NFC_PROTO_ISO14443_MASK) && |
|---|
| 1698 | + (im_protocols & NFC_PROTO_NFC_DEP_MASK)) |
|---|
| 1699 | + *((u8 *)skb_put(skb, sizeof(u8))) = |
|---|
| 1700 | + PN532_AUTOPOLL_TYPE_GENERIC_106; |
|---|
| 1701 | + else { |
|---|
| 1702 | + if (im_protocols & NFC_PROTO_MIFARE_MASK) |
|---|
| 1703 | + *((u8 *)skb_put(skb, sizeof(u8))) = |
|---|
| 1704 | + PN532_AUTOPOLL_TYPE_MIFARE; |
|---|
| 1705 | + |
|---|
| 1706 | + if (im_protocols & NFC_PROTO_ISO14443_MASK) |
|---|
| 1707 | + *((u8 *)skb_put(skb, sizeof(u8))) = |
|---|
| 1708 | + PN532_AUTOPOLL_TYPE_ISOA; |
|---|
| 1709 | + |
|---|
| 1710 | + if (im_protocols & NFC_PROTO_NFC_DEP_MASK) { |
|---|
| 1711 | + *((u8 *)skb_put(skb, sizeof(u8))) = |
|---|
| 1712 | + PN532_AUTOPOLL_TYPE_DEP_PASSIVE_106; |
|---|
| 1713 | + *((u8 *)skb_put(skb, sizeof(u8))) = |
|---|
| 1714 | + PN532_AUTOPOLL_TYPE_DEP_PASSIVE_212; |
|---|
| 1715 | + *((u8 *)skb_put(skb, sizeof(u8))) = |
|---|
| 1716 | + PN532_AUTOPOLL_TYPE_DEP_PASSIVE_424; |
|---|
| 1717 | + } |
|---|
| 1718 | + } |
|---|
| 1719 | + |
|---|
| 1720 | + if (im_protocols & NFC_PROTO_FELICA_MASK || |
|---|
| 1721 | + im_protocols & NFC_PROTO_NFC_DEP_MASK) { |
|---|
| 1722 | + *((u8 *)skb_put(skb, sizeof(u8))) = |
|---|
| 1723 | + PN532_AUTOPOLL_TYPE_FELICA212; |
|---|
| 1724 | + *((u8 *)skb_put(skb, sizeof(u8))) = |
|---|
| 1725 | + PN532_AUTOPOLL_TYPE_FELICA424; |
|---|
| 1726 | + } |
|---|
| 1727 | + |
|---|
| 1728 | + if (im_protocols & NFC_PROTO_JEWEL_MASK) |
|---|
| 1729 | + *((u8 *)skb_put(skb, sizeof(u8))) = |
|---|
| 1730 | + PN532_AUTOPOLL_TYPE_JEWEL; |
|---|
| 1731 | + |
|---|
| 1732 | + if (im_protocols & NFC_PROTO_ISO14443_B_MASK) |
|---|
| 1733 | + *((u8 *)skb_put(skb, sizeof(u8))) = |
|---|
| 1734 | + PN532_AUTOPOLL_TYPE_ISOB; |
|---|
| 1735 | + |
|---|
| 1736 | + if (tm_protocols) |
|---|
| 1737 | + *((u8 *)skb_put(skb, sizeof(u8))) = |
|---|
| 1738 | + PN532_AUTOPOLL_TYPE_DEP_ACTIVE_106; |
|---|
| 1739 | + |
|---|
| 1740 | + rc = pn533_send_cmd_async(dev, PN533_CMD_IN_AUTOPOLL, skb, |
|---|
| 1741 | + pn533_autopoll_complete, NULL); |
|---|
| 1742 | + |
|---|
| 1743 | + if (rc < 0) |
|---|
| 1744 | + dev_kfree_skb(skb); |
|---|
| 1745 | + else |
|---|
| 1746 | + dev->poll_mod_count++; |
|---|
| 1747 | + |
|---|
| 1748 | + return rc; |
|---|
| 1749 | + } |
|---|
| 1750 | + |
|---|
| 1751 | + pn533_poll_create_mod_list(dev, im_protocols, tm_protocols); |
|---|
| 1578 | 1752 | |
|---|
| 1579 | 1753 | /* Do not always start polling from the same modulation */ |
|---|
| 1580 | 1754 | get_random_bytes(&rand_mod, sizeof(rand_mod)); |
|---|
| .. | .. |
|---|
| 2150 | 2324 | |
|---|
| 2151 | 2325 | break; |
|---|
| 2152 | 2326 | } |
|---|
| 2327 | + fallthrough; |
|---|
| 2153 | 2328 | default: |
|---|
| 2154 | 2329 | /* jumbo frame ? */ |
|---|
| 2155 | 2330 | if (skb->len > PN533_CMD_DATAEXCH_DATA_MAXLEN) { |
|---|
| .. | .. |
|---|
| 2276 | 2451 | |
|---|
| 2277 | 2452 | break; |
|---|
| 2278 | 2453 | } |
|---|
| 2454 | + fallthrough; |
|---|
| 2279 | 2455 | default: |
|---|
| 2280 | 2456 | skb_put_u8(skb, 1); /*TG*/ |
|---|
| 2281 | 2457 | |
|---|
| .. | .. |
|---|
| 2470 | 2646 | static int pn533_dev_up(struct nfc_dev *nfc_dev) |
|---|
| 2471 | 2647 | { |
|---|
| 2472 | 2648 | struct pn533 *dev = nfc_get_drvdata(nfc_dev); |
|---|
| 2649 | + int rc; |
|---|
| 2473 | 2650 | |
|---|
| 2474 | | - if (dev->device_type == PN533_DEVICE_PN532) { |
|---|
| 2475 | | - int rc = pn532_sam_configuration(nfc_dev); |
|---|
| 2651 | + if (dev->phy_ops->dev_up) { |
|---|
| 2652 | + rc = dev->phy_ops->dev_up(dev); |
|---|
| 2653 | + if (rc) |
|---|
| 2654 | + return rc; |
|---|
| 2655 | + } |
|---|
| 2656 | + |
|---|
| 2657 | + if ((dev->device_type == PN533_DEVICE_PN532) || |
|---|
| 2658 | + (dev->device_type == PN533_DEVICE_PN532_AUTOPOLL)) { |
|---|
| 2659 | + rc = pn532_sam_configuration(nfc_dev); |
|---|
| 2476 | 2660 | |
|---|
| 2477 | 2661 | if (rc) |
|---|
| 2478 | 2662 | return rc; |
|---|
| .. | .. |
|---|
| 2483 | 2667 | |
|---|
| 2484 | 2668 | static int pn533_dev_down(struct nfc_dev *nfc_dev) |
|---|
| 2485 | 2669 | { |
|---|
| 2486 | | - return pn533_rf_field(nfc_dev, 0); |
|---|
| 2670 | + struct pn533 *dev = nfc_get_drvdata(nfc_dev); |
|---|
| 2671 | + int ret; |
|---|
| 2672 | + |
|---|
| 2673 | + ret = pn533_rf_field(nfc_dev, 0); |
|---|
| 2674 | + if (dev->phy_ops->dev_down && !ret) |
|---|
| 2675 | + ret = dev->phy_ops->dev_down(dev); |
|---|
| 2676 | + |
|---|
| 2677 | + return ret; |
|---|
| 2487 | 2678 | } |
|---|
| 2488 | 2679 | |
|---|
| 2489 | 2680 | static struct nfc_ops pn533_nfc_ops = { |
|---|
| .. | .. |
|---|
| 2511 | 2702 | case PN533_DEVICE_PASORI: |
|---|
| 2512 | 2703 | case PN533_DEVICE_ACR122U: |
|---|
| 2513 | 2704 | case PN533_DEVICE_PN532: |
|---|
| 2705 | + case PN533_DEVICE_PN532_AUTOPOLL: |
|---|
| 2514 | 2706 | max_retries.mx_rty_atr = 0x2; |
|---|
| 2515 | 2707 | max_retries.mx_rty_psl = 0x1; |
|---|
| 2516 | 2708 | max_retries.mx_rty_passive_act = |
|---|
| .. | .. |
|---|
| 2547 | 2739 | switch (dev->device_type) { |
|---|
| 2548 | 2740 | case PN533_DEVICE_STD: |
|---|
| 2549 | 2741 | case PN533_DEVICE_PN532: |
|---|
| 2742 | + case PN533_DEVICE_PN532_AUTOPOLL: |
|---|
| 2550 | 2743 | break; |
|---|
| 2551 | 2744 | |
|---|
| 2552 | 2745 | case PN533_DEVICE_PASORI: |
|---|
| .. | .. |
|---|
| 2593 | 2786 | } |
|---|
| 2594 | 2787 | EXPORT_SYMBOL_GPL(pn533_finalize_setup); |
|---|
| 2595 | 2788 | |
|---|
| 2596 | | -struct pn533 *pn533_register_device(u32 device_type, |
|---|
| 2597 | | - u32 protocols, |
|---|
| 2789 | +struct pn533 *pn53x_common_init(u32 device_type, |
|---|
| 2598 | 2790 | enum pn533_protocol_type protocol_type, |
|---|
| 2599 | 2791 | void *phy, |
|---|
| 2600 | 2792 | struct pn533_phy_ops *phy_ops, |
|---|
| 2601 | 2793 | struct pn533_frame_ops *fops, |
|---|
| 2602 | | - struct device *dev, |
|---|
| 2603 | | - struct device *parent) |
|---|
| 2794 | + struct device *dev) |
|---|
| 2604 | 2795 | { |
|---|
| 2605 | 2796 | struct pn533 *priv; |
|---|
| 2606 | 2797 | int rc = -ENOMEM; |
|---|
| .. | .. |
|---|
| 2641 | 2832 | skb_queue_head_init(&priv->fragment_skb); |
|---|
| 2642 | 2833 | |
|---|
| 2643 | 2834 | INIT_LIST_HEAD(&priv->cmd_queue); |
|---|
| 2644 | | - |
|---|
| 2645 | | - priv->nfc_dev = nfc_allocate_device(&pn533_nfc_ops, protocols, |
|---|
| 2646 | | - priv->ops->tx_header_len + |
|---|
| 2647 | | - PN533_CMD_DATAEXCH_HEAD_LEN, |
|---|
| 2648 | | - priv->ops->tx_tail_len); |
|---|
| 2649 | | - if (!priv->nfc_dev) { |
|---|
| 2650 | | - rc = -ENOMEM; |
|---|
| 2651 | | - goto destroy_wq; |
|---|
| 2652 | | - } |
|---|
| 2653 | | - |
|---|
| 2654 | | - nfc_set_parent_dev(priv->nfc_dev, parent); |
|---|
| 2655 | | - nfc_set_drvdata(priv->nfc_dev, priv); |
|---|
| 2656 | | - |
|---|
| 2657 | | - rc = nfc_register_device(priv->nfc_dev); |
|---|
| 2658 | | - if (rc) |
|---|
| 2659 | | - goto free_nfc_dev; |
|---|
| 2660 | | - |
|---|
| 2661 | 2835 | return priv; |
|---|
| 2662 | 2836 | |
|---|
| 2663 | | -free_nfc_dev: |
|---|
| 2664 | | - nfc_free_device(priv->nfc_dev); |
|---|
| 2665 | | - |
|---|
| 2666 | | -destroy_wq: |
|---|
| 2667 | | - destroy_workqueue(priv->wq); |
|---|
| 2668 | 2837 | error: |
|---|
| 2669 | 2838 | kfree(priv); |
|---|
| 2670 | 2839 | return ERR_PTR(rc); |
|---|
| 2671 | 2840 | } |
|---|
| 2672 | | -EXPORT_SYMBOL_GPL(pn533_register_device); |
|---|
| 2841 | +EXPORT_SYMBOL_GPL(pn53x_common_init); |
|---|
| 2673 | 2842 | |
|---|
| 2674 | | -void pn533_unregister_device(struct pn533 *priv) |
|---|
| 2843 | +void pn53x_common_clean(struct pn533 *priv) |
|---|
| 2675 | 2844 | { |
|---|
| 2676 | 2845 | struct pn533_cmd *cmd, *n; |
|---|
| 2677 | 2846 | |
|---|
| 2678 | | - nfc_unregister_device(priv->nfc_dev); |
|---|
| 2679 | | - nfc_free_device(priv->nfc_dev); |
|---|
| 2847 | + /* delete the timer before cleanup the worker */ |
|---|
| 2848 | + del_timer_sync(&priv->listen_timer); |
|---|
| 2680 | 2849 | |
|---|
| 2681 | 2850 | flush_delayed_work(&priv->poll_work); |
|---|
| 2682 | 2851 | destroy_workqueue(priv->wq); |
|---|
| 2683 | 2852 | |
|---|
| 2684 | 2853 | skb_queue_purge(&priv->resp_q); |
|---|
| 2685 | | - |
|---|
| 2686 | | - del_timer(&priv->listen_timer); |
|---|
| 2687 | 2854 | |
|---|
| 2688 | 2855 | list_for_each_entry_safe(cmd, n, &priv->cmd_queue, queue) { |
|---|
| 2689 | 2856 | list_del(&cmd->queue); |
|---|
| .. | .. |
|---|
| 2692 | 2859 | |
|---|
| 2693 | 2860 | kfree(priv); |
|---|
| 2694 | 2861 | } |
|---|
| 2695 | | -EXPORT_SYMBOL_GPL(pn533_unregister_device); |
|---|
| 2862 | +EXPORT_SYMBOL_GPL(pn53x_common_clean); |
|---|
| 2696 | 2863 | |
|---|
| 2864 | +int pn532_i2c_nfc_alloc(struct pn533 *priv, u32 protocols, |
|---|
| 2865 | + struct device *parent) |
|---|
| 2866 | +{ |
|---|
| 2867 | + priv->nfc_dev = nfc_allocate_device(&pn533_nfc_ops, protocols, |
|---|
| 2868 | + priv->ops->tx_header_len + |
|---|
| 2869 | + PN533_CMD_DATAEXCH_HEAD_LEN, |
|---|
| 2870 | + priv->ops->tx_tail_len); |
|---|
| 2871 | + if (!priv->nfc_dev) |
|---|
| 2872 | + return -ENOMEM; |
|---|
| 2873 | + |
|---|
| 2874 | + nfc_set_parent_dev(priv->nfc_dev, parent); |
|---|
| 2875 | + nfc_set_drvdata(priv->nfc_dev, priv); |
|---|
| 2876 | + return 0; |
|---|
| 2877 | +} |
|---|
| 2878 | +EXPORT_SYMBOL_GPL(pn532_i2c_nfc_alloc); |
|---|
| 2879 | + |
|---|
| 2880 | +int pn53x_register_nfc(struct pn533 *priv, u32 protocols, |
|---|
| 2881 | + struct device *parent) |
|---|
| 2882 | +{ |
|---|
| 2883 | + int rc; |
|---|
| 2884 | + |
|---|
| 2885 | + rc = pn532_i2c_nfc_alloc(priv, protocols, parent); |
|---|
| 2886 | + if (rc) |
|---|
| 2887 | + return rc; |
|---|
| 2888 | + |
|---|
| 2889 | + rc = nfc_register_device(priv->nfc_dev); |
|---|
| 2890 | + if (rc) |
|---|
| 2891 | + nfc_free_device(priv->nfc_dev); |
|---|
| 2892 | + |
|---|
| 2893 | + return rc; |
|---|
| 2894 | +} |
|---|
| 2895 | +EXPORT_SYMBOL_GPL(pn53x_register_nfc); |
|---|
| 2896 | + |
|---|
| 2897 | +void pn53x_unregister_nfc(struct pn533 *priv) |
|---|
| 2898 | +{ |
|---|
| 2899 | + nfc_unregister_device(priv->nfc_dev); |
|---|
| 2900 | + nfc_free_device(priv->nfc_dev); |
|---|
| 2901 | +} |
|---|
| 2902 | +EXPORT_SYMBOL_GPL(pn53x_unregister_nfc); |
|---|
| 2697 | 2903 | |
|---|
| 2698 | 2904 | MODULE_AUTHOR("Lauro Ramos Venancio <lauro.venancio@openbossa.org>"); |
|---|
| 2699 | 2905 | MODULE_AUTHOR("Aloisio Almeida Jr <aloisio.almeida@openbossa.org>"); |
|---|