aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/nfc/pn533.c
diff options
context:
space:
mode:
authorSamuel Ortiz <sameo@linux.intel.com>2012-05-30 18:09:11 -0400
committerSamuel Ortiz <sameo@linux.intel.com>2012-06-04 15:34:31 -0400
commitdadb06f270ad7cd9572b82995f6261f8ca4620ac (patch)
tree63c71b84c55eba95aa71fa6f1551957270a36b12 /drivers/nfc/pn533.c
parent103b34cf5fe2bb72c38afa8523dd206e6ef3b5fe (diff)
NFC: Implement the pn533 target mode Tx op
Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
Diffstat (limited to 'drivers/nfc/pn533.c')
-rw-r--r--drivers/nfc/pn533.c82
1 files changed, 73 insertions, 9 deletions
diff --git a/drivers/nfc/pn533.c b/drivers/nfc/pn533.c
index 6a506e267d20..db4078765ac9 100644
--- a/drivers/nfc/pn533.c
+++ b/drivers/nfc/pn533.c
@@ -76,6 +76,7 @@ MODULE_DEVICE_TABLE(usb, pn533_table);
76 76
77#define PN533_CMD_TG_INIT_AS_TARGET 0x8c 77#define PN533_CMD_TG_INIT_AS_TARGET 0x8c
78#define PN533_CMD_TG_GET_DATA 0x86 78#define PN533_CMD_TG_GET_DATA 0x86
79#define PN533_CMD_TG_SET_DATA 0x8e
79 80
80#define PN533_CMD_RESPONSE(cmd) (cmd + 1) 81#define PN533_CMD_RESPONSE(cmd) (cmd + 1)
81 82
@@ -1630,7 +1631,8 @@ static int pn533_dep_link_down(struct nfc_dev *nfc_dev)
1630 return 0; 1631 return 0;
1631} 1632}
1632 1633
1633static int pn533_data_exchange_tx_frame(struct pn533 *dev, struct sk_buff *skb) 1634static int pn533_build_tx_frame(struct pn533 *dev, struct sk_buff *skb,
1635 bool target)
1634{ 1636{
1635 int payload_len = skb->len; 1637 int payload_len = skb->len;
1636 struct pn533_frame *out_frame; 1638 struct pn533_frame *out_frame;
@@ -1647,14 +1649,20 @@ static int pn533_data_exchange_tx_frame(struct pn533 *dev, struct sk_buff *skb)
1647 return -ENOSYS; 1649 return -ENOSYS;
1648 } 1650 }
1649 1651
1650 skb_push(skb, PN533_CMD_DATAEXCH_HEAD_LEN); 1652 if (target == true) {
1651 out_frame = (struct pn533_frame *) skb->data; 1653 skb_push(skb, PN533_CMD_DATAEXCH_HEAD_LEN);
1654 out_frame = (struct pn533_frame *) skb->data;
1652 1655
1653 pn533_tx_frame_init(out_frame, PN533_CMD_IN_DATA_EXCHANGE); 1656 pn533_tx_frame_init(out_frame, PN533_CMD_IN_DATA_EXCHANGE);
1657 tg = 1;
1658 memcpy(PN533_FRAME_CMD_PARAMS_PTR(out_frame), &tg, sizeof(u8));
1659 out_frame->datalen += sizeof(u8);
1660 } else {
1661 skb_push(skb, PN533_CMD_DATAEXCH_HEAD_LEN - 1);
1662 out_frame = (struct pn533_frame *) skb->data;
1663 pn533_tx_frame_init(out_frame, PN533_CMD_TG_SET_DATA);
1664 }
1654 1665
1655 tg = 1;
1656 memcpy(PN533_FRAME_CMD_PARAMS_PTR(out_frame), &tg, sizeof(u8));
1657 out_frame->datalen += sizeof(u8);
1658 1666
1659 /* The data is already in the out_frame, just update the datalen */ 1667 /* The data is already in the out_frame, just update the datalen */
1660 out_frame->datalen += payload_len; 1668 out_frame->datalen += payload_len;
@@ -1785,7 +1793,7 @@ static int pn533_transceive(struct nfc_dev *nfc_dev,
1785 goto error; 1793 goto error;
1786 } 1794 }
1787 1795
1788 rc = pn533_data_exchange_tx_frame(dev, skb); 1796 rc = pn533_build_tx_frame(dev, skb, true);
1789 if (rc) 1797 if (rc)
1790 goto error; 1798 goto error;
1791 1799
@@ -1833,6 +1841,61 @@ error:
1833 return rc; 1841 return rc;
1834} 1842}
1835 1843
1844static int pn533_tm_send_complete(struct pn533 *dev, void *arg,
1845 u8 *params, int params_len)
1846{
1847 nfc_dev_dbg(&dev->interface->dev, "%s", __func__);
1848
1849 if (params_len < 0) {
1850 nfc_dev_err(&dev->interface->dev,
1851 "Error %d when sending data",
1852 params_len);
1853
1854 return params_len;
1855 }
1856
1857 if (params_len > 0 && params[0] != 0) {
1858 nfc_tm_deactivated(dev->nfc_dev);
1859
1860 return 0;
1861 }
1862
1863 queue_work(dev->wq, &dev->tg_work);
1864
1865 return 0;
1866}
1867
1868static int pn533_tm_send(struct nfc_dev *nfc_dev, struct sk_buff *skb)
1869{
1870 struct pn533 *dev = nfc_get_drvdata(nfc_dev);
1871 struct pn533_frame *out_frame;
1872 int rc;
1873
1874 nfc_dev_dbg(&dev->interface->dev, "%s", __func__);
1875
1876 rc = pn533_build_tx_frame(dev, skb, false);
1877 if (rc)
1878 goto error;
1879
1880 out_frame = (struct pn533_frame *) skb->data;
1881
1882 rc = pn533_send_cmd_frame_async(dev, out_frame, dev->in_frame,
1883 dev->in_maxlen, pn533_tm_send_complete,
1884 NULL, GFP_KERNEL);
1885 if (rc) {
1886 nfc_dev_err(&dev->interface->dev,
1887 "Error %d when trying to send data", rc);
1888 goto error;
1889 }
1890
1891 return 0;
1892
1893error:
1894 kfree_skb(skb);
1895
1896 return rc;
1897}
1898
1836static void pn533_wq_mi_recv(struct work_struct *work) 1899static void pn533_wq_mi_recv(struct work_struct *work)
1837{ 1900{
1838 struct pn533 *dev = container_of(work, struct pn533, mi_work); 1901 struct pn533 *dev = container_of(work, struct pn533, mi_work);
@@ -1853,7 +1916,7 @@ static void pn533_wq_mi_recv(struct work_struct *work)
1853 1916
1854 skb_reserve(skb_cmd, PN533_CMD_DATAEXCH_HEAD_LEN); 1917 skb_reserve(skb_cmd, PN533_CMD_DATAEXCH_HEAD_LEN);
1855 1918
1856 rc = pn533_data_exchange_tx_frame(dev, skb_cmd); 1919 rc = pn533_build_tx_frame(dev, skb_cmd, true);
1857 if (rc) 1920 if (rc)
1858 goto error_frame; 1921 goto error_frame;
1859 1922
@@ -1928,6 +1991,7 @@ struct nfc_ops pn533_nfc_ops = {
1928 .activate_target = pn533_activate_target, 1991 .activate_target = pn533_activate_target,
1929 .deactivate_target = pn533_deactivate_target, 1992 .deactivate_target = pn533_deactivate_target,
1930 .im_transceive = pn533_transceive, 1993 .im_transceive = pn533_transceive,
1994 .tm_send = pn533_tm_send,
1931}; 1995};
1932 1996
1933static int pn533_probe(struct usb_interface *interface, 1997static int pn533_probe(struct usb_interface *interface,