aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorArron Wang <arron.wang@intel.com>2013-08-23 04:01:58 -0400
committerSamuel Ortiz <sameo@linux.intel.com>2013-09-24 19:35:38 -0400
commit5faba2fdf9819ebebd6d1a1cef70fddb0518cd08 (patch)
treeb9d52b453da916f760424af305df68b029847ace
parentb75ff5e84bb6c2d43a8ec39b240c80f0543821f0 (diff)
NFC: pn544: Add SE discover operation
For the SWP secure element, we send the proprietary SELF_TEST_SWP command and check the response. For the WI secure element, we simply try to switch to the default embedded SE mode. If that works, it means we have an embedded SE. Signed-off-by: Arron Wang <arron.wang@intel.com> Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
-rw-r--r--drivers/nfc/pn544/pn544.c30
1 files changed, 30 insertions, 0 deletions
diff --git a/drivers/nfc/pn544/pn544.c b/drivers/nfc/pn544/pn544.c
index 078e62feba17..727f312e05d2 100644
--- a/drivers/nfc/pn544/pn544.c
+++ b/drivers/nfc/pn544/pn544.c
@@ -41,6 +41,7 @@ enum pn544_state {
41 41
42/* Proprietary commands */ 42/* Proprietary commands */
43#define PN544_WRITE 0x3f 43#define PN544_WRITE 0x3f
44#define PN544_TEST_SWP 0x21
44 45
45/* Proprietary gates, events, commands and registers */ 46/* Proprietary gates, events, commands and registers */
46 47
@@ -83,12 +84,14 @@ enum pn544_state {
83#define PN544_SWP_MGMT_GATE 0xA0 84#define PN544_SWP_MGMT_GATE 0xA0
84 85
85#define PN544_NFC_WI_MGMT_GATE 0xA1 86#define PN544_NFC_WI_MGMT_GATE 0xA1
87#define PN544_NFC_ESE_DEFAULT_MODE 0x01
86 88
87#define PN544_HCI_EVT_SND_DATA 0x01 89#define PN544_HCI_EVT_SND_DATA 0x01
88#define PN544_HCI_EVT_ACTIVATED 0x02 90#define PN544_HCI_EVT_ACTIVATED 0x02
89#define PN544_HCI_EVT_DEACTIVATED 0x03 91#define PN544_HCI_EVT_DEACTIVATED 0x03
90#define PN544_HCI_EVT_RCV_DATA 0x04 92#define PN544_HCI_EVT_RCV_DATA 0x04
91#define PN544_HCI_EVT_CONTINUE_MI 0x05 93#define PN544_HCI_EVT_CONTINUE_MI 0x05
94#define PN544_HCI_EVT_SWITCH_MODE 0x03
92 95
93#define PN544_HCI_CMD_ATTREQUEST 0x12 96#define PN544_HCI_CMD_ATTREQUEST 0x12
94#define PN544_HCI_CMD_CONTINUE_ACTIVATION 0x13 97#define PN544_HCI_CMD_CONTINUE_ACTIVATION 0x13
@@ -792,6 +795,32 @@ static int pn544_hci_fw_download(struct nfc_hci_dev *hdev,
792 return info->fw_download(info->phy_id, firmware_name); 795 return info->fw_download(info->phy_id, firmware_name);
793} 796}
794 797
798static int pn544_hci_discover_se(struct nfc_hci_dev *hdev)
799{
800 u32 se_idx = 0;
801 u8 ese_mode = 0x01; /* Default mode */
802 struct sk_buff *res_skb;
803 int r;
804
805 r = nfc_hci_send_cmd(hdev, PN544_SYS_MGMT_GATE, PN544_TEST_SWP,
806 NULL, 0, &res_skb);
807
808 if (r == 0) {
809 if (res_skb->len == 2 && res_skb->data[0] == 0x00)
810 nfc_add_se(hdev->ndev, se_idx++, NFC_SE_UICC);
811
812 kfree_skb(res_skb);
813 }
814
815 r = nfc_hci_send_event(hdev, PN544_NFC_WI_MGMT_GATE,
816 PN544_HCI_EVT_SWITCH_MODE,
817 &ese_mode, 1);
818 if (r == 0)
819 nfc_add_se(hdev->ndev, se_idx++, NFC_SE_EMBEDDED);
820
821 return !se_idx;
822}
823
795static struct nfc_hci_ops pn544_hci_ops = { 824static struct nfc_hci_ops pn544_hci_ops = {
796 .open = pn544_hci_open, 825 .open = pn544_hci_open,
797 .close = pn544_hci_close, 826 .close = pn544_hci_close,
@@ -807,6 +836,7 @@ static struct nfc_hci_ops pn544_hci_ops = {
807 .check_presence = pn544_hci_check_presence, 836 .check_presence = pn544_hci_check_presence,
808 .event_received = pn544_hci_event_received, 837 .event_received = pn544_hci_event_received,
809 .fw_download = pn544_hci_fw_download, 838 .fw_download = pn544_hci_fw_download,
839 .discover_se = pn544_hci_discover_se,
810}; 840};
811 841
812int pn544_hci_probe(void *phy_id, struct nfc_phy_ops *phy_ops, char *llc_name, 842int pn544_hci_probe(void *phy_id, struct nfc_phy_ops *phy_ops, char *llc_name,