diff options
-rw-r--r-- | drivers/nfc/pn544/pn544.c | 86 |
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 | ||
820 | static 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 | |||
875 | static 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 | |||
824 | static struct nfc_hci_ops pn544_hci_ops = { | 894 | static 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 | ||
842 | int pn544_hci_probe(void *phy_id, struct nfc_phy_ops *phy_ops, char *llc_name, | 914 | int pn544_hci_probe(void *phy_id, struct nfc_phy_ops *phy_ops, char *llc_name, |