diff options
-rw-r--r-- | drivers/nfc/trf7970a.c | 160 |
1 files changed, 154 insertions, 6 deletions
diff --git a/drivers/nfc/trf7970a.c b/drivers/nfc/trf7970a.c index b33cc0211f53..2a521bb38060 100644 --- a/drivers/nfc/trf7970a.c +++ b/drivers/nfc/trf7970a.c | |||
@@ -340,6 +340,39 @@ | |||
340 | #define TRF7970A_NFC_TARGET_LEVEL_LD_S_7BYTES (0x1 << 6) | 340 | #define TRF7970A_NFC_TARGET_LEVEL_LD_S_7BYTES (0x1 << 6) |
341 | #define TRF7970A_NFC_TARGET_LEVEL_LD_S_10BYTES (0x2 << 6) | 341 | #define TRF7970A_NFC_TARGET_LEVEL_LD_S_10BYTES (0x2 << 6) |
342 | 342 | ||
343 | #define TRF79070A_NFC_TARGET_PROTOCOL_NFCBR_106 BIT(0) | ||
344 | #define TRF79070A_NFC_TARGET_PROTOCOL_NFCBR_212 BIT(1) | ||
345 | #define TRF79070A_NFC_TARGET_PROTOCOL_NFCBR_424 (BIT(0) | BIT(1)) | ||
346 | #define TRF79070A_NFC_TARGET_PROTOCOL_PAS_14443B BIT(2) | ||
347 | #define TRF79070A_NFC_TARGET_PROTOCOL_PAS_106 BIT(3) | ||
348 | #define TRF79070A_NFC_TARGET_PROTOCOL_FELICA BIT(4) | ||
349 | #define TRF79070A_NFC_TARGET_PROTOCOL_RF_L BIT(6) | ||
350 | #define TRF79070A_NFC_TARGET_PROTOCOL_RF_H BIT(7) | ||
351 | |||
352 | #define TRF79070A_NFC_TARGET_PROTOCOL_106A \ | ||
353 | (TRF79070A_NFC_TARGET_PROTOCOL_RF_H | \ | ||
354 | TRF79070A_NFC_TARGET_PROTOCOL_RF_L | \ | ||
355 | TRF79070A_NFC_TARGET_PROTOCOL_PAS_106 | \ | ||
356 | TRF79070A_NFC_TARGET_PROTOCOL_NFCBR_106) | ||
357 | |||
358 | #define TRF79070A_NFC_TARGET_PROTOCOL_106B \ | ||
359 | (TRF79070A_NFC_TARGET_PROTOCOL_RF_H | \ | ||
360 | TRF79070A_NFC_TARGET_PROTOCOL_RF_L | \ | ||
361 | TRF79070A_NFC_TARGET_PROTOCOL_PAS_14443B | \ | ||
362 | TRF79070A_NFC_TARGET_PROTOCOL_NFCBR_106) | ||
363 | |||
364 | #define TRF79070A_NFC_TARGET_PROTOCOL_212F \ | ||
365 | (TRF79070A_NFC_TARGET_PROTOCOL_RF_H | \ | ||
366 | TRF79070A_NFC_TARGET_PROTOCOL_RF_L | \ | ||
367 | TRF79070A_NFC_TARGET_PROTOCOL_FELICA | \ | ||
368 | TRF79070A_NFC_TARGET_PROTOCOL_NFCBR_212) | ||
369 | |||
370 | #define TRF79070A_NFC_TARGET_PROTOCOL_424F \ | ||
371 | (TRF79070A_NFC_TARGET_PROTOCOL_RF_H | \ | ||
372 | TRF79070A_NFC_TARGET_PROTOCOL_RF_L | \ | ||
373 | TRF79070A_NFC_TARGET_PROTOCOL_FELICA | \ | ||
374 | TRF79070A_NFC_TARGET_PROTOCOL_NFCBR_424) | ||
375 | |||
343 | #define TRF7970A_FIFO_STATUS_OVERFLOW BIT(7) | 376 | #define TRF7970A_FIFO_STATUS_OVERFLOW BIT(7) |
344 | 377 | ||
345 | /* NFC (ISO/IEC 14443A) Type 2 Tag commands */ | 378 | /* NFC (ISO/IEC 14443A) Type 2 Tag commands */ |
@@ -385,6 +418,7 @@ enum trf7970a_state { | |||
385 | TRF7970A_ST_WAIT_FOR_RX_DATA_CONT, | 418 | TRF7970A_ST_WAIT_FOR_RX_DATA_CONT, |
386 | TRF7970A_ST_WAIT_TO_ISSUE_EOF, | 419 | TRF7970A_ST_WAIT_TO_ISSUE_EOF, |
387 | TRF7970A_ST_LISTENING, | 420 | TRF7970A_ST_LISTENING, |
421 | TRF7970A_ST_LISTENING_MD, | ||
388 | TRF7970A_ST_MAX | 422 | TRF7970A_ST_MAX |
389 | }; | 423 | }; |
390 | 424 | ||
@@ -409,6 +443,7 @@ struct trf7970a { | |||
409 | unsigned int guard_time; | 443 | unsigned int guard_time; |
410 | int technology; | 444 | int technology; |
411 | int framing; | 445 | int framing; |
446 | u8 md_rf_tech; | ||
412 | u8 tx_cmd; | 447 | u8 tx_cmd; |
413 | bool issue_eof; | 448 | bool issue_eof; |
414 | int en2_gpio; | 449 | int en2_gpio; |
@@ -516,6 +551,58 @@ static int trf7970a_read_irqstatus(struct trf7970a *trf, u8 *status) | |||
516 | return ret; | 551 | return ret; |
517 | } | 552 | } |
518 | 553 | ||
554 | static int trf7970a_read_target_proto(struct trf7970a *trf, u8 *target_proto) | ||
555 | { | ||
556 | int ret; | ||
557 | u8 buf[2]; | ||
558 | u8 addr; | ||
559 | |||
560 | addr = TRF79070A_NFC_TARGET_PROTOCOL | TRF7970A_CMD_BIT_RW | | ||
561 | TRF7970A_CMD_BIT_CONTINUOUS; | ||
562 | |||
563 | ret = spi_write_then_read(trf->spi, &addr, 1, buf, 2); | ||
564 | if (ret) | ||
565 | dev_err(trf->dev, "%s - target_proto: Read failed: %d\n", | ||
566 | __func__, ret); | ||
567 | else | ||
568 | *target_proto = buf[0]; | ||
569 | |||
570 | return ret; | ||
571 | } | ||
572 | |||
573 | static int trf7970a_mode_detect(struct trf7970a *trf, u8 *rf_tech) | ||
574 | { | ||
575 | int ret; | ||
576 | u8 target_proto, tech; | ||
577 | |||
578 | ret = trf7970a_read_target_proto(trf, &target_proto); | ||
579 | if (ret) | ||
580 | return ret; | ||
581 | |||
582 | switch (target_proto) { | ||
583 | case TRF79070A_NFC_TARGET_PROTOCOL_106A: | ||
584 | tech = NFC_DIGITAL_RF_TECH_106A; | ||
585 | break; | ||
586 | case TRF79070A_NFC_TARGET_PROTOCOL_106B: | ||
587 | tech = NFC_DIGITAL_RF_TECH_106B; | ||
588 | break; | ||
589 | case TRF79070A_NFC_TARGET_PROTOCOL_212F: | ||
590 | tech = NFC_DIGITAL_RF_TECH_212F; | ||
591 | break; | ||
592 | case TRF79070A_NFC_TARGET_PROTOCOL_424F: | ||
593 | tech = NFC_DIGITAL_RF_TECH_424F; | ||
594 | break; | ||
595 | default: | ||
596 | dev_dbg(trf->dev, "%s - mode_detect: target_proto: 0x%x\n", | ||
597 | __func__, target_proto); | ||
598 | return -EIO; | ||
599 | } | ||
600 | |||
601 | *rf_tech = tech; | ||
602 | |||
603 | return ret; | ||
604 | } | ||
605 | |||
519 | static void trf7970a_send_upstream(struct trf7970a *trf) | 606 | static void trf7970a_send_upstream(struct trf7970a *trf) |
520 | { | 607 | { |
521 | dev_kfree_skb_any(trf->tx_skb); | 608 | dev_kfree_skb_any(trf->tx_skb); |
@@ -867,6 +954,22 @@ static irqreturn_t trf7970a_irq(int irq, void *dev_id) | |||
867 | trf7970a_send_err_upstream(trf, -EIO); | 954 | trf7970a_send_err_upstream(trf, -EIO); |
868 | } | 955 | } |
869 | break; | 956 | break; |
957 | case TRF7970A_ST_LISTENING_MD: | ||
958 | if (status & TRF7970A_IRQ_STATUS_SRX) { | ||
959 | trf->ignore_timeout = | ||
960 | !cancel_delayed_work(&trf->timeout_work); | ||
961 | |||
962 | ret = trf7970a_mode_detect(trf, &trf->md_rf_tech); | ||
963 | if (ret) { | ||
964 | trf7970a_send_err_upstream(trf, ret); | ||
965 | } else { | ||
966 | trf->state = TRF7970A_ST_LISTENING; | ||
967 | trf7970a_drain_fifo(trf, status); | ||
968 | } | ||
969 | } else if (!(status & TRF7970A_IRQ_STATUS_NFC_RF)) { | ||
970 | trf7970a_send_err_upstream(trf, -EIO); | ||
971 | } | ||
972 | break; | ||
870 | default: | 973 | default: |
871 | dev_err(trf->dev, "%s - Driver in invalid state: %d\n", | 974 | dev_err(trf->dev, "%s - Driver in invalid state: %d\n", |
872 | __func__, trf->state); | 975 | __func__, trf->state); |
@@ -1587,15 +1690,12 @@ err_unlock: | |||
1587 | return ret; | 1690 | return ret; |
1588 | } | 1691 | } |
1589 | 1692 | ||
1590 | static int trf7970a_tg_listen(struct nfc_digital_dev *ddev, u16 timeout, | 1693 | static int _trf7970a_tg_listen(struct nfc_digital_dev *ddev, u16 timeout, |
1591 | nfc_digital_cmd_complete_t cb, void *arg) | 1694 | nfc_digital_cmd_complete_t cb, void *arg, bool mode_detect) |
1592 | { | 1695 | { |
1593 | struct trf7970a *trf = nfc_digital_get_drvdata(ddev); | 1696 | struct trf7970a *trf = nfc_digital_get_drvdata(ddev); |
1594 | int ret; | 1697 | int ret; |
1595 | 1698 | ||
1596 | dev_dbg(trf->dev, "Listen - state: %d, timeout: %d ms\n", | ||
1597 | trf->state, timeout); | ||
1598 | |||
1599 | mutex_lock(&trf->lock); | 1699 | mutex_lock(&trf->lock); |
1600 | 1700 | ||
1601 | if ((trf->state != TRF7970A_ST_IDLE) && | 1701 | if ((trf->state != TRF7970A_ST_IDLE) && |
@@ -1654,7 +1754,8 @@ static int trf7970a_tg_listen(struct nfc_digital_dev *ddev, u16 timeout, | |||
1654 | if (ret) | 1754 | if (ret) |
1655 | goto out_err; | 1755 | goto out_err; |
1656 | 1756 | ||
1657 | trf->state = TRF7970A_ST_LISTENING; | 1757 | trf->state = mode_detect ? TRF7970A_ST_LISTENING_MD : |
1758 | TRF7970A_ST_LISTENING; | ||
1658 | 1759 | ||
1659 | schedule_delayed_work(&trf->timeout_work, msecs_to_jiffies(timeout)); | 1760 | schedule_delayed_work(&trf->timeout_work, msecs_to_jiffies(timeout)); |
1660 | 1761 | ||
@@ -1663,6 +1764,51 @@ out_err: | |||
1663 | return ret; | 1764 | return ret; |
1664 | } | 1765 | } |
1665 | 1766 | ||
1767 | static int trf7970a_tg_listen(struct nfc_digital_dev *ddev, u16 timeout, | ||
1768 | nfc_digital_cmd_complete_t cb, void *arg) | ||
1769 | { | ||
1770 | struct trf7970a *trf = nfc_digital_get_drvdata(ddev); | ||
1771 | |||
1772 | dev_dbg(trf->dev, "Listen - state: %d, timeout: %d ms\n", | ||
1773 | trf->state, timeout); | ||
1774 | |||
1775 | return _trf7970a_tg_listen(ddev, timeout, cb, arg, false); | ||
1776 | } | ||
1777 | |||
1778 | static int trf7970a_tg_listen_md(struct nfc_digital_dev *ddev, | ||
1779 | u16 timeout, nfc_digital_cmd_complete_t cb, void *arg) | ||
1780 | { | ||
1781 | struct trf7970a *trf = nfc_digital_get_drvdata(ddev); | ||
1782 | int ret; | ||
1783 | |||
1784 | dev_dbg(trf->dev, "Listen MD - state: %d, timeout: %d ms\n", | ||
1785 | trf->state, timeout); | ||
1786 | |||
1787 | ret = trf7970a_tg_configure_hw(ddev, NFC_DIGITAL_CONFIG_RF_TECH, | ||
1788 | NFC_DIGITAL_RF_TECH_106A); | ||
1789 | if (ret) | ||
1790 | return ret; | ||
1791 | |||
1792 | ret = trf7970a_tg_configure_hw(ddev, NFC_DIGITAL_CONFIG_FRAMING, | ||
1793 | NFC_DIGITAL_FRAMING_NFCA_NFC_DEP); | ||
1794 | if (ret) | ||
1795 | return ret; | ||
1796 | |||
1797 | return _trf7970a_tg_listen(ddev, timeout, cb, arg, true); | ||
1798 | } | ||
1799 | |||
1800 | static int trf7970a_tg_get_rf_tech(struct nfc_digital_dev *ddev, u8 *rf_tech) | ||
1801 | { | ||
1802 | struct trf7970a *trf = nfc_digital_get_drvdata(ddev); | ||
1803 | |||
1804 | dev_dbg(trf->dev, "Get RF Tech - state: %d, rf_tech: %d\n", | ||
1805 | trf->state, trf->md_rf_tech); | ||
1806 | |||
1807 | *rf_tech = trf->md_rf_tech; | ||
1808 | |||
1809 | return 0; | ||
1810 | } | ||
1811 | |||
1666 | static void trf7970a_abort_cmd(struct nfc_digital_dev *ddev) | 1812 | static void trf7970a_abort_cmd(struct nfc_digital_dev *ddev) |
1667 | { | 1813 | { |
1668 | struct trf7970a *trf = nfc_digital_get_drvdata(ddev); | 1814 | struct trf7970a *trf = nfc_digital_get_drvdata(ddev); |
@@ -1696,6 +1842,8 @@ static struct nfc_digital_ops trf7970a_nfc_ops = { | |||
1696 | .tg_configure_hw = trf7970a_tg_configure_hw, | 1842 | .tg_configure_hw = trf7970a_tg_configure_hw, |
1697 | .tg_send_cmd = trf7970a_send_cmd, | 1843 | .tg_send_cmd = trf7970a_send_cmd, |
1698 | .tg_listen = trf7970a_tg_listen, | 1844 | .tg_listen = trf7970a_tg_listen, |
1845 | .tg_listen_md = trf7970a_tg_listen_md, | ||
1846 | .tg_get_rf_tech = trf7970a_tg_get_rf_tech, | ||
1699 | .switch_rf = trf7970a_switch_rf, | 1847 | .switch_rf = trf7970a_switch_rf, |
1700 | .abort_cmd = trf7970a_abort_cmd, | 1848 | .abort_cmd = trf7970a_abort_cmd, |
1701 | }; | 1849 | }; |