Add the rt linux 4.1.3-rt3 as base
[kvmfornfv.git] / kernel / drivers / nfc / nfcmrvl / main.c
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/nfc.h>
21 #include <net/nfc/nci.h>
22 #include <net/nfc/nci_core.h>
23 #include "nfcmrvl.h"
24
25 #define VERSION "1.0"
26
27 static int nfcmrvl_nci_open(struct nci_dev *ndev)
28 {
29         struct nfcmrvl_private *priv = nci_get_drvdata(ndev);
30         int err;
31
32         if (test_and_set_bit(NFCMRVL_NCI_RUNNING, &priv->flags))
33                 return 0;
34
35         err = priv->if_ops->nci_open(priv);
36
37         if (err)
38                 clear_bit(NFCMRVL_NCI_RUNNING, &priv->flags);
39
40         return err;
41 }
42
43 static int nfcmrvl_nci_close(struct nci_dev *ndev)
44 {
45         struct nfcmrvl_private *priv = nci_get_drvdata(ndev);
46
47         if (!test_and_clear_bit(NFCMRVL_NCI_RUNNING, &priv->flags))
48                 return 0;
49
50         priv->if_ops->nci_close(priv);
51
52         return 0;
53 }
54
55 static int nfcmrvl_nci_send(struct nci_dev *ndev, struct sk_buff *skb)
56 {
57         struct nfcmrvl_private *priv = nci_get_drvdata(ndev);
58
59         nfc_info(priv->dev, "send entry, len %d\n", skb->len);
60
61         skb->dev = (void *)ndev;
62
63         if (!test_bit(NFCMRVL_NCI_RUNNING, &priv->flags))
64                 return -EBUSY;
65
66         return priv->if_ops->nci_send(priv, skb);
67 }
68
69 static int nfcmrvl_nci_setup(struct nci_dev *ndev)
70 {
71         __u8 val;
72
73         val = NFCMRVL_GPIO_PIN_NFC_NOT_ALLOWED;
74         nci_set_config(ndev, NFCMRVL_NOT_ALLOWED_ID, 1, &val);
75         val = NFCMRVL_GPIO_PIN_NFC_ACTIVE;
76         nci_set_config(ndev, NFCMRVL_ACTIVE_ID, 1, &val);
77         val = NFCMRVL_EXT_COEX_ENABLE;
78         nci_set_config(ndev, NFCMRVL_EXT_COEX_ID, 1, &val);
79
80         return 0;
81 }
82
83 static struct nci_ops nfcmrvl_nci_ops = {
84         .open = nfcmrvl_nci_open,
85         .close = nfcmrvl_nci_close,
86         .send = nfcmrvl_nci_send,
87         .setup = nfcmrvl_nci_setup,
88 };
89
90 struct nfcmrvl_private *nfcmrvl_nci_register_dev(void *drv_data,
91                                                  struct nfcmrvl_if_ops *ops,
92                                                  struct device *dev)
93 {
94         struct nfcmrvl_private *priv;
95         int rc;
96         u32 protocols;
97
98         priv = kzalloc(sizeof(*priv), GFP_KERNEL);
99         if (!priv)
100                 return ERR_PTR(-ENOMEM);
101
102         priv->drv_data = drv_data;
103         priv->if_ops = ops;
104         priv->dev = dev;
105
106         protocols = NFC_PROTO_JEWEL_MASK
107                 | NFC_PROTO_MIFARE_MASK | NFC_PROTO_FELICA_MASK
108                 | NFC_PROTO_ISO14443_MASK
109                 | NFC_PROTO_ISO14443_B_MASK
110                 | NFC_PROTO_NFC_DEP_MASK;
111
112         priv->ndev = nci_allocate_device(&nfcmrvl_nci_ops, protocols, 0, 0);
113         if (!priv->ndev) {
114                 nfc_err(dev, "nci_allocate_device failed\n");
115                 rc = -ENOMEM;
116                 goto error;
117         }
118
119         nci_set_drvdata(priv->ndev, priv);
120
121         rc = nci_register_device(priv->ndev);
122         if (rc) {
123                 nfc_err(dev, "nci_register_device failed %d\n", rc);
124                 nci_free_device(priv->ndev);
125                 goto error;
126         }
127
128         nfc_info(dev, "registered with nci successfully\n");
129         return priv;
130
131 error:
132         kfree(priv);
133         return ERR_PTR(rc);
134 }
135 EXPORT_SYMBOL_GPL(nfcmrvl_nci_register_dev);
136
137 void nfcmrvl_nci_unregister_dev(struct nfcmrvl_private *priv)
138 {
139         struct nci_dev *ndev = priv->ndev;
140
141         nci_unregister_device(ndev);
142         nci_free_device(ndev);
143         kfree(priv);
144 }
145 EXPORT_SYMBOL_GPL(nfcmrvl_nci_unregister_dev);
146
147 int nfcmrvl_nci_recv_frame(struct nfcmrvl_private *priv, void *data, int count)
148 {
149         struct sk_buff *skb;
150
151         skb = nci_skb_alloc(priv->ndev, count, GFP_ATOMIC);
152         if (!skb)
153                 return -ENOMEM;
154
155         memcpy(skb_put(skb, count), data, count);
156         nci_recv_frame(priv->ndev, skb);
157
158         return count;
159 }
160 EXPORT_SYMBOL_GPL(nfcmrvl_nci_recv_frame);
161
162 MODULE_AUTHOR("Marvell International Ltd.");
163 MODULE_DESCRIPTION("Marvell NFC driver ver " VERSION);
164 MODULE_VERSION(VERSION);
165 MODULE_LICENSE("GPL v2");