/* * HCI based Driver for NXP PN544 NFC Chip * * Copyright (C) 2012 Intel Corporation. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms and conditions of the GNU General Public License, * version 2, as published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the * Free Software Foundation, Inc., * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include #include #include #include #include #include #include #include #include #include #include #define DRIVER_DESC "HCI NFC driver for PN544" #define PN544_HCI_DRIVER_NAME "pn544_hci" /* Timing restrictions (ms) */ #define PN544_HCI_RESETVEN_TIME 30 static struct i2c_device_id pn544_hci_id_table[] = { {"pn544", 0}, {} }; MODULE_DEVICE_TABLE(i2c, pn544_hci_id_table); #define HCI_MODE 0 #define FW_MODE 1 /* framing in HCI mode */ #define PN544_HCI_LLC_LEN 1 #define PN544_HCI_LLC_CRC 2 #define PN544_HCI_LLC_LEN_CRC (PN544_HCI_LLC_LEN + PN544_HCI_LLC_CRC) #define PN544_HCI_LLC_MIN_SIZE (1 + PN544_HCI_LLC_LEN_CRC) #define PN544_HCI_LLC_MAX_PAYLOAD 29 #define PN544_HCI_LLC_MAX_SIZE (PN544_HCI_LLC_LEN_CRC + 1 + \ PN544_HCI_LLC_MAX_PAYLOAD) enum pn544_state { PN544_ST_COLD, PN544_ST_FW_READY, PN544_ST_READY, }; #define FULL_VERSION_LEN 11 /* Proprietary commands */ #define PN544_WRITE 0x3f /* Proprietary gates, events, commands and registers */ /* NFC_HCI_RF_READER_A_GATE additional registers and commands */ #define PN544_RF_READER_A_AUTO_ACTIVATION 0x10 #define PN544_RF_READER_A_CMD_CONTINUE_ACTIVATION 0x12 #define PN544_MIFARE_CMD 0x21 /* Commands that apply to all RF readers */ #define PN544_RF_READER_CMD_PRESENCE_CHECK 0x30 #define PN544_RF_READER_CMD_ACTIVATE_NEXT 0x32 /* NFC_HCI_ID_MGMT_GATE additional registers */ #define PN544_ID_MGMT_FULL_VERSION_SW 0x10 #define PN544_RF_READER_ISO15693_GATE 0x12 #define PN544_RF_READER_F_GATE 0x14 #define PN544_FELICA_ID 0x04 #define PN544_FELICA_RAW 0x20 #define PN544_RF_READER_JEWEL_GATE 0x15 #define PN544_JEWEL_RAW_CMD 0x23 #define PN544_RF_READER_NFCIP1_INITIATOR_GATE 0x30 #define PN544_RF_READER_NFCIP1_TARGET_GATE 0x31 #define PN544_SYS_MGMT_GATE 0x90 #define PN544_SYS_MGMT_INFO_NOTIFICATION 0x02 #define PN544_POLLING_LOOP_MGMT_GATE 0x94 #define PN544_DEP_MODE 0x01 #define PN544_DEP_ATR_REQ 0x02 #define PN544_DEP_ATR_RES 0x03 #define PN544_DEP_MERGE 0x0D #define PN544_PL_RDPHASES 0x06 #define PN544_PL_EMULATION 0x07 #define PN544_PL_NFCT_DEACTIVATED 0x09 #define PN544_SWP_MGMT_GATE 0xA0 #define PN544_NFC_WI_MGMT_GATE 0xA1 #define PN544_HCI_EVT_SND_DATA 0x01 #define PN544_HCI_EVT_ACTIVATED 0x02 #define PN544_HCI_EVT_DEACTIVATED 0x03 #define PN544_HCI_EVT_RCV_DATA 0x04 #define PN544_HCI_EVT_CONTINUE_MI 0x05 #define PN544_HCI_CMD_CONTINUE_ACTIVATION 0x13 static struct nfc_hci_gate pn544_gates[] = { {NFC_HCI_ADMIN_GATE, NFC_HCI_INVALID_PIPE}, {NFC_HCI_LOOPBACK_GATE, NFC_HCI_INVALID_PIPE}, {NFC_HCI_ID_MGMT_GATE, NFC_HCI_INVALID_PIPE}, {NFC_HCI_LINK_MGMT_GATE, NFC_HCI_INVALID_PIPE}, {NFC_HCI_RF_READER_B_GATE, NFC_HCI_INVALID_PIPE}, {NFC_HCI_RF_READER_A_GATE, NFC_HCI_INVALID_PIPE}, {PN544_SYS_MGMT_GATE, NFC_HCI_INVALID_PIPE}, {PN544_SWP_MGMT_GATE, NFC_HCI_INVALID_PIPE}, {PN544_POLLING_LOOP_MGMT_GATE, NFC_HCI_INVALID_PIPE}, {PN544_NFC_WI_MGMT_GATE, NFC_HCI_INVALID_PIPE}, {PN544_RF_READER_F_GATE, NFC_HCI_INVALID_PIPE}, {PN544_RF_READER_JEWEL_GATE, NFC_HCI_INVALID_PIPE}, {PN544_RF_READER_ISO15693_GATE, NFC_HCI_INVALID_PIPE}, {PN544_RF_READER_NFCIP1_INITIATOR_GATE, NFC_HCI_INVALID_PIPE}, {PN544_RF_READER_NFCIP1_TARGET_GATE, NFC_HCI_INVALID_PIPE} }; /* Largest headroom needed for outgoing custom commands */ #define PN544_CMDS_HEADROOM 2 #define PN544_FRAME_HEADROOM 1 #define PN544_FRAME_TAILROOM 2 struct pn544_hci_info { struct i2c_client *i2c_dev; struct nfc_hci_dev *hdev; enum pn544_state state; struct mutex info_lock; unsigned int gpio_en; unsigned int gpio_irq; unsigned int gpio_fw; unsigned int en_polarity; int hard_fault; /* * < 0 if hardware error occured (e.g. i2c err) * and prevents normal operation. */ int async_cb_type; data_exchange_cb_t async_cb; void *async_cb_context; }; static void pn544_hci_platform_init(struct pn544_hci_info *info) { int polarity, retry, ret; char rset_cmd[] = { 0x05, 0xF9, 0x04, 0x00, 0xC3, 0xE5 }; int count = sizeof(rset_cmd); pr_info(DRIVER_DESC ": %s\n", __func__); dev_info(&info->i2c_dev->dev, "Detecting nfc_en polarity\n"); /* Disable fw download */ gpio_set_value(info->gpio_fw, 0); for (polarity = 0; polarity < 2; polarity++) { info->en_polarity = polarity; retry = 3; while (retry--) { /* power off */ gpio_set_value(info->gpio_en, !info->en_polarity); usleep_range(10000, 15000); /* power on */ gpio_set_value(info->gpio_en, info->en_polarity); usleep_range(10000, 15000); /* send reset */ dev_dbg(&info->i2c_dev->dev, "Sending reset cmd\n"); ret = i2c_master_send(info->i2c_dev, rset_cmd, count); if (ret == count) { dev_info(&info->i2c_dev->dev, "nfc_en polarity : active %s\n", (polarity == 0 ? "low" : "high")); goto out; } } } dev_err(&info->i2c_dev->dev, "Could not detect nfc_en polarity, fallback to active high\n"); out: gpio_set_value(info->gpio_en, !info->en_polarity); } static int pn544_hci_enable(struct pn544_hci_info *info, int mode) { pr_info(DRIVER_DESC ": %s\n", __func__); gpio_set_value(info->gpio_fw, 0); gpio_set_value(info->gpio_en, info->en_polarity); usleep_range(10000, 15000); return 0; } static void pn544_hci_disable(struct pn544_hci_info *info) { pr_info(DRIVER_DESC ": %s\n", __func__); gpio_set_value(info->gpio_fw, 0); gpio_set_value(info->gpio_en, !info->en_polarity); usleep_range(10000, 15000); gpio_set_value(info->gpio_en, info->en_polarity); usleep_range(10000, 15000); gpio_set_value(info->gpio_en, !info->en_polarity); usleep_range(10000, 15000); } static int pn544_hci_i2c_write(struct i2c_client *client, u8 *buf, int len) { int r; usleep_range(3000, 6000); r = i2c_master_send(client, buf, len); if (r == -EREMOTEIO) { /* Retry, chip was in standby */ usleep_range(6000, 10000); r = i2c_master_send(client, buf, len); } if (r >= 0) { if (r != len) return -EREMOTEIO; else return 0; } return r; } static int check_crc(u8 *buf, int buflen) { int len; u16 crc; len = buf[0] + 1; crc = crc_ccitt(0xffff, buf, len - 2); crc = ~crc; if (buf[len - 2] != (crc & 0xff) || buf[len - 1] != (crc >> 8)) { pr_err(PN544_HCI_DRIVER_NAME ": CRC error 0x%x != 0x%x 0x%x\n", crc, buf[len - 1], buf[len - 2]); pr_info(DRIVER_DESC ": %s : BAD CRC\n", __func__); print_hex_dump(KERN_DEBUG, "crc: ", DUMP_PREFIX_NONE, 16, 2, buf, buflen, false); return -EPERM; } return 0; } /* * Reads an shdlc frame and returns it in a newly allocated sk_buff. Guarantees * that i2c bus will be flushed and that next read will start on a new frame. * returned skb contains only LLC header and payload. * returns: * -EREMOTEIO : i2c read error (fatal) * -EBADMSG : frame was incorrect and discarded * -ENOMEM : cannot allocate skb, frame dropped */ static int pn544_hci_i2c_read(struct i2c_client *client, struct sk_buff **skb) { int r; u8 len; u8 tmp[PN544_HCI_LLC_MAX_SIZE - 1]; r = i2c_master_recv(client, &len, 1); if (r != 1) { dev_err(&client->dev, "cannot read len byte\n"); return -EREMOTEIO; } if ((len < (PN544_HCI_LLC_MIN_SIZE - 1)) || (len > (PN544_HCI_LLC_MAX_SIZE - 1))) { dev_err(&client->dev, "invalid len byte\n"); r = -EBADMSG; goto flush; } *skb = alloc_skb(1 + len, GFP_KERNEL); if (*skb == NULL) { r = -ENOMEM; goto flush; } *skb_put(*skb, 1) = len; r = i2c_master_recv(client, skb_put(*skb, len), len); if (r != len) { kfree_skb(*skb); return -EREMOTEIO; } r = check_crc((*skb)->data, (*skb)->len); if (r != 0) { kfree_skb(*skb); r = -EBADMSG; goto flush; } skb_pull(*skb, 1); skb_trim(*skb, (*skb)->len - 2); usleep_range(3000, 6000); return 0; flush: if (i2c_master_recv(client, tmp, sizeof(tmp)) < 0) r = -EREMOTEIO; usleep_range(3000, 6000); return r; } /* * Reads an shdlc frame from the chip. This is not as straightforward as it * seems. There are cases where we could loose the frame start synchronization. * The frame format is len-data-crc, and corruption can occur anywhere while * transiting on i2c bus, such that we could read an invalid len. * In order to recover synchronization with the next frame, we must be sure * to read the real amount of data without using the len byte. We do this by * assuming the following: * - the chip will always present only one single complete frame on the bus * before triggering the interrupt * - the chip will not present a new frame until we have completely read * the previous one (or until we have handled the interrupt). * The tricky case is when we read a corrupted len that is less than the real * len. We must detect this here in order to determine that we need to flush * the bus. This is the reason why we check the crc here. */ static irqreturn_t pn544_hci_irq_thread_fn(int irq, void *dev_id) { struct pn544_hci_info *info = dev_id; struct i2c_client *client; struct sk_buff *skb = NULL; int r; if (!info || irq != info->i2c_dev->irq) { WARN_ON_ONCE(1); return IRQ_NONE; } client = info->i2c_dev; dev_dbg(&client->dev, "IRQ\n"); if (info->hard_fault != 0) return IRQ_HANDLED; r = pn544_hci_i2c_read(client, &skb); if (r == -EREMOTEIO) { info->hard_fault = r; nfc_hci_recv_frame(info->hdev, NULL); return IRQ_HANDLED; } else if ((r == -ENOMEM) || (r == -EBADMSG)) { return IRQ_HANDLED; } nfc_hci_recv_frame(info->hdev, skb); return IRQ_HANDLED; } static int pn544_hci_open(struct nfc_hci_dev *hdev) { struct pn544_hci_info *info = nfc_hci_get_clientdata(hdev); int r = 0; mutex_lock(&info->info_lock); if (info->state != PN544_ST_COLD) { r = -EBUSY; goto out; } r = pn544_hci_enable(info, HCI_MODE); if (r == 0) info->state = PN544_ST_READY; out: mutex_unlock(&info->info_lock); return r; } static void pn544_hci_close(struct nfc_hci_dev *hdev) { struct pn544_hci_info *info = nfc_hci_get_clientdata(hdev); mutex_lock(&info->info_lock); if (info->state == PN544_ST_COLD) goto out; pn544_hci_disable(info); info->state = PN544_ST_COLD; out: mutex_unlock(&info->info_lock); } static int pn544_hci_ready(struct nfc_hci_dev *hdev) { struct sk_buff *skb; static struct hw_config { u8 adr[2]; u8 value; } hw_config[] = { {{0x9f, 0x9a}, 0x00}, {{0x98, 0x10}, 0xbc}, {{0x9e, 0x71}, 0x00}, {{0x98, 0x09}, 0x00}, {{0x9e, 0xb4}, 0x00}, {{0x9e, 0xd9}, 0xff}, {{0x9e, 0xda}, 0xff}, {{0x9e, 0xdb}, 0x23}, {{0x9e, 0xdc}, 0x21}, {{0x9e, 0xdd}, 0x22}, {{0x9e, 0xde}, 0x24}, {{0x9c, 0x01}, 0x08}, {{0x9e, 0xaa}, 0x01}, {{0x9b, 0xd1}, 0x0d}, {{0x9b, 0xd2}, 0x24}, {{0x9b, 0xd3}, 0x0a}, {{0x9b, 0xd4}, 0x22}, {{0x9b, 0xd5}, 0x08}, {{0x9b, 0xd6}, 0x1e}, {{0x9b, 0xdd}, 0x1c}, {{0x9b, 0x84}, 0x13}, {{0x99, 0x81}, 0x7f}, {{0x99, 0x31}, 0x70}, {{0x98, 0x00}, 0x3f}, {{0x9f, 0x09}, 0x00}, {{0x9f, 0x0a}, 0x05}, {{0x9e, 0xd1}, 0xa1}, {{0x99, 0x23}, 0x00}, {{0x9e, 0x74}, 0x80}, {{0x9f, 0x28}, 0x10}, {{0x9f, 0x35}, 0x14}, {{0x9f, 0x36}, 0x60}, {{0x9c, 0x31}, 0x00}, {{0x9c, 0x32}, 0xc8}, {{0x9c, 0x19}, 0x40}, {{0x9c, 0x1a}, 0x40}, {{0x9c, 0x0c}, 0x00}, {{0x9c, 0x0d}, 0x00}, {{0x9c, 0x12}, 0x00}, {{0x9c, 0x13}, 0x00}, {{0x98, 0xa2}, 0x0e}, {{0x98, 0x93}, 0x40}, {{0x98, 0x7d}, 0x02}, {{0x98, 0x7e}, 0x00}, {{0x9f, 0xc8}, 0x01}, }; struct hw_config *p = hw_config; int count = ARRAY_SIZE(hw_config); struct sk_buff *res_skb; u8 param[4]; int r; param[0] = 0; while (count--) { param[1] = p->adr[0]; param[2] = p->adr[1]; param[3] = p->value; r = nfc_hci_send_cmd(hdev, PN544_SYS_MGMT_GATE, PN544_WRITE, param, 4, &res_skb); if (r < 0) return r; if (res_skb->len != 1) { kfree_skb(res_skb); return -EPROTO; } if (res_skb->data[0] != p->value) { kfree_skb(res_skb); return -EIO; } kfree_skb(res_skb); p++; } param[0] = NFC_HCI_UICC_HOST_ID; r = nfc_hci_set_param(hdev, NFC_HCI_ADMIN_GATE, NFC_HCI_ADMIN_WHITELIST, param, 1); if (r < 0) return r; param[0] = 0x3d; r = nfc_hci_set_param(hdev, PN544_SYS_MGMT_GATE, PN544_SYS_MGMT_INFO_NOTIFICATION, param, 1); if (r < 0) return r; param[0] = 0x0; r = nfc_hci_set_param(hdev, NFC_HCI_RF_READER_A_GATE, PN544_RF_READER_A_AUTO_ACTIVATION, param, 1); if (r < 0) return r; r = nfc_hci_send_event(hdev, NFC_HCI_RF_READER_A_GATE, NFC_HCI_EVT_END_OPERATION, NULL, 0); if (r < 0) return r; param[0] = 0x1; r = nfc_hci_set_param(hdev, PN544_POLLING_LOOP_MGMT_GATE, PN544_PL_NFCT_DEACTIVATED, param, 1); if (r < 0) return r; param[0] = 0x0; r = nfc_hci_set_param(hdev, PN544_POLLING_LOOP_MGMT_GATE, PN544_PL_RDPHASES, param, 1); if (r < 0) return r; r = nfc_hci_get_param(hdev, NFC_HCI_ID_MGMT_GATE, PN544_ID_MGMT_FULL_VERSION_SW, &skb); if (r < 0) return r; if (skb->len != FULL_VERSION_LEN) { kfree_skb(skb); return -EINVAL; } print_hex_dump(KERN_DEBUG, "FULL VERSION SOFTWARE INFO: ", DUMP_PREFIX_NONE, 16, 1, skb->data, FULL_VERSION_LEN, false); kfree_skb(skb); return 0; } static void pn544_hci_add_len_crc(struct sk_buff *skb) { u16 crc; int len; len = skb->len + 2; *skb_push(skb, 1) = len; crc = crc_ccitt(0xffff, skb->data, skb->len); crc = ~crc; *skb_put(skb, 1) = crc & 0xff; *skb_put(skb, 1) = crc >> 8; } static void pn544_hci_remove_len_crc(struct sk_buff *skb) { skb_pull(skb, PN544_FRAME_HEADROOM); skb_trim(skb, PN544_FRAME_TAILROOM); } static int pn544_hci_xmit(struct nfc_hci_dev *hdev, struct sk_buff *skb) { struct pn544_hci_info *info = nfc_hci_get_clientdata(hdev); struct i2c_client *client = info->i2c_dev; int r; if (info->hard_fault != 0) return info->hard_fault; pn544_hci_add_len_crc(skb); r = pn544_hci_i2c_write(client, skb->data, skb->len); pn544_hci_remove_len_crc(skb); return r; } static int pn544_hci_start_poll(struct nfc_hci_dev *hdev, u32 im_protocols, u32 tm_protocols) { u8 phases = 0; int r; u8 duration[2]; u8 activated; u8 i_mode = 0x3f; /* Enable all supported modes */ u8 t_mode = 0x0f; u8 t_merge = 0x01; /* Enable merge by default */ pr_info(DRIVER_DESC ": %s protocols 0x%x 0x%x\n", __func__, im_protocols, tm_protocols); r = nfc_hci_send_event(hdev, NFC_HCI_RF_READER_A_GATE, NFC_HCI_EVT_END_OPERATION, NULL, 0); if (r < 0) return r; duration[0] = 0x18; duration[1] = 0x6a; r = nfc_hci_set_param(hdev, PN544_POLLING_LOOP_MGMT_GATE, PN544_PL_EMULATION, duration, 2); if (r < 0) return r; activated = 0; r = nfc_hci_set_param(hdev, PN544_POLLING_LOOP_MGMT_GATE, PN544_PL_NFCT_DEACTIVATED, &activated, 1); if (r < 0) return r; if (im_protocols & (NFC_PROTO_ISO14443_MASK | NFC_PROTO_MIFARE_MASK | NFC_PROTO_JEWEL_MASK)) phases |= 1; /* Type A */ if (im_protocols & NFC_PROTO_FELICA_MASK) { phases |= (1 << 2); /* Type F 212 */ phases |= (1 << 3); /* Type F 424 */ } phases |= (1 << 5); /* NFC active */ r = nfc_hci_set_param(hdev, PN544_POLLING_LOOP_MGMT_GATE, PN544_PL_RDPHASES, &phases, 1); if (r < 0) return r; if ((im_protocols | tm_protocols) & NFC_PROTO_NFC_DEP_MASK) { hdev->gb = nfc_get_local_general_bytes(hdev->ndev, &hdev->gb_len); pr_debug("generate local bytes %p", hdev->gb); if (hdev->gb == NULL || hdev->gb_len == 0) { im_protocols &= ~NFC_PROTO_NFC_DEP_MASK; tm_protocols &= ~NFC_PROTO_NFC_DEP_MASK; } } if (im_protocols & NFC_PROTO_NFC_DEP_MASK) { r = nfc_hci_send_event(hdev, PN544_RF_READER_NFCIP1_INITIATOR_GATE, NFC_HCI_EVT_END_OPERATION, NULL, 0); if (r < 0) return r; r = nfc_hci_set_param(hdev, PN544_RF_READER_NFCIP1_INITIATOR_GATE, PN544_DEP_MODE, &i_mode, 1); if (r < 0) return r; r = nfc_hci_set_param(hdev, PN544_RF_READER_NFCIP1_INITIATOR_GATE, PN544_DEP_ATR_REQ, hdev->gb, hdev->gb_len); if (r < 0) return r; r = nfc_hci_send_event(hdev, PN544_RF_READER_NFCIP1_INITIATOR_GATE, NFC_HCI_EVT_READER_REQUESTED, NULL, 0); if (r < 0) nfc_hci_send_event(hdev, PN544_RF_READER_NFCIP1_INITIATOR_GATE, NFC_HCI_EVT_END_OPERATION, NULL, 0); } if (tm_protocols & NFC_PROTO_NFC_DEP_MASK) { r = nfc_hci_set_param(hdev, PN544_RF_READER_NFCIP1_TARGET_GATE, PN544_DEP_MODE, &t_mode, 1); if (r < 0) return r; r = nfc_hci_set_param(hdev, PN544_RF_READER_NFCIP1_TARGET_GATE, PN544_DEP_ATR_RES, hdev->gb, hdev->gb_len); if (r < 0) return r; r = nfc_hci_set_param(hdev, PN544_RF_READER_NFCIP1_TARGET_GATE, PN544_DEP_MERGE, &t_merge, 1); if (r < 0) return r; } r = nfc_hci_send_event(hdev, NFC_HCI_RF_READER_A_GATE, NFC_HCI_EVT_READER_REQUESTED, NULL, 0); if (r < 0) nfc_hci_send_event(hdev, NFC_HCI_RF_READER_A_GATE, NFC_HCI_EVT_END_OPERATION, NULL, 0); return r; } static int pn544_hci_dep_link_up(struct nfc_hci_dev *hdev, struct nfc_target *target, u8 comm_mode, u8 *gb, size_t gb_len) { struct sk_buff *rgb_skb = NULL; int r; r = nfc_hci_get_param(hdev, target->hci_reader_gate, PN544_DEP_ATR_RES, &rgb_skb); if (r < 0) return r; if (rgb_skb->len == 0 || rgb_skb->len > NFC_GB_MAXSIZE) { r = -EPROTO; goto exit; } print_hex_dump(KERN_DEBUG, "remote gb: ", DUMP_PREFIX_OFFSET, 16, 1, rgb_skb->data, rgb_skb->len, true); r = nfc_set_remote_general_bytes(hdev->ndev, rgb_skb->data, rgb_skb->len); if (r == 0) r = nfc_dep_link_is_up(hdev->ndev, target->idx, comm_mode, NFC_RF_INITIATOR); exit: kfree_skb(rgb_skb); return r; } static int pn544_hci_dep_link_down(struct nfc_hci_dev *hdev) { return nfc_hci_send_event(hdev, PN544_RF_READER_NFCIP1_INITIATOR_GATE, NFC_HCI_EVT_END_OPERATION, NULL, 0); } static int pn544_hci_target_from_gate(struct nfc_hci_dev *hdev, u8 gate, struct nfc_target *target) { switch (gate) { case PN544_RF_READER_F_GATE: target->supported_protocols = NFC_PROTO_FELICA_MASK; break; case PN544_RF_READER_JEWEL_GATE: target->supported_protocols = NFC_PROTO_JEWEL_MASK; target->sens_res = 0x0c00; break; case PN544_RF_READER_NFCIP1_INITIATOR_GATE: target->supported_protocols = NFC_PROTO_NFC_DEP_MASK; break; default: return -EPROTO; } return 0; } static int pn544_hci_complete_target_discovered(struct nfc_hci_dev *hdev, u8 gate, struct nfc_target *target) { struct sk_buff *uid_skb; int r = 0; if (gate == PN544_RF_READER_NFCIP1_INITIATOR_GATE) return r; if (target->supported_protocols & NFC_PROTO_NFC_DEP_MASK) { r = nfc_hci_send_cmd(hdev, PN544_RF_READER_NFCIP1_INITIATOR_GATE, PN544_HCI_CMD_CONTINUE_ACTIVATION, NULL, 0, NULL); if (r < 0) return r; target->hci_reader_gate = PN544_RF_READER_NFCIP1_INITIATOR_GATE; } else if (target->supported_protocols & NFC_PROTO_MIFARE_MASK) { if (target->nfcid1_len != 4 && target->nfcid1_len != 7 && target->nfcid1_len != 10) return -EPROTO; r = nfc_hci_send_cmd(hdev, NFC_HCI_RF_READER_A_GATE, PN544_RF_READER_CMD_ACTIVATE_NEXT, target->nfcid1, target->nfcid1_len, NULL); } else if (target->supported_protocols & NFC_PROTO_FELICA_MASK) { r = nfc_hci_get_param(hdev, PN544_RF_READER_F_GATE, PN544_FELICA_ID, &uid_skb); if (r < 0) return r; if (uid_skb->len != 8) { kfree_skb(uid_skb); return -EPROTO; } r = nfc_hci_send_cmd(hdev, PN544_RF_READER_F_GATE, PN544_RF_READER_CMD_ACTIVATE_NEXT, uid_skb->data, uid_skb->len, NULL); kfree_skb(uid_skb); r = nfc_hci_send_cmd(hdev, PN544_RF_READER_NFCIP1_INITIATOR_GATE, PN544_HCI_CMD_CONTINUE_ACTIVATION, NULL, 0, NULL); if (r < 0) return r; target->hci_reader_gate = PN544_RF_READER_NFCIP1_INITIATOR_GATE; target->supported_protocols = NFC_PROTO_NFC_DEP_MASK; } else if (target->supported_protocols & NFC_PROTO_ISO14443_MASK) { /* * TODO: maybe other ISO 14443 require some kind of continue * activation, but for now we've seen only this one below. */ if (target->sens_res == 0x4403) /* Type 4 Mifare DESFire */ r = nfc_hci_send_cmd(hdev, NFC_HCI_RF_READER_A_GATE, PN544_RF_READER_A_CMD_CONTINUE_ACTIVATION, NULL, 0, NULL); } return r; } #define PN544_CB_TYPE_READER_F 1 static void pn544_hci_data_exchange_cb(void *context, struct sk_buff *skb, int err) { struct pn544_hci_info *info = context; switch (info->async_cb_type) { case PN544_CB_TYPE_READER_F: if (err == 0) skb_pull(skb, 1); info->async_cb(info->async_cb_context, skb, err); break; default: if (err == 0) kfree_skb(skb); break; } } #define MIFARE_CMD_AUTH_KEY_A 0x60 #define MIFARE_CMD_AUTH_KEY_B 0x61 #define MIFARE_CMD_HEADER 2 #define MIFARE_UID_LEN 4 #define MIFARE_KEY_LEN 6 #define MIFARE_CMD_LEN 12 /* * Returns: * <= 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, struct nfc_target *target, struct sk_buff *skb, data_exchange_cb_t cb, void *cb_context) { struct pn544_hci_info *info = nfc_hci_get_clientdata(hdev); pr_info(DRIVER_DESC ": %s for gate=%d\n", __func__, target->hci_reader_gate); switch (target->hci_reader_gate) { case NFC_HCI_RF_READER_A_GATE: if (target->supported_protocols & NFC_PROTO_MIFARE_MASK) { /* * It seems that pn544 is inverting key and UID for * MIFARE authentication commands. */ if (skb->len == MIFARE_CMD_LEN && (skb->data[0] == MIFARE_CMD_AUTH_KEY_A || skb->data[0] == MIFARE_CMD_AUTH_KEY_B)) { u8 uid[MIFARE_UID_LEN]; u8 *data = skb->data + MIFARE_CMD_HEADER; memcpy(uid, data + MIFARE_KEY_LEN, MIFARE_UID_LEN); memmove(data + MIFARE_UID_LEN, data, MIFARE_KEY_LEN); memcpy(data, uid, MIFARE_UID_LEN); } return nfc_hci_send_cmd_async(hdev, target->hci_reader_gate, PN544_MIFARE_CMD, skb->data, skb->len, cb, cb_context); } else return 1; case PN544_RF_READER_F_GATE: *skb_push(skb, 1) = 0; *skb_push(skb, 1) = 0; info->async_cb_type = PN544_CB_TYPE_READER_F; info->async_cb = cb; info->async_cb_context = cb_context; return nfc_hci_send_cmd_async(hdev, target->hci_reader_gate, PN544_FELICA_RAW, skb->data, skb->len, pn544_hci_data_exchange_cb, info); case PN544_RF_READER_JEWEL_GATE: return nfc_hci_send_cmd_async(hdev, target->hci_reader_gate, PN544_JEWEL_RAW_CMD, skb->data, skb->len, cb, cb_context); default: return 1; } } static int pn544_hci_check_presence(struct nfc_hci_dev *hdev, struct nfc_target *target) { return nfc_hci_send_cmd(hdev, target->hci_reader_gate, PN544_RF_READER_CMD_PRESENCE_CHECK, NULL, 0, NULL); } void pn544_hci_event_received(struct nfc_hci_dev *hdev, u8 gate, u8 event, struct sk_buff *skb) { struct sk_buff *rgb_skb = NULL; int r = 0; pr_debug("hci event %d", event); switch (event) { case PN544_HCI_EVT_ACTIVATED: if (gate == PN544_RF_READER_NFCIP1_INITIATOR_GATE) nfc_hci_target_discovered(hdev, gate); else if (gate == PN544_RF_READER_NFCIP1_TARGET_GATE) { r = nfc_hci_get_param(hdev, gate, PN544_DEP_ATR_REQ, &rgb_skb); if (r < 0) goto exit; nfc_tm_activated(hdev->ndev, NFC_PROTO_NFC_DEP_MASK, NFC_COMM_PASSIVE, rgb_skb->data, rgb_skb->len); kfree_skb(rgb_skb); } break; case PN544_HCI_EVT_DEACTIVATED: nfc_hci_send_event(hdev, gate, NFC_HCI_EVT_END_OPERATION, NULL, 0); break; default: break; } exit: kfree_skb(skb); } static struct nfc_hci_ops pn544_hci_ops = { .open = pn544_hci_open, .close = pn544_hci_close, .hci_ready = pn544_hci_ready, .xmit = pn544_hci_xmit, .start_poll = pn544_hci_start_poll, .dep_link_up = pn544_hci_dep_link_up, .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, .check_presence = pn544_hci_check_presence, .event_received = pn544_hci_event_received, }; static int __devinit pn544_hci_probe(struct i2c_client *client, const struct i2c_device_id *id) { struct pn544_hci_info *info; struct pn544_nfc_platform_data *pdata; int r = 0; u32 protocols; struct nfc_hci_init_data init_data; dev_dbg(&client->dev, "%s\n", __func__); dev_dbg(&client->dev, "IRQ: %d\n", client->irq); if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) { dev_err(&client->dev, "Need I2C_FUNC_I2C\n"); return -ENODEV; } info = kzalloc(sizeof(struct pn544_hci_info), GFP_KERNEL); if (!info) { dev_err(&client->dev, "Cannot allocate memory for pn544_hci_info.\n"); r = -ENOMEM; goto err_info_alloc; } info->i2c_dev = client; info->state = PN544_ST_COLD; mutex_init(&info->info_lock); i2c_set_clientdata(client, info); pdata = client->dev.platform_data; if (pdata == NULL) { dev_err(&client->dev, "No platform data\n"); r = -EINVAL; goto err_pdata; } if (pdata->request_resources == NULL) { dev_err(&client->dev, "request_resources() missing\n"); r = -EINVAL; goto err_pdata; } r = pdata->request_resources(client); if (r) { dev_err(&client->dev, "Cannot get platform resources\n"); goto err_pdata; } info->gpio_en = pdata->get_gpio(NFC_GPIO_ENABLE); info->gpio_fw = pdata->get_gpio(NFC_GPIO_FW_RESET); info->gpio_irq = pdata->get_gpio(NFC_GPIO_IRQ); pn544_hci_platform_init(info); r = request_threaded_irq(client->irq, NULL, pn544_hci_irq_thread_fn, IRQF_TRIGGER_RISING | IRQF_ONESHOT, PN544_HCI_DRIVER_NAME, info); if (r < 0) { dev_err(&client->dev, "Unable to register IRQ handler\n"); goto err_rti; } init_data.gate_count = ARRAY_SIZE(pn544_gates); memcpy(init_data.gates, pn544_gates, sizeof(pn544_gates)); /* * TODO: Session id must include the driver name + some bus addr * persistent info to discriminate 2 identical chips */ strcpy(init_data.session_id, "ID544HCI"); protocols = NFC_PROTO_JEWEL_MASK | NFC_PROTO_MIFARE_MASK | NFC_PROTO_FELICA_MASK | NFC_PROTO_ISO14443_MASK | NFC_PROTO_ISO14443_B_MASK | NFC_PROTO_NFC_DEP_MASK; info->hdev = nfc_hci_allocate_device(&pn544_hci_ops, &init_data, protocols, LLC_SHDLC_NAME, PN544_FRAME_HEADROOM + PN544_CMDS_HEADROOM, PN544_FRAME_TAILROOM, PN544_HCI_LLC_MAX_PAYLOAD); if (!info->hdev) { dev_err(&client->dev, "Cannot allocate nfc hdev.\n"); r = -ENOMEM; goto err_alloc_hdev; } nfc_hci_set_clientdata(info->hdev, info); r = nfc_hci_register_device(info->hdev); if (r) goto err_regdev; return 0; err_regdev: nfc_hci_free_device(info->hdev); err_alloc_hdev: free_irq(client->irq, info); err_rti: if (pdata->free_resources != NULL) pdata->free_resources(); err_pdata: kfree(info); err_info_alloc: return r; } static __devexit int pn544_hci_remove(struct i2c_client *client) { struct pn544_hci_info *info = i2c_get_clientdata(client); struct pn544_nfc_platform_data *pdata = client->dev.platform_data; dev_dbg(&client->dev, "%s\n", __func__); nfc_hci_free_device(info->hdev); if (info->state != PN544_ST_COLD) { if (pdata->disable) pdata->disable(); } free_irq(client->irq, info); if (pdata->free_resources) pdata->free_resources(); kfree(info); return 0; } static struct i2c_driver pn544_hci_driver = { .driver = { .name = PN544_HCI_DRIVER_NAME, }, .probe = pn544_hci_probe, .id_table = pn544_hci_id_table, .remove = __devexit_p(pn544_hci_remove), }; static int __init pn544_hci_init(void) { int r; pr_debug(DRIVER_DESC ": %s\n", __func__); r = i2c_add_driver(&pn544_hci_driver); if (r) { pr_err(PN544_HCI_DRIVER_NAME ": driver registration failed\n"); return r; } return 0; } static void __exit pn544_hci_exit(void) { i2c_del_driver(&pn544_hci_driver); } module_init(pn544_hci_init); module_exit(pn544_hci_exit); MODULE_LICENSE("GPL"); MODULE_DESCRIPTION(DRIVER_DESC);