aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMark A. Greer <mgreer@animalcreek.com>2014-09-02 18:12:46 -0400
committerSamuel Ortiz <sameo@linux.intel.com>2014-09-07 17:13:45 -0400
commitcb174aba86fe10ddac8b692c90a9480526c02953 (patch)
tree626ac14bbca3ceb2fa2a7ec05d8202b66e3f6e76
parent13b4272a8264220ec043a922fd1fa05da72d57ae (diff)
NFC: trf7970a: Add Target Mode Detection Support
Add the ability to detect the mode (i.e., RF technology) used by the initiator. The RF technology that was detected can be retrieved by calling the 'tg_get_rf_tech' driver hook. Signed-off-by: Mark A. Greer <mgreer@animalcreek.com> Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
-rw-r--r--drivers/nfc/trf7970a.c160
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
554static 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
573static 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
519static void trf7970a_send_upstream(struct trf7970a *trf) 606static 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
1590static int trf7970a_tg_listen(struct nfc_digital_dev *ddev, u16 timeout, 1693static 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
1767static 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
1778static 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
1800static 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
1666static void trf7970a_abort_cmd(struct nfc_digital_dev *ddev) 1812static 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};