]>
Commit | Line | Data |
---|---|---|
dd7bedcd MT |
1 | /* |
2 | * Driver for NXP PN533 NFC Chip - I2C transport layer | |
3 | * | |
4 | * Copyright (C) 2011 Instituto Nokia de Tecnologia | |
5 | * Copyright (C) 2012-2013 Tieto Poland | |
6 | * Copyright (C) 2016 HALE electronic | |
7 | * | |
8 | * | |
9 | * This program is free software; you can redistribute it and/or modify | |
10 | * it under the terms of the GNU General Public License as published by | |
11 | * the Free Software Foundation; either version 2 of the License, or | |
12 | * (at your option) any later version. | |
13 | * | |
14 | * This program is distributed in the hope that it will be useful, | |
15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
17 | * GNU General Public License for more details. | |
18 | * | |
19 | * You should have received a copy of the GNU General Public License | |
20 | * along with this program; if not, see <http://www.gnu.org/licenses/>. | |
21 | */ | |
22 | ||
23 | #include <linux/device.h> | |
24 | #include <linux/kernel.h> | |
25 | #include <linux/module.h> | |
26 | #include <linux/slab.h> | |
27 | #include <linux/i2c.h> | |
28 | #include <linux/nfc.h> | |
29 | #include <linux/netdevice.h> | |
30 | #include <linux/interrupt.h> | |
31 | #include <net/nfc/nfc.h> | |
32 | #include "pn533.h" | |
33 | ||
34 | #define VERSION "0.1" | |
35 | ||
36 | #define PN533_I2C_DRIVER_NAME "pn533_i2c" | |
37 | ||
38 | struct pn533_i2c_phy { | |
39 | struct i2c_client *i2c_dev; | |
40 | struct pn533 *priv; | |
41 | ||
30f98489 MT |
42 | bool aborted; |
43 | ||
dd7bedcd MT |
44 | int hard_fault; /* |
45 | * < 0 if hardware error occurred (e.g. i2c err) | |
46 | * and prevents normal operation. | |
47 | */ | |
48 | }; | |
49 | ||
50 | static int pn533_i2c_send_ack(struct pn533 *dev, gfp_t flags) | |
51 | { | |
52 | struct pn533_i2c_phy *phy = dev->phy; | |
53 | struct i2c_client *client = phy->i2c_dev; | |
8b55d758 | 54 | static const u8 ack[6] = {0x00, 0x00, 0xff, 0x00, 0xff, 0x00}; |
dd7bedcd MT |
55 | /* spec 6.2.1.3: Preamble, SoPC (2), ACK Code (2), Postamble */ |
56 | int rc; | |
57 | ||
58 | rc = i2c_master_send(client, ack, 6); | |
59 | ||
60 | return rc; | |
61 | } | |
62 | ||
63 | static int pn533_i2c_send_frame(struct pn533 *dev, | |
64 | struct sk_buff *out) | |
65 | { | |
66 | struct pn533_i2c_phy *phy = dev->phy; | |
67 | struct i2c_client *client = phy->i2c_dev; | |
68 | int rc; | |
69 | ||
70 | if (phy->hard_fault != 0) | |
71 | return phy->hard_fault; | |
72 | ||
73 | if (phy->priv == NULL) | |
74 | phy->priv = dev; | |
75 | ||
30f98489 MT |
76 | phy->aborted = false; |
77 | ||
dd7bedcd MT |
78 | print_hex_dump_debug("PN533_i2c TX: ", DUMP_PREFIX_NONE, 16, 1, |
79 | out->data, out->len, false); | |
80 | ||
81 | rc = i2c_master_send(client, out->data, out->len); | |
82 | ||
83 | if (rc == -EREMOTEIO) { /* Retry, chip was in power down */ | |
84 | usleep_range(6000, 10000); | |
85 | rc = i2c_master_send(client, out->data, out->len); | |
86 | } | |
87 | ||
88 | if (rc >= 0) { | |
89 | if (rc != out->len) | |
90 | rc = -EREMOTEIO; | |
91 | else | |
92 | rc = 0; | |
93 | } | |
94 | ||
95 | return rc; | |
96 | } | |
97 | ||
98 | static void pn533_i2c_abort_cmd(struct pn533 *dev, gfp_t flags) | |
99 | { | |
30f98489 MT |
100 | struct pn533_i2c_phy *phy = dev->phy; |
101 | ||
102 | phy->aborted = true; | |
103 | ||
dd7bedcd MT |
104 | /* An ack will cancel the last issued command */ |
105 | pn533_i2c_send_ack(dev, flags); | |
106 | ||
107 | /* schedule cmd_complete_work to finish current command execution */ | |
30f98489 | 108 | pn533_recv_frame(phy->priv, NULL, -ENOENT); |
dd7bedcd MT |
109 | } |
110 | ||
111 | static int pn533_i2c_read(struct pn533_i2c_phy *phy, struct sk_buff **skb) | |
112 | { | |
113 | struct i2c_client *client = phy->i2c_dev; | |
114 | int len = PN533_EXT_FRAME_HEADER_LEN + | |
115 | PN533_STD_FRAME_MAX_PAYLOAD_LEN + | |
116 | PN533_STD_FRAME_TAIL_LEN + 1; | |
117 | int r; | |
118 | ||
119 | *skb = alloc_skb(len, GFP_KERNEL); | |
120 | if (*skb == NULL) | |
121 | return -ENOMEM; | |
122 | ||
123 | r = i2c_master_recv(client, skb_put(*skb, len), len); | |
124 | if (r != len) { | |
125 | nfc_err(&client->dev, "cannot read. r=%d len=%d\n", r, len); | |
126 | kfree_skb(*skb); | |
127 | return -EREMOTEIO; | |
128 | } | |
129 | ||
130 | if (!((*skb)->data[0] & 0x01)) { | |
131 | nfc_err(&client->dev, "READY flag not set"); | |
132 | kfree_skb(*skb); | |
133 | return -EBUSY; | |
134 | } | |
135 | ||
136 | /* remove READY byte */ | |
137 | skb_pull(*skb, 1); | |
138 | /* trim to frame size */ | |
139 | skb_trim(*skb, phy->priv->ops->rx_frame_size((*skb)->data)); | |
140 | ||
141 | return 0; | |
142 | } | |
143 | ||
144 | static irqreturn_t pn533_i2c_irq_thread_fn(int irq, void *data) | |
145 | { | |
146 | struct pn533_i2c_phy *phy = data; | |
147 | struct i2c_client *client; | |
148 | struct sk_buff *skb = NULL; | |
149 | int r; | |
150 | ||
151 | if (!phy || irq != phy->i2c_dev->irq) { | |
152 | WARN_ON_ONCE(1); | |
153 | return IRQ_NONE; | |
154 | } | |
155 | ||
156 | client = phy->i2c_dev; | |
157 | dev_dbg(&client->dev, "IRQ\n"); | |
158 | ||
159 | if (phy->hard_fault != 0) | |
160 | return IRQ_HANDLED; | |
161 | ||
162 | r = pn533_i2c_read(phy, &skb); | |
163 | if (r == -EREMOTEIO) { | |
164 | phy->hard_fault = r; | |
165 | ||
166 | pn533_recv_frame(phy->priv, NULL, -EREMOTEIO); | |
167 | ||
168 | return IRQ_HANDLED; | |
169 | } else if ((r == -ENOMEM) || (r == -EBADMSG) || (r == -EBUSY)) { | |
170 | return IRQ_HANDLED; | |
171 | } | |
172 | ||
30f98489 MT |
173 | if (!phy->aborted) |
174 | pn533_recv_frame(phy->priv, skb, 0); | |
dd7bedcd MT |
175 | |
176 | return IRQ_HANDLED; | |
177 | } | |
178 | ||
179 | static struct pn533_phy_ops i2c_phy_ops = { | |
180 | .send_frame = pn533_i2c_send_frame, | |
181 | .send_ack = pn533_i2c_send_ack, | |
182 | .abort_cmd = pn533_i2c_abort_cmd, | |
183 | }; | |
184 | ||
185 | ||
186 | static int pn533_i2c_probe(struct i2c_client *client, | |
187 | const struct i2c_device_id *id) | |
188 | { | |
189 | struct pn533_i2c_phy *phy; | |
190 | struct pn533 *priv; | |
191 | int r = 0; | |
192 | ||
193 | dev_dbg(&client->dev, "%s\n", __func__); | |
194 | dev_dbg(&client->dev, "IRQ: %d\n", client->irq); | |
195 | ||
196 | if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) { | |
197 | nfc_err(&client->dev, "Need I2C_FUNC_I2C\n"); | |
198 | return -ENODEV; | |
199 | } | |
200 | ||
201 | phy = devm_kzalloc(&client->dev, sizeof(struct pn533_i2c_phy), | |
202 | GFP_KERNEL); | |
203 | if (!phy) | |
204 | return -ENOMEM; | |
205 | ||
206 | phy->i2c_dev = client; | |
207 | i2c_set_clientdata(client, phy); | |
208 | ||
dd7bedcd MT |
209 | priv = pn533_register_device(PN533_DEVICE_PN532, |
210 | PN533_NO_TYPE_B_PROTOCOLS, | |
211 | PN533_PROTO_REQ_ACK_RESP, | |
212 | phy, &i2c_phy_ops, NULL, | |
b16931b1 MT |
213 | &phy->i2c_dev->dev, |
214 | &client->dev); | |
dd7bedcd MT |
215 | |
216 | if (IS_ERR(priv)) { | |
217 | r = PTR_ERR(priv); | |
32ecc75d | 218 | return r; |
dd7bedcd MT |
219 | } |
220 | ||
221 | phy->priv = priv; | |
222 | ||
32ecc75d AR |
223 | r = request_threaded_irq(client->irq, NULL, pn533_i2c_irq_thread_fn, |
224 | IRQF_TRIGGER_FALLING | | |
225 | IRQF_SHARED | IRQF_ONESHOT, | |
226 | PN533_I2C_DRIVER_NAME, phy); | |
227 | if (r < 0) { | |
228 | nfc_err(&client->dev, "Unable to register IRQ handler\n"); | |
229 | goto irq_rqst_err; | |
230 | } | |
231 | ||
232 | r = pn533_finalize_setup(priv); | |
233 | if (r) | |
234 | goto fn_setup_err; | |
235 | ||
dd7bedcd MT |
236 | return 0; |
237 | ||
32ecc75d | 238 | fn_setup_err: |
dd7bedcd MT |
239 | free_irq(client->irq, phy); |
240 | ||
32ecc75d AR |
241 | irq_rqst_err: |
242 | pn533_unregister_device(phy->priv); | |
243 | ||
dd7bedcd MT |
244 | return r; |
245 | } | |
246 | ||
247 | static int pn533_i2c_remove(struct i2c_client *client) | |
248 | { | |
249 | struct pn533_i2c_phy *phy = i2c_get_clientdata(client); | |
250 | ||
251 | dev_dbg(&client->dev, "%s\n", __func__); | |
252 | ||
79f09fa7 MT |
253 | free_irq(client->irq, phy); |
254 | ||
068a496c AR |
255 | pn533_unregister_device(phy->priv); |
256 | ||
dd7bedcd MT |
257 | return 0; |
258 | } | |
259 | ||
260 | static const struct of_device_id of_pn533_i2c_match[] = { | |
261 | { .compatible = "nxp,pn533-i2c", }, | |
262 | { .compatible = "nxp,pn532-i2c", }, | |
263 | {}, | |
264 | }; | |
265 | MODULE_DEVICE_TABLE(of, of_pn533_i2c_match); | |
266 | ||
f98786da | 267 | static const struct i2c_device_id pn533_i2c_id_table[] = { |
dd7bedcd MT |
268 | { PN533_I2C_DRIVER_NAME, 0 }, |
269 | {} | |
270 | }; | |
271 | MODULE_DEVICE_TABLE(i2c, pn533_i2c_id_table); | |
272 | ||
273 | static struct i2c_driver pn533_i2c_driver = { | |
274 | .driver = { | |
275 | .name = PN533_I2C_DRIVER_NAME, | |
276 | .owner = THIS_MODULE, | |
277 | .of_match_table = of_match_ptr(of_pn533_i2c_match), | |
278 | }, | |
279 | .probe = pn533_i2c_probe, | |
280 | .id_table = pn533_i2c_id_table, | |
281 | .remove = pn533_i2c_remove, | |
282 | }; | |
283 | ||
284 | module_i2c_driver(pn533_i2c_driver); | |
285 | ||
286 | MODULE_AUTHOR("Michael Thalmeier <[email protected]>"); | |
287 | MODULE_DESCRIPTION("PN533 I2C driver ver " VERSION); | |
288 | MODULE_VERSION(VERSION); | |
289 | MODULE_LICENSE("GPL"); |