2 * Marvell NFC driver: major functions
4 * Copyright (C) 2014-2015 Marvell International Ltd.
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.
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.
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>
28 static int nfcmrvl_nci_open(struct nci_dev
*ndev
)
30 struct nfcmrvl_private
*priv
= nci_get_drvdata(ndev
);
33 if (test_and_set_bit(NFCMRVL_NCI_RUNNING
, &priv
->flags
))
36 /* Reset possible fault of previous session */
37 clear_bit(NFCMRVL_PHY_ERROR
, &priv
->flags
);
39 err
= priv
->if_ops
->nci_open(priv
);
42 clear_bit(NFCMRVL_NCI_RUNNING
, &priv
->flags
);
47 static int nfcmrvl_nci_close(struct nci_dev
*ndev
)
49 struct nfcmrvl_private
*priv
= nci_get_drvdata(ndev
);
51 if (!test_and_clear_bit(NFCMRVL_NCI_RUNNING
, &priv
->flags
))
54 priv
->if_ops
->nci_close(priv
);
59 static int nfcmrvl_nci_send(struct nci_dev
*ndev
, struct sk_buff
*skb
)
61 struct nfcmrvl_private
*priv
= nci_get_drvdata(ndev
);
63 nfc_info(priv
->dev
, "send entry, len %d\n", skb
->len
);
65 skb
->dev
= (void *)ndev
;
67 if (priv
->config
.hci_muxed
) {
69 unsigned char len
= skb
->len
;
71 hdr
= skb_push(skb
, NFCMRVL_HCI_EVENT_HEADER_SIZE
);
72 hdr
[0] = NFCMRVL_HCI_COMMAND_CODE
;
73 hdr
[1] = NFCMRVL_HCI_OGF
;
74 hdr
[2] = NFCMRVL_HCI_OCF
;
78 return priv
->if_ops
->nci_send(priv
, skb
);
81 static int nfcmrvl_nci_setup(struct nci_dev
*ndev
)
85 nci_set_config(ndev
, NFCMRVL_PB_BAIL_OUT
, 1, &val
);
89 static int nfcmrvl_nci_fw_download(struct nci_dev
*ndev
,
90 const char *firmware_name
)
92 return nfcmrvl_fw_dnld_start(ndev
, firmware_name
);
95 static struct nci_ops nfcmrvl_nci_ops
= {
96 .open
= nfcmrvl_nci_open
,
97 .close
= nfcmrvl_nci_close
,
98 .send
= nfcmrvl_nci_send
,
99 .setup
= nfcmrvl_nci_setup
,
100 .fw_download
= nfcmrvl_nci_fw_download
,
103 struct nfcmrvl_private
*nfcmrvl_nci_register_dev(enum nfcmrvl_phy phy
,
105 struct nfcmrvl_if_ops
*ops
,
107 struct nfcmrvl_platform_data
*pdata
)
109 struct nfcmrvl_private
*priv
;
115 priv
= kzalloc(sizeof(*priv
), GFP_KERNEL
);
117 return ERR_PTR(-ENOMEM
);
119 priv
->drv_data
= drv_data
;
124 memcpy(&priv
->config
, pdata
, sizeof(*pdata
));
126 if (gpio_is_valid(priv
->config
.reset_n_io
)) {
127 rc
= gpio_request_one(priv
->config
.reset_n_io
,
131 priv
->config
.reset_n_io
= -EINVAL
;
132 nfc_err(dev
, "failed to request reset_n io\n");
136 if (phy
== NFCMRVL_PHY_SPI
) {
137 headroom
= NCI_SPI_HDR_LEN
;
140 headroom
= tailroom
= 0;
142 if (priv
->config
.hci_muxed
)
143 headroom
+= NFCMRVL_HCI_EVENT_HEADER_SIZE
;
145 protocols
= NFC_PROTO_JEWEL_MASK
146 | NFC_PROTO_MIFARE_MASK
147 | NFC_PROTO_FELICA_MASK
148 | NFC_PROTO_ISO14443_MASK
149 | NFC_PROTO_ISO14443_B_MASK
150 | NFC_PROTO_ISO15693_MASK
151 | NFC_PROTO_NFC_DEP_MASK
;
153 priv
->ndev
= nci_allocate_device(&nfcmrvl_nci_ops
, protocols
,
156 nfc_err(dev
, "nci_allocate_device failed\n");
158 goto error_free_gpio
;
161 rc
= nfcmrvl_fw_dnld_init(priv
);
163 nfc_err(dev
, "failed to initialize FW download %d\n", rc
);
167 nci_set_drvdata(priv
->ndev
, priv
);
169 rc
= nci_register_device(priv
->ndev
);
171 nfc_err(dev
, "nci_register_device failed %d\n", rc
);
172 goto error_fw_dnld_deinit
;
175 /* Ensure that controller is powered off */
176 nfcmrvl_chip_halt(priv
);
178 nfc_info(dev
, "registered with nci successfully\n");
181 error_fw_dnld_deinit
:
182 nfcmrvl_fw_dnld_deinit(priv
);
184 nci_free_device(priv
->ndev
);
186 if (gpio_is_valid(priv
->config
.reset_n_io
))
187 gpio_free(priv
->config
.reset_n_io
);
191 EXPORT_SYMBOL_GPL(nfcmrvl_nci_register_dev
);
193 void nfcmrvl_nci_unregister_dev(struct nfcmrvl_private
*priv
)
195 struct nci_dev
*ndev
= priv
->ndev
;
197 if (priv
->ndev
->nfc_dev
->fw_download_in_progress
)
198 nfcmrvl_fw_dnld_abort(priv
);
200 nfcmrvl_fw_dnld_deinit(priv
);
202 if (gpio_is_valid(priv
->config
.reset_n_io
))
203 gpio_free(priv
->config
.reset_n_io
);
205 nci_unregister_device(ndev
);
206 nci_free_device(ndev
);
209 EXPORT_SYMBOL_GPL(nfcmrvl_nci_unregister_dev
);
211 int nfcmrvl_nci_recv_frame(struct nfcmrvl_private
*priv
, struct sk_buff
*skb
)
213 if (priv
->config
.hci_muxed
) {
214 if (skb
->data
[0] == NFCMRVL_HCI_EVENT_CODE
&&
215 skb
->data
[1] == NFCMRVL_HCI_NFC_EVENT_CODE
) {
216 /* Data packet, let's extract NCI payload */
217 skb_pull(skb
, NFCMRVL_HCI_EVENT_HEADER_SIZE
);
219 /* Skip this packet */
225 if (priv
->ndev
->nfc_dev
->fw_download_in_progress
) {
226 nfcmrvl_fw_dnld_recv_frame(priv
, skb
);
230 if (test_bit(NFCMRVL_NCI_RUNNING
, &priv
->flags
))
231 nci_recv_frame(priv
->ndev
, skb
);
233 /* Drop this packet since nobody wants it */
240 EXPORT_SYMBOL_GPL(nfcmrvl_nci_recv_frame
);
242 void nfcmrvl_chip_reset(struct nfcmrvl_private
*priv
)
244 /* Reset possible fault of previous session */
245 clear_bit(NFCMRVL_PHY_ERROR
, &priv
->flags
);
247 if (priv
->config
.reset_n_io
) {
248 nfc_info(priv
->dev
, "reset the chip\n");
249 gpio_set_value(priv
->config
.reset_n_io
, 0);
250 usleep_range(5000, 10000);
251 gpio_set_value(priv
->config
.reset_n_io
, 1);
253 nfc_info(priv
->dev
, "no reset available on this interface\n");
256 void nfcmrvl_chip_halt(struct nfcmrvl_private
*priv
)
258 if (priv
->config
.reset_n_io
)
259 gpio_set_value(priv
->config
.reset_n_io
, 0);
262 int nfcmrvl_parse_dt(struct device_node
*node
,
263 struct nfcmrvl_platform_data
*pdata
)
267 reset_n_io
= of_get_named_gpio(node
, "reset-n-io", 0);
268 if (reset_n_io
< 0) {
269 pr_info("no reset-n-io config\n");
270 } else if (!gpio_is_valid(reset_n_io
)) {
271 pr_err("invalid reset-n-io GPIO\n");
274 pdata
->reset_n_io
= reset_n_io
;
276 if (of_find_property(node
, "hci-muxed", NULL
))
277 pdata
->hci_muxed
= 1;
279 pdata
->hci_muxed
= 0;
283 EXPORT_SYMBOL_GPL(nfcmrvl_parse_dt
);
285 MODULE_AUTHOR("Marvell International Ltd.");
286 MODULE_DESCRIPTION("Marvell NFC driver");
287 MODULE_LICENSE("GPL v2");