diff options
author | Arron Wang <arron.wang@intel.com> | 2012-09-27 05:32:55 -0400 |
---|---|---|
committer | Samuel Ortiz <sameo@linux.intel.com> | 2012-10-26 12:26:45 -0400 |
commit | f7a5f6c532f33ba66a7ca19e81ed447a83dab2db (patch) | |
tree | 6ac75749971e6870a0a8fbbf059fcca2af9ee55b | |
parent | 7e2afc9d072b9f84b314b208a125c2b1ce36b685 (diff) |
NFC: Pass hardware specific HCI event to driver
Signed-off-by: Arron Wang <arron.wang@intel.com>
Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
-rw-r--r-- | drivers/nfc/pn544_hci.c | 45 | ||||
-rw-r--r-- | include/net/nfc/hci.h | 3 | ||||
-rw-r--r-- | net/nfc/hci/core.c | 12 |
3 files changed, 57 insertions, 3 deletions
diff --git a/drivers/nfc/pn544_hci.c b/drivers/nfc/pn544_hci.c index 8b21a8efd751..d81242f4a92b 100644 --- a/drivers/nfc/pn544_hci.c +++ b/drivers/nfc/pn544_hci.c | |||
@@ -112,6 +112,12 @@ enum pn544_state { | |||
112 | 112 | ||
113 | #define PN544_NFC_WI_MGMT_GATE 0xA1 | 113 | #define PN544_NFC_WI_MGMT_GATE 0xA1 |
114 | 114 | ||
115 | #define PN544_HCI_EVT_SND_DATA 0x01 | ||
116 | #define PN544_HCI_EVT_ACTIVATED 0x02 | ||
117 | #define PN544_HCI_EVT_DEACTIVATED 0x03 | ||
118 | #define PN544_HCI_EVT_RCV_DATA 0x04 | ||
119 | #define PN544_HCI_EVT_CONTINUE_MI 0x05 | ||
120 | |||
115 | static struct nfc_hci_gate pn544_gates[] = { | 121 | static struct nfc_hci_gate pn544_gates[] = { |
116 | {NFC_HCI_ADMIN_GATE, NFC_HCI_INVALID_PIPE}, | 122 | {NFC_HCI_ADMIN_GATE, NFC_HCI_INVALID_PIPE}, |
117 | {NFC_HCI_LOOPBACK_GATE, NFC_HCI_INVALID_PIPE}, | 123 | {NFC_HCI_LOOPBACK_GATE, NFC_HCI_INVALID_PIPE}, |
@@ -897,6 +903,44 @@ static int pn544_hci_check_presence(struct nfc_hci_dev *hdev, | |||
897 | NULL, 0, NULL); | 903 | NULL, 0, NULL); |
898 | } | 904 | } |
899 | 905 | ||
906 | void pn544_hci_event_received(struct nfc_hci_dev *hdev, u8 gate, u8 event, | ||
907 | struct sk_buff *skb) | ||
908 | { | ||
909 | struct sk_buff *rgb_skb = NULL; | ||
910 | int r = 0; | ||
911 | |||
912 | pr_debug("hci event %d", event); | ||
913 | switch (event) { | ||
914 | case PN544_HCI_EVT_ACTIVATED: | ||
915 | if (gate == PN544_RF_READER_NFCIP1_INITIATOR_GATE) | ||
916 | nfc_hci_target_discovered(hdev, gate); | ||
917 | else if (gate == PN544_RF_READER_NFCIP1_TARGET_GATE) { | ||
918 | r = nfc_hci_get_param(hdev, gate, PN544_DEP_ATR_REQ, | ||
919 | &rgb_skb); | ||
920 | |||
921 | if (r < 0) | ||
922 | goto exit; | ||
923 | |||
924 | nfc_tm_activated(hdev->ndev, NFC_PROTO_NFC_DEP_MASK, | ||
925 | NFC_COMM_PASSIVE, rgb_skb->data, | ||
926 | rgb_skb->len); | ||
927 | |||
928 | kfree_skb(rgb_skb); | ||
929 | } | ||
930 | |||
931 | break; | ||
932 | case PN544_HCI_EVT_DEACTIVATED: | ||
933 | nfc_hci_send_event(hdev, gate, | ||
934 | NFC_HCI_EVT_END_OPERATION, NULL, 0); | ||
935 | break; | ||
936 | default: | ||
937 | break; | ||
938 | } | ||
939 | |||
940 | exit: | ||
941 | kfree_skb(skb); | ||
942 | } | ||
943 | |||
900 | static struct nfc_hci_ops pn544_hci_ops = { | 944 | static struct nfc_hci_ops pn544_hci_ops = { |
901 | .open = pn544_hci_open, | 945 | .open = pn544_hci_open, |
902 | .close = pn544_hci_close, | 946 | .close = pn544_hci_close, |
@@ -907,6 +951,7 @@ static struct nfc_hci_ops pn544_hci_ops = { | |||
907 | .complete_target_discovered = pn544_hci_complete_target_discovered, | 951 | .complete_target_discovered = pn544_hci_complete_target_discovered, |
908 | .data_exchange = pn544_hci_data_exchange, | 952 | .data_exchange = pn544_hci_data_exchange, |
909 | .check_presence = pn544_hci_check_presence, | 953 | .check_presence = pn544_hci_check_presence, |
954 | .event_received = pn544_hci_event_received, | ||
910 | }; | 955 | }; |
911 | 956 | ||
912 | static int __devinit pn544_hci_probe(struct i2c_client *client, | 957 | static int __devinit pn544_hci_probe(struct i2c_client *client, |
diff --git a/include/net/nfc/hci.h b/include/net/nfc/hci.h index df6523dcd3c8..490d323a9ec3 100644 --- a/include/net/nfc/hci.h +++ b/include/net/nfc/hci.h | |||
@@ -47,6 +47,8 @@ struct nfc_hci_ops { | |||
47 | data_exchange_cb_t cb, void *cb_context); | 47 | data_exchange_cb_t cb, void *cb_context); |
48 | int (*check_presence)(struct nfc_hci_dev *hdev, | 48 | int (*check_presence)(struct nfc_hci_dev *hdev, |
49 | struct nfc_target *target); | 49 | struct nfc_target *target); |
50 | void (*event_received)(struct nfc_hci_dev *hdev, u8 gate, u8 event, | ||
51 | struct sk_buff *skb); | ||
50 | }; | 52 | }; |
51 | 53 | ||
52 | /* Pipes */ | 54 | /* Pipes */ |
@@ -222,5 +224,6 @@ int nfc_hci_send_response(struct nfc_hci_dev *hdev, u8 gate, u8 response, | |||
222 | const u8 *param, size_t param_len); | 224 | const u8 *param, size_t param_len); |
223 | int nfc_hci_send_event(struct nfc_hci_dev *hdev, u8 gate, u8 event, | 225 | int nfc_hci_send_event(struct nfc_hci_dev *hdev, u8 gate, u8 event, |
224 | const u8 *param, size_t param_len); | 226 | const u8 *param, size_t param_len); |
227 | int nfc_hci_target_discovered(struct nfc_hci_dev *hdev, u8 gate); | ||
225 | 228 | ||
226 | #endif /* __NET_HCI_H */ | 229 | #endif /* __NET_HCI_H */ |
diff --git a/net/nfc/hci/core.c b/net/nfc/hci/core.c index 5fbb6e40793e..8a9a811b558a 100644 --- a/net/nfc/hci/core.c +++ b/net/nfc/hci/core.c | |||
@@ -182,7 +182,7 @@ static u32 nfc_hci_sak_to_protocol(u8 sak) | |||
182 | } | 182 | } |
183 | } | 183 | } |
184 | 184 | ||
185 | static int nfc_hci_target_discovered(struct nfc_hci_dev *hdev, u8 gate) | 185 | int nfc_hci_target_discovered(struct nfc_hci_dev *hdev, u8 gate) |
186 | { | 186 | { |
187 | struct nfc_target *targets; | 187 | struct nfc_target *targets; |
188 | struct sk_buff *atqa_skb = NULL; | 188 | struct sk_buff *atqa_skb = NULL; |
@@ -275,6 +275,7 @@ exit: | |||
275 | 275 | ||
276 | return r; | 276 | return r; |
277 | } | 277 | } |
278 | EXPORT_SYMBOL(nfc_hci_target_discovered); | ||
278 | 279 | ||
279 | void nfc_hci_event_received(struct nfc_hci_dev *hdev, u8 pipe, u8 event, | 280 | void nfc_hci_event_received(struct nfc_hci_dev *hdev, u8 pipe, u8 event, |
280 | struct sk_buff *skb) | 281 | struct sk_buff *skb) |
@@ -307,8 +308,13 @@ void nfc_hci_event_received(struct nfc_hci_dev *hdev, u8 pipe, u8 event, | |||
307 | nfc_hci_pipe2gate(hdev, pipe)); | 308 | nfc_hci_pipe2gate(hdev, pipe)); |
308 | break; | 309 | break; |
309 | default: | 310 | default: |
310 | /* TODO: Unknown events are hardware specific | 311 | if (hdev->ops->event_received) { |
311 | * pass them to the driver (needs a new hci_ops) */ | 312 | hdev->ops->event_received(hdev, |
313 | nfc_hci_pipe2gate(hdev, pipe), | ||
314 | event, skb); | ||
315 | return; | ||
316 | } | ||
317 | |||
312 | break; | 318 | break; |
313 | } | 319 | } |
314 | 320 | ||