diff options
-rw-r--r-- | Documentation/devicetree/bindings/net/nfc/st-nci.txt (renamed from Documentation/devicetree/bindings/net/nfc/st21nfcb.txt) | 4 | ||||
-rw-r--r-- | drivers/nfc/Kconfig | 2 | ||||
-rw-r--r-- | drivers/nfc/Makefile | 2 | ||||
-rw-r--r-- | drivers/nfc/st-nci/Kconfig | 23 | ||||
-rw-r--r-- | drivers/nfc/st-nci/Makefile | 9 | ||||
-rw-r--r-- | drivers/nfc/st-nci/core.c | 179 | ||||
-rw-r--r-- | drivers/nfc/st-nci/i2c.c (renamed from drivers/nfc/st21nfcb/i2c.c) | 123 | ||||
-rw-r--r-- | drivers/nfc/st-nci/ndlc.c (renamed from drivers/nfc/st21nfcb/ndlc.c) | 12 | ||||
-rw-r--r-- | drivers/nfc/st-nci/ndlc.h (renamed from drivers/nfc/st21nfcb/ndlc.h) | 4 | ||||
-rw-r--r-- | drivers/nfc/st-nci/st-nci.h (renamed from drivers/nfc/st21nfcb/st21nfcb.h) | 22 | ||||
-rw-r--r-- | drivers/nfc/st-nci/st-nci_se.c (renamed from drivers/nfc/st21nfcb/st21nfcb_se.c) | 383 | ||||
-rw-r--r-- | drivers/nfc/st-nci/st-nci_se.h | 61 | ||||
-rw-r--r-- | drivers/nfc/st21nfcb/Kconfig | 22 | ||||
-rw-r--r-- | drivers/nfc/st21nfcb/Makefile | 9 | ||||
-rw-r--r-- | drivers/nfc/st21nfcb/st21nfcb.c | 179 | ||||
-rw-r--r-- | drivers/nfc/st21nfcb/st21nfcb_se.h | 61 | ||||
-rw-r--r-- | include/linux/platform_data/st-nci.h (renamed from include/linux/platform_data/st21nfcb.h) | 14 | ||||
-rw-r--r-- | include/linux/platform_data/st_nci.h | 29 |
18 files changed, 585 insertions, 553 deletions
diff --git a/Documentation/devicetree/bindings/net/nfc/st21nfcb.txt b/Documentation/devicetree/bindings/net/nfc/st-nci.txt index bb23707..d707588 100644 --- a/Documentation/devicetree/bindings/net/nfc/st21nfcb.txt +++ b/Documentation/devicetree/bindings/net/nfc/st-nci.txt @@ -1,7 +1,7 @@ -* STMicroelectronics SAS. ST21NFCB NFC Controller +* STMicroelectronics SAS. ST NCI NFC Controller Required properties: -- compatible: Should be "st,st21nfcb-i2c". +- compatible: Should be "st,st21nfcb-i2c" or "st,st21nfcc-i2c". - clock-frequency: I²C work frequency. - reg: address on the bus - interrupt-parent: phandle for the interrupt gpio controller diff --git a/drivers/nfc/Kconfig b/drivers/nfc/Kconfig index 107714e..722673c 100644 --- a/drivers/nfc/Kconfig +++ b/drivers/nfc/Kconfig @@ -72,6 +72,6 @@ source "drivers/nfc/pn544/Kconfig" source "drivers/nfc/microread/Kconfig" source "drivers/nfc/nfcmrvl/Kconfig" source "drivers/nfc/st21nfca/Kconfig" -source "drivers/nfc/st21nfcb/Kconfig" +source "drivers/nfc/st-nci/Kconfig" source "drivers/nfc/nxp-nci/Kconfig" endmenu diff --git a/drivers/nfc/Makefile b/drivers/nfc/Makefile index 13b648b..368b6df 100644 --- a/drivers/nfc/Makefile +++ b/drivers/nfc/Makefile @@ -12,5 +12,5 @@ obj-$(CONFIG_NFC_PORT100) += port100.o obj-$(CONFIG_NFC_MRVL) += nfcmrvl/ obj-$(CONFIG_NFC_TRF7970A) += trf7970a.o obj-$(CONFIG_NFC_ST21NFCA) += st21nfca/ -obj-$(CONFIG_NFC_ST21NFCB) += st21nfcb/ +obj-$(CONFIG_NFC_ST_NCI) += st-nci/ obj-$(CONFIG_NFC_NXP_NCI) += nxp-nci/ diff --git a/drivers/nfc/st-nci/Kconfig b/drivers/nfc/st-nci/Kconfig new file mode 100644 index 0000000..fc3904c --- /dev/null +++ b/drivers/nfc/st-nci/Kconfig @@ -0,0 +1,23 @@ +config NFC_ST_NCI + tristate "STMicroelectronics ST NCI NFC driver" + depends on NFC_NCI + default n + ---help--- + STMicroelectronics NFC NCI chips core driver. It implements the chipset + NCI logic and hooks into the NFC kernel APIs. Physical layers will + register against it. + + To compile this driver as a module, choose m here. The module will + be called st-nci. + Say N if unsure. + +config NFC_ST_NCI_I2C + tristate "NFC ST NCI i2c support" + depends on NFC_ST_NCI && I2C + ---help--- + This module adds support for an I2C interface to the + STMicroelectronics NFC NCI chips familly. + Select this if your platform is using the i2c bus. + + If you choose to build a module, it'll be called st-nci_i2c. + Say N if unsure. diff --git a/drivers/nfc/st-nci/Makefile b/drivers/nfc/st-nci/Makefile new file mode 100644 index 0000000..0df157d --- /dev/null +++ b/drivers/nfc/st-nci/Makefile @@ -0,0 +1,9 @@ +# +# Makefile for ST21NFCB NCI based NFC driver +# + +st-nci-objs = ndlc.o core.o st-nci_se.o +obj-$(CONFIG_NFC_ST_NCI) += st-nci.o + +st-nci_i2c-objs = i2c.o +obj-$(CONFIG_NFC_ST_NCI_I2C) += st-nci_i2c.o diff --git a/drivers/nfc/st-nci/core.c b/drivers/nfc/st-nci/core.c new file mode 100644 index 0000000..c419d39 --- /dev/null +++ b/drivers/nfc/st-nci/core.c @@ -0,0 +1,179 @@ +/* + * NCI based Driver for STMicroelectronics NFC Chip + * + * Copyright (C) 2014-2015 STMicroelectronics SAS. 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, see <http://www.gnu.org/licenses/>. + */ + +#include <linux/module.h> +#include <linux/nfc.h> +#include <net/nfc/nci.h> +#include <net/nfc/nci_core.h> +#include <linux/gpio.h> +#include <linux/delay.h> + +#include "st-nci.h" +#include "st-nci_se.h" + +#define DRIVER_DESC "NCI NFC driver for ST_NCI" + +#define ST_NCI1_X_PROPRIETARY_ISO15693 0x83 + +static int st_nci_init(struct nci_dev *ndev) +{ + struct nci_mode_set_cmd cmd; + + cmd.cmd_type = ST_NCI_SET_NFC_MODE; + cmd.mode = 1; + + return nci_prop_cmd(ndev, ST_NCI_CORE_PROP, + sizeof(struct nci_mode_set_cmd), (__u8 *)&cmd); +} + +static int st_nci_open(struct nci_dev *ndev) +{ + struct st_nci_info *info = nci_get_drvdata(ndev); + int r; + + if (test_and_set_bit(ST_NCI_RUNNING, &info->flags)) + return 0; + + r = ndlc_open(info->ndlc); + if (r) + clear_bit(ST_NCI_RUNNING, &info->flags); + + return r; +} + +static int st_nci_close(struct nci_dev *ndev) +{ + struct st_nci_info *info = nci_get_drvdata(ndev); + + if (!test_bit(ST_NCI_RUNNING, &info->flags)) + return 0; + + ndlc_close(info->ndlc); + + clear_bit(ST_NCI_RUNNING, &info->flags); + + return 0; +} + +static int st_nci_send(struct nci_dev *ndev, struct sk_buff *skb) +{ + struct st_nci_info *info = nci_get_drvdata(ndev); + + skb->dev = (void *)ndev; + + if (!test_bit(ST_NCI_RUNNING, &info->flags)) + return -EBUSY; + + return ndlc_send(info->ndlc, skb); +} + +static __u32 st_nci_get_rfprotocol(struct nci_dev *ndev, + __u8 rf_protocol) +{ + return rf_protocol == ST_NCI1_X_PROPRIETARY_ISO15693 ? + NFC_PROTO_ISO15693_MASK : 0; +} + +static int st_nci_prop_rsp_packet(struct nci_dev *ndev, + struct sk_buff *skb) +{ + __u8 status = skb->data[0]; + + nci_req_complete(ndev, status); + return 0; +} + +static struct nci_prop_ops st_nci_prop_ops[] = { + { + .opcode = nci_opcode_pack(NCI_GID_PROPRIETARY, + ST_NCI_CORE_PROP), + .rsp = st_nci_prop_rsp_packet, + }, +}; + +static struct nci_ops st_nci_ops = { + .init = st_nci_init, + .open = st_nci_open, + .close = st_nci_close, + .send = st_nci_send, + .get_rfprotocol = st_nci_get_rfprotocol, + .discover_se = st_nci_discover_se, + .enable_se = st_nci_enable_se, + .disable_se = st_nci_disable_se, + .se_io = st_nci_se_io, + .hci_load_session = st_nci_hci_load_session, + .hci_event_received = st_nci_hci_event_received, + .hci_cmd_received = st_nci_hci_cmd_received, + .prop_ops = st_nci_prop_ops, + .n_prop_ops = ARRAY_SIZE(st_nci_prop_ops), +}; + +int st_nci_probe(struct llt_ndlc *ndlc, int phy_headroom, + int phy_tailroom) +{ + struct st_nci_info *info; + int r; + u32 protocols; + + info = devm_kzalloc(ndlc->dev, + sizeof(struct st_nci_info), GFP_KERNEL); + if (!info) + return -ENOMEM; + + protocols = NFC_PROTO_JEWEL_MASK + | NFC_PROTO_MIFARE_MASK + | NFC_PROTO_FELICA_MASK + | NFC_PROTO_ISO14443_MASK + | NFC_PROTO_ISO14443_B_MASK + | NFC_PROTO_ISO15693_MASK + | NFC_PROTO_NFC_DEP_MASK; + + ndlc->ndev = nci_allocate_device(&st_nci_ops, protocols, + phy_headroom, phy_tailroom); + if (!ndlc->ndev) { + pr_err("Cannot allocate nfc ndev\n"); + return -ENOMEM; + } + info->ndlc = ndlc; + + nci_set_drvdata(ndlc->ndev, info); + + r = nci_register_device(ndlc->ndev); + if (r) { + pr_err("Cannot register nfc device to nci core\n"); + nci_free_device(ndlc->ndev); + return r; + } + + return st_nci_se_init(ndlc->ndev); +} +EXPORT_SYMBOL_GPL(st_nci_probe); + +void st_nci_remove(struct nci_dev *ndev) +{ + struct st_nci_info *info = nci_get_drvdata(ndev); + + ndlc_close(info->ndlc); + + nci_unregister_device(ndev); + nci_free_device(ndev); +} +EXPORT_SYMBOL_GPL(st_nci_remove); + +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION(DRIVER_DESC); diff --git a/drivers/nfc/st21nfcb/i2c.c b/drivers/nfc/st-nci/i2c.c index dbc0dfd..06175ce 100644 --- a/drivers/nfc/st21nfcb/i2c.c +++ b/drivers/nfc/st-nci/i2c.c @@ -1,6 +1,6 @@ /* - * I2C Link Layer for ST21NFCB NCI based Driver - * Copyright (C) 2014 STMicroelectronics SAS. All rights reserved. + * I2C Link Layer for ST NCI NFC controller familly based Driver + * Copyright (C) 2014-2015 STMicroelectronics SAS. 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, @@ -25,7 +25,7 @@ #include <linux/interrupt.h> #include <linux/delay.h> #include <linux/nfc.h> -#include <linux/platform_data/st21nfcb.h> +#include <linux/platform_data/st_nci.h> #include "ndlc.h" @@ -35,18 +35,18 @@ #define ST21NFCB_FRAME_HEADROOM 1 #define ST21NFCB_FRAME_TAILROOM 0 -#define ST21NFCB_NCI_I2C_MIN_SIZE 4 /* PCB(1) + NCI Packet header(3) */ -#define ST21NFCB_NCI_I2C_MAX_SIZE 250 /* req 4.2.1 */ +#define ST_NCI_I2C_MIN_SIZE 4 /* PCB(1) + NCI Packet header(3) */ +#define ST_NCI_I2C_MAX_SIZE 250 /* req 4.2.1 */ -#define ST21NFCB_NCI_I2C_DRIVER_NAME "st21nfcb_nci_i2c" +#define ST_NCI_I2C_DRIVER_NAME "st_nci_i2c" -static struct i2c_device_id st21nfcb_nci_i2c_id_table[] = { - {ST21NFCB_NCI_DRIVER_NAME, 0}, +static struct i2c_device_id st_nci_i2c_id_table[] = { + {ST_NCI_DRIVER_NAME, 0}, {} }; -MODULE_DEVICE_TABLE(i2c, st21nfcb_nci_i2c_id_table); +MODULE_DEVICE_TABLE(i2c, st_nci_i2c_id_table); -struct st21nfcb_i2c_phy { +struct st_nci_i2c_phy { struct i2c_client *i2c_dev; struct llt_ndlc *ndlc; @@ -61,9 +61,9 @@ do { \ 16, 1, (skb)->data, (skb)->len, 0); \ } while (0) -static int st21nfcb_nci_i2c_enable(void *phy_id) +static int st_nci_i2c_enable(void *phy_id) { - struct st21nfcb_i2c_phy *phy = phy_id; + struct st_nci_i2c_phy *phy = phy_id; gpio_set_value(phy->gpio_reset, 0); usleep_range(10000, 15000); @@ -76,9 +76,9 @@ static int st21nfcb_nci_i2c_enable(void *phy_id) return 0; } -static void st21nfcb_nci_i2c_disable(void *phy_id) +static void st_nci_i2c_disable(void *phy_id) { - struct st21nfcb_i2c_phy *phy = phy_id; + struct st_nci_i2c_phy *phy = phy_id; disable_irq_nosync(phy->i2c_dev->irq); } @@ -88,13 +88,13 @@ static void st21nfcb_nci_i2c_disable(void *phy_id) * It must return either zero for success, or <0 for error. * In addition, it must not alter the skb */ -static int st21nfcb_nci_i2c_write(void *phy_id, struct sk_buff *skb) +static int st_nci_i2c_write(void *phy_id, struct sk_buff *skb) { int r = -1; - struct st21nfcb_i2c_phy *phy = phy_id; + struct st_nci_i2c_phy *phy = phy_id; struct i2c_client *client = phy->i2c_dev; - I2C_DUMP_SKB("st21nfcb_nci_i2c_write", skb); + I2C_DUMP_SKB("st_nci_i2c_write", skb); if (phy->ndlc->hard_fault != 0) return phy->ndlc->hard_fault; @@ -124,40 +124,40 @@ static int st21nfcb_nci_i2c_write(void *phy_id, struct sk_buff *skb) * at end of read) * -EREMOTEIO : i2c read error (fatal) * -EBADMSG : frame was incorrect and discarded - * (value returned from st21nfcb_nci_i2c_repack) + * (value returned from st_nci_i2c_repack) * -EIO : if no ST21NFCB_SOF_EOF is found after reaching * the read length end sequence */ -static int st21nfcb_nci_i2c_read(struct st21nfcb_i2c_phy *phy, +static int st_nci_i2c_read(struct st_nci_i2c_phy *phy, struct sk_buff **skb) { int r; u8 len; - u8 buf[ST21NFCB_NCI_I2C_MAX_SIZE]; + u8 buf[ST_NCI_I2C_MAX_SIZE]; struct i2c_client *client = phy->i2c_dev; - r = i2c_master_recv(client, buf, ST21NFCB_NCI_I2C_MIN_SIZE); + r = i2c_master_recv(client, buf, ST_NCI_I2C_MIN_SIZE); if (r < 0) { /* Retry, chip was in standby */ usleep_range(1000, 4000); - r = i2c_master_recv(client, buf, ST21NFCB_NCI_I2C_MIN_SIZE); + r = i2c_master_recv(client, buf, ST_NCI_I2C_MIN_SIZE); } - if (r != ST21NFCB_NCI_I2C_MIN_SIZE) + if (r != ST_NCI_I2C_MIN_SIZE) return -EREMOTEIO; len = be16_to_cpu(*(__be16 *) (buf + 2)); - if (len > ST21NFCB_NCI_I2C_MAX_SIZE) { + if (len > ST_NCI_I2C_MAX_SIZE) { nfc_err(&client->dev, "invalid frame len\n"); return -EBADMSG; } - *skb = alloc_skb(ST21NFCB_NCI_I2C_MIN_SIZE + len, GFP_KERNEL); + *skb = alloc_skb(ST_NCI_I2C_MIN_SIZE + len, GFP_KERNEL); if (*skb == NULL) return -ENOMEM; - skb_reserve(*skb, ST21NFCB_NCI_I2C_MIN_SIZE); - skb_put(*skb, ST21NFCB_NCI_I2C_MIN_SIZE); - memcpy((*skb)->data, buf, ST21NFCB_NCI_I2C_MIN_SIZE); + skb_reserve(*skb, ST_NCI_I2C_MIN_SIZE); + skb_put(*skb, ST_NCI_I2C_MIN_SIZE); + memcpy((*skb)->data, buf, ST_NCI_I2C_MIN_SIZE); if (!len) return 0; @@ -169,7 +169,7 @@ static int st21nfcb_nci_i2c_read(struct st21nfcb_i2c_phy *phy, } skb_put(*skb, len); - memcpy((*skb)->data + ST21NFCB_NCI_I2C_MIN_SIZE, buf, len); + memcpy((*skb)->data + ST_NCI_I2C_MIN_SIZE, buf, len); I2C_DUMP_SKB("i2c frame read", *skb); @@ -181,9 +181,9 @@ static int st21nfcb_nci_i2c_read(struct st21nfcb_i2c_phy *phy, * * On ST21NFCB, IRQ goes in idle state when read starts. */ -static irqreturn_t st21nfcb_nci_irq_thread_fn(int irq, void *phy_id) +static irqreturn_t st_nci_irq_thread_fn(int irq, void *phy_id) { - struct st21nfcb_i2c_phy *phy = phy_id; + struct st_nci_i2c_phy *phy = phy_id; struct i2c_client *client; struct sk_buff *skb = NULL; int r; @@ -200,11 +200,11 @@ static irqreturn_t st21nfcb_nci_irq_thread_fn(int irq, void *phy_id) return IRQ_HANDLED; if (!phy->ndlc->powered) { - st21nfcb_nci_i2c_disable(phy); + st_nci_i2c_disable(phy); return IRQ_HANDLED; } - r = st21nfcb_nci_i2c_read(phy, &skb); + r = st_nci_i2c_read(phy, &skb); if (r == -EREMOTEIO || r == -ENOMEM || r == -EBADMSG) return IRQ_HANDLED; @@ -214,15 +214,15 @@ static irqreturn_t st21nfcb_nci_irq_thread_fn(int irq, void *phy_id) } static struct nfc_phy_ops i2c_phy_ops = { - .write = st21nfcb_nci_i2c_write, - .enable = st21nfcb_nci_i2c_enable, - .disable = st21nfcb_nci_i2c_disable, + .write = st_nci_i2c_write, + .enable = st_nci_i2c_enable, + .disable = st_nci_i2c_disable, }; #ifdef CONFIG_OF -static int st21nfcb_nci_i2c_of_request_resources(struct i2c_client *client) +static int st_nci_i2c_of_request_resources(struct i2c_client *client) { - struct st21nfcb_i2c_phy *phy = i2c_get_clientdata(client); + struct st_nci_i2c_phy *phy = i2c_get_clientdata(client); struct device_node *pp; int gpio; int r; @@ -253,16 +253,16 @@ static int st21nfcb_nci_i2c_of_request_resources(struct i2c_client *client) return 0; } #else -static int st21nfcb_nci_i2c_of_request_resources(struct i2c_client *client) +static int st_nci_i2c_of_request_resources(struct i2c_client *client) { return -ENODEV; } #endif -static int st21nfcb_nci_i2c_request_resources(struct i2c_client *client) +static int st_nci_i2c_request_resources(struct i2c_client *client) { - struct st21nfcb_nfc_platform_data *pdata; - struct st21nfcb_i2c_phy *phy = i2c_get_clientdata(client); + struct st_nci_nfc_platform_data *pdata; + struct st_nci_i2c_phy *phy = i2c_get_clientdata(client); int r; pdata = client->dev.platform_data; @@ -285,11 +285,11 @@ static int st21nfcb_nci_i2c_request_resources(struct i2c_client *client) return 0; } -static int st21nfcb_nci_i2c_probe(struct i2c_client *client, +static int st_nci_i2c_probe(struct i2c_client *client, const struct i2c_device_id *id) { - struct st21nfcb_i2c_phy *phy; - struct st21nfcb_nfc_platform_data *pdata; + struct st_nci_i2c_phy *phy; + struct st_nci_nfc_platform_data *pdata; int r; dev_dbg(&client->dev, "%s\n", __func__); @@ -300,7 +300,7 @@ static int st21nfcb_nci_i2c_probe(struct i2c_client *client, return -ENODEV; } - phy = devm_kzalloc(&client->dev, sizeof(struct st21nfcb_i2c_phy), + phy = devm_kzalloc(&client->dev, sizeof(struct st_nci_i2c_phy), GFP_KERNEL); if (!phy) return -ENOMEM; @@ -311,13 +311,13 @@ static int st21nfcb_nci_i2c_probe(struct i2c_client *client, pdata = client->dev.platform_data; if (!pdata && client->dev.of_node) { - r = st21nfcb_nci_i2c_of_request_resources(client); + r = st_nci_i2c_of_request_resources(client); if (r) { nfc_err(&client->dev, "No platform data\n"); return r; } } else if (pdata) { - r = st21nfcb_nci_i2c_request_resources(client); + r = st_nci_i2c_request_resources(client); if (r) { nfc_err(&client->dev, "Cannot get platform resources\n"); @@ -338,18 +338,18 @@ static int st21nfcb_nci_i2c_probe(struct i2c_client *client, } r = devm_request_threaded_irq(&client->dev, client->irq, NULL, - st21nfcb_nci_irq_thread_fn, + st_nci_irq_thread_fn, phy->irq_polarity | IRQF_ONESHOT, - ST21NFCB_NCI_DRIVER_NAME, phy); + ST_NCI_DRIVER_NAME, phy); if (r < 0) nfc_err(&client->dev, "Unable to register IRQ handler\n"); return r; } -static int st21nfcb_nci_i2c_remove(struct i2c_client *client) +static int st_nci_i2c_remove(struct i2c_client *client) { - struct st21nfcb_i2c_phy *phy = i2c_get_clientdata(client); + struct st_nci_i2c_phy *phy = i2c_get_clientdata(client); dev_dbg(&client->dev, "%s\n", __func__); @@ -359,26 +359,27 @@ static int st21nfcb_nci_i2c_remove(struct i2c_client *client) } #ifdef CONFIG_OF -static const struct of_device_id of_st21nfcb_i2c_match[] = { +static const struct of_device_id of_st_nci_i2c_match[] = { { .compatible = "st,st21nfcb-i2c", }, { .compatible = "st,st21nfcb_i2c", }, + { .compatible = "st,st21nfcc-i2c", }, {} }; -MODULE_DEVICE_TABLE(of, of_st21nfcb_i2c_match); +MODULE_DEVICE_TABLE(of, of_st_nci_i2c_match); #endif -static struct i2c_driver st21nfcb_nci_i2c_driver = { +static struct i2c_driver st_nci_i2c_driver = { .driver = { .owner = THIS_MODULE, - .name = ST21NFCB_NCI_I2C_DRIVER_NAME, - .of_match_table = of_match_ptr(of_st21nfcb_i2c_match), + .name = ST_NCI_I2C_DRIVER_NAME, + .of_match_table = of_match_ptr(of_st_nci_i2c_match), }, - .probe = st21nfcb_nci_i2c_probe, - .id_table = st21nfcb_nci_i2c_id_table, - .remove = st21nfcb_nci_i2c_remove, + .probe = st_nci_i2c_probe, + .id_table = st_nci_i2c_id_table, + .remove = st_nci_i2c_remove, }; -module_i2c_driver(st21nfcb_nci_i2c_driver); +module_i2c_driver(st_nci_i2c_driver); MODULE_LICENSE("GPL"); MODULE_DESCRIPTION(DRIVER_DESC); diff --git a/drivers/nfc/st21nfcb/ndlc.c b/drivers/nfc/st-nci/ndlc.c index 91e81f3..56c6a4c 100644 --- a/drivers/nfc/st21nfcb/ndlc.c +++ b/drivers/nfc/st-nci/ndlc.c @@ -1,7 +1,7 @@ /* * Low Level Transport (NDLC) Driver for STMicroelectronics NFC Chip * - * Copyright (C) 2014 STMicroelectronics SAS. All rights reserved. + * Copyright (C) 2014-2015 STMicroelectronics SAS. 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, @@ -20,7 +20,7 @@ #include <net/nfc/nci_core.h> #include "ndlc.h" -#include "st21nfcb.h" +#include "st-nci.h" #define NDLC_TIMER_T1 100 #define NDLC_TIMER_T1_WAIT 400 @@ -68,13 +68,13 @@ void ndlc_close(struct llt_ndlc *ndlc) { struct nci_mode_set_cmd cmd; - cmd.cmd_type = ST21NFCB_NCI_SET_NFC_MODE; + cmd.cmd_type = ST_NCI_SET_NFC_MODE; cmd.mode = 0; /* toggle reset pin */ ndlc->ops->enable(ndlc->phy_id); - nci_prop_cmd(ndlc->ndev, ST21NFCB_NCI_CORE_PROP, + nci_prop_cmd(ndlc->ndev, ST_NCI_CORE_PROP, sizeof(struct nci_mode_set_cmd), (__u8 *)&cmd); ndlc->powered = 0; @@ -293,13 +293,13 @@ int ndlc_probe(void *phy_id, struct nfc_phy_ops *phy_ops, struct device *dev, INIT_WORK(&ndlc->sm_work, llt_ndlc_sm_work); - return st21nfcb_nci_probe(ndlc, phy_headroom, phy_tailroom); + return st_nci_probe(ndlc, phy_headroom, phy_tailroom); } EXPORT_SYMBOL(ndlc_probe); void ndlc_remove(struct llt_ndlc *ndlc) { - st21nfcb_nci_remove(ndlc->ndev); + st_nci_remove(ndlc->ndev); /* cancel timers */ del_timer_sync(&ndlc->t1_timer); diff --git a/drivers/nfc/st21nfcb/ndlc.h b/drivers/nfc/st-nci/ndlc.h index cf6a9d9..6361005 100644 --- a/drivers/nfc/st21nfcb/ndlc.h +++ b/drivers/nfc/st-nci/ndlc.h @@ -1,7 +1,7 @@ /* * NCI based Driver for STMicroelectronics NFC Chip * - * Copyright (C) 2014 STMicroelectronics SAS. All rights reserved. + * Copyright (C) 2014-2015 STMicroelectronics SAS. 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, @@ -43,7 +43,7 @@ struct llt_ndlc { struct device *dev; /* - * < 0 if hardware error occured + * < 0 if hardware error occurred * and prevents normal operation. */ int hard_fault; diff --git a/drivers/nfc/st21nfcb/st21nfcb.h b/drivers/nfc/st-nci/st-nci.h index 7106363..850a239 100644 --- a/drivers/nfc/st21nfcb/st21nfcb.h +++ b/drivers/nfc/st-nci/st-nci.h @@ -16,17 +16,17 @@ * along with this program; if not, see <http://www.gnu.org/licenses/>. */ -#ifndef __LOCAL_ST21NFCB_H_ -#define __LOCAL_ST21NFCB_H_ +#ifndef __LOCAL_ST_NCI_H_ +#define __LOCAL_ST_NCI_H_ -#include "st21nfcb_se.h" +#include "st-nci_se.h" #include "ndlc.h" /* Define private flags: */ -#define ST21NFCB_NCI_RUNNING 1 +#define ST_NCI_RUNNING 1 -#define ST21NFCB_NCI_CORE_PROP 0x01 -#define ST21NFCB_NCI_SET_NFC_MODE 0x02 +#define ST_NCI_CORE_PROP 0x01 +#define ST_NCI_SET_NFC_MODE 0x02 struct nci_mode_set_cmd { u8 cmd_type; @@ -37,14 +37,14 @@ struct nci_mode_set_rsp { u8 status; } __packed; -struct st21nfcb_nci_info { +struct st_nci_info { struct llt_ndlc *ndlc; unsigned long flags; - struct st21nfcb_se_info se_info; + struct st_nci_se_info se_info; }; -void st21nfcb_nci_remove(struct nci_dev *ndev); -int st21nfcb_nci_probe(struct llt_ndlc *ndlc, int phy_headroom, +void st_nci_remove(struct nci_dev *ndev); +int st_nci_probe(struct llt_ndlc *ndlc, int phy_headroom, int phy_tailroom); -#endif /* __LOCAL_ST21NFCB_H_ */ +#endif /* __LOCAL_ST_NCI_H_ */ diff --git a/drivers/nfc/st21nfcb/st21nfcb_se.c b/drivers/nfc/st-nci/st-nci_se.c index 24862a5..97addfa 100644 --- a/drivers/nfc/st21nfcb/st21nfcb_se.c +++ b/drivers/nfc/st-nci/st-nci_se.c @@ -1,7 +1,7 @@ /* - * NCI based Driver for STMicroelectronics NFC Chip + * Secure Element driver for STMicroelectronics NFC NCI chip * - * Copyright (C) 2014 STMicroelectronics SAS. All rights reserved. + * Copyright (C) 2014-2015 STMicroelectronics SAS. 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, @@ -22,10 +22,10 @@ #include <net/nfc/nci.h> #include <net/nfc/nci_core.h> -#include "st21nfcb.h" -#include "st21nfcb_se.h" +#include "st-nci.h" +#include "st-nci_se.h" -struct st21nfcb_pipe_info { +struct st_nci_pipe_info { u8 pipe_state; u8 src_host_id; u8 src_gate_id; @@ -34,166 +34,166 @@ struct st21nfcb_pipe_info { } __packed; /* Hosts */ -#define ST21NFCB_HOST_CONTROLLER_ID 0x00 -#define ST21NFCB_TERMINAL_HOST_ID 0x01 -#define ST21NFCB_UICC_HOST_ID 0x02 -#define ST21NFCB_ESE_HOST_ID 0xc0 +#define ST_NCI_HOST_CONTROLLER_ID 0x00 +#define ST_NCI_TERMINAL_HOST_ID 0x01 +#define ST_NCI_UICC_HOST_ID 0x02 +#define ST_NCI_ESE_HOST_ID 0xc0 /* Gates */ -#define ST21NFCB_DEVICE_MGNT_GATE 0x01 -#define ST21NFCB_APDU_READER_GATE 0xf0 -#define ST21NFCB_CONNECTIVITY_GATE 0x41 +#define ST_NCI_DEVICE_MGNT_GATE 0x01 +#define ST_NCI_APDU_READER_GATE 0xf0 +#define ST_NCI_CONNECTIVITY_GATE 0x41 /* Pipes */ -#define ST21NFCB_DEVICE_MGNT_PIPE 0x02 +#define ST_NCI_DEVICE_MGNT_PIPE 0x02 /* Connectivity pipe only */ -#define ST21NFCB_SE_COUNT_PIPE_UICC 0x01 +#define ST_NCI_SE_COUNT_PIPE_UICC 0x01 /* Connectivity + APDU Reader pipe */ -#define ST21NFCB_SE_COUNT_PIPE_EMBEDDED 0x02 +#define ST_NCI_SE_COUNT_PIPE_EMBEDDED 0x02 -#define ST21NFCB_SE_TO_HOT_PLUG 1000 /* msecs */ -#define ST21NFCB_SE_TO_PIPES 2000 +#define ST_NCI_SE_TO_HOT_PLUG 1000 /* msecs */ +#define ST_NCI_SE_TO_PIPES 2000 -#define ST21NFCB_EVT_HOT_PLUG_IS_INHIBITED(x) (x->data[0] & 0x80) +#define ST_NCI_EVT_HOT_PLUG_IS_INHIBITED(x) (x->data[0] & 0x80) #define NCI_HCI_APDU_PARAM_ATR 0x01 #define NCI_HCI_ADMIN_PARAM_SESSION_IDENTITY 0x01 #define NCI_HCI_ADMIN_PARAM_WHITELIST 0x03 #define NCI_HCI_ADMIN_PARAM_HOST_LIST 0x04 -#define ST21NFCB_EVT_SE_HARD_RESET 0x20 -#define ST21NFCB_EVT_TRANSMIT_DATA 0x10 -#define ST21NFCB_EVT_WTX_REQUEST 0x11 -#define ST21NFCB_EVT_SE_SOFT_RESET 0x11 -#define ST21NFCB_EVT_SE_END_OF_APDU_TRANSFER 0x21 -#define ST21NFCB_EVT_HOT_PLUG 0x03 +#define ST_NCI_EVT_SE_HARD_RESET 0x20 +#define ST_NCI_EVT_TRANSMIT_DATA 0x10 +#define ST_NCI_EVT_WTX_REQUEST 0x11 +#define ST_NCI_EVT_SE_SOFT_RESET 0x11 +#define ST_NCI_EVT_SE_END_OF_APDU_TRANSFER 0x21 +#define ST_NCI_EVT_HOT_PLUG 0x03 -#define ST21NFCB_SE_MODE_OFF 0x00 -#define ST21NFCB_SE_MODE_ON 0x01 +#define ST_NCI_SE_MODE_OFF 0x00 +#define ST_NCI_SE_MODE_ON 0x01 -#define ST21NFCB_EVT_CONNECTIVITY 0x10 -#define ST21NFCB_EVT_TRANSACTION 0x12 +#define ST_NCI_EVT_CONNECTIVITY 0x10 +#define ST_NCI_EVT_TRANSACTION 0x12 -#define ST21NFCB_DM_GETINFO 0x13 -#define ST21NFCB_DM_GETINFO_PIPE_LIST 0x02 -#define ST21NFCB_DM_GETINFO_PIPE_INFO 0x01 -#define ST21NFCB_DM_PIPE_CREATED 0x02 -#define ST21NFCB_DM_PIPE_OPEN 0x04 -#define ST21NFCB_DM_RF_ACTIVE 0x80 -#define ST21NFCB_DM_DISCONNECT 0x30 +#define ST_NCI_DM_GETINFO 0x13 +#define ST_NCI_DM_GETINFO_PIPE_LIST 0x02 +#define ST_NCI_DM_GETINFO_PIPE_INFO 0x01 +#define ST_NCI_DM_PIPE_CREATED 0x02 +#define ST_NCI_DM_PIPE_OPEN 0x04 +#define ST_NCI_DM_RF_ACTIVE 0x80 +#define ST_NCI_DM_DISCONNECT 0x30 -#define ST21NFCB_DM_IS_PIPE_OPEN(p) \ - ((p & 0x0f) == (ST21NFCB_DM_PIPE_CREATED | ST21NFCB_DM_PIPE_OPEN)) +#define ST_NCI_DM_IS_PIPE_OPEN(p) \ + ((p & 0x0f) == (ST_NCI_DM_PIPE_CREATED | ST_NCI_DM_PIPE_OPEN)) -#define ST21NFCB_ATR_DEFAULT_BWI 0x04 +#define ST_NCI_ATR_DEFAULT_BWI 0x04 /* * WT = 2^BWI/10[s], convert into msecs and add a secure * room by increasing by 2 this timeout */ -#define ST21NFCB_BWI_TO_TIMEOUT(x) ((1 << x) * 200) -#define ST21NFCB_ATR_GET_Y_FROM_TD(x) (x >> 4) +#define ST_NCI_BWI_TO_TIMEOUT(x) ((1 << x) * 200) +#define ST_NCI_ATR_GET_Y_FROM_TD(x) (x >> 4) /* If TA is present bit 0 is set */ -#define ST21NFCB_ATR_TA_PRESENT(x) (x & 0x01) +#define ST_NCI_ATR_TA_PRESENT(x) (x & 0x01) /* If TB is present bit 1 is set */ -#define ST21NFCB_ATR_TB_PRESENT(x) (x & 0x02) +#define ST_NCI_ATR_TB_PRESENT(x) (x & 0x02) -#define ST21NFCB_NUM_DEVICES 256 +#define ST_NCI_NUM_DEVICES 256 -static DECLARE_BITMAP(dev_mask, ST21NFCB_NUM_DEVICES); +static DECLARE_BITMAP(dev_mask, ST_NCI_NUM_DEVICES); -/* Here are the mandatory pipe for st21nfcb */ -static struct nci_hci_gate st21nfcb_gates[] = { +/* Here are the mandatory pipe for st_nci */ +static struct nci_hci_gate st_nci_gates[] = { {NCI_HCI_ADMIN_GATE, NCI_HCI_ADMIN_PIPE, - ST21NFCB_HOST_CONTROLLER_ID}, + ST_NCI_HOST_CONTROLLER_ID}, {NCI_HCI_LINK_MGMT_GATE, NCI_HCI_LINK_MGMT_PIPE, - ST21NFCB_HOST_CONTROLLER_ID}, - {ST21NFCB_DEVICE_MGNT_GATE, ST21NFCB_DEVICE_MGNT_PIPE, - ST21NFCB_HOST_CONTROLLER_ID}, + ST_NCI_HOST_CONTROLLER_ID}, + {ST_NCI_DEVICE_MGNT_GATE, ST_NCI_DEVICE_MGNT_PIPE, + ST_NCI_HOST_CONTROLLER_ID}, /* Secure element pipes are created by secure element host */ - {ST21NFCB_CONNECTIVITY_GATE, NCI_HCI_DO_NOT_OPEN_PIPE, - ST21NFCB_HOST_CONTROLLER_ID}, - {ST21NFCB_APDU_READER_GATE, NCI_HCI_DO_NOT_OPEN_PIPE, - ST21NFCB_HOST_CONTROLLER_ID}, + {ST_NCI_CONNECTIVITY_GATE, NCI_HCI_DO_NOT_OPEN_PIPE, + ST_NCI_HOST_CONTROLLER_ID}, + {ST_NCI_APDU_READER_GATE, NCI_HCI_DO_NOT_OPEN_PIPE, + ST_NCI_HOST_CONTROLLER_ID}, }; -static u8 st21nfcb_se_get_bwi(struct nci_dev *ndev) +static u8 st_nci_se_get_bwi(struct nci_dev *ndev) { int i; u8 td; - struct st21nfcb_nci_info *info = nci_get_drvdata(ndev); + struct st_nci_info *info = nci_get_drvdata(ndev); /* Bits 8 to 5 of the first TB for T=1 encode BWI from zero to nine */ - for (i = 1; i < ST21NFCB_ESE_MAX_LENGTH; i++) { - td = ST21NFCB_ATR_GET_Y_FROM_TD(info->se_info.atr[i]); - if (ST21NFCB_ATR_TA_PRESENT(td)) + for (i = 1; i < ST_NCI_ESE_MAX_LENGTH; i++) { + td = ST_NCI_ATR_GET_Y_FROM_TD(info->se_info.atr[i]); + if (ST_NCI_ATR_TA_PRESENT(td)) i++; - if (ST21NFCB_ATR_TB_PRESENT(td)) { + if (ST_NCI_ATR_TB_PRESENT(td)) { i++; return info->se_info.atr[i] >> 4; } } - return ST21NFCB_ATR_DEFAULT_BWI; + return ST_NCI_ATR_DEFAULT_BWI; } -static void st21nfcb_se_get_atr(struct nci_dev *ndev) +static void st_nci_se_get_atr(struct nci_dev *ndev) { - struct st21nfcb_nci_info *info = nci_get_drvdata(ndev); + struct st_nci_info *info = nci_get_drvdata(ndev); int r; struct sk_buff *skb; - r = nci_hci_get_param(ndev, ST21NFCB_APDU_READER_GATE, + r = nci_hci_get_param(ndev, ST_NCI_APDU_READER_GATE, NCI_HCI_APDU_PARAM_ATR, &skb); if (r < 0) return; - if (skb->len <= ST21NFCB_ESE_MAX_LENGTH) { + if (skb->len <= ST_NCI_ESE_MAX_LENGTH) { memcpy(info->se_info.atr, skb->data, skb->len); info->se_info.wt_timeout = - ST21NFCB_BWI_TO_TIMEOUT(st21nfcb_se_get_bwi(ndev)); + ST_NCI_BWI_TO_TIMEOUT(st_nci_se_get_bwi(ndev)); } kfree_skb(skb); } -int st21nfcb_hci_load_session(struct nci_dev *ndev) +int st_nci_hci_load_session(struct nci_dev *ndev) { int i, j, r; struct sk_buff *skb_pipe_list, *skb_pipe_info; - struct st21nfcb_pipe_info *dm_pipe_info; - u8 pipe_list[] = { ST21NFCB_DM_GETINFO_PIPE_LIST, - ST21NFCB_TERMINAL_HOST_ID}; - u8 pipe_info[] = { ST21NFCB_DM_GETINFO_PIPE_INFO, - ST21NFCB_TERMINAL_HOST_ID, 0}; + struct st_nci_pipe_info *dm_pipe_info; + u8 pipe_list[] = { ST_NCI_DM_GETINFO_PIPE_LIST, + ST_NCI_TERMINAL_HOST_ID}; + u8 pipe_info[] = { ST_NCI_DM_GETINFO_PIPE_INFO, + ST_NCI_TERMINAL_HOST_ID, 0}; - /* On ST21NFCB device pipes number are dynamics + /* On ST_NCI device pipes number are dynamics * If pipes are already created, hci_dev_up will fail. * Doing a clear all pipe is a bad idea because: * - It does useless EEPROM cycling * - It might cause issue for secure elements support * (such as removing connectivity or APDU reader pipe) - * A better approach on ST21NFCB is to: + * A better approach on ST_NCI is to: * - get a pipe list for each host. - * (eg: ST21NFCB_HOST_CONTROLLER_ID for now). + * (eg: ST_NCI_HOST_CONTROLLER_ID for now). * (TODO Later on UICC HOST and eSE HOST) * - get pipe information - * - match retrieved pipe list in st21nfcb_gates - * ST21NFCB_DEVICE_MGNT_GATE is a proprietary gate - * with ST21NFCB_DEVICE_MGNT_PIPE. + * - match retrieved pipe list in st_nci_gates + * ST_NCI_DEVICE_MGNT_GATE is a proprietary gate + * with ST_NCI_DEVICE_MGNT_PIPE. * Pipe can be closed and need to be open. */ - r = nci_hci_connect_gate(ndev, ST21NFCB_HOST_CONTROLLER_ID, - ST21NFCB_DEVICE_MGNT_GATE, - ST21NFCB_DEVICE_MGNT_PIPE); + r = nci_hci_connect_gate(ndev, ST_NCI_HOST_CONTROLLER_ID, + ST_NCI_DEVICE_MGNT_GATE, + ST_NCI_DEVICE_MGNT_PIPE); if (r < 0) goto free_info; /* Get pipe list */ - r = nci_hci_send_cmd(ndev, ST21NFCB_DEVICE_MGNT_GATE, - ST21NFCB_DM_GETINFO, pipe_list, sizeof(pipe_list), + r = nci_hci_send_cmd(ndev, ST_NCI_DEVICE_MGNT_GATE, + ST_NCI_DM_GETINFO, pipe_list, sizeof(pipe_list), &skb_pipe_list); if (r < 0) goto free_info; @@ -201,8 +201,8 @@ int st21nfcb_hci_load_session(struct nci_dev *ndev) /* Complete the existing gate_pipe table */ for (i = 0; i < skb_pipe_list->len; i++) { pipe_info[2] = skb_pipe_list->data[i]; - r = nci_hci_send_cmd(ndev, ST21NFCB_DEVICE_MGNT_GATE, - ST21NFCB_DM_GETINFO, pipe_info, + r = nci_hci_send_cmd(ndev, ST_NCI_DEVICE_MGNT_GATE, + ST_NCI_DM_GETINFO, pipe_info, sizeof(pipe_info), &skb_pipe_info); if (r) @@ -217,81 +217,81 @@ int st21nfcb_hci_load_session(struct nci_dev *ndev) * - destination hid (1byte) * - destination gid (1byte) */ - dm_pipe_info = (struct st21nfcb_pipe_info *)skb_pipe_info->data; - if (dm_pipe_info->dst_gate_id == ST21NFCB_APDU_READER_GATE && - dm_pipe_info->src_host_id != ST21NFCB_ESE_HOST_ID) { + dm_pipe_info = (struct st_nci_pipe_info *)skb_pipe_info->data; + if (dm_pipe_info->dst_gate_id == ST_NCI_APDU_READER_GATE && + dm_pipe_info->src_host_id != ST_NCI_ESE_HOST_ID) { pr_err("Unexpected apdu_reader pipe on host %x\n", dm_pipe_info->src_host_id); continue; } - for (j = 0; (j < ARRAY_SIZE(st21nfcb_gates)) && - (st21nfcb_gates[j].gate != dm_pipe_info->dst_gate_id); j++) + for (j = 0; (j < ARRAY_SIZE(st_nci_gates)) && + (st_nci_gates[j].gate != dm_pipe_info->dst_gate_id); j++) ; - if (j < ARRAY_SIZE(st21nfcb_gates) && - st21nfcb_gates[j].gate == dm_pipe_info->dst_gate_id && - ST21NFCB_DM_IS_PIPE_OPEN(dm_pipe_info->pipe_state)) { - st21nfcb_gates[j].pipe = pipe_info[2]; + if (j < ARRAY_SIZE(st_nci_gates) && + st_nci_gates[j].gate == dm_pipe_info->dst_gate_id && + ST_NCI_DM_IS_PIPE_OPEN(dm_pipe_info->pipe_state)) { + st_nci_gates[j].pipe = pipe_info[2]; - ndev->hci_dev->gate2pipe[st21nfcb_gates[j].gate] = - st21nfcb_gates[j].pipe; - ndev->hci_dev->pipes[st21nfcb_gates[j].pipe].gate = - st21nfcb_gates[j].gate; - ndev->hci_dev->pipes[st21nfcb_gates[j].pipe].host = + ndev->hci_dev->gate2pipe[st_nci_gates[j].gate] = + st_nci_gates[j].pipe; + ndev->hci_dev->pipes[st_nci_gates[j].pipe].gate = + st_nci_gates[j].gate; + ndev->hci_dev->pipes[st_nci_gates[j].pipe].host = dm_pipe_info->src_host_id; } } - memcpy(ndev->hci_dev->init_data.gates, st21nfcb_gates, - sizeof(st21nfcb_gates)); + memcpy(ndev->hci_dev->init_data.gates, st_nci_gates, + sizeof(st_nci_gates)); free_info: kfree_skb(skb_pipe_info); kfree_skb(skb_pipe_list); return r; } -EXPORT_SYMBOL_GPL(st21nfcb_hci_load_session); +EXPORT_SYMBOL_GPL(st_nci_hci_load_session); -static void st21nfcb_hci_admin_event_received(struct nci_dev *ndev, +static void st_nci_hci_admin_event_received(struct nci_dev *ndev, u8 event, struct sk_buff *skb) { - struct st21nfcb_nci_info *info = nci_get_drvdata(ndev); + struct st_nci_info *info = nci_get_drvdata(ndev); switch (event) { - case ST21NFCB_EVT_HOT_PLUG: + case ST_NCI_EVT_HOT_PLUG: if (info->se_info.se_active) { - if (!ST21NFCB_EVT_HOT_PLUG_IS_INHIBITED(skb)) { + if (!ST_NCI_EVT_HOT_PLUG_IS_INHIBITED(skb)) { del_timer_sync(&info->se_info.se_active_timer); info->se_info.se_active = false; complete(&info->se_info.req_completion); } else { mod_timer(&info->se_info.se_active_timer, jiffies + - msecs_to_jiffies(ST21NFCB_SE_TO_PIPES)); + msecs_to_jiffies(ST_NCI_SE_TO_PIPES)); } } break; } } -static int st21nfcb_hci_apdu_reader_event_received(struct nci_dev *ndev, +static int st_nci_hci_apdu_reader_event_received(struct nci_dev *ndev, u8 event, struct sk_buff *skb) { int r = 0; - struct st21nfcb_nci_info *info = nci_get_drvdata(ndev); + struct st_nci_info *info = nci_get_drvdata(ndev); pr_debug("apdu reader gate event: %x\n", event); switch (event) { - case ST21NFCB_EVT_TRANSMIT_DATA: + case ST_NCI_EVT_TRANSMIT_DATA: del_timer_sync(&info->se_info.bwi_timer); info->se_info.bwi_active = false; info->se_info.cb(info->se_info.cb_context, skb->data, skb->len, 0); break; - case ST21NFCB_EVT_WTX_REQUEST: + case ST_NCI_EVT_WTX_REQUEST: mod_timer(&info->se_info.bwi_timer, jiffies + msecs_to_jiffies(info->se_info.wt_timeout)); break; @@ -306,7 +306,7 @@ static int st21nfcb_hci_apdu_reader_event_received(struct nci_dev *ndev, * <= 0: driver handled the event, skb consumed * 1: driver does not handle the event, please do standard processing */ -static int st21nfcb_hci_connectivity_event_received(struct nci_dev *ndev, +static int st_nci_hci_connectivity_event_received(struct nci_dev *ndev, u8 host, u8 event, struct sk_buff *skb) { @@ -317,10 +317,10 @@ static int st21nfcb_hci_connectivity_event_received(struct nci_dev *ndev, pr_debug("connectivity gate event: %x\n", event); switch (event) { - case ST21NFCB_EVT_CONNECTIVITY: + case ST_NCI_EVT_CONNECTIVITY: break; - case ST21NFCB_EVT_TRANSACTION: + case ST_NCI_EVT_TRANSACTION: /* According to specification etsi 102 622 * 11.2.2.4 EVT_TRANSACTION Table 52 * Description Tag Length @@ -355,7 +355,7 @@ static int st21nfcb_hci_connectivity_event_received(struct nci_dev *ndev, return r; } -void st21nfcb_hci_event_received(struct nci_dev *ndev, u8 pipe, +void st_nci_hci_event_received(struct nci_dev *ndev, u8 pipe, u8 event, struct sk_buff *skb) { u8 gate = ndev->hci_dev->pipes[pipe].gate; @@ -363,32 +363,32 @@ void st21nfcb_hci_event_received(struct nci_dev *ndev, u8 pipe, switch (gate) { case NCI_HCI_ADMIN_GATE: - st21nfcb_hci_admin_event_received(ndev, event, skb); + st_nci_hci_admin_event_received(ndev, event, skb); break; - case ST21NFCB_APDU_READER_GATE: - st21nfcb_hci_apdu_reader_event_received(ndev, event, skb); + case ST_NCI_APDU_READER_GATE: + st_nci_hci_apdu_reader_event_received(ndev, event, skb); break; - case ST21NFCB_CONNECTIVITY_GATE: - st21nfcb_hci_connectivity_event_received(ndev, host, event, + case ST_NCI_CONNECTIVITY_GATE: + st_nci_hci_connectivity_event_received(ndev, host, event, skb); break; } } -EXPORT_SYMBOL_GPL(st21nfcb_hci_event_received); +EXPORT_SYMBOL_GPL(st_nci_hci_event_received); -void st21nfcb_hci_cmd_received(struct nci_dev *ndev, u8 pipe, u8 cmd, +void st_nci_hci_cmd_received(struct nci_dev *ndev, u8 pipe, u8 cmd, struct sk_buff *skb) { - struct st21nfcb_nci_info *info = nci_get_drvdata(ndev); + struct st_nci_info *info = nci_get_drvdata(ndev); u8 gate = ndev->hci_dev->pipes[pipe].gate; pr_debug("cmd: %x\n", cmd); switch (cmd) { case NCI_HCI_ANY_OPEN_PIPE: - if (gate != ST21NFCB_APDU_READER_GATE && - ndev->hci_dev->pipes[pipe].host != ST21NFCB_UICC_HOST_ID) + if (gate != ST_NCI_APDU_READER_GATE && + ndev->hci_dev->pipes[pipe].host != ST_NCI_UICC_HOST_ID) ndev->hci_dev->count_pipes++; if (ndev->hci_dev->count_pipes == @@ -401,28 +401,28 @@ void st21nfcb_hci_cmd_received(struct nci_dev *ndev, u8 pipe, u8 cmd, break; } } -EXPORT_SYMBOL_GPL(st21nfcb_hci_cmd_received); +EXPORT_SYMBOL_GPL(st_nci_hci_cmd_received); /* - * Remarks: On some early st21nfcb firmware, nci_nfcee_mode_set(0) + * Remarks: On some early st_nci firmware, nci_nfcee_mode_set(0) * is rejected */ -static int st21nfcb_nci_control_se(struct nci_dev *ndev, u8 se_idx, +static int st_nci_control_se(struct nci_dev *ndev, u8 se_idx, u8 state) { - struct st21nfcb_nci_info *info = nci_get_drvdata(ndev); + struct st_nci_info *info = nci_get_drvdata(ndev); int r; struct sk_buff *sk_host_list; u8 host_id; switch (se_idx) { - case ST21NFCB_UICC_HOST_ID: + case ST_NCI_UICC_HOST_ID: ndev->hci_dev->count_pipes = 0; - ndev->hci_dev->expected_pipes = ST21NFCB_SE_COUNT_PIPE_UICC; + ndev->hci_dev->expected_pipes = ST_NCI_SE_COUNT_PIPE_UICC; break; - case ST21NFCB_ESE_HOST_ID: + case ST_NCI_ESE_HOST_ID: ndev->hci_dev->count_pipes = 0; - ndev->hci_dev->expected_pipes = ST21NFCB_SE_COUNT_PIPE_EMBEDDED; + ndev->hci_dev->expected_pipes = ST_NCI_SE_COUNT_PIPE_EMBEDDED; break; default: return -EINVAL; @@ -438,7 +438,7 @@ static int st21nfcb_nci_control_se(struct nci_dev *ndev, u8 se_idx, return r; mod_timer(&info->se_info.se_active_timer, jiffies + - msecs_to_jiffies(ST21NFCB_SE_TO_HOT_PLUG)); + msecs_to_jiffies(ST_NCI_SE_TO_HOT_PLUG)); info->se_info.se_active = true; /* Ignore return value and check in any case the host_list */ @@ -458,49 +458,49 @@ static int st21nfcb_nci_control_se(struct nci_dev *ndev, u8 se_idx, host_id = sk_host_list->data[sk_host_list->len - 1]; kfree_skb(sk_host_list); - if (state == ST21NFCB_SE_MODE_ON && host_id == se_idx) + if (state == ST_NCI_SE_MODE_ON && host_id == se_idx) return se_idx; - else if (state == ST21NFCB_SE_MODE_OFF && host_id != se_idx) + else if (state == ST_NCI_SE_MODE_OFF && host_id != se_idx) return se_idx; return -1; } -int st21nfcb_nci_disable_se(struct nci_dev *ndev, u32 se_idx) +int st_nci_disable_se(struct nci_dev *ndev, u32 se_idx) { int r; - pr_debug("st21nfcb_nci_disable_se\n"); + pr_debug("st_nci_disable_se\n"); if (se_idx == NFC_SE_EMBEDDED) { - r = nci_hci_send_event(ndev, ST21NFCB_APDU_READER_GATE, - ST21NFCB_EVT_SE_END_OF_APDU_TRANSFER, NULL, 0); + r = nci_hci_send_event(ndev, ST_NCI_APDU_READER_GATE, + ST_NCI_EVT_SE_END_OF_APDU_TRANSFER, NULL, 0); if (r < 0) return r; } return 0; } -EXPORT_SYMBOL_GPL(st21nfcb_nci_disable_se); +EXPORT_SYMBOL_GPL(st_nci_disable_se); -int st21nfcb_nci_enable_se(struct nci_dev *ndev, u32 se_idx) +int st_nci_enable_se(struct nci_dev *ndev, u32 se_idx) { int r; - pr_debug("st21nfcb_nci_enable_se\n"); + pr_debug("st_nci_enable_se\n"); - if (se_idx == ST21NFCB_HCI_HOST_ID_ESE) { - r = nci_hci_send_event(ndev, ST21NFCB_APDU_READER_GATE, - ST21NFCB_EVT_SE_SOFT_RESET, NULL, 0); + if (se_idx == ST_NCI_HCI_HOST_ID_ESE) { + r = nci_hci_send_event(ndev, ST_NCI_APDU_READER_GATE, + ST_NCI_EVT_SE_SOFT_RESET, NULL, 0); if (r < 0) return r; } return 0; } -EXPORT_SYMBOL_GPL(st21nfcb_nci_enable_se); +EXPORT_SYMBOL_GPL(st_nci_enable_se); -static int st21nfcb_hci_network_init(struct nci_dev *ndev) +static int st_nci_hci_network_init(struct nci_dev *ndev) { struct core_conn_create_dest_spec_params *dest_params; struct dest_spec_params spec_params; @@ -519,7 +519,8 @@ static int st21nfcb_hci_network_init(struct nci_dev *ndev) dest_params->length = sizeof(struct dest_spec_params); spec_params.id = ndev->hci_dev->nfcee_id; spec_params.protocol = NCI_NFCEE_INTERFACE_HCI_ACCESS; - memcpy(dest_params->value, &spec_params, sizeof(struct dest_spec_params)); + memcpy(dest_params->value, &spec_params, + sizeof(struct dest_spec_params)); r = nci_core_conn_create(ndev, NCI_DESTINATION_NFCEE, 1, sizeof(struct core_conn_create_dest_spec_params) + sizeof(struct dest_spec_params), @@ -531,15 +532,15 @@ static int st21nfcb_hci_network_init(struct nci_dev *ndev) if (!conn_info) goto free_dest_params; - memcpy(ndev->hci_dev->init_data.gates, st21nfcb_gates, - sizeof(st21nfcb_gates)); + memcpy(ndev->hci_dev->init_data.gates, st_nci_gates, + sizeof(st_nci_gates)); /* * Session id must include the driver name + i2c bus addr * persistent info to discriminate 2 identical chips */ - dev_num = find_first_zero_bit(dev_mask, ST21NFCB_NUM_DEVICES); - if (dev_num >= ST21NFCB_NUM_DEVICES) { + dev_num = find_first_zero_bit(dev_mask, ST_NCI_NUM_DEVICES); + if (dev_num >= ST_NCI_NUM_DEVICES) { r = -ENODEV; goto free_dest_params; } @@ -564,72 +565,72 @@ exit: return r; } -int st21nfcb_nci_discover_se(struct nci_dev *ndev) +int st_nci_discover_se(struct nci_dev *ndev) { u8 param[2]; int r; int se_count = 0; - pr_debug("st21nfcb_nci_discover_se\n"); + pr_debug("st_nci_discover_se\n"); - r = st21nfcb_hci_network_init(ndev); + r = st_nci_hci_network_init(ndev); if (r != 0) return r; - param[0] = ST21NFCB_UICC_HOST_ID; - param[1] = ST21NFCB_HCI_HOST_ID_ESE; + param[0] = ST_NCI_UICC_HOST_ID; + param[1] = ST_NCI_HCI_HOST_ID_ESE; r = nci_hci_set_param(ndev, NCI_HCI_ADMIN_GATE, NCI_HCI_ADMIN_PARAM_WHITELIST, param, sizeof(param)); if (r != NCI_HCI_ANY_OK) return r; - r = st21nfcb_nci_control_se(ndev, ST21NFCB_UICC_HOST_ID, - ST21NFCB_SE_MODE_ON); - if (r == ST21NFCB_UICC_HOST_ID) { - nfc_add_se(ndev->nfc_dev, ST21NFCB_UICC_HOST_ID, NFC_SE_UICC); + r = st_nci_control_se(ndev, ST_NCI_UICC_HOST_ID, + ST_NCI_SE_MODE_ON); + if (r == ST_NCI_UICC_HOST_ID) { + nfc_add_se(ndev->nfc_dev, ST_NCI_UICC_HOST_ID, NFC_SE_UICC); se_count++; } /* Try to enable eSE in order to check availability */ - r = st21nfcb_nci_control_se(ndev, ST21NFCB_HCI_HOST_ID_ESE, - ST21NFCB_SE_MODE_ON); - if (r == ST21NFCB_HCI_HOST_ID_ESE) { - nfc_add_se(ndev->nfc_dev, ST21NFCB_HCI_HOST_ID_ESE, + r = st_nci_control_se(ndev, ST_NCI_HCI_HOST_ID_ESE, + ST_NCI_SE_MODE_ON); + if (r == ST_NCI_HCI_HOST_ID_ESE) { + nfc_add_se(ndev->nfc_dev, ST_NCI_HCI_HOST_ID_ESE, NFC_SE_EMBEDDED); se_count++; - st21nfcb_se_get_atr(ndev); + st_nci_se_get_atr(ndev); } return !se_count; } -EXPORT_SYMBOL_GPL(st21nfcb_nci_discover_se); +EXPORT_SYMBOL_GPL(st_nci_discover_se); -int st21nfcb_nci_se_io(struct nci_dev *ndev, u32 se_idx, +int st_nci_se_io(struct nci_dev *ndev, u32 se_idx, u8 *apdu, size_t apdu_length, se_io_cb_t cb, void *cb_context) { - struct st21nfcb_nci_info *info = nci_get_drvdata(ndev); + struct st_nci_info *info = nci_get_drvdata(ndev); pr_debug("\n"); switch (se_idx) { - case ST21NFCB_HCI_HOST_ID_ESE: + case ST_NCI_HCI_HOST_ID_ESE: info->se_info.cb = cb; info->se_info.cb_context = cb_context; mod_timer(&info->se_info.bwi_timer, jiffies + msecs_to_jiffies(info->se_info.wt_timeout)); info->se_info.bwi_active = true; - return nci_hci_send_event(ndev, ST21NFCB_APDU_READER_GATE, - ST21NFCB_EVT_TRANSMIT_DATA, apdu, + return nci_hci_send_event(ndev, ST_NCI_APDU_READER_GATE, + ST_NCI_EVT_TRANSMIT_DATA, apdu, apdu_length); default: return -ENODEV; } } -EXPORT_SYMBOL(st21nfcb_nci_se_io); +EXPORT_SYMBOL(st_nci_se_io); -static void st21nfcb_se_wt_timeout(unsigned long data) +static void st_nci_se_wt_timeout(unsigned long data) { /* * No answer from the secure element @@ -642,7 +643,7 @@ static void st21nfcb_se_wt_timeout(unsigned long data) */ /* hardware reset managed through VCC_UICC_OUT power supply */ u8 param = 0x01; - struct st21nfcb_nci_info *info = (struct st21nfcb_nci_info *) data; + struct st_nci_info *info = (struct st_nci_info *) data; pr_debug("\n"); @@ -650,19 +651,19 @@ static void st21nfcb_se_wt_timeout(unsigned long data) if (!info->se_info.xch_error) { info->se_info.xch_error = true; - nci_hci_send_event(info->ndlc->ndev, ST21NFCB_APDU_READER_GATE, - ST21NFCB_EVT_SE_SOFT_RESET, NULL, 0); + nci_hci_send_event(info->ndlc->ndev, ST_NCI_APDU_READER_GATE, + ST_NCI_EVT_SE_SOFT_RESET, NULL, 0); } else { info->se_info.xch_error = false; - nci_hci_send_event(info->ndlc->ndev, ST21NFCB_DEVICE_MGNT_GATE, - ST21NFCB_EVT_SE_HARD_RESET, ¶m, 1); + nci_hci_send_event(info->ndlc->ndev, ST_NCI_DEVICE_MGNT_GATE, + ST_NCI_EVT_SE_HARD_RESET, ¶m, 1); } info->se_info.cb(info->se_info.cb_context, NULL, 0, -ETIME); } -static void st21nfcb_se_activation_timeout(unsigned long data) +static void st_nci_se_activation_timeout(unsigned long data) { - struct st21nfcb_nci_info *info = (struct st21nfcb_nci_info *) data; + struct st_nci_info *info = (struct st_nci_info *) data; pr_debug("\n"); @@ -671,35 +672,35 @@ static void st21nfcb_se_activation_timeout(unsigned long data) complete(&info->se_info.req_completion); } -int st21nfcb_se_init(struct nci_dev *ndev) +int st_nci_se_init(struct nci_dev *ndev) { - struct st21nfcb_nci_info *info = nci_get_drvdata(ndev); + struct st_nci_info *info = nci_get_drvdata(ndev); init_completion(&info->se_info.req_completion); /* initialize timers */ init_timer(&info->se_info.bwi_timer); info->se_info.bwi_timer.data = (unsigned long)info; - info->se_info.bwi_timer.function = st21nfcb_se_wt_timeout; + info->se_info.bwi_timer.function = st_nci_se_wt_timeout; info->se_info.bwi_active = false; init_timer(&info->se_info.se_active_timer); info->se_info.se_active_timer.data = (unsigned long)info; info->se_info.se_active_timer.function = - st21nfcb_se_activation_timeout; + st_nci_se_activation_timeout; info->se_info.se_active = false; info->se_info.xch_error = false; info->se_info.wt_timeout = - ST21NFCB_BWI_TO_TIMEOUT(ST21NFCB_ATR_DEFAULT_BWI); + ST_NCI_BWI_TO_TIMEOUT(ST_NCI_ATR_DEFAULT_BWI); return 0; } -EXPORT_SYMBOL(st21nfcb_se_init); +EXPORT_SYMBOL(st_nci_se_init); -void st21nfcb_se_deinit(struct nci_dev *ndev) +void st_nci_se_deinit(struct nci_dev *ndev) { - struct st21nfcb_nci_info *info = nci_get_drvdata(ndev); + struct st_nci_info *info = nci_get_drvdata(ndev); if (info->se_info.bwi_active) del_timer_sync(&info->se_info.bwi_timer); @@ -709,5 +710,5 @@ void st21nfcb_se_deinit(struct nci_dev *ndev) info->se_info.se_active = false; info->se_info.bwi_active = false; } -EXPORT_SYMBOL(st21nfcb_se_deinit); +EXPORT_SYMBOL(st_nci_se_deinit); diff --git a/drivers/nfc/st-nci/st-nci_se.h b/drivers/nfc/st-nci/st-nci_se.h new file mode 100644 index 0000000..ea66e87 --- /dev/null +++ b/drivers/nfc/st-nci/st-nci_se.h @@ -0,0 +1,61 @@ +/* + * Secure Element Driver for STMicroelectronics NFC NCI Chip + * + * Copyright (C) 2014-2015 STMicroelectronics SAS. 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, see <http://www.gnu.org/licenses/>. + */ +#ifndef __LOCAL_ST_NCI_SE_H_ +#define __LOCAL_ST_NCI_SE_H_ + +/* + * ref ISO7816-3 chap 8.1. the initial character TS is followed by a + * sequence of at most 32 characters. + */ +#define ST_NCI_ESE_MAX_LENGTH 33 +#define ST_NCI_HCI_HOST_ID_ESE 0xc0 + +struct st_nci_se_info { + u8 atr[ST_NCI_ESE_MAX_LENGTH]; + struct completion req_completion; + + struct timer_list bwi_timer; + int wt_timeout; /* in msecs */ + bool bwi_active; + + struct timer_list se_active_timer; + bool se_active; + + bool xch_error; + + se_io_cb_t cb; + void *cb_context; +}; + +int st_nci_se_init(struct nci_dev *ndev); +void st_nci_se_deinit(struct nci_dev *ndev); + +int st_nci_discover_se(struct nci_dev *ndev); +int st_nci_enable_se(struct nci_dev *ndev, u32 se_idx); +int st_nci_disable_se(struct nci_dev *ndev, u32 se_idx); +int st_nci_se_io(struct nci_dev *ndev, u32 se_idx, + u8 *apdu, size_t apdu_length, + se_io_cb_t cb, void *cb_context); +int st_nci_hci_load_session(struct nci_dev *ndev); +void st_nci_hci_event_received(struct nci_dev *ndev, u8 pipe, + u8 event, struct sk_buff *skb); +void st_nci_hci_cmd_received(struct nci_dev *ndev, u8 pipe, u8 cmd, + struct sk_buff *skb); + + +#endif /* __LOCAL_ST_NCI_SE_H_ */ diff --git a/drivers/nfc/st21nfcb/Kconfig b/drivers/nfc/st21nfcb/Kconfig deleted file mode 100644 index e0322dd..0000000 --- a/drivers/nfc/st21nfcb/Kconfig +++ /dev/null @@ -1,22 +0,0 @@ -config NFC_ST21NFCB - tristate "STMicroelectronics ST21NFCB NFC driver" - depends on NFC_NCI - default n - ---help--- - STMicroelectronics ST21NFCB core driver. It implements the chipset - NCI logic and hooks into the NFC kernel APIs. Physical layers will - register against it. - - To compile this driver as a module, choose m here. The module will - be called st21nfcb. - Say N if unsure. - -config NFC_ST21NFCB_I2C - tristate "NFC ST21NFCB i2c support" - depends on NFC_ST21NFCB && I2C - ---help--- - This module adds support for the STMicroelectronics st21nfcb i2c interface. - Select this if your platform is using the i2c bus. - - If you choose to build a module, it'll be called st21nfcb_i2c. - Say N if unsure. diff --git a/drivers/nfc/st21nfcb/Makefile b/drivers/nfc/st21nfcb/Makefile deleted file mode 100644 index ce659a9..0000000 --- a/drivers/nfc/st21nfcb/Makefile +++ /dev/null @@ -1,9 +0,0 @@ -# -# Makefile for ST21NFCB NCI based NFC driver -# - -st21nfcb_nci-objs = ndlc.o st21nfcb.o st21nfcb_se.o -obj-$(CONFIG_NFC_ST21NFCB) += st21nfcb_nci.o - -st21nfcb_i2c-objs = i2c.o -obj-$(CONFIG_NFC_ST21NFCB_I2C) += st21nfcb_i2c.o diff --git a/drivers/nfc/st21nfcb/st21nfcb.c b/drivers/nfc/st21nfcb/st21nfcb.c deleted file mode 100644 index a16c3a3..0000000 --- a/drivers/nfc/st21nfcb/st21nfcb.c +++ /dev/null @@ -1,179 +0,0 @@ -/* - * NCI based Driver for STMicroelectronics NFC Chip - * - * Copyright (C) 2014 STMicroelectronics SAS. 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, see <http://www.gnu.org/licenses/>. - */ - -#include <linux/module.h> -#include <linux/nfc.h> -#include <net/nfc/nci.h> -#include <net/nfc/nci_core.h> -#include <linux/gpio.h> -#include <linux/delay.h> - -#include "st21nfcb.h" -#include "st21nfcb_se.h" - -#define DRIVER_DESC "NCI NFC driver for ST21NFCB" - -#define ST21NFCB_NCI1_X_PROPRIETARY_ISO15693 0x83 - -static int st21nfcb_nci_init(struct nci_dev *ndev) -{ - struct nci_mode_set_cmd cmd; - - cmd.cmd_type = ST21NFCB_NCI_SET_NFC_MODE; - cmd.mode = 1; - - return nci_prop_cmd(ndev, ST21NFCB_NCI_CORE_PROP, - sizeof(struct nci_mode_set_cmd), (__u8 *)&cmd); -} - -static int st21nfcb_nci_open(struct nci_dev *ndev) -{ - struct st21nfcb_nci_info *info = nci_get_drvdata(ndev); - int r; - - if (test_and_set_bit(ST21NFCB_NCI_RUNNING, &info->flags)) - return 0; - - r = ndlc_open(info->ndlc); - if (r) - clear_bit(ST21NFCB_NCI_RUNNING, &info->flags); - - return r; -} - -static int st21nfcb_nci_close(struct nci_dev *ndev) -{ - struct st21nfcb_nci_info *info = nci_get_drvdata(ndev); - - if (!test_bit(ST21NFCB_NCI_RUNNING, &info->flags)) - return 0; - - ndlc_close(info->ndlc); - - clear_bit(ST21NFCB_NCI_RUNNING, &info->flags); - - return 0; -} - -static int st21nfcb_nci_send(struct nci_dev *ndev, struct sk_buff *skb) -{ - struct st21nfcb_nci_info *info = nci_get_drvdata(ndev); - - skb->dev = (void *)ndev; - - if (!test_bit(ST21NFCB_NCI_RUNNING, &info->flags)) - return -EBUSY; - - return ndlc_send(info->ndlc, skb); -} - -static __u32 st21nfcb_nci_get_rfprotocol(struct nci_dev *ndev, - __u8 rf_protocol) -{ - return rf_protocol == ST21NFCB_NCI1_X_PROPRIETARY_ISO15693 ? - NFC_PROTO_ISO15693_MASK : 0; -} - -static int st21nfcb_nci_prop_rsp_packet(struct nci_dev *ndev, - struct sk_buff *skb) -{ - __u8 status = skb->data[0]; - - nci_req_complete(ndev, status); - return 0; -} - -static struct nci_prop_ops st21nfcb_nci_prop_ops[] = { - { - .opcode = nci_opcode_pack(NCI_GID_PROPRIETARY, - ST21NFCB_NCI_CORE_PROP), - .rsp = st21nfcb_nci_prop_rsp_packet, - }, -}; - -static struct nci_ops st21nfcb_nci_ops = { - .init = st21nfcb_nci_init, - .open = st21nfcb_nci_open, - .close = st21nfcb_nci_close, - .send = st21nfcb_nci_send, - .get_rfprotocol = st21nfcb_nci_get_rfprotocol, - .discover_se = st21nfcb_nci_discover_se, - .enable_se = st21nfcb_nci_enable_se, - .disable_se = st21nfcb_nci_disable_se, - .se_io = st21nfcb_nci_se_io, - .hci_load_session = st21nfcb_hci_load_session, - .hci_event_received = st21nfcb_hci_event_received, - .hci_cmd_received = st21nfcb_hci_cmd_received, - .prop_ops = st21nfcb_nci_prop_ops, - .n_prop_ops = ARRAY_SIZE(st21nfcb_nci_prop_ops), -}; - -int st21nfcb_nci_probe(struct llt_ndlc *ndlc, int phy_headroom, - int phy_tailroom) -{ - struct st21nfcb_nci_info *info; - int r; - u32 protocols; - - info = devm_kzalloc(ndlc->dev, - sizeof(struct st21nfcb_nci_info), GFP_KERNEL); - if (!info) - return -ENOMEM; - - protocols = NFC_PROTO_JEWEL_MASK - | NFC_PROTO_MIFARE_MASK - | NFC_PROTO_FELICA_MASK - | NFC_PROTO_ISO14443_MASK - | NFC_PROTO_ISO14443_B_MASK - | NFC_PROTO_ISO15693_MASK - | NFC_PROTO_NFC_DEP_MASK; - - ndlc->ndev = nci_allocate_device(&st21nfcb_nci_ops, protocols, - phy_headroom, phy_tailroom); - if (!ndlc->ndev) { - pr_err("Cannot allocate nfc ndev\n"); - return -ENOMEM; - } - info->ndlc = ndlc; - - nci_set_drvdata(ndlc->ndev, info); - - r = nci_register_device(ndlc->ndev); - if (r) { - pr_err("Cannot register nfc device to nci core\n"); - nci_free_device(ndlc->ndev); - return r; - } - - return st21nfcb_se_init(ndlc->ndev); -} -EXPORT_SYMBOL_GPL(st21nfcb_nci_probe); - -void st21nfcb_nci_remove(struct nci_dev *ndev) -{ - struct st21nfcb_nci_info *info = nci_get_drvdata(ndev); - - ndlc_close(info->ndlc); - - nci_unregister_device(ndev); - nci_free_device(ndev); -} -EXPORT_SYMBOL_GPL(st21nfcb_nci_remove); - -MODULE_LICENSE("GPL"); -MODULE_DESCRIPTION(DRIVER_DESC); diff --git a/drivers/nfc/st21nfcb/st21nfcb_se.h b/drivers/nfc/st21nfcb/st21nfcb_se.h deleted file mode 100644 index 52a3238..0000000 --- a/drivers/nfc/st21nfcb/st21nfcb_se.h +++ /dev/null @@ -1,61 +0,0 @@ -/* - * NCI based Driver for STMicroelectronics NFC Chip - * - * Copyright (C) 2014 STMicroelectronics SAS. 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, see <http://www.gnu.org/licenses/>. - */ -#ifndef __LOCAL_ST21NFCB_SE_H_ -#define __LOCAL_ST21NFCB_SE_H_ - -/* - * ref ISO7816-3 chap 8.1. the initial character TS is followed by a - * sequence of at most 32 characters. - */ -#define ST21NFCB_ESE_MAX_LENGTH 33 -#define ST21NFCB_HCI_HOST_ID_ESE 0xc0 - -struct st21nfcb_se_info { - u8 atr[ST21NFCB_ESE_MAX_LENGTH]; - struct completion req_completion; - - struct timer_list bwi_timer; - int wt_timeout; /* in msecs */ - bool bwi_active; - - struct timer_list se_active_timer; - bool se_active; - - bool xch_error; - - se_io_cb_t cb; - void *cb_context; -}; - -int st21nfcb_se_init(struct nci_dev *ndev); -void st21nfcb_se_deinit(struct nci_dev *ndev); - -int st21nfcb_nci_discover_se(struct nci_dev *ndev); -int st21nfcb_nci_enable_se(struct nci_dev *ndev, u32 se_idx); -int st21nfcb_nci_disable_se(struct nci_dev *ndev, u32 se_idx); -int st21nfcb_nci_se_io(struct nci_dev *ndev, u32 se_idx, - u8 *apdu, size_t apdu_length, - se_io_cb_t cb, void *cb_context); -int st21nfcb_hci_load_session(struct nci_dev *ndev); -void st21nfcb_hci_event_received(struct nci_dev *ndev, u8 pipe, - u8 event, struct sk_buff *skb); -void st21nfcb_hci_cmd_received(struct nci_dev *ndev, u8 pipe, u8 cmd, - struct sk_buff *skb); - - -#endif /* __LOCAL_ST21NFCB_NCI_H_ */ diff --git a/include/linux/platform_data/st21nfcb.h b/include/linux/platform_data/st-nci.h index b023373..d9d400a 100644 --- a/include/linux/platform_data/st21nfcb.h +++ b/include/linux/platform_data/st-nci.h @@ -1,7 +1,7 @@ /* - * Driver include for the ST21NFCB NFC chip. + * Driver include for ST NCI NFC chip family. * - * Copyright (C) 2014 STMicroelectronics SAS. All rights reserved. + * Copyright (C) 2014-2015 STMicroelectronics SAS. 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, @@ -16,14 +16,14 @@ * along with this program; if not, see <http://www.gnu.org/licenses/>. */ -#ifndef _ST21NFCB_NCI_H_ -#define _ST21NFCB_NCI_H_ +#ifndef _ST_NCI_H_ +#define _ST_NCI_H_ -#define ST21NFCB_NCI_DRIVER_NAME "st21nfcb_nci" +#define ST_NCI_DRIVER_NAME "st_nci" -struct st21nfcb_nfc_platform_data { +struct st_nci_nfc_platform_data { unsigned int gpio_reset; unsigned int irq_polarity; }; -#endif /* _ST21NFCB_NCI_H_ */ +#endif /* _ST_NCI_H_ */ diff --git a/include/linux/platform_data/st_nci.h b/include/linux/platform_data/st_nci.h new file mode 100644 index 0000000..d9d400a --- /dev/null +++ b/include/linux/platform_data/st_nci.h @@ -0,0 +1,29 @@ +/* + * Driver include for ST NCI NFC chip family. + * + * Copyright (C) 2014-2015 STMicroelectronics SAS. 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, see <http://www.gnu.org/licenses/>. + */ + +#ifndef _ST_NCI_H_ +#define _ST_NCI_H_ + +#define ST_NCI_DRIVER_NAME "st_nci" + +struct st_nci_nfc_platform_data { + unsigned int gpio_reset; + unsigned int irq_polarity; +}; + +#endif /* _ST_NCI_H_ */ |