.. | .. |
---|
| 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 |
---|
.. | .. |
---|
1305 | 1319 | if (IS_ERR(resp)) |
---|
1306 | 1320 | return PTR_ERR(resp); |
---|
1307 | 1321 | |
---|
| 1322 | + memset(&nfc_target, 0, sizeof(struct nfc_target)); |
---|
| 1323 | + |
---|
1308 | 1324 | rsp = (struct pn533_cmd_jump_dep_response *)resp->data; |
---|
1309 | 1325 | |
---|
1310 | 1326 | rc = rsp->status & PN533_CMD_RET_MASK; |
---|
.. | .. |
---|
1401 | 1417 | if (rc < 0) |
---|
1402 | 1418 | dev_kfree_skb(skb); |
---|
1403 | 1419 | |
---|
| 1420 | + return rc; |
---|
| 1421 | +} |
---|
| 1422 | + |
---|
| 1423 | +static int pn533_autopoll_complete(struct pn533 *dev, void *arg, |
---|
| 1424 | + struct sk_buff *resp) |
---|
| 1425 | +{ |
---|
| 1426 | + struct pn532_autopoll_resp *apr; |
---|
| 1427 | + struct nfc_target nfc_tgt; |
---|
| 1428 | + u8 nbtg; |
---|
| 1429 | + int rc; |
---|
| 1430 | + |
---|
| 1431 | + if (IS_ERR(resp)) { |
---|
| 1432 | + rc = PTR_ERR(resp); |
---|
| 1433 | + |
---|
| 1434 | + nfc_err(dev->dev, "%s autopoll complete error %d\n", |
---|
| 1435 | + __func__, rc); |
---|
| 1436 | + |
---|
| 1437 | + if (rc == -ENOENT) { |
---|
| 1438 | + if (dev->poll_mod_count != 0) |
---|
| 1439 | + return rc; |
---|
| 1440 | + goto stop_poll; |
---|
| 1441 | + } else if (rc < 0) { |
---|
| 1442 | + nfc_err(dev->dev, |
---|
| 1443 | + "Error %d when running autopoll\n", rc); |
---|
| 1444 | + goto stop_poll; |
---|
| 1445 | + } |
---|
| 1446 | + } |
---|
| 1447 | + |
---|
| 1448 | + nbtg = resp->data[0]; |
---|
| 1449 | + if ((nbtg > 2) || (nbtg <= 0)) |
---|
| 1450 | + return -EAGAIN; |
---|
| 1451 | + |
---|
| 1452 | + apr = (struct pn532_autopoll_resp *)&resp->data[1]; |
---|
| 1453 | + while (nbtg--) { |
---|
| 1454 | + memset(&nfc_tgt, 0, sizeof(struct nfc_target)); |
---|
| 1455 | + switch (apr->type) { |
---|
| 1456 | + case PN532_AUTOPOLL_TYPE_ISOA: |
---|
| 1457 | + dev_dbg(dev->dev, "ISOA\n"); |
---|
| 1458 | + rc = pn533_target_found_type_a(&nfc_tgt, apr->tgdata, |
---|
| 1459 | + apr->ln - 1); |
---|
| 1460 | + break; |
---|
| 1461 | + case PN532_AUTOPOLL_TYPE_FELICA212: |
---|
| 1462 | + case PN532_AUTOPOLL_TYPE_FELICA424: |
---|
| 1463 | + dev_dbg(dev->dev, "FELICA\n"); |
---|
| 1464 | + rc = pn533_target_found_felica(&nfc_tgt, apr->tgdata, |
---|
| 1465 | + apr->ln - 1); |
---|
| 1466 | + break; |
---|
| 1467 | + case PN532_AUTOPOLL_TYPE_JEWEL: |
---|
| 1468 | + dev_dbg(dev->dev, "JEWEL\n"); |
---|
| 1469 | + rc = pn533_target_found_jewel(&nfc_tgt, apr->tgdata, |
---|
| 1470 | + apr->ln - 1); |
---|
| 1471 | + break; |
---|
| 1472 | + case PN532_AUTOPOLL_TYPE_ISOB: |
---|
| 1473 | + dev_dbg(dev->dev, "ISOB\n"); |
---|
| 1474 | + rc = pn533_target_found_type_b(&nfc_tgt, apr->tgdata, |
---|
| 1475 | + apr->ln - 1); |
---|
| 1476 | + break; |
---|
| 1477 | + case PN532_AUTOPOLL_TYPE_MIFARE: |
---|
| 1478 | + dev_dbg(dev->dev, "Mifare\n"); |
---|
| 1479 | + rc = pn533_target_found_type_a(&nfc_tgt, apr->tgdata, |
---|
| 1480 | + apr->ln - 1); |
---|
| 1481 | + break; |
---|
| 1482 | + default: |
---|
| 1483 | + nfc_err(dev->dev, |
---|
| 1484 | + "Unknown current poll modulation\n"); |
---|
| 1485 | + rc = -EPROTO; |
---|
| 1486 | + } |
---|
| 1487 | + |
---|
| 1488 | + if (rc) |
---|
| 1489 | + goto done; |
---|
| 1490 | + |
---|
| 1491 | + if (!(nfc_tgt.supported_protocols & dev->poll_protocols)) { |
---|
| 1492 | + nfc_err(dev->dev, |
---|
| 1493 | + "The Tg found doesn't have the desired protocol\n"); |
---|
| 1494 | + rc = -EAGAIN; |
---|
| 1495 | + goto done; |
---|
| 1496 | + } |
---|
| 1497 | + |
---|
| 1498 | + dev->tgt_available_prots = nfc_tgt.supported_protocols; |
---|
| 1499 | + apr = (struct pn532_autopoll_resp *) |
---|
| 1500 | + (apr->tgdata + (apr->ln - 1)); |
---|
| 1501 | + } |
---|
| 1502 | + |
---|
| 1503 | + pn533_poll_reset_mod_list(dev); |
---|
| 1504 | + nfc_targets_found(dev->nfc_dev, &nfc_tgt, 1); |
---|
| 1505 | + |
---|
| 1506 | +done: |
---|
| 1507 | + dev_kfree_skb(resp); |
---|
| 1508 | + return rc; |
---|
| 1509 | + |
---|
| 1510 | +stop_poll: |
---|
| 1511 | + nfc_err(dev->dev, "autopoll operation has been stopped\n"); |
---|
| 1512 | + |
---|
| 1513 | + pn533_poll_reset_mod_list(dev); |
---|
| 1514 | + dev->poll_protocols = 0; |
---|
1404 | 1515 | return rc; |
---|
1405 | 1516 | } |
---|
1406 | 1517 | |
---|
.. | .. |
---|
1547 | 1658 | { |
---|
1548 | 1659 | struct pn533 *dev = nfc_get_drvdata(nfc_dev); |
---|
1549 | 1660 | struct pn533_poll_modulations *cur_mod; |
---|
| 1661 | + struct sk_buff *skb; |
---|
1550 | 1662 | u8 rand_mod; |
---|
1551 | 1663 | int rc; |
---|
1552 | 1664 | |
---|
.. | .. |
---|
1572 | 1684 | tm_protocols = 0; |
---|
1573 | 1685 | } |
---|
1574 | 1686 | |
---|
1575 | | - pn533_poll_create_mod_list(dev, im_protocols, tm_protocols); |
---|
1576 | 1687 | dev->poll_protocols = im_protocols; |
---|
1577 | 1688 | dev->listen_protocols = tm_protocols; |
---|
| 1689 | + if (dev->device_type == PN533_DEVICE_PN532_AUTOPOLL) { |
---|
| 1690 | + skb = pn533_alloc_skb(dev, 4 + 6); |
---|
| 1691 | + if (!skb) |
---|
| 1692 | + return -ENOMEM; |
---|
| 1693 | + |
---|
| 1694 | + *((u8 *)skb_put(skb, sizeof(u8))) = |
---|
| 1695 | + PN532_AUTOPOLL_POLLNR_INFINITE; |
---|
| 1696 | + *((u8 *)skb_put(skb, sizeof(u8))) = PN532_AUTOPOLL_PERIOD; |
---|
| 1697 | + |
---|
| 1698 | + if ((im_protocols & NFC_PROTO_MIFARE_MASK) && |
---|
| 1699 | + (im_protocols & NFC_PROTO_ISO14443_MASK) && |
---|
| 1700 | + (im_protocols & NFC_PROTO_NFC_DEP_MASK)) |
---|
| 1701 | + *((u8 *)skb_put(skb, sizeof(u8))) = |
---|
| 1702 | + PN532_AUTOPOLL_TYPE_GENERIC_106; |
---|
| 1703 | + else { |
---|
| 1704 | + if (im_protocols & NFC_PROTO_MIFARE_MASK) |
---|
| 1705 | + *((u8 *)skb_put(skb, sizeof(u8))) = |
---|
| 1706 | + PN532_AUTOPOLL_TYPE_MIFARE; |
---|
| 1707 | + |
---|
| 1708 | + if (im_protocols & NFC_PROTO_ISO14443_MASK) |
---|
| 1709 | + *((u8 *)skb_put(skb, sizeof(u8))) = |
---|
| 1710 | + PN532_AUTOPOLL_TYPE_ISOA; |
---|
| 1711 | + |
---|
| 1712 | + if (im_protocols & NFC_PROTO_NFC_DEP_MASK) { |
---|
| 1713 | + *((u8 *)skb_put(skb, sizeof(u8))) = |
---|
| 1714 | + PN532_AUTOPOLL_TYPE_DEP_PASSIVE_106; |
---|
| 1715 | + *((u8 *)skb_put(skb, sizeof(u8))) = |
---|
| 1716 | + PN532_AUTOPOLL_TYPE_DEP_PASSIVE_212; |
---|
| 1717 | + *((u8 *)skb_put(skb, sizeof(u8))) = |
---|
| 1718 | + PN532_AUTOPOLL_TYPE_DEP_PASSIVE_424; |
---|
| 1719 | + } |
---|
| 1720 | + } |
---|
| 1721 | + |
---|
| 1722 | + if (im_protocols & NFC_PROTO_FELICA_MASK || |
---|
| 1723 | + im_protocols & NFC_PROTO_NFC_DEP_MASK) { |
---|
| 1724 | + *((u8 *)skb_put(skb, sizeof(u8))) = |
---|
| 1725 | + PN532_AUTOPOLL_TYPE_FELICA212; |
---|
| 1726 | + *((u8 *)skb_put(skb, sizeof(u8))) = |
---|
| 1727 | + PN532_AUTOPOLL_TYPE_FELICA424; |
---|
| 1728 | + } |
---|
| 1729 | + |
---|
| 1730 | + if (im_protocols & NFC_PROTO_JEWEL_MASK) |
---|
| 1731 | + *((u8 *)skb_put(skb, sizeof(u8))) = |
---|
| 1732 | + PN532_AUTOPOLL_TYPE_JEWEL; |
---|
| 1733 | + |
---|
| 1734 | + if (im_protocols & NFC_PROTO_ISO14443_B_MASK) |
---|
| 1735 | + *((u8 *)skb_put(skb, sizeof(u8))) = |
---|
| 1736 | + PN532_AUTOPOLL_TYPE_ISOB; |
---|
| 1737 | + |
---|
| 1738 | + if (tm_protocols) |
---|
| 1739 | + *((u8 *)skb_put(skb, sizeof(u8))) = |
---|
| 1740 | + PN532_AUTOPOLL_TYPE_DEP_ACTIVE_106; |
---|
| 1741 | + |
---|
| 1742 | + rc = pn533_send_cmd_async(dev, PN533_CMD_IN_AUTOPOLL, skb, |
---|
| 1743 | + pn533_autopoll_complete, NULL); |
---|
| 1744 | + |
---|
| 1745 | + if (rc < 0) |
---|
| 1746 | + dev_kfree_skb(skb); |
---|
| 1747 | + else |
---|
| 1748 | + dev->poll_mod_count++; |
---|
| 1749 | + |
---|
| 1750 | + return rc; |
---|
| 1751 | + } |
---|
| 1752 | + |
---|
| 1753 | + pn533_poll_create_mod_list(dev, im_protocols, tm_protocols); |
---|
1578 | 1754 | |
---|
1579 | 1755 | /* Do not always start polling from the same modulation */ |
---|
1580 | 1756 | get_random_bytes(&rand_mod, sizeof(rand_mod)); |
---|
.. | .. |
---|
1785 | 1961 | struct nfc_target nfc_target; |
---|
1786 | 1962 | |
---|
1787 | 1963 | dev_dbg(dev->dev, "Creating new target\n"); |
---|
| 1964 | + |
---|
| 1965 | + memset(&nfc_target, 0, sizeof(struct nfc_target)); |
---|
1788 | 1966 | |
---|
1789 | 1967 | nfc_target.supported_protocols = NFC_PROTO_NFC_DEP_MASK; |
---|
1790 | 1968 | nfc_target.nfcid1_len = 10; |
---|
.. | .. |
---|
2150 | 2328 | |
---|
2151 | 2329 | break; |
---|
2152 | 2330 | } |
---|
| 2331 | + fallthrough; |
---|
2153 | 2332 | default: |
---|
2154 | 2333 | /* jumbo frame ? */ |
---|
2155 | 2334 | if (skb->len > PN533_CMD_DATAEXCH_DATA_MAXLEN) { |
---|
.. | .. |
---|
2276 | 2455 | |
---|
2277 | 2456 | break; |
---|
2278 | 2457 | } |
---|
| 2458 | + fallthrough; |
---|
2279 | 2459 | default: |
---|
2280 | 2460 | skb_put_u8(skb, 1); /*TG*/ |
---|
2281 | 2461 | |
---|
.. | .. |
---|
2470 | 2650 | static int pn533_dev_up(struct nfc_dev *nfc_dev) |
---|
2471 | 2651 | { |
---|
2472 | 2652 | struct pn533 *dev = nfc_get_drvdata(nfc_dev); |
---|
| 2653 | + int rc; |
---|
2473 | 2654 | |
---|
2474 | | - if (dev->device_type == PN533_DEVICE_PN532) { |
---|
2475 | | - int rc = pn532_sam_configuration(nfc_dev); |
---|
| 2655 | + if (dev->phy_ops->dev_up) { |
---|
| 2656 | + rc = dev->phy_ops->dev_up(dev); |
---|
| 2657 | + if (rc) |
---|
| 2658 | + return rc; |
---|
| 2659 | + } |
---|
| 2660 | + |
---|
| 2661 | + if ((dev->device_type == PN533_DEVICE_PN532) || |
---|
| 2662 | + (dev->device_type == PN533_DEVICE_PN532_AUTOPOLL)) { |
---|
| 2663 | + rc = pn532_sam_configuration(nfc_dev); |
---|
2476 | 2664 | |
---|
2477 | 2665 | if (rc) |
---|
2478 | 2666 | return rc; |
---|
.. | .. |
---|
2483 | 2671 | |
---|
2484 | 2672 | static int pn533_dev_down(struct nfc_dev *nfc_dev) |
---|
2485 | 2673 | { |
---|
2486 | | - return pn533_rf_field(nfc_dev, 0); |
---|
| 2674 | + struct pn533 *dev = nfc_get_drvdata(nfc_dev); |
---|
| 2675 | + int ret; |
---|
| 2676 | + |
---|
| 2677 | + ret = pn533_rf_field(nfc_dev, 0); |
---|
| 2678 | + if (dev->phy_ops->dev_down && !ret) |
---|
| 2679 | + ret = dev->phy_ops->dev_down(dev); |
---|
| 2680 | + |
---|
| 2681 | + return ret; |
---|
2487 | 2682 | } |
---|
2488 | 2683 | |
---|
2489 | 2684 | static struct nfc_ops pn533_nfc_ops = { |
---|
.. | .. |
---|
2511 | 2706 | case PN533_DEVICE_PASORI: |
---|
2512 | 2707 | case PN533_DEVICE_ACR122U: |
---|
2513 | 2708 | case PN533_DEVICE_PN532: |
---|
| 2709 | + case PN533_DEVICE_PN532_AUTOPOLL: |
---|
2514 | 2710 | max_retries.mx_rty_atr = 0x2; |
---|
2515 | 2711 | max_retries.mx_rty_psl = 0x1; |
---|
2516 | 2712 | max_retries.mx_rty_passive_act = |
---|
.. | .. |
---|
2547 | 2743 | switch (dev->device_type) { |
---|
2548 | 2744 | case PN533_DEVICE_STD: |
---|
2549 | 2745 | case PN533_DEVICE_PN532: |
---|
| 2746 | + case PN533_DEVICE_PN532_AUTOPOLL: |
---|
2550 | 2747 | break; |
---|
2551 | 2748 | |
---|
2552 | 2749 | case PN533_DEVICE_PASORI: |
---|
.. | .. |
---|
2593 | 2790 | } |
---|
2594 | 2791 | EXPORT_SYMBOL_GPL(pn533_finalize_setup); |
---|
2595 | 2792 | |
---|
2596 | | -struct pn533 *pn533_register_device(u32 device_type, |
---|
2597 | | - u32 protocols, |
---|
| 2793 | +struct pn533 *pn53x_common_init(u32 device_type, |
---|
2598 | 2794 | enum pn533_protocol_type protocol_type, |
---|
2599 | 2795 | void *phy, |
---|
2600 | 2796 | struct pn533_phy_ops *phy_ops, |
---|
2601 | 2797 | struct pn533_frame_ops *fops, |
---|
2602 | | - struct device *dev, |
---|
2603 | | - struct device *parent) |
---|
| 2798 | + struct device *dev) |
---|
2604 | 2799 | { |
---|
2605 | 2800 | struct pn533 *priv; |
---|
2606 | 2801 | int rc = -ENOMEM; |
---|
.. | .. |
---|
2641 | 2836 | skb_queue_head_init(&priv->fragment_skb); |
---|
2642 | 2837 | |
---|
2643 | 2838 | 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 | 2839 | return priv; |
---|
2662 | 2840 | |
---|
2663 | | -free_nfc_dev: |
---|
2664 | | - nfc_free_device(priv->nfc_dev); |
---|
2665 | | - |
---|
2666 | | -destroy_wq: |
---|
2667 | | - destroy_workqueue(priv->wq); |
---|
2668 | 2841 | error: |
---|
2669 | 2842 | kfree(priv); |
---|
2670 | 2843 | return ERR_PTR(rc); |
---|
2671 | 2844 | } |
---|
2672 | | -EXPORT_SYMBOL_GPL(pn533_register_device); |
---|
| 2845 | +EXPORT_SYMBOL_GPL(pn53x_common_init); |
---|
2673 | 2846 | |
---|
2674 | | -void pn533_unregister_device(struct pn533 *priv) |
---|
| 2847 | +void pn53x_common_clean(struct pn533 *priv) |
---|
2675 | 2848 | { |
---|
2676 | 2849 | struct pn533_cmd *cmd, *n; |
---|
2677 | 2850 | |
---|
2678 | | - nfc_unregister_device(priv->nfc_dev); |
---|
2679 | | - nfc_free_device(priv->nfc_dev); |
---|
| 2851 | + /* delete the timer before cleanup the worker */ |
---|
| 2852 | + del_timer_sync(&priv->listen_timer); |
---|
2680 | 2853 | |
---|
2681 | 2854 | flush_delayed_work(&priv->poll_work); |
---|
2682 | 2855 | destroy_workqueue(priv->wq); |
---|
2683 | 2856 | |
---|
2684 | 2857 | skb_queue_purge(&priv->resp_q); |
---|
2685 | | - |
---|
2686 | | - del_timer(&priv->listen_timer); |
---|
2687 | 2858 | |
---|
2688 | 2859 | list_for_each_entry_safe(cmd, n, &priv->cmd_queue, queue) { |
---|
2689 | 2860 | list_del(&cmd->queue); |
---|
.. | .. |
---|
2692 | 2863 | |
---|
2693 | 2864 | kfree(priv); |
---|
2694 | 2865 | } |
---|
2695 | | -EXPORT_SYMBOL_GPL(pn533_unregister_device); |
---|
| 2866 | +EXPORT_SYMBOL_GPL(pn53x_common_clean); |
---|
2696 | 2867 | |
---|
| 2868 | +int pn532_i2c_nfc_alloc(struct pn533 *priv, u32 protocols, |
---|
| 2869 | + struct device *parent) |
---|
| 2870 | +{ |
---|
| 2871 | + priv->nfc_dev = nfc_allocate_device(&pn533_nfc_ops, protocols, |
---|
| 2872 | + priv->ops->tx_header_len + |
---|
| 2873 | + PN533_CMD_DATAEXCH_HEAD_LEN, |
---|
| 2874 | + priv->ops->tx_tail_len); |
---|
| 2875 | + if (!priv->nfc_dev) |
---|
| 2876 | + return -ENOMEM; |
---|
| 2877 | + |
---|
| 2878 | + nfc_set_parent_dev(priv->nfc_dev, parent); |
---|
| 2879 | + nfc_set_drvdata(priv->nfc_dev, priv); |
---|
| 2880 | + return 0; |
---|
| 2881 | +} |
---|
| 2882 | +EXPORT_SYMBOL_GPL(pn532_i2c_nfc_alloc); |
---|
| 2883 | + |
---|
| 2884 | +int pn53x_register_nfc(struct pn533 *priv, u32 protocols, |
---|
| 2885 | + struct device *parent) |
---|
| 2886 | +{ |
---|
| 2887 | + int rc; |
---|
| 2888 | + |
---|
| 2889 | + rc = pn532_i2c_nfc_alloc(priv, protocols, parent); |
---|
| 2890 | + if (rc) |
---|
| 2891 | + return rc; |
---|
| 2892 | + |
---|
| 2893 | + rc = nfc_register_device(priv->nfc_dev); |
---|
| 2894 | + if (rc) |
---|
| 2895 | + nfc_free_device(priv->nfc_dev); |
---|
| 2896 | + |
---|
| 2897 | + return rc; |
---|
| 2898 | +} |
---|
| 2899 | +EXPORT_SYMBOL_GPL(pn53x_register_nfc); |
---|
| 2900 | + |
---|
| 2901 | +void pn53x_unregister_nfc(struct pn533 *priv) |
---|
| 2902 | +{ |
---|
| 2903 | + nfc_unregister_device(priv->nfc_dev); |
---|
| 2904 | + nfc_free_device(priv->nfc_dev); |
---|
| 2905 | +} |
---|
| 2906 | +EXPORT_SYMBOL_GPL(pn53x_unregister_nfc); |
---|
2697 | 2907 | |
---|
2698 | 2908 | MODULE_AUTHOR("Lauro Ramos Venancio <lauro.venancio@openbossa.org>"); |
---|
2699 | 2909 | MODULE_AUTHOR("Aloisio Almeida Jr <aloisio.almeida@openbossa.org>"); |
---|