aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/nfc/pn544/pn544.c86
1 files changed, 79 insertions, 7 deletions
diff --git a/drivers/nfc/pn544/pn544.c b/drivers/nfc/pn544/pn544.c
index 727f312e05d2..b5048cbcc182 100644
--- a/drivers/nfc/pn544/pn544.c
+++ b/drivers/nfc/pn544/pn544.c
@@ -82,6 +82,7 @@ enum pn544_state {
82#define PN544_PL_NFCT_DEACTIVATED 0x09 82#define PN544_PL_NFCT_DEACTIVATED 0x09
83 83
84#define PN544_SWP_MGMT_GATE 0xA0 84#define PN544_SWP_MGMT_GATE 0xA0
85#define PN544_SWP_DEFAULT_MODE 0x01
85 86
86#define PN544_NFC_WI_MGMT_GATE 0xA1 87#define PN544_NFC_WI_MGMT_GATE 0xA1
87#define PN544_NFC_ESE_DEFAULT_MODE 0x01 88#define PN544_NFC_ESE_DEFAULT_MODE 0x01
@@ -190,13 +191,6 @@ static int pn544_hci_ready(struct nfc_hci_dev *hdev)
190 191
191 {{0x9e, 0xb4}, 0x00}, 192 {{0x9e, 0xb4}, 0x00},
192 193
193 {{0x9e, 0xd9}, 0xff},
194 {{0x9e, 0xda}, 0xff},
195 {{0x9e, 0xdb}, 0x23},
196 {{0x9e, 0xdc}, 0x21},
197 {{0x9e, 0xdd}, 0x22},
198 {{0x9e, 0xde}, 0x24},
199
200 {{0x9c, 0x01}, 0x08}, 194 {{0x9c, 0x01}, 0x08},
201 195
202 {{0x9e, 0xaa}, 0x01}, 196 {{0x9e, 0xaa}, 0x01},
@@ -821,6 +815,82 @@ static int pn544_hci_discover_se(struct nfc_hci_dev *hdev)
821 return !se_idx; 815 return !se_idx;
822} 816}
823 817
818#define PN544_SE_MODE_OFF 0x00
819#define PN544_SE_MODE_ON 0x01
820static int pn544_hci_enable_se(struct nfc_hci_dev *hdev, u32 se_idx)
821{
822 struct nfc_se *se;
823 u8 enable = PN544_SE_MODE_ON;
824 static struct uicc_gatelist {
825 u8 head;
826 u8 adr[2];
827 u8 value;
828 } uicc_gatelist[] = {
829 {0x00, {0x9e, 0xd9}, 0x23},
830 {0x00, {0x9e, 0xda}, 0x21},
831 {0x00, {0x9e, 0xdb}, 0x22},
832 {0x00, {0x9e, 0xdc}, 0x24},
833 };
834 struct uicc_gatelist *p = uicc_gatelist;
835 int count = ARRAY_SIZE(uicc_gatelist);
836 struct sk_buff *res_skb;
837 int r;
838
839 se = nfc_find_se(hdev->ndev, se_idx);
840
841 switch (se->type) {
842 case NFC_SE_UICC:
843 while (count--) {
844 r = nfc_hci_send_cmd(hdev, PN544_SYS_MGMT_GATE,
845 PN544_WRITE, (u8 *)p, 4, &res_skb);
846 if (r < 0)
847 return r;
848
849 if (res_skb->len != 1) {
850 kfree_skb(res_skb);
851 return -EPROTO;
852 }
853
854 if (res_skb->data[0] != p->value) {
855 kfree_skb(res_skb);
856 return -EIO;
857 }
858
859 kfree_skb(res_skb);
860
861 p++;
862 }
863
864 return nfc_hci_set_param(hdev, PN544_SWP_MGMT_GATE,
865 PN544_SWP_DEFAULT_MODE, &enable, 1);
866 case NFC_SE_EMBEDDED:
867 return nfc_hci_set_param(hdev, PN544_NFC_WI_MGMT_GATE,
868 PN544_NFC_ESE_DEFAULT_MODE, &enable, 1);
869
870 default:
871 return -EINVAL;
872 }
873}
874
875static int pn544_hci_disable_se(struct nfc_hci_dev *hdev, u32 se_idx)
876{
877 struct nfc_se *se;
878 u8 disable = PN544_SE_MODE_OFF;
879
880 se = nfc_find_se(hdev->ndev, se_idx);
881
882 switch (se->type) {
883 case NFC_SE_UICC:
884 return nfc_hci_set_param(hdev, PN544_SWP_MGMT_GATE,
885 PN544_SWP_DEFAULT_MODE, &disable, 1);
886 case NFC_SE_EMBEDDED:
887 return nfc_hci_set_param(hdev, PN544_NFC_WI_MGMT_GATE,
888 PN544_NFC_ESE_DEFAULT_MODE, &disable, 1);
889 default:
890 return -EINVAL;
891 }
892}
893
824static struct nfc_hci_ops pn544_hci_ops = { 894static struct nfc_hci_ops pn544_hci_ops = {
825 .open = pn544_hci_open, 895 .open = pn544_hci_open,
826 .close = pn544_hci_close, 896 .close = pn544_hci_close,
@@ -837,6 +907,8 @@ static struct nfc_hci_ops pn544_hci_ops = {
837 .event_received = pn544_hci_event_received, 907 .event_received = pn544_hci_event_received,
838 .fw_download = pn544_hci_fw_download, 908 .fw_download = pn544_hci_fw_download,
839 .discover_se = pn544_hci_discover_se, 909 .discover_se = pn544_hci_discover_se,
910 .enable_se = pn544_hci_enable_se,
911 .disable_se = pn544_hci_disable_se,
840}; 912};
841 913
842int pn544_hci_probe(void *phy_id, struct nfc_phy_ops *phy_ops, char *llc_name, 914int pn544_hci_probe(void *phy_id, struct nfc_phy_ops *phy_ops, char *llc_name,