1 /* 2 * Marvell NFC driver: major functions 3 * 4 * Copyright (C) 2014, Marvell International Ltd. 5 * 6 * This software file (the "File") is distributed by Marvell International 7 * Ltd. under the terms of the GNU General Public License Version 2, June 1991 8 * (the "License"). You may use, redistribute and/or modify this File in 9 * accordance with the terms and conditions of the License, a copy of which 10 * is available on the worldwide web at 11 * http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt. 12 * 13 * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE 14 * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE 15 * ARE EXPRESSLY DISCLAIMED. The License provides additional details about 16 * this warranty disclaimer. 17 */ 18 19 #include <linux/module.h> 20 #include <linux/gpio.h> 21 #include <linux/delay.h> 22 #include <linux/of_gpio.h> 23 #include <linux/nfc.h> 24 #include <net/nfc/nci.h> 25 #include <net/nfc/nci_core.h> 26 #include "nfcmrvl.h" 27 28 #define VERSION "1.0" 29 30 static int nfcmrvl_nci_open(struct nci_dev *ndev) 31 { 32 struct nfcmrvl_private *priv = nci_get_drvdata(ndev); 33 int err; 34 35 if (test_and_set_bit(NFCMRVL_NCI_RUNNING, &priv->flags)) 36 return 0; 37 38 err = priv->if_ops->nci_open(priv); 39 40 if (err) 41 clear_bit(NFCMRVL_NCI_RUNNING, &priv->flags); 42 43 return err; 44 } 45 46 static int nfcmrvl_nci_close(struct nci_dev *ndev) 47 { 48 struct nfcmrvl_private *priv = nci_get_drvdata(ndev); 49 50 if (!test_and_clear_bit(NFCMRVL_NCI_RUNNING, &priv->flags)) 51 return 0; 52 53 priv->if_ops->nci_close(priv); 54 55 return 0; 56 } 57 58 static int nfcmrvl_nci_send(struct nci_dev *ndev, struct sk_buff *skb) 59 { 60 struct nfcmrvl_private *priv = nci_get_drvdata(ndev); 61 62 nfc_info(priv->dev, "send entry, len %d\n", skb->len); 63 64 skb->dev = (void *)ndev; 65 66 if (!test_bit(NFCMRVL_NCI_RUNNING, &priv->flags)) 67 return -EBUSY; 68 69 if (priv->config.hci_muxed) { 70 unsigned char *hdr; 71 unsigned char len = skb->len; 72 73 hdr = (char *) skb_push(skb, NFCMRVL_HCI_EVENT_HEADER_SIZE); 74 hdr[0] = NFCMRVL_HCI_COMMAND_CODE; 75 hdr[1] = NFCMRVL_HCI_OGF; 76 hdr[2] = NFCMRVL_HCI_OCF; 77 hdr[3] = len; 78 } 79 80 return priv->if_ops->nci_send(priv, skb); 81 } 82 83 static int nfcmrvl_nci_setup(struct nci_dev *ndev) 84 { 85 __u8 val = 1; 86 87 nci_set_config(ndev, NFCMRVL_PB_BAIL_OUT, 1, &val); 88 return 0; 89 } 90 91 static struct nci_ops nfcmrvl_nci_ops = { 92 .open = nfcmrvl_nci_open, 93 .close = nfcmrvl_nci_close, 94 .send = nfcmrvl_nci_send, 95 .setup = nfcmrvl_nci_setup, 96 }; 97 98 struct nfcmrvl_private *nfcmrvl_nci_register_dev(void *drv_data, 99 struct nfcmrvl_if_ops *ops, 100 struct device *dev, 101 struct nfcmrvl_platform_data *pdata) 102 { 103 struct nfcmrvl_private *priv; 104 int rc; 105 int headroom = 0; 106 u32 protocols; 107 108 priv = kzalloc(sizeof(*priv), GFP_KERNEL); 109 if (!priv) 110 return ERR_PTR(-ENOMEM); 111 112 priv->drv_data = drv_data; 113 priv->if_ops = ops; 114 priv->dev = dev; 115 116 memcpy(&priv->config, pdata, sizeof(*pdata)); 117 118 if (priv->config.reset_n_io) { 119 rc = devm_gpio_request_one(dev, 120 priv->config.reset_n_io, 121 GPIOF_OUT_INIT_LOW, 122 "nfcmrvl_reset_n"); 123 if (rc < 0) 124 nfc_err(dev, "failed to request reset_n io\n"); 125 } 126 127 if (priv->config.hci_muxed) 128 headroom = NFCMRVL_HCI_EVENT_HEADER_SIZE; 129 130 protocols = NFC_PROTO_JEWEL_MASK 131 | NFC_PROTO_MIFARE_MASK 132 | NFC_PROTO_FELICA_MASK 133 | NFC_PROTO_ISO14443_MASK 134 | NFC_PROTO_ISO14443_B_MASK 135 | NFC_PROTO_ISO15693_MASK 136 | NFC_PROTO_NFC_DEP_MASK; 137 138 priv->ndev = nci_allocate_device(&nfcmrvl_nci_ops, protocols, 139 headroom, 0); 140 if (!priv->ndev) { 141 nfc_err(dev, "nci_allocate_device failed\n"); 142 rc = -ENOMEM; 143 goto error; 144 } 145 146 nci_set_drvdata(priv->ndev, priv); 147 148 nfcmrvl_chip_reset(priv); 149 150 rc = nci_register_device(priv->ndev); 151 if (rc) { 152 nfc_err(dev, "nci_register_device failed %d\n", rc); 153 nci_free_device(priv->ndev); 154 goto error; 155 } 156 157 nfc_info(dev, "registered with nci successfully\n"); 158 return priv; 159 160 error: 161 kfree(priv); 162 return ERR_PTR(rc); 163 } 164 EXPORT_SYMBOL_GPL(nfcmrvl_nci_register_dev); 165 166 void nfcmrvl_nci_unregister_dev(struct nfcmrvl_private *priv) 167 { 168 struct nci_dev *ndev = priv->ndev; 169 170 nci_unregister_device(ndev); 171 nci_free_device(ndev); 172 kfree(priv); 173 } 174 EXPORT_SYMBOL_GPL(nfcmrvl_nci_unregister_dev); 175 176 int nfcmrvl_nci_recv_frame(struct nfcmrvl_private *priv, struct sk_buff *skb) 177 { 178 if (priv->config.hci_muxed) { 179 if (skb->data[0] == NFCMRVL_HCI_EVENT_CODE && 180 skb->data[1] == NFCMRVL_HCI_NFC_EVENT_CODE) { 181 /* Data packet, let's extract NCI payload */ 182 skb_pull(skb, NFCMRVL_HCI_EVENT_HEADER_SIZE); 183 } else { 184 /* Skip this packet */ 185 kfree_skb(skb); 186 return 0; 187 } 188 } 189 190 if (test_bit(NFCMRVL_NCI_RUNNING, &priv->flags)) 191 nci_recv_frame(priv->ndev, skb); 192 else { 193 /* Drop this packet since nobody wants it */ 194 kfree_skb(skb); 195 return 0; 196 } 197 198 return 0; 199 } 200 EXPORT_SYMBOL_GPL(nfcmrvl_nci_recv_frame); 201 202 void nfcmrvl_chip_reset(struct nfcmrvl_private *priv) 203 { 204 /* 205 * This function does not take care if someone is using the device. 206 * To be improved. 207 */ 208 209 if (priv->config.reset_n_io) { 210 nfc_info(priv->dev, "reset the chip\n"); 211 gpio_set_value(priv->config.reset_n_io, 0); 212 usleep_range(5000, 10000); 213 gpio_set_value(priv->config.reset_n_io, 1); 214 } else 215 nfc_info(priv->dev, "no reset available on this interface\n"); 216 } 217 218 #ifdef CONFIG_OF 219 220 int nfcmrvl_parse_dt(struct device_node *node, 221 struct nfcmrvl_platform_data *pdata) 222 { 223 int reset_n_io; 224 225 reset_n_io = of_get_named_gpio(node, "reset-n-io", 0); 226 if (reset_n_io < 0) { 227 pr_info("no reset-n-io config\n"); 228 reset_n_io = 0; 229 } else if (!gpio_is_valid(reset_n_io)) { 230 pr_err("invalid reset-n-io GPIO\n"); 231 return reset_n_io; 232 } 233 pdata->reset_n_io = reset_n_io; 234 235 if (of_find_property(node, "hci-muxed", NULL)) 236 pdata->hci_muxed = 1; 237 else 238 pdata->hci_muxed = 0; 239 240 return 0; 241 } 242 243 #else 244 245 int nfcmrvl_parse_dt(struct device_node *node, 246 struct nfcmrvl_platform_data *pdata) 247 { 248 return -ENODEV; 249 } 250 251 #endif 252 EXPORT_SYMBOL_GPL(nfcmrvl_parse_dt); 253 254 MODULE_AUTHOR("Marvell International Ltd."); 255 MODULE_DESCRIPTION("Marvell NFC driver ver " VERSION); 256 MODULE_VERSION(VERSION); 257 MODULE_LICENSE("GPL v2"); 258