aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRobert Dolca <robert.dolca@intel.com>2015-10-22 05:11:42 -0400
committerSamuel Ortiz <sameo@linux.intel.com>2015-10-25 15:29:16 -0400
commita06347c04c13e380afce0c9816df51f00b83faf1 (patch)
treef1e61e0644b74541296828a14060f86691a0496e
parent85b9ce9a21b119a8163f20d60e7f0ce58fffbeef (diff)
NFC: Add Intel Fields Peak NFC solution driver
Fields Peak complies with the ISO/IEC 14443A/B, 15693, 18092, and JIS X 6319-4. It is an NCI based controller. RF Protocols supported: - NFC Forum Type 1 Tags (Jewel, Topaz) - NFC Forum Type 2 Tags (Mifare UL) - NFC Forum Type 3 Tags (FeliCa) - NFC Forum Type 4A (ISO/IEC 14443 A-4 106kbps to 848kbps) - NFC Forum Type 4B (ISO/IEC 14443 B-4 106kbps to 848kbps) - NFCIP in passive and active modes (ISO/IEC 18092 106kbps to 424kbps) - B’ (based on ISO/IEC 14443 B-2) - iCLASS (based on ISO/IEC 15693-2) - Vicinity cards (ISO/IEC 15693-3) - Kovio tags (NFC Forum Type 2) The device can be enumerated using ACPI using the id INT339A. The 1st GPIO is the IRQ and the 2nd is the RESET pin. Signed-off-by: Robert Dolca <robert.dolca@intel.com> Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
-rw-r--r--drivers/nfc/Kconfig1
-rw-r--r--drivers/nfc/Makefile1
-rw-r--r--drivers/nfc/fdp/Kconfig23
-rw-r--r--drivers/nfc/fdp/Makefile9
-rw-r--r--drivers/nfc/fdp/fdp.c817
-rw-r--r--drivers/nfc/fdp/fdp.h38
-rw-r--r--drivers/nfc/fdp/i2c.c388
7 files changed, 1277 insertions, 0 deletions
diff --git a/drivers/nfc/Kconfig b/drivers/nfc/Kconfig
index 6639cd1cae36..0d6003dee3af 100644
--- a/drivers/nfc/Kconfig
+++ b/drivers/nfc/Kconfig
@@ -68,6 +68,7 @@ config NFC_PORT100
68 68
69 If unsure, say N. 69 If unsure, say N.
70 70
71source "drivers/nfc/fdp/Kconfig"
71source "drivers/nfc/pn544/Kconfig" 72source "drivers/nfc/pn544/Kconfig"
72source "drivers/nfc/microread/Kconfig" 73source "drivers/nfc/microread/Kconfig"
73source "drivers/nfc/nfcmrvl/Kconfig" 74source "drivers/nfc/nfcmrvl/Kconfig"
diff --git a/drivers/nfc/Makefile b/drivers/nfc/Makefile
index 2757fe1b8aa5..e3621416a48e 100644
--- a/drivers/nfc/Makefile
+++ b/drivers/nfc/Makefile
@@ -2,6 +2,7 @@
2# Makefile for nfc devices 2# Makefile for nfc devices
3# 3#
4 4
5obj-$(CONFIG_NFC_FDP) += fdp/
5obj-$(CONFIG_NFC_PN544) += pn544/ 6obj-$(CONFIG_NFC_PN544) += pn544/
6obj-$(CONFIG_NFC_MICROREAD) += microread/ 7obj-$(CONFIG_NFC_MICROREAD) += microread/
7obj-$(CONFIG_NFC_PN533) += pn533.o 8obj-$(CONFIG_NFC_PN533) += pn533.o
diff --git a/drivers/nfc/fdp/Kconfig b/drivers/nfc/fdp/Kconfig
new file mode 100644
index 000000000000..fbccd9dd887d
--- /dev/null
+++ b/drivers/nfc/fdp/Kconfig
@@ -0,0 +1,23 @@
1config NFC_FDP
2 tristate "Intel FDP NFC driver"
3 depends on NFC_NCI
4 select CRC_CCITT
5 default n
6 ---help---
7 Intel Fields Peak NFC controller core driver.
8 This is a driver based on the NCI NFC kernel layers.
9
10 To compile this driver as a module, choose m here. The module will
11 be called fdp.
12 Say N if unsure.
13
14config NFC_FDP_I2C
15 tristate "NFC FDP i2c support"
16 depends on NFC_FDP && I2C
17 ---help---
18 This module adds support for the Intel Fields Peak NFC controller
19 i2c interface.
20 Select this if your platform is using the i2c bus.
21
22 If you choose to build a module, it'll be called fdp_i2c.
23 Say N if unsure.
diff --git a/drivers/nfc/fdp/Makefile b/drivers/nfc/fdp/Makefile
new file mode 100644
index 000000000000..e79d51bdeec7
--- /dev/null
+++ b/drivers/nfc/fdp/Makefile
@@ -0,0 +1,9 @@
1#
2# Makefile for FDP NCI based NFC driver
3#
4
5obj-$(CONFIG_NFC_FDP) += fdp.o
6obj-$(CONFIG_NFC_FDP_I2C) += fdp_i2c.o
7
8fdp_i2c-objs = i2c.o
9
diff --git a/drivers/nfc/fdp/fdp.c b/drivers/nfc/fdp/fdp.c
new file mode 100644
index 000000000000..ccb07a1b153d
--- /dev/null
+++ b/drivers/nfc/fdp/fdp.c
@@ -0,0 +1,817 @@
1/* -------------------------------------------------------------------------
2 * Copyright (C) 2014-2016, Intel Corporation
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 * -------------------------------------------------------------------------
14 */
15
16#include <linux/module.h>
17#include <linux/nfc.h>
18#include <linux/i2c.h>
19#include <linux/delay.h>
20#include <linux/firmware.h>
21#include <net/nfc/nci_core.h>
22
23#include "fdp.h"
24
25#define FDP_OTP_PATCH_NAME "otp.bin"
26#define FDP_RAM_PATCH_NAME "ram.bin"
27#define FDP_FW_HEADER_SIZE 576
28#define FDP_FW_UPDATE_SLEEP 1000
29
30#define NCI_GET_VERSION_TIMEOUT 8000
31#define NCI_PATCH_REQUEST_TIMEOUT 8000
32#define FDP_PATCH_CONN_DEST 0xC2
33#define FDP_PATCH_CONN_PARAM_TYPE 0xA0
34
35#define NCI_PATCH_TYPE_RAM 0x00
36#define NCI_PATCH_TYPE_OTP 0x01
37#define NCI_PATCH_TYPE_EOT 0xFF
38
39#define NCI_PARAM_ID_FW_RAM_VERSION 0xA0
40#define NCI_PARAM_ID_FW_OTP_VERSION 0xA1
41#define NCI_PARAM_ID_OTP_LIMITED_VERSION 0xC5
42#define NCI_PARAM_ID_KEY_INDEX_ID 0xC6
43
44#define NCI_GID_PROP 0x0F
45#define NCI_OP_PROP_PATCH_OID 0x08
46#define NCI_OP_PROP_SET_PDATA_OID 0x23
47
48struct fdp_nci_info {
49 struct nfc_phy_ops *phy_ops;
50 struct fdp_i2c_phy *phy;
51 struct nci_dev *ndev;
52
53 const struct firmware *otp_patch;
54 const struct firmware *ram_patch;
55 u32 otp_patch_version;
56 u32 ram_patch_version;
57
58 u32 otp_version;
59 u32 ram_version;
60 u32 limited_otp_version;
61 u8 key_index;
62
63 u8 *fw_vsc_cfg;
64 u8 clock_type;
65 u32 clock_freq;
66
67 atomic_t data_pkt_counter;
68 void (*data_pkt_counter_cb)(struct nci_dev *ndev);
69 u8 setup_patch_sent;
70 u8 setup_patch_ntf;
71 u8 setup_patch_status;
72 u8 setup_reset_ntf;
73 wait_queue_head_t setup_wq;
74};
75
76static u8 nci_core_get_config_otp_ram_version[5] = {
77 0x04,
78 NCI_PARAM_ID_FW_RAM_VERSION,
79 NCI_PARAM_ID_FW_OTP_VERSION,
80 NCI_PARAM_ID_OTP_LIMITED_VERSION,
81 NCI_PARAM_ID_KEY_INDEX_ID
82};
83
84struct nci_core_get_config_rsp {
85 u8 status;
86 u8 count;
87 u8 data[0];
88};
89
90static int fdp_nci_create_conn(struct nci_dev *ndev)
91{
92 struct fdp_nci_info *info = nci_get_drvdata(ndev);
93 struct core_conn_create_dest_spec_params param;
94 int r;
95
96 /* proprietary destination specific paramerer without value */
97 param.type = FDP_PATCH_CONN_PARAM_TYPE;
98 param.length = 0x00;
99
100 r = nci_core_conn_create(info->ndev, FDP_PATCH_CONN_DEST, 1,
101 sizeof(param), &param);
102 if (r)
103 return r;
104
105 return nci_get_conn_info_by_id(ndev, 0);
106}
107
108static inline int fdp_nci_get_versions(struct nci_dev *ndev)
109{
110 return nci_core_cmd(ndev, NCI_OP_CORE_GET_CONFIG_CMD,
111 sizeof(nci_core_get_config_otp_ram_version),
112 (__u8 *) &nci_core_get_config_otp_ram_version);
113}
114
115static inline int fdp_nci_patch_cmd(struct nci_dev *ndev, u8 type)
116{
117 return nci_prop_cmd(ndev, NCI_OP_PROP_PATCH_OID, sizeof(type), &type);
118}
119
120static inline int fdp_nci_set_production_data(struct nci_dev *ndev, u8 len,
121 char *data)
122{
123 return nci_prop_cmd(ndev, NCI_OP_PROP_SET_PDATA_OID, len, data);
124}
125
126static int fdp_nci_set_clock(struct nci_dev *ndev, u8 clock_type,
127 u32 clock_freq)
128{
129 u32 fc = 13560;
130 u32 nd, num, delta;
131 char data[9];
132
133 nd = (24 * fc) / clock_freq;
134 delta = 24 * fc - nd * clock_freq;
135 num = (32768 * delta) / clock_freq;
136
137 data[0] = 0x00;
138 data[1] = 0x00;
139 data[2] = 0x00;
140
141 data[3] = 0x10;
142 data[4] = 0x04;
143 data[5] = num & 0xFF;
144 data[6] = (num >> 8) & 0xff;
145 data[7] = nd;
146 data[8] = clock_type;
147
148 return fdp_nci_set_production_data(ndev, 9, data);
149}
150
151static void fdp_nci_send_patch_cb(struct nci_dev *ndev)
152{
153 struct fdp_nci_info *info = nci_get_drvdata(ndev);
154
155 info->setup_patch_sent = 1;
156 wake_up(&info->setup_wq);
157}
158
159/**
160 * Register a packet sent counter and a callback
161 *
162 * We have no other way of knowing when all firmware packets were sent out
163 * on the i2c bus. We need to know that in order to close the connection and
164 * send the patch end message.
165 */
166static void fdp_nci_set_data_pkt_counter(struct nci_dev *ndev,
167 void (*cb)(struct nci_dev *ndev), int count)
168{
169 struct fdp_nci_info *info = nci_get_drvdata(ndev);
170 struct device *dev = &info->phy->i2c_dev->dev;
171
172 dev_dbg(dev, "NCI data pkt counter %d\n", count);
173 atomic_set(&info->data_pkt_counter, count);
174 info->data_pkt_counter_cb = cb;
175}
176
177/**
178 * The device is expecting a stream of packets. All packets need to
179 * have the PBF flag set to 0x0 (last packet) even if the firmware
180 * file is segmented and there are multiple packets. If we give the
181 * whole firmware to nci_send_data it will segment it and it will set
182 * the PBF flag to 0x01 so we need to do the segmentation here.
183 *
184 * The firmware will be analyzed and applied when we send NCI_OP_PROP_PATCH_CMD
185 * command with NCI_PATCH_TYPE_EOT parameter. The device will send a
186 * NFCC_PATCH_NTF packaet and a NCI_OP_CORE_RESET_NTF packet.
187 */
188static int fdp_nci_send_patch(struct nci_dev *ndev, u8 conn_id, u8 type)
189{
190 struct fdp_nci_info *info = nci_get_drvdata(ndev);
191 const struct firmware *fw;
192 struct sk_buff *skb;
193 unsigned long len;
194 u8 max_size, payload_size;
195 int rc = 0;
196
197 if ((type == NCI_PATCH_TYPE_OTP && !info->otp_patch) ||
198 (type == NCI_PATCH_TYPE_RAM && !info->ram_patch))
199 return -EINVAL;
200
201 if (type == NCI_PATCH_TYPE_OTP)
202 fw = info->otp_patch;
203 else
204 fw = info->ram_patch;
205
206 max_size = nci_conn_max_data_pkt_payload_size(ndev, conn_id);
207 if (max_size <= 0)
208 return -EINVAL;
209
210 len = fw->size;
211
212 fdp_nci_set_data_pkt_counter(ndev, fdp_nci_send_patch_cb,
213 DIV_ROUND_UP(fw->size, max_size));
214
215 while (len) {
216
217 payload_size = min_t(unsigned long, (unsigned long) max_size,
218 len);
219
220 skb = nci_skb_alloc(ndev, (NCI_CTRL_HDR_SIZE + payload_size),
221 GFP_KERNEL);
222 if (!skb) {
223 fdp_nci_set_data_pkt_counter(ndev, NULL, 0);
224 return -ENOMEM;
225 }
226
227
228 skb_reserve(skb, NCI_CTRL_HDR_SIZE);
229
230 memcpy(skb_put(skb, payload_size), fw->data + (fw->size - len),
231 payload_size);
232
233 rc = nci_send_data(ndev, conn_id, skb);
234
235 if (rc) {
236 fdp_nci_set_data_pkt_counter(ndev, NULL, 0);
237 return rc;
238 }
239
240 len -= payload_size;
241 }
242
243 return rc;
244}
245
246static int fdp_nci_open(struct nci_dev *ndev)
247{
248 int r;
249 struct fdp_nci_info *info = nci_get_drvdata(ndev);
250 struct device *dev = &info->phy->i2c_dev->dev;
251
252 dev_dbg(dev, "%s\n", __func__);
253
254 r = info->phy_ops->enable(info->phy);
255
256 return r;
257}
258
259static int fdp_nci_close(struct nci_dev *ndev)
260{
261 struct fdp_nci_info *info = nci_get_drvdata(ndev);
262 struct device *dev = &info->phy->i2c_dev->dev;
263
264 dev_dbg(dev, "%s\n", __func__);
265 return 0;
266}
267
268static int fdp_nci_send(struct nci_dev *ndev, struct sk_buff *skb)
269{
270 struct fdp_nci_info *info = nci_get_drvdata(ndev);
271 struct device *dev = &info->phy->i2c_dev->dev;
272
273 dev_dbg(dev, "%s\n", __func__);
274
275 if (atomic_dec_and_test(&info->data_pkt_counter))
276 info->data_pkt_counter_cb(ndev);
277
278 return info->phy_ops->write(info->phy, skb);
279}
280
281int fdp_nci_recv_frame(struct nci_dev *ndev, struct sk_buff *skb)
282{
283 struct fdp_nci_info *info = nci_get_drvdata(ndev);
284 struct device *dev = &info->phy->i2c_dev->dev;
285
286 dev_dbg(dev, "%s\n", __func__);
287 return nci_recv_frame(ndev, skb);
288}
289EXPORT_SYMBOL(fdp_nci_recv_frame);
290
291static int fdp_nci_request_firmware(struct nci_dev *ndev)
292{
293 struct fdp_nci_info *info = nci_get_drvdata(ndev);
294 struct device *dev = &info->phy->i2c_dev->dev;
295 u8 *data;
296 int r;
297
298 r = request_firmware(&info->ram_patch, FDP_RAM_PATCH_NAME, dev);
299 if (r < 0) {
300 nfc_err(dev, "RAM patch request error\n");
301 goto error;
302 }
303
304 data = (u8 *) info->ram_patch->data;
305 info->ram_patch_version =
306 data[FDP_FW_HEADER_SIZE] |
307 (data[FDP_FW_HEADER_SIZE + 1] << 8) |
308 (data[FDP_FW_HEADER_SIZE + 2] << 16) |
309 (data[FDP_FW_HEADER_SIZE + 3] << 24);
310
311 dev_dbg(dev, "RAM patch version: %d, size: %d\n",
312 info->ram_patch_version, (int) info->ram_patch->size);
313
314
315 r = request_firmware(&info->otp_patch, FDP_OTP_PATCH_NAME, dev);
316 if (r < 0) {
317 nfc_err(dev, "OTP patch request error\n");
318 goto out;
319 }
320
321 data = (u8 *) info->otp_patch->data;
322 info->otp_patch_version =
323 data[FDP_FW_HEADER_SIZE] |
324 (data[FDP_FW_HEADER_SIZE + 1] << 8) |
325 (data[FDP_FW_HEADER_SIZE+2] << 16) |
326 (data[FDP_FW_HEADER_SIZE+3] << 24);
327
328 dev_dbg(dev, "OTP patch version: %d, size: %d\n",
329 info->otp_patch_version, (int) info->otp_patch->size);
330out:
331 return 0;
332error:
333 return r;
334}
335
336static void fdp_nci_release_firmware(struct nci_dev *ndev)
337{
338 struct fdp_nci_info *info = nci_get_drvdata(ndev);
339
340 if (info->otp_patch) {
341 release_firmware(info->otp_patch);
342 info->otp_patch = NULL;
343 }
344
345 if (info->ram_patch) {
346 release_firmware(info->ram_patch);
347 info->otp_patch = NULL;
348 }
349}
350
351static int fdp_nci_patch_otp(struct nci_dev *ndev)
352{
353 struct fdp_nci_info *info = nci_get_drvdata(ndev);
354 struct device *dev = &info->phy->i2c_dev->dev;
355 u8 conn_id;
356 int r = 0;
357
358 if (info->otp_version >= info->otp_patch_version)
359 goto out;
360
361 info->setup_patch_sent = 0;
362 info->setup_reset_ntf = 0;
363 info->setup_patch_ntf = 0;
364
365 /* Patch init request */
366 r = fdp_nci_patch_cmd(ndev, NCI_PATCH_TYPE_OTP);
367 if (r)
368 goto out;
369
370 /* Patch data connection creation */
371 conn_id = fdp_nci_create_conn(ndev);
372 if (conn_id < 0) {
373 r = conn_id;
374 goto out;
375 }
376
377 /* Send the patch over the data connection */
378 r = fdp_nci_send_patch(ndev, conn_id, NCI_PATCH_TYPE_OTP);
379 if (r)
380 goto out;
381
382 /* Wait for all the packets to be send over i2c */
383 wait_event_interruptible(info->setup_wq,
384 info->setup_patch_sent == 1);
385
386 /* make sure that the NFCC processed the last data packet */
387 msleep(FDP_FW_UPDATE_SLEEP);
388
389 /* Close the data connection */
390 r = nci_core_conn_close(info->ndev, conn_id);
391 if (r)
392 goto out;
393
394 /* Patch finish message */
395 if (fdp_nci_patch_cmd(ndev, NCI_PATCH_TYPE_EOT)) {
396 nfc_err(dev, "OTP patch error 0x%x\n", r);
397 r = -EINVAL;
398 goto out;
399 }
400
401 /* If the patch notification didn't arrive yet, wait for it */
402 wait_event_interruptible(info->setup_wq, info->setup_patch_ntf);
403
404 /* Check if the patching was successful */
405 r = info->setup_patch_status;
406 if (r) {
407 nfc_err(dev, "OTP patch error 0x%x\n", r);
408 r = -EINVAL;
409 goto out;
410 }
411
412 /*
413 * We need to wait for the reset notification before we
414 * can continue
415 */
416 wait_event_interruptible(info->setup_wq, info->setup_reset_ntf);
417
418out:
419 return r;
420}
421
422static int fdp_nci_patch_ram(struct nci_dev *ndev)
423{
424 struct fdp_nci_info *info = nci_get_drvdata(ndev);
425 struct device *dev = &info->phy->i2c_dev->dev;
426 u8 conn_id;
427 int r = 0;
428
429 if (info->ram_version >= info->ram_patch_version)
430 goto out;
431
432 info->setup_patch_sent = 0;
433 info->setup_reset_ntf = 0;
434 info->setup_patch_ntf = 0;
435
436 /* Patch init request */
437 r = fdp_nci_patch_cmd(ndev, NCI_PATCH_TYPE_RAM);
438 if (r)
439 goto out;
440
441 /* Patch data connection creation */
442 conn_id = fdp_nci_create_conn(ndev);
443 if (conn_id < 0) {
444 r = conn_id;
445 goto out;
446 }
447
448 /* Send the patch over the data connection */
449 r = fdp_nci_send_patch(ndev, conn_id, NCI_PATCH_TYPE_RAM);
450 if (r)
451 goto out;
452
453 /* Wait for all the packets to be send over i2c */
454 wait_event_interruptible(info->setup_wq,
455 info->setup_patch_sent == 1);
456
457 /* make sure that the NFCC processed the last data packet */
458 msleep(FDP_FW_UPDATE_SLEEP);
459
460 /* Close the data connection */
461 r = nci_core_conn_close(info->ndev, conn_id);
462 if (r)
463 goto out;
464
465 /* Patch finish message */
466 if (fdp_nci_patch_cmd(ndev, NCI_PATCH_TYPE_EOT)) {
467 nfc_err(dev, "RAM patch error 0x%x\n", r);
468 r = -EINVAL;
469 goto out;
470 }
471
472 /* If the patch notification didn't arrive yet, wait for it */
473 wait_event_interruptible(info->setup_wq, info->setup_patch_ntf);
474
475 /* Check if the patching was successful */
476 r = info->setup_patch_status;
477 if (r) {
478 nfc_err(dev, "RAM patch error 0x%x\n", r);
479 r = -EINVAL;
480 goto out;
481 }
482
483 /*
484 * We need to wait for the reset notification before we
485 * can continue
486 */
487 wait_event_interruptible(info->setup_wq, info->setup_reset_ntf);
488
489out:
490 return r;
491}
492
493static int fdp_nci_setup(struct nci_dev *ndev)
494{
495 /* Format: total length followed by an NCI packet */
496 struct fdp_nci_info *info = nci_get_drvdata(ndev);
497 struct device *dev = &info->phy->i2c_dev->dev;
498 int r;
499 u8 patched = 0;
500
501 dev_dbg(dev, "%s\n", __func__);
502
503 r = nci_core_init(ndev);
504 if (r)
505 goto error;
506
507 /* Get RAM and OTP version */
508 r = fdp_nci_get_versions(ndev);
509 if (r)
510 goto error;
511
512 /* Load firmware from disk */
513 r = fdp_nci_request_firmware(ndev);
514 if (r)
515 goto error;
516
517 /* Update OTP */
518 if (info->otp_version < info->otp_patch_version) {
519 r = fdp_nci_patch_otp(ndev);
520 if (r)
521 goto error;
522 patched = 1;
523 }
524
525 /* Update RAM */
526 if (info->ram_version < info->ram_patch_version) {
527 r = fdp_nci_patch_ram(ndev);
528 if (r)
529 goto error;
530 patched = 1;
531 }
532
533 /* Release the firmware buffers */
534 fdp_nci_release_firmware(ndev);
535
536 /* If a patch was applied the new version is checked */
537 if (patched) {
538 r = nci_core_init(ndev);
539 if (r)
540 goto error;
541
542 r = fdp_nci_get_versions(ndev);
543 if (r)
544 goto error;
545
546 if (info->otp_version != info->otp_patch_version ||
547 info->ram_version != info->ram_patch_version) {
548 nfc_err(dev, "Firmware update failed");
549 r = -EINVAL;
550 goto error;
551 }
552 }
553
554 /*
555 * We initialized the devices but the NFC subsystem expects
556 * it to not be initialized.
557 */
558 return nci_core_reset(ndev);
559
560error:
561 fdp_nci_release_firmware(ndev);
562 nfc_err(dev, "Setup error %d\n", r);
563 return r;
564}
565
566static int fdp_nci_post_setup(struct nci_dev *ndev)
567{
568 struct fdp_nci_info *info = nci_get_drvdata(ndev);
569 struct device *dev = &info->phy->i2c_dev->dev;
570 int r;
571
572 /* Check if the device has VSC */
573 if (info->fw_vsc_cfg && info->fw_vsc_cfg[0]) {
574
575 /* Set the vendor specific configuration */
576 r = fdp_nci_set_production_data(ndev, info->fw_vsc_cfg[3],
577 &info->fw_vsc_cfg[4]);
578 if (r) {
579 nfc_err(dev, "Vendor specific config set error %d\n",
580 r);
581 return r;
582 }
583 }
584
585 /* Set clock type and frequency */
586 r = fdp_nci_set_clock(ndev, info->clock_type, info->clock_freq);
587 if (r) {
588 nfc_err(dev, "Clock set error %d\n", r);
589 return r;
590 }
591
592 /*
593 * In order to apply the VSC FDP needs a reset
594 */
595 r = nci_core_reset(ndev);
596 if (r)
597 return r;
598
599 /**
600 * The nci core was initialized when post setup was called
601 * so we leave it like that
602 */
603 return nci_core_init(ndev);
604}
605
606static int fdp_nci_core_reset_ntf_packet(struct nci_dev *ndev,
607 struct sk_buff *skb)
608{
609 struct fdp_nci_info *info = nci_get_drvdata(ndev);
610 struct device *dev = &info->phy->i2c_dev->dev;
611
612 dev_dbg(dev, "%s\n", __func__);
613 info->setup_reset_ntf = 1;
614 wake_up(&info->setup_wq);
615
616 return 0;
617}
618
619static int fdp_nci_prop_patch_ntf_packet(struct nci_dev *ndev,
620 struct sk_buff *skb)
621{
622 struct fdp_nci_info *info = nci_get_drvdata(ndev);
623 struct device *dev = &info->phy->i2c_dev->dev;
624
625 dev_dbg(dev, "%s\n", __func__);
626 info->setup_patch_ntf = 1;
627 info->setup_patch_status = skb->data[0];
628 wake_up(&info->setup_wq);
629
630 return 0;
631}
632
633static int fdp_nci_prop_patch_rsp_packet(struct nci_dev *ndev,
634 struct sk_buff *skb)
635{
636 struct fdp_nci_info *info = nci_get_drvdata(ndev);
637 struct device *dev = &info->phy->i2c_dev->dev;
638 u8 status = skb->data[0];
639
640 dev_dbg(dev, "%s: status 0x%x\n", __func__, status);
641 nci_req_complete(ndev, status);
642
643 return 0;
644}
645
646static int fdp_nci_prop_set_production_data_rsp_packet(struct nci_dev *ndev,
647 struct sk_buff *skb)
648{
649 struct fdp_nci_info *info = nci_get_drvdata(ndev);
650 struct device *dev = &info->phy->i2c_dev->dev;
651 u8 status = skb->data[0];
652
653 dev_dbg(dev, "%s: status 0x%x\n", __func__, status);
654 nci_req_complete(ndev, status);
655
656 return 0;
657}
658
659static int fdp_nci_core_get_config_rsp_packet(struct nci_dev *ndev,
660 struct sk_buff *skb)
661{
662 struct fdp_nci_info *info = nci_get_drvdata(ndev);
663 struct device *dev = &info->phy->i2c_dev->dev;
664 struct nci_core_get_config_rsp *rsp = (void *) skb->data;
665 u8 i, *p;
666
667 if (rsp->status == NCI_STATUS_OK) {
668
669 p = rsp->data;
670 for (i = 0; i < 4; i++) {
671
672 switch (*p++) {
673 case NCI_PARAM_ID_FW_RAM_VERSION:
674 p++;
675 info->ram_version = le32_to_cpup((__le32 *) p);
676 p += 4;
677 break;
678 case NCI_PARAM_ID_FW_OTP_VERSION:
679 p++;
680 info->otp_version = le32_to_cpup((__le32 *) p);
681 p += 4;
682 break;
683 case NCI_PARAM_ID_OTP_LIMITED_VERSION:
684 p++;
685 info->otp_version = le32_to_cpup((__le32 *) p);
686 p += 4;
687 break;
688 case NCI_PARAM_ID_KEY_INDEX_ID:
689 p++;
690 info->key_index = *p++;
691 }
692 }
693 }
694
695 dev_dbg(dev, "OTP version %d\n", info->otp_version);
696 dev_dbg(dev, "RAM version %d\n", info->ram_version);
697 dev_dbg(dev, "key index %d\n", info->key_index);
698 dev_dbg(dev, "%s: status 0x%x\n", __func__, rsp->status);
699
700 nci_req_complete(ndev, rsp->status);
701
702 return 0;
703}
704
705static struct nci_driver_ops fdp_core_ops[] = {
706 {
707 .opcode = NCI_OP_CORE_GET_CONFIG_RSP,
708 .rsp = fdp_nci_core_get_config_rsp_packet,
709 },
710 {
711 .opcode = NCI_OP_CORE_RESET_NTF,
712 .ntf = fdp_nci_core_reset_ntf_packet,
713 },
714};
715
716static struct nci_driver_ops fdp_prop_ops[] = {
717 {
718 .opcode = nci_opcode_pack(NCI_GID_PROP, NCI_OP_PROP_PATCH_OID),
719 .rsp = fdp_nci_prop_patch_rsp_packet,
720 .ntf = fdp_nci_prop_patch_ntf_packet,
721 },
722 {
723 .opcode = nci_opcode_pack(NCI_GID_PROP,
724 NCI_OP_PROP_SET_PDATA_OID),
725 .rsp = fdp_nci_prop_set_production_data_rsp_packet,
726 },
727};
728
729struct nci_ops nci_ops = {
730 .open = fdp_nci_open,
731 .close = fdp_nci_close,
732 .send = fdp_nci_send,
733 .setup = fdp_nci_setup,
734 .post_setup = fdp_nci_post_setup,
735 .prop_ops = fdp_prop_ops,
736 .n_prop_ops = ARRAY_SIZE(fdp_prop_ops),
737 .core_ops = fdp_core_ops,
738 .n_core_ops = ARRAY_SIZE(fdp_core_ops),
739};
740
741int fdp_nci_probe(struct fdp_i2c_phy *phy, struct nfc_phy_ops *phy_ops,
742 struct nci_dev **ndevp, int tx_headroom,
743 int tx_tailroom, u8 clock_type, u32 clock_freq,
744 u8 *fw_vsc_cfg)
745{
746 struct device *dev = &phy->i2c_dev->dev;
747 struct fdp_nci_info *info;
748 struct nci_dev *ndev;
749 u32 protocols;
750 int r;
751
752 info = kzalloc(sizeof(struct fdp_nci_info), GFP_KERNEL);
753 if (!info) {
754 r = -ENOMEM;
755 goto err_info_alloc;
756 }
757
758 info->phy = phy;
759 info->phy_ops = phy_ops;
760 info->clock_type = clock_type;
761 info->clock_freq = clock_freq;
762 info->fw_vsc_cfg = fw_vsc_cfg;
763
764 init_waitqueue_head(&info->setup_wq);
765
766 protocols = NFC_PROTO_JEWEL_MASK |
767 NFC_PROTO_MIFARE_MASK |
768 NFC_PROTO_FELICA_MASK |
769 NFC_PROTO_ISO14443_MASK |
770 NFC_PROTO_ISO14443_B_MASK |
771 NFC_PROTO_NFC_DEP_MASK |
772 NFC_PROTO_ISO15693_MASK;
773
774 ndev = nci_allocate_device(&nci_ops, protocols, tx_headroom,
775 tx_tailroom);
776 if (!ndev) {
777 nfc_err(dev, "Cannot allocate nfc ndev\n");
778 r = -ENOMEM;
779 goto err_alloc_ndev;
780 }
781
782 r = nci_register_device(ndev);
783 if (r)
784 goto err_regdev;
785
786 *ndevp = ndev;
787 info->ndev = ndev;
788
789 nci_set_drvdata(ndev, info);
790
791 return 0;
792
793err_regdev:
794 nci_free_device(ndev);
795err_alloc_ndev:
796 kfree(info);
797err_info_alloc:
798 return r;
799}
800EXPORT_SYMBOL(fdp_nci_probe);
801
802void fdp_nci_remove(struct nci_dev *ndev)
803{
804 struct fdp_nci_info *info = nci_get_drvdata(ndev);
805 struct device *dev = &info->phy->i2c_dev->dev;
806
807 dev_dbg(dev, "%s\n", __func__);
808
809 nci_unregister_device(ndev);
810 nci_free_device(ndev);
811 kfree(info);
812}
813EXPORT_SYMBOL(fdp_nci_remove);
814
815MODULE_LICENSE("GPL");
816MODULE_DESCRIPTION("NFC NCI driver for Intel Fields Peak NFC controller");
817MODULE_AUTHOR("Robert Dolca <robert.dolca@intel.com>");
diff --git a/drivers/nfc/fdp/fdp.h b/drivers/nfc/fdp/fdp.h
new file mode 100644
index 000000000000..0bd36c00535d
--- /dev/null
+++ b/drivers/nfc/fdp/fdp.h
@@ -0,0 +1,38 @@
1/* -------------------------------------------------------------------------
2 * Copyright (C) 2014-2016, Intel Corporation
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 * -------------------------------------------------------------------------
14 */
15
16#ifndef __LOCAL_FDP_H_
17#define __LOCAL_FDP_H_
18
19#include <net/nfc/nci_core.h>
20#include <linux/gpio/consumer.h>
21
22struct fdp_i2c_phy {
23 struct i2c_client *i2c_dev;
24 struct gpio_desc *power_gpio;
25 struct nci_dev *ndev;
26
27 /* < 0 if i2c error occurred */
28 int hard_fault;
29 uint16_t next_read_size;
30};
31
32int fdp_nci_probe(struct fdp_i2c_phy *phy, struct nfc_phy_ops *phy_ops,
33 struct nci_dev **ndev, int tx_headroom, int tx_tailroom,
34 u8 clock_type, u32 clock_freq, u8 *fw_vsc_cfg);
35void fdp_nci_remove(struct nci_dev *ndev);
36int fdp_nci_recv_frame(struct nci_dev *ndev, struct sk_buff *skb);
37
38#endif /* __LOCAL_FDP_H_ */
diff --git a/drivers/nfc/fdp/i2c.c b/drivers/nfc/fdp/i2c.c
new file mode 100644
index 000000000000..532db28145c7
--- /dev/null
+++ b/drivers/nfc/fdp/i2c.c
@@ -0,0 +1,388 @@
1/* -------------------------------------------------------------------------
2 * Copyright (C) 2014-2016, Intel Corporation
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 * -------------------------------------------------------------------------
14 */
15
16#include <linux/module.h>
17#include <linux/acpi.h>
18#include <linux/i2c.h>
19#include <linux/interrupt.h>
20#include <linux/nfc.h>
21#include <linux/delay.h>
22#include <linux/gpio/consumer.h>
23#include <net/nfc/nfc.h>
24#include <net/nfc/nci_core.h>
25
26#include "fdp.h"
27
28#define FDP_I2C_DRIVER_NAME "fdp_nci_i2c"
29
30#define FDP_DP_POWER_GPIO_NAME "power"
31#define FDP_DP_CLOCK_TYPE_NAME "clock-type"
32#define FDP_DP_CLOCK_FREQ_NAME "clock-freq"
33#define FDP_DP_FW_VSC_CFG_NAME "fw-vsc-cfg"
34
35#define FDP_FRAME_HEADROOM 2
36#define FDP_FRAME_TAILROOM 1
37
38#define FDP_NCI_I2C_MIN_PAYLOAD 5
39#define FDP_NCI_I2C_MAX_PAYLOAD 261
40
41#define FDP_POWER_OFF 0
42#define FDP_POWER_ON 1
43
44#define fdp_nci_i2c_dump_skb(dev, prefix, skb) \
45 print_hex_dump(KERN_DEBUG, prefix": ", DUMP_PREFIX_OFFSET, \
46 16, 1, (skb)->data, (skb)->len, 0)
47
48static void fdp_nci_i2c_reset(struct fdp_i2c_phy *phy)
49{
50 /* Reset RST/WakeUP for at least 100 micro-second */
51 gpiod_set_value_cansleep(phy->power_gpio, FDP_POWER_OFF);
52 usleep_range(1000, 4000);
53 gpiod_set_value_cansleep(phy->power_gpio, FDP_POWER_ON);
54 usleep_range(10000, 14000);
55}
56
57static int fdp_nci_i2c_enable(void *phy_id)
58{
59 struct fdp_i2c_phy *phy = phy_id;
60
61 dev_dbg(&phy->i2c_dev->dev, "%s\n", __func__);
62 fdp_nci_i2c_reset(phy);
63
64 return 0;
65}
66
67static void fdp_nci_i2c_disable(void *phy_id)
68{
69 struct fdp_i2c_phy *phy = phy_id;
70
71 dev_dbg(&phy->i2c_dev->dev, "%s\n", __func__);
72 fdp_nci_i2c_reset(phy);
73}
74
75static void fdp_nci_i2c_add_len_lrc(struct sk_buff *skb)
76{
77 u8 lrc = 0;
78 u16 len, i;
79
80 /* Add length header */
81 len = skb->len;
82 *skb_push(skb, 1) = len & 0xff;
83 *skb_push(skb, 1) = len >> 8;
84
85 /* Compute and add lrc */
86 for (i = 0; i < len + 2; i++)
87 lrc ^= skb->data[i];
88
89 *skb_put(skb, 1) = lrc;
90}
91
92static void fdp_nci_i2c_remove_len_lrc(struct sk_buff *skb)
93{
94 skb_pull(skb, FDP_FRAME_HEADROOM);
95 skb_trim(skb, skb->len - FDP_FRAME_TAILROOM);
96}
97
98static int fdp_nci_i2c_write(void *phy_id, struct sk_buff *skb)
99{
100 struct fdp_i2c_phy *phy = phy_id;
101 struct i2c_client *client = phy->i2c_dev;
102 int r;
103
104 if (phy->hard_fault != 0)
105 return phy->hard_fault;
106
107 fdp_nci_i2c_add_len_lrc(skb);
108 fdp_nci_i2c_dump_skb(&client->dev, "fdp_wr", skb);
109
110 r = i2c_master_send(client, skb->data, skb->len);
111 if (r == -EREMOTEIO) { /* Retry, chip was in standby */
112 usleep_range(1000, 4000);
113 r = i2c_master_send(client, skb->data, skb->len);
114 }
115
116 if (r < 0 || r != skb->len)
117 dev_dbg(&client->dev, "%s: error err=%d len=%d\n",
118 __func__, r, skb->len);
119
120 if (r >= 0) {
121 if (r != skb->len) {
122 phy->hard_fault = r;
123 r = -EREMOTEIO;
124 } else {
125 r = 0;
126 }
127 }
128
129 fdp_nci_i2c_remove_len_lrc(skb);
130
131 return r;
132}
133
134static struct nfc_phy_ops i2c_phy_ops = {
135 .write = fdp_nci_i2c_write,
136 .enable = fdp_nci_i2c_enable,
137 .disable = fdp_nci_i2c_disable,
138};
139
140static int fdp_nci_i2c_read(struct fdp_i2c_phy *phy, struct sk_buff **skb)
141{
142 int r, len;
143 u8 tmp[FDP_NCI_I2C_MAX_PAYLOAD], lrc, k;
144 u16 i;
145 struct i2c_client *client = phy->i2c_dev;
146
147 *skb = NULL;
148
149 /* Read the length packet and the data packet */
150 for (k = 0; k < 2; k++) {
151
152 len = phy->next_read_size;
153
154 r = i2c_master_recv(client, tmp, len);
155 if (r != len) {
156 dev_dbg(&client->dev, "%s: i2c recv err: %d\n",
157 __func__, r);
158 goto flush;
159 }
160
161 /* Check packet integruty */
162 for (lrc = i = 0; i < r; i++)
163 lrc ^= tmp[i];
164
165 /*
166 * LRC check failed. This may due to transmission error or
167 * desynchronization between driver and FDP. Drop the paquet
168 * and force resynchronization
169 */
170 if (lrc) {
171 dev_dbg(&client->dev, "%s: corrupted packet\n",
172 __func__);
173 phy->next_read_size = 5;
174 goto flush;
175 }
176
177 /* Packet that contains a length */
178 if (tmp[0] == 0 && tmp[1] == 0) {
179 phy->next_read_size = (tmp[2] << 8) + tmp[3] + 3;
180 } else {
181 phy->next_read_size = FDP_NCI_I2C_MIN_PAYLOAD;
182
183 *skb = alloc_skb(len, GFP_KERNEL);
184 if (*skb == NULL) {
185 r = -ENOMEM;
186 goto flush;
187 }
188
189 memcpy(skb_put(*skb, len), tmp, len);
190 fdp_nci_i2c_dump_skb(&client->dev, "fdp_rd", *skb);
191
192 fdp_nci_i2c_remove_len_lrc(*skb);
193 }
194 }
195
196 return 0;
197
198flush:
199 /* Flush the remaining data */
200 if (i2c_master_recv(client, tmp, sizeof(tmp)) < 0)
201 r = -EREMOTEIO;
202
203 return r;
204}
205
206static irqreturn_t fdp_nci_i2c_irq_thread_fn(int irq, void *phy_id)
207{
208 struct fdp_i2c_phy *phy = phy_id;
209 struct i2c_client *client;
210 struct sk_buff *skb;
211 int r;
212
213 client = phy->i2c_dev;
214 dev_dbg(&client->dev, "%s\n", __func__);
215
216 if (!phy || irq != phy->i2c_dev->irq) {
217 WARN_ON_ONCE(1);
218 return IRQ_NONE;
219 }
220
221 r = fdp_nci_i2c_read(phy, &skb);
222
223 if (r == -EREMOTEIO)
224 return IRQ_HANDLED;
225 else if (r == -ENOMEM || r == -EBADMSG)
226 return IRQ_HANDLED;
227
228 if (skb != NULL)
229 fdp_nci_recv_frame(phy->ndev, skb);
230
231 return IRQ_HANDLED;
232}
233
234static void fdp_nci_i2c_read_device_properties(struct device *dev,
235 u8 *clock_type, u32 *clock_freq,
236 u8 **fw_vsc_cfg)
237{
238 int r;
239 u8 len;
240
241 r = device_property_read_u8(dev, FDP_DP_CLOCK_TYPE_NAME, clock_type);
242 if (r) {
243 dev_dbg(dev, "Using default clock type");
244 *clock_type = 0;
245 }
246
247 r = device_property_read_u32(dev, FDP_DP_CLOCK_FREQ_NAME, clock_freq);
248 if (r) {
249 dev_dbg(dev, "Using default clock frequency\n");
250 *clock_freq = 26000;
251 }
252
253 if (device_property_present(dev, FDP_DP_FW_VSC_CFG_NAME)) {
254 r = device_property_read_u8(dev, FDP_DP_FW_VSC_CFG_NAME,
255 &len);
256
257 if (r || len <= 0)
258 goto vsc_read_err;
259
260 /* Add 1 to the length to inclue the length byte itself */
261 len++;
262
263 *fw_vsc_cfg = devm_kmalloc(dev,
264 len * sizeof(**fw_vsc_cfg),
265 GFP_KERNEL);
266
267 r = device_property_read_u8_array(dev, FDP_DP_FW_VSC_CFG_NAME,
268 *fw_vsc_cfg, len);
269
270 if (r) {
271 devm_kfree(dev, fw_vsc_cfg);
272 goto vsc_read_err;
273 }
274 } else {
275vsc_read_err:
276 dev_dbg(dev, "FW vendor specific commands not present\n");
277 *fw_vsc_cfg = NULL;
278 }
279
280 dev_dbg(dev, "Clock type: %d, clock frequency: %d, VSC: %s",
281 *clock_type, *clock_freq, *fw_vsc_cfg != NULL ? "yes" : "no");
282}
283
284static int fdp_nci_i2c_probe(struct i2c_client *client,
285 const struct i2c_device_id *id)
286{
287 struct fdp_i2c_phy *phy;
288 struct device *dev = &client->dev;
289 u8 *fw_vsc_cfg;
290 u8 clock_type;
291 u32 clock_freq;
292 int r = 0;
293
294 dev_dbg(dev, "%s\n", __func__);
295
296 if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
297 nfc_err(dev, "No I2C_FUNC_I2C support\n");
298 return -ENODEV;
299 }
300
301 phy = devm_kzalloc(dev, sizeof(struct fdp_i2c_phy),
302 GFP_KERNEL);
303 if (!phy)
304 return -ENOMEM;
305
306 phy->i2c_dev = client;
307 phy->next_read_size = FDP_NCI_I2C_MIN_PAYLOAD;
308 i2c_set_clientdata(client, phy);
309
310 /* Checking if we have an irq */
311 if (client->irq <= 0) {
312 dev_err(dev, "IRQ not present\n");
313 return -ENODEV;
314 }
315
316 r = request_threaded_irq(client->irq, NULL, fdp_nci_i2c_irq_thread_fn,
317 IRQF_TRIGGER_RISING | IRQF_ONESHOT,
318 FDP_I2C_DRIVER_NAME, phy);
319
320 if (r < 0) {
321 nfc_err(&client->dev, "Unable to register IRQ handler\n");
322 return r;
323 }
324
325 /* Requesting the power gpio */
326 phy->power_gpio = devm_gpiod_get(dev, FDP_DP_POWER_GPIO_NAME,
327 GPIOD_OUT_LOW);
328
329 if (IS_ERR(phy->power_gpio)) {
330 nfc_err(dev, "Power GPIO request failed\n");
331 return PTR_ERR(phy->power_gpio);
332 }
333
334 /* read device properties to get the clock and production settings */
335 fdp_nci_i2c_read_device_properties(dev, &clock_type, &clock_freq,
336 &fw_vsc_cfg);
337
338 /* Call the NFC specific probe function */
339 r = fdp_nci_probe(phy, &i2c_phy_ops, &phy->ndev,
340 FDP_FRAME_HEADROOM, FDP_FRAME_TAILROOM,
341 clock_type, clock_freq, fw_vsc_cfg);
342 if (r < 0) {
343 nfc_err(dev, "NCI probing error\n");
344 return r;
345 }
346
347 dev_dbg(dev, "I2C driver loaded\n");
348 return 0;
349}
350
351static int fdp_nci_i2c_remove(struct i2c_client *client)
352{
353 struct fdp_i2c_phy *phy = i2c_get_clientdata(client);
354
355 dev_dbg(&client->dev, "%s\n", __func__);
356
357 fdp_nci_remove(phy->ndev);
358 fdp_nci_i2c_disable(phy);
359
360 return 0;
361}
362
363static struct i2c_device_id fdp_nci_i2c_id_table[] = {
364 {"int339a", 0},
365 {}
366};
367MODULE_DEVICE_TABLE(i2c, fdp_nci_i2c_id_table);
368
369static const struct acpi_device_id fdp_nci_i2c_acpi_match[] = {
370 {"INT339A", 0},
371 {}
372};
373MODULE_DEVICE_TABLE(acpi, fdp_nci_i2c_acpi_match);
374
375static struct i2c_driver fdp_nci_i2c_driver = {
376 .driver = {
377 .name = FDP_I2C_DRIVER_NAME,
378 .acpi_match_table = ACPI_PTR(fdp_nci_i2c_acpi_match),
379 },
380 .id_table = fdp_nci_i2c_id_table,
381 .probe = fdp_nci_i2c_probe,
382 .remove = fdp_nci_i2c_remove,
383};
384module_i2c_driver(fdp_nci_i2c_driver);
385
386MODULE_LICENSE("GPL");
387MODULE_DESCRIPTION("I2C driver for Intel Fields Peak NFC controller");
388MODULE_AUTHOR("Robert Dolca <robert.dolca@intel.com>");