aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/nfc
diff options
context:
space:
mode:
authorThierry Escande <thierry.escande@linux.intel.com>2013-10-04 06:12:00 -0400
committerSamuel Ortiz <sameo@linux.intel.com>2013-10-07 08:09:33 -0400
commit562d4d59b8a1d5f3ca75115d6ac10c7b7bc68c06 (patch)
tree825309abdc1268dbd44f584ce4ba9a414d491cb3 /drivers/nfc
parent93ad42020c2d3fb4a277cc04c014e1ea0d8b0850 (diff)
NFC: Sony Port-100 Series driver
This adds support for the Sony NFC USB dongle RC-S380, based on the Port-100 chip. This dongle is an analog frontend and does not implement the digital layer. This driver uses the nfc_digital module which is an implementation of the NFC Digital Protocol stack. This patch is a skeleton. It only registers the dongle against the NFC digital protocol stack. All NFC digital operation functions are stubbed out. Signed-off-by: Thierry Escande <thierry.escande@linux.intel.com> Cc: Stephen Tiedemann <stephen.tiedemann@gmail.com> Tested-by: Cho, Yu-Chen <acho@suse.com> Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
Diffstat (limited to 'drivers/nfc')
-rw-r--r--drivers/nfc/Kconfig10
-rw-r--r--drivers/nfc/Makefile1
-rw-r--r--drivers/nfc/port100.c187
3 files changed, 198 insertions, 0 deletions
diff --git a/drivers/nfc/Kconfig b/drivers/nfc/Kconfig
index b0b64ccb7d7d..c1fb20603338 100644
--- a/drivers/nfc/Kconfig
+++ b/drivers/nfc/Kconfig
@@ -46,6 +46,16 @@ config NFC_SIM
46 46
47 If unsure, say N. 47 If unsure, say N.
48 48
49config NFC_PORT100
50 tristate "Sony NFC Port-100 Series USB device support"
51 depends on USB
52 depends on NFC_DIGITAL
53 help
54 This adds support for Sony Port-100 chip based USB devices such as the
55 RC-S380 dongle.
56
57 If unsure, say N.
58
49source "drivers/nfc/pn544/Kconfig" 59source "drivers/nfc/pn544/Kconfig"
50source "drivers/nfc/microread/Kconfig" 60source "drivers/nfc/microread/Kconfig"
51 61
diff --git a/drivers/nfc/Makefile b/drivers/nfc/Makefile
index be7636abcb3f..c715fe8582a8 100644
--- a/drivers/nfc/Makefile
+++ b/drivers/nfc/Makefile
@@ -8,5 +8,6 @@ obj-$(CONFIG_NFC_PN533) += pn533.o
8obj-$(CONFIG_NFC_WILINK) += nfcwilink.o 8obj-$(CONFIG_NFC_WILINK) += nfcwilink.o
9obj-$(CONFIG_NFC_MEI_PHY) += mei_phy.o 9obj-$(CONFIG_NFC_MEI_PHY) += mei_phy.o
10obj-$(CONFIG_NFC_SIM) += nfcsim.o 10obj-$(CONFIG_NFC_SIM) += nfcsim.o
11obj-$(CONFIG_NFC_PORT100) += port100.o
11 12
12ccflags-$(CONFIG_NFC_DEBUG) := -DDEBUG 13ccflags-$(CONFIG_NFC_DEBUG) := -DDEBUG
diff --git a/drivers/nfc/port100.c b/drivers/nfc/port100.c
new file mode 100644
index 000000000000..f167907ae39c
--- /dev/null
+++ b/drivers/nfc/port100.c
@@ -0,0 +1,187 @@
1/*
2 * Sony NFC Port-100 Series driver
3 * Copyright (c) 2013, Intel Corporation.
4 *
5 * Partly based/Inspired by Stephen Tiedemann's nfcpy
6 *
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms and conditions of the GNU General Public License,
9 * version 2, as published by the Free Software Foundation.
10 *
11 * This program is distributed in the hope it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
14 * more details.
15 *
16 */
17
18#include <linux/module.h>
19#include <linux/usb.h>
20#include <net/nfc/digital.h>
21
22#define VERSION "0.1"
23
24#define SONY_VENDOR_ID 0x054c
25#define RCS380_PRODUCT_ID 0x06c1
26
27#define PORT100_PROTOCOLS (NFC_PROTO_JEWEL_MASK | \
28 NFC_PROTO_MIFARE_MASK | \
29 NFC_PROTO_FELICA_MASK | \
30 NFC_PROTO_NFC_DEP_MASK)
31
32#define PORT100_CAPABILITIES (NFC_DIGITAL_DRV_CAPS_IN_CRC | \
33 NFC_DIGITAL_DRV_CAPS_TG_CRC)
34
35struct port100 {
36 struct nfc_digital_dev *nfc_digital_dev;
37
38 int skb_headroom;
39 int skb_tailroom;
40
41 struct usb_device *udev;
42 struct usb_interface *interface;
43};
44
45static void port100_abort_cmd(struct nfc_digital_dev *ddev)
46{
47}
48
49static int port100_switch_rf(struct nfc_digital_dev *ddev, bool on)
50{
51 return -EOPNOTSUPP;
52}
53
54static int port100_in_configure_hw(struct nfc_digital_dev *ddev, int type,
55 int param)
56{
57 return -EOPNOTSUPP;
58}
59
60static int port100_in_send_cmd(struct nfc_digital_dev *ddev,
61 struct sk_buff *skb, u16 _timeout,
62 nfc_digital_cmd_complete_t cb, void *arg)
63{
64 return -EOPNOTSUPP;
65}
66
67static int port100_tg_configure_hw(struct nfc_digital_dev *ddev, int type,
68 int param)
69{
70 return -EOPNOTSUPP;
71}
72
73static int port100_tg_send_cmd(struct nfc_digital_dev *ddev,
74 struct sk_buff *skb, u16 timeout,
75 nfc_digital_cmd_complete_t cb, void *arg)
76{
77 return -EOPNOTSUPP;
78}
79
80static int port100_listen_mdaa(struct nfc_digital_dev *ddev,
81 struct digital_tg_mdaa_params *params,
82 u16 timeout,
83 nfc_digital_cmd_complete_t cb, void *arg)
84{
85 return -EOPNOTSUPP;
86}
87
88static int port100_listen(struct nfc_digital_dev *ddev, u16 timeout,
89 nfc_digital_cmd_complete_t cb, void *arg)
90{
91 return -EOPNOTSUPP;
92}
93
94static struct nfc_digital_ops port100_digital_ops = {
95 .in_configure_hw = port100_in_configure_hw,
96 .in_send_cmd = port100_in_send_cmd,
97
98 .tg_listen_mdaa = port100_listen_mdaa,
99 .tg_listen = port100_listen,
100 .tg_configure_hw = port100_tg_configure_hw,
101 .tg_send_cmd = port100_tg_send_cmd,
102
103 .switch_rf = port100_switch_rf,
104 .abort_cmd = port100_abort_cmd,
105};
106
107static const struct usb_device_id port100_table[] = {
108 { .match_flags = USB_DEVICE_ID_MATCH_DEVICE,
109 .idVendor = SONY_VENDOR_ID,
110 .idProduct = RCS380_PRODUCT_ID,
111 },
112 { }
113};
114MODULE_DEVICE_TABLE(usb, port100_table);
115
116static int port100_probe(struct usb_interface *interface,
117 const struct usb_device_id *id)
118{
119 struct port100 *dev;
120 int rc;
121
122 dev = devm_kzalloc(&interface->dev, sizeof(struct port100), GFP_KERNEL);
123 if (!dev)
124 return -ENOMEM;
125
126 dev->udev = usb_get_dev(interface_to_usbdev(interface));
127 dev->interface = interface;
128 usb_set_intfdata(interface, dev);
129
130 nfc_info(&interface->dev, "Sony NFC Port-100 Series attached\n");
131
132 dev->nfc_digital_dev = nfc_digital_allocate_device(&port100_digital_ops,
133 PORT100_PROTOCOLS,
134 PORT100_CAPABILITIES,
135 dev->skb_headroom,
136 dev->skb_tailroom);
137 if (!dev->nfc_digital_dev) {
138 nfc_err(&interface->dev,
139 "Could not allocate nfc_digital_dev.\n");
140 rc = -ENOMEM;
141 goto error;
142 }
143
144 nfc_digital_set_parent_dev(dev->nfc_digital_dev, &interface->dev);
145 nfc_digital_set_drvdata(dev->nfc_digital_dev, dev);
146
147 rc = nfc_digital_register_device(dev->nfc_digital_dev);
148 if (rc) {
149 nfc_err(&interface->dev,
150 "Could not register digital device.\n");
151 goto free_nfc_dev;
152 }
153
154 return 0;
155
156free_nfc_dev:
157 nfc_digital_free_device(dev->nfc_digital_dev);
158
159error:
160 return rc;
161}
162
163static void port100_disconnect(struct usb_interface *interface)
164{
165 struct port100 *dev;
166
167 dev = usb_get_intfdata(interface);
168 usb_set_intfdata(interface, NULL);
169
170 nfc_digital_unregister_device(dev->nfc_digital_dev);
171 nfc_digital_free_device(dev->nfc_digital_dev);
172
173 nfc_info(&interface->dev, "Sony Port-100 NFC device disconnected");
174}
175
176static struct usb_driver port100_driver = {
177 .name = "port100",
178 .probe = port100_probe,
179 .disconnect = port100_disconnect,
180 .id_table = port100_table,
181};
182
183module_usb_driver(port100_driver);
184
185MODULE_DESCRIPTION("NFC Port-100 series usb driver ver " VERSION);
186MODULE_VERSION(VERSION);
187MODULE_LICENSE("GPL");