summaryrefslogtreecommitdiffstats
path: root/drivers/nfc
diff options
context:
space:
mode:
authorArron Wang <arron.wang@intel.com>2012-09-27 11:32:58 +0200
committerSamuel Ortiz <sameo@linux.intel.com>2012-10-26 18:26:46 +0200
commite81076235b46189a776362ec5e4c6626bf1599ff (patch)
treef1623677ef0202907a94ef32ee52b928b9aa36f8 /drivers/nfc
parentNFC: Implement HCI DEP link up and down (diff)
downloadlinux-e81076235b46189a776362ec5e4c6626bf1599ff.tar.xz
linux-e81076235b46189a776362ec5e4c6626bf1599ff.zip
NFC: Implement HCI DEP send and receive data
And implement the corresponding hooks for pn544. Signed-off-by: Arron Wang <arron.wang@intel.com> Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
Diffstat (limited to 'drivers/nfc')
-rw-r--r--drivers/nfc/pn544_hci.c36
1 files changed, 34 insertions, 2 deletions
diff --git a/drivers/nfc/pn544_hci.c b/drivers/nfc/pn544_hci.c
index 4ed2b8356017..554faf0a92d7 100644
--- a/drivers/nfc/pn544_hci.c
+++ b/drivers/nfc/pn544_hci.c
@@ -900,7 +900,7 @@ static void pn544_hci_data_exchange_cb(void *context, struct sk_buff *skb,
* <= 0: driver handled the data exchange
* 1: driver doesn't especially handle, please do standard processing
*/
-static int pn544_hci_data_exchange(struct nfc_hci_dev *hdev,
+static int pn544_hci_im_transceive(struct nfc_hci_dev *hdev,
struct nfc_target *target,
struct sk_buff *skb, data_exchange_cb_t cb,
void *cb_context)
@@ -953,11 +953,26 @@ static int pn544_hci_data_exchange(struct nfc_hci_dev *hdev,
return nfc_hci_send_cmd_async(hdev, target->hci_reader_gate,
PN544_JEWEL_RAW_CMD, skb->data,
skb->len, cb, cb_context);
+ case PN544_RF_READER_NFCIP1_INITIATOR_GATE:
+ *skb_push(skb, 1) = 0;
+
+ return nfc_hci_send_event(hdev, target->hci_reader_gate,
+ PN544_HCI_EVT_SND_DATA, skb->data,
+ skb->len);
default:
return 1;
}
}
+static int pn544_hci_tm_send(struct nfc_hci_dev *hdev, struct sk_buff *skb)
+{
+ /* Set default false for multiple information chaining */
+ *skb_push(skb, 1) = 0;
+
+ return nfc_hci_send_event(hdev, PN544_RF_READER_NFCIP1_TARGET_GATE,
+ PN544_HCI_EVT_SND_DATA, skb->data, skb->len);
+}
+
static int pn544_hci_check_presence(struct nfc_hci_dev *hdev,
struct nfc_target *target)
{
@@ -996,6 +1011,22 @@ void pn544_hci_event_received(struct nfc_hci_dev *hdev, u8 gate, u8 event,
nfc_hci_send_event(hdev, gate,
NFC_HCI_EVT_END_OPERATION, NULL, 0);
break;
+ case PN544_HCI_EVT_RCV_DATA:
+ if (skb->len < 2) {
+ r = -EPROTO;
+ goto exit;
+ }
+
+ if (skb->data[0] != 0) {
+ pr_debug("data0 %d", skb->data[0]);
+ r = -EPROTO;
+ goto exit;
+ }
+
+ skb_pull(skb, 2);
+ nfc_tm_data_received(hdev->ndev, skb);
+
+ return;
default:
break;
}
@@ -1014,7 +1045,8 @@ static struct nfc_hci_ops pn544_hci_ops = {
.dep_link_down = pn544_hci_dep_link_down,
.target_from_gate = pn544_hci_target_from_gate,
.complete_target_discovered = pn544_hci_complete_target_discovered,
- .data_exchange = pn544_hci_data_exchange,
+ .im_transceive = pn544_hci_im_transceive,
+ .tm_send = pn544_hci_tm_send,
.check_presence = pn544_hci_check_presence,
.event_received = pn544_hci_event_received,
};