Commit | Line | Data |
---|---|---|
0329326e MA |
1 | /* |
2 | * Driver for the PN544 NFC chip. | |
3 | * | |
4 | * Copyright (C) Nokia Corporation | |
5 | * | |
6 | * Author: Jari Vanhala <ext-jari.vanhala@nokia.com> | |
7 | * Contact: Matti Aaltonen <matti.j.aaltonen@nokia.com> | |
8 | * | |
9 | * This program is free software; you can redistribute it and/or | |
10 | * modify it under the terms of the GNU General Public License | |
11 | * version 2 as published by the Free Software Foundation. | |
12 | * | |
13 | * This program is distributed in the hope that it will be useful, | |
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
16 | * GNU General Public License for more details. | |
17 | * | |
18 | * You should have received a copy of the GNU General Public License | |
19 | * along with this program; if not, write to the Free Software | |
20 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |
21 | */ | |
22 | ||
23 | #include <linux/completion.h> | |
24 | #include <linux/crc-ccitt.h> | |
25 | #include <linux/delay.h> | |
26 | #include <linux/interrupt.h> | |
27 | #include <linux/kernel.h> | |
28 | #include <linux/miscdevice.h> | |
29 | #include <linux/module.h> | |
30 | #include <linux/mutex.h> | |
31 | #include <linux/nfc/pn544.h> | |
32 | #include <linux/poll.h> | |
33 | #include <linux/regulator/consumer.h> | |
34 | #include <linux/serial_core.h> /* for TCGETS */ | |
35 | #include <linux/slab.h> | |
36 | ||
37 | #define DRIVER_CARD "PN544 NFC" | |
38 | #define DRIVER_DESC "NFC driver for PN544" | |
39 | ||
40 | static struct i2c_device_id pn544_id_table[] = { | |
41 | { PN544_DRIVER_NAME, 0 }, | |
42 | { } | |
43 | }; | |
44 | MODULE_DEVICE_TABLE(i2c, pn544_id_table); | |
45 | ||
46 | #define HCI_MODE 0 | |
47 | #define FW_MODE 1 | |
48 | ||
49 | enum pn544_state { | |
50 | PN544_ST_COLD, | |
51 | PN544_ST_FW_READY, | |
52 | PN544_ST_READY, | |
53 | }; | |
54 | ||
55 | enum pn544_irq { | |
56 | PN544_NONE, | |
57 | PN544_INT, | |
58 | }; | |
59 | ||
60 | struct pn544_info { | |
61 | struct miscdevice miscdev; | |
62 | struct i2c_client *i2c_dev; | |
63 | struct regulator_bulk_data regs[2]; | |
64 | ||
65 | enum pn544_state state; | |
66 | wait_queue_head_t read_wait; | |
67 | loff_t read_offset; | |
68 | enum pn544_irq read_irq; | |
69 | struct mutex read_mutex; /* Serialize read_irq access */ | |
70 | struct mutex mutex; /* Serialize info struct access */ | |
71 | u8 *buf; | |
72 | unsigned int buflen; | |
73 | }; | |
74 | ||
75 | static const char reg_vdd_io[] = "Vdd_IO"; | |
76 | static const char reg_vbat[] = "VBat"; | |
77 | ||
78 | /* sysfs interface */ | |
79 | static ssize_t pn544_test(struct device *dev, | |
80 | struct device_attribute *attr, char *buf) | |
81 | { | |
82 | struct pn544_info *info = dev_get_drvdata(dev); | |
83 | struct i2c_client *client = info->i2c_dev; | |
84 | struct pn544_nfc_platform_data *pdata = client->dev.platform_data; | |
85 | ||
86 | return snprintf(buf, PAGE_SIZE, "%d\n", pdata->test()); | |
87 | } | |
88 | ||
89 | static int pn544_enable(struct pn544_info *info, int mode) | |
90 | { | |
91 | struct pn544_nfc_platform_data *pdata; | |
92 | struct i2c_client *client = info->i2c_dev; | |
93 | ||
94 | int r; | |
95 | ||
96 | r = regulator_bulk_enable(ARRAY_SIZE(info->regs), info->regs); | |
97 | if (r < 0) | |
98 | return r; | |
99 | ||
100 | pdata = client->dev.platform_data; | |
101 | info->read_irq = PN544_NONE; | |
102 | if (pdata->enable) | |
103 | pdata->enable(mode); | |
104 | ||
105 | if (mode) { | |
106 | info->state = PN544_ST_FW_READY; | |
107 | dev_dbg(&client->dev, "now in FW-mode\n"); | |
108 | } else { | |
109 | info->state = PN544_ST_READY; | |
110 | dev_dbg(&client->dev, "now in HCI-mode\n"); | |
111 | } | |
112 | ||
113 | usleep_range(10000, 15000); | |
114 | ||
115 | return 0; | |
116 | } | |
117 | ||
118 | static void pn544_disable(struct pn544_info *info) | |
119 | { | |
120 | struct pn544_nfc_platform_data *pdata; | |
121 | struct i2c_client *client = info->i2c_dev; | |
122 | ||
123 | pdata = client->dev.platform_data; | |
124 | if (pdata->disable) | |
125 | pdata->disable(); | |
126 | ||
127 | info->state = PN544_ST_COLD; | |
128 | ||
129 | dev_dbg(&client->dev, "Now in OFF-mode\n"); | |
130 | ||
131 | msleep(PN544_RESETVEN_TIME); | |
132 | ||
133 | info->read_irq = PN544_NONE; | |
134 | regulator_bulk_disable(ARRAY_SIZE(info->regs), info->regs); | |
135 | } | |
136 | ||
137 | static int check_crc(u8 *buf, int buflen) | |
138 | { | |
139 | u8 len; | |
140 | u16 crc; | |
141 | ||
142 | len = buf[0] + 1; | |
143 | if (len < 4 || len != buflen || len > PN544_MSG_MAX_SIZE) { | |
144 | pr_err(PN544_DRIVER_NAME | |
145 | ": CRC; corrupt packet len %u (%d)\n", len, buflen); | |
146 | print_hex_dump(KERN_DEBUG, "crc: ", DUMP_PREFIX_NONE, | |
147 | 16, 2, buf, buflen, false); | |
148 | return -EPERM; | |
149 | } | |
150 | crc = crc_ccitt(0xffff, buf, len - 2); | |
151 | crc = ~crc; | |
152 | ||
153 | if (buf[len-2] != (crc & 0xff) || buf[len-1] != (crc >> 8)) { | |
154 | pr_err(PN544_DRIVER_NAME ": CRC error 0x%x != 0x%x 0x%x\n", | |
155 | crc, buf[len-1], buf[len-2]); | |
156 | ||
157 | print_hex_dump(KERN_DEBUG, "crc: ", DUMP_PREFIX_NONE, | |
158 | 16, 2, buf, buflen, false); | |
159 | return -EPERM; | |
160 | } | |
161 | return 0; | |
162 | } | |
163 | ||
164 | static int pn544_i2c_write(struct i2c_client *client, u8 *buf, int len) | |
165 | { | |
166 | int r; | |
167 | ||
168 | if (len < 4 || len != (buf[0] + 1)) { | |
169 | dev_err(&client->dev, "%s: Illegal message length: %d\n", | |
170 | __func__, len); | |
171 | return -EINVAL; | |
172 | } | |
173 | ||
174 | if (check_crc(buf, len)) | |
175 | return -EINVAL; | |
176 | ||
177 | usleep_range(3000, 6000); | |
178 | ||
179 | r = i2c_master_send(client, buf, len); | |
180 | dev_dbg(&client->dev, "send: %d\n", r); | |
181 | ||
182 | if (r == -EREMOTEIO) { /* Retry, chip was in standby */ | |
183 | usleep_range(6000, 10000); | |
184 | r = i2c_master_send(client, buf, len); | |
185 | dev_dbg(&client->dev, "send2: %d\n", r); | |
186 | } | |
187 | ||
188 | if (r != len) | |
189 | return -EREMOTEIO; | |
190 | ||
191 | return r; | |
192 | } | |
193 | ||
194 | static int pn544_i2c_read(struct i2c_client *client, u8 *buf, int buflen) | |
195 | { | |
196 | int r; | |
197 | u8 len; | |
198 | ||
199 | /* | |
200 | * You could read a packet in one go, but then you'd need to read | |
201 | * max size and rest would be 0xff fill, so we do split reads. | |
202 | */ | |
203 | r = i2c_master_recv(client, &len, 1); | |
204 | dev_dbg(&client->dev, "recv1: %d\n", r); | |
205 | ||
206 | if (r != 1) | |
207 | return -EREMOTEIO; | |
208 | ||
209 | if (len < PN544_LLC_HCI_OVERHEAD) | |
210 | len = PN544_LLC_HCI_OVERHEAD; | |
211 | else if (len > (PN544_MSG_MAX_SIZE - 1)) | |
212 | len = PN544_MSG_MAX_SIZE - 1; | |
213 | ||
214 | if (1 + len > buflen) /* len+(data+crc16) */ | |
215 | return -EMSGSIZE; | |
216 | ||
217 | buf[0] = len; | |
218 | ||
219 | r = i2c_master_recv(client, buf + 1, len); | |
220 | dev_dbg(&client->dev, "recv2: %d\n", r); | |
221 | ||
222 | if (r != len) | |
223 | return -EREMOTEIO; | |
224 | ||
225 | usleep_range(3000, 6000); | |
226 | ||
227 | return r + 1; | |
228 | } | |
229 | ||
230 | static int pn544_fw_write(struct i2c_client *client, u8 *buf, int len) | |
231 | { | |
232 | int r; | |
233 | ||
234 | dev_dbg(&client->dev, "%s\n", __func__); | |
235 | ||
236 | if (len < PN544_FW_HEADER_SIZE || | |
237 | (PN544_FW_HEADER_SIZE + (buf[1] << 8) + buf[2]) != len) | |
238 | return -EINVAL; | |
239 | ||
240 | r = i2c_master_send(client, buf, len); | |
241 | dev_dbg(&client->dev, "fw send: %d\n", r); | |
242 | ||
243 | if (r == -EREMOTEIO) { /* Retry, chip was in standby */ | |
244 | usleep_range(6000, 10000); | |
245 | r = i2c_master_send(client, buf, len); | |
246 | dev_dbg(&client->dev, "fw send2: %d\n", r); | |
247 | } | |
248 | ||
249 | if (r != len) | |
250 | return -EREMOTEIO; | |
251 | ||
252 | return r; | |
253 | } | |
254 | ||
255 | static int pn544_fw_read(struct i2c_client *client, u8 *buf, int buflen) | |
256 | { | |
257 | int r, len; | |
258 | ||
259 | if (buflen < PN544_FW_HEADER_SIZE) | |
260 | return -EINVAL; | |
261 | ||
262 | r = i2c_master_recv(client, buf, PN544_FW_HEADER_SIZE); | |
263 | dev_dbg(&client->dev, "FW recv1: %d\n", r); | |
264 | ||
265 | if (r < 0) | |
266 | return r; | |
267 | ||
268 | if (r < PN544_FW_HEADER_SIZE) | |
269 | return -EINVAL; | |
270 | ||
271 | len = (buf[1] << 8) + buf[2]; | |
272 | if (len == 0) /* just header, no additional data */ | |
273 | return r; | |
274 | ||
275 | if (len > buflen - PN544_FW_HEADER_SIZE) | |
276 | return -EMSGSIZE; | |
277 | ||
278 | r = i2c_master_recv(client, buf + PN544_FW_HEADER_SIZE, len); | |
279 | dev_dbg(&client->dev, "fw recv2: %d\n", r); | |
280 | ||
281 | if (r != len) | |
282 | return -EINVAL; | |
283 | ||
284 | return r + PN544_FW_HEADER_SIZE; | |
285 | } | |
286 | ||
287 | static irqreturn_t pn544_irq_thread_fn(int irq, void *dev_id) | |
288 | { | |
289 | struct pn544_info *info = dev_id; | |
290 | struct i2c_client *client = info->i2c_dev; | |
291 | ||
292 | BUG_ON(!info); | |
293 | BUG_ON(irq != info->i2c_dev->irq); | |
294 | ||
295 | dev_dbg(&client->dev, "IRQ\n"); | |
296 | ||
297 | mutex_lock(&info->read_mutex); | |
298 | info->read_irq = PN544_INT; | |
299 | mutex_unlock(&info->read_mutex); | |
300 | ||
301 | wake_up_interruptible(&info->read_wait); | |
302 | ||
303 | return IRQ_HANDLED; | |
304 | } | |
305 | ||
306 | static enum pn544_irq pn544_irq_state(struct pn544_info *info) | |
307 | { | |
308 | enum pn544_irq irq; | |
309 | ||
310 | mutex_lock(&info->read_mutex); | |
311 | irq = info->read_irq; | |
312 | mutex_unlock(&info->read_mutex); | |
313 | /* | |
314 | * XXX: should we check GPIO-line status directly? | |
315 | * return pdata->irq_status() ? PN544_INT : PN544_NONE; | |
316 | */ | |
317 | ||
318 | return irq; | |
319 | } | |
320 | ||
321 | static ssize_t pn544_read(struct file *file, char __user *buf, | |
322 | size_t count, loff_t *offset) | |
323 | { | |
324 | struct pn544_info *info = container_of(file->private_data, | |
325 | struct pn544_info, miscdev); | |
326 | struct i2c_client *client = info->i2c_dev; | |
327 | enum pn544_irq irq; | |
328 | size_t len; | |
329 | int r = 0; | |
330 | ||
331 | dev_dbg(&client->dev, "%s: info: %p, count: %zu\n", __func__, | |
332 | info, count); | |
333 | ||
334 | mutex_lock(&info->mutex); | |
335 | ||
336 | if (info->state == PN544_ST_COLD) { | |
337 | r = -ENODEV; | |
338 | goto out; | |
339 | } | |
340 | ||
341 | irq = pn544_irq_state(info); | |
342 | if (irq == PN544_NONE) { | |
343 | if (file->f_flags & O_NONBLOCK) { | |
344 | r = -EAGAIN; | |
345 | goto out; | |
346 | } | |
347 | ||
348 | if (wait_event_interruptible(info->read_wait, | |
349 | (info->read_irq == PN544_INT))) { | |
350 | r = -ERESTARTSYS; | |
351 | goto out; | |
352 | } | |
353 | } | |
354 | ||
355 | if (info->state == PN544_ST_FW_READY) { | |
356 | len = min(count, info->buflen); | |
357 | ||
358 | mutex_lock(&info->read_mutex); | |
359 | r = pn544_fw_read(info->i2c_dev, info->buf, len); | |
360 | info->read_irq = PN544_NONE; | |
361 | mutex_unlock(&info->read_mutex); | |
362 | ||
363 | if (r < 0) { | |
364 | dev_err(&info->i2c_dev->dev, "FW read failed: %d\n", r); | |
365 | goto out; | |
366 | } | |
367 | ||
368 | print_hex_dump(KERN_DEBUG, "FW read: ", DUMP_PREFIX_NONE, | |
369 | 16, 2, info->buf, r, false); | |
370 | ||
371 | *offset += r; | |
372 | if (copy_to_user(buf, info->buf, r)) { | |
373 | r = -EFAULT; | |
374 | goto out; | |
375 | } | |
376 | } else { | |
377 | len = min(count, info->buflen); | |
378 | ||
379 | mutex_lock(&info->read_mutex); | |
380 | r = pn544_i2c_read(info->i2c_dev, info->buf, len); | |
381 | info->read_irq = PN544_NONE; | |
382 | mutex_unlock(&info->read_mutex); | |
383 | ||
384 | if (r < 0) { | |
385 | dev_err(&info->i2c_dev->dev, "read failed (%d)\n", r); | |
386 | goto out; | |
387 | } | |
388 | print_hex_dump(KERN_DEBUG, "read: ", DUMP_PREFIX_NONE, | |
389 | 16, 2, info->buf, r, false); | |
390 | ||
391 | *offset += r; | |
392 | if (copy_to_user(buf, info->buf, r)) { | |
393 | r = -EFAULT; | |
394 | goto out; | |
395 | } | |
396 | } | |
397 | ||
398 | out: | |
399 | mutex_unlock(&info->mutex); | |
400 | ||
401 | return r; | |
402 | } | |
403 | ||
404 | static unsigned int pn544_poll(struct file *file, poll_table *wait) | |
405 | { | |
406 | struct pn544_info *info = container_of(file->private_data, | |
407 | struct pn544_info, miscdev); | |
408 | struct i2c_client *client = info->i2c_dev; | |
409 | int r = 0; | |
410 | ||
411 | dev_dbg(&client->dev, "%s: info: %p\n", __func__, info); | |
412 | ||
413 | mutex_lock(&info->mutex); | |
414 | ||
415 | if (info->state == PN544_ST_COLD) { | |
416 | r = -ENODEV; | |
417 | goto out; | |
418 | } | |
419 | ||
420 | poll_wait(file, &info->read_wait, wait); | |
421 | ||
422 | if (pn544_irq_state(info) == PN544_INT) { | |
423 | r = POLLIN | POLLRDNORM; | |
424 | goto out; | |
425 | } | |
426 | out: | |
427 | mutex_unlock(&info->mutex); | |
428 | ||
429 | return r; | |
430 | } | |
431 | ||
432 | static ssize_t pn544_write(struct file *file, const char __user *buf, | |
433 | size_t count, loff_t *ppos) | |
434 | { | |
435 | struct pn544_info *info = container_of(file->private_data, | |
436 | struct pn544_info, miscdev); | |
437 | struct i2c_client *client = info->i2c_dev; | |
438 | ssize_t len; | |
439 | int r; | |
440 | ||
441 | dev_dbg(&client->dev, "%s: info: %p, count %zu\n", __func__, | |
442 | info, count); | |
443 | ||
444 | mutex_lock(&info->mutex); | |
445 | ||
446 | if (info->state == PN544_ST_COLD) { | |
447 | r = -ENODEV; | |
448 | goto out; | |
449 | } | |
450 | ||
451 | /* | |
452 | * XXX: should we detect rset-writes and clean possible | |
453 | * read_irq state | |
454 | */ | |
455 | if (info->state == PN544_ST_FW_READY) { | |
456 | size_t fw_len; | |
457 | ||
458 | if (count < PN544_FW_HEADER_SIZE) { | |
459 | r = -EINVAL; | |
460 | goto out; | |
461 | } | |
462 | ||
463 | len = min(count, info->buflen); | |
464 | if (copy_from_user(info->buf, buf, len)) { | |
465 | r = -EFAULT; | |
466 | goto out; | |
467 | } | |
468 | ||
469 | print_hex_dump(KERN_DEBUG, "FW write: ", DUMP_PREFIX_NONE, | |
470 | 16, 2, info->buf, len, false); | |
471 | ||
472 | fw_len = PN544_FW_HEADER_SIZE + (info->buf[1] << 8) + | |
473 | info->buf[2]; | |
474 | ||
475 | if (len > fw_len) /* 1 msg at a time */ | |
476 | len = fw_len; | |
477 | ||
478 | r = pn544_fw_write(info->i2c_dev, info->buf, len); | |
479 | } else { | |
480 | if (count < PN544_LLC_MIN_SIZE) { | |
481 | r = -EINVAL; | |
482 | goto out; | |
483 | } | |
484 | ||
485 | len = min(count, info->buflen); | |
486 | if (copy_from_user(info->buf, buf, len)) { | |
487 | r = -EFAULT; | |
488 | goto out; | |
489 | } | |
490 | ||
491 | print_hex_dump(KERN_DEBUG, "write: ", DUMP_PREFIX_NONE, | |
492 | 16, 2, info->buf, len, false); | |
493 | ||
494 | if (len > (info->buf[0] + 1)) /* 1 msg at a time */ | |
495 | len = info->buf[0] + 1; | |
496 | ||
497 | r = pn544_i2c_write(info->i2c_dev, info->buf, len); | |
498 | } | |
499 | out: | |
500 | mutex_unlock(&info->mutex); | |
501 | ||
502 | return r; | |
503 | ||
504 | } | |
505 | ||
506 | static long pn544_ioctl(struct file *file, unsigned int cmd, unsigned long arg) | |
507 | { | |
508 | struct pn544_info *info = container_of(file->private_data, | |
509 | struct pn544_info, miscdev); | |
510 | struct i2c_client *client = info->i2c_dev; | |
511 | struct pn544_nfc_platform_data *pdata; | |
512 | unsigned int val; | |
513 | int r = 0; | |
514 | ||
515 | dev_dbg(&client->dev, "%s: info: %p, cmd: 0x%x\n", __func__, info, cmd); | |
516 | ||
517 | mutex_lock(&info->mutex); | |
518 | ||
519 | if (info->state == PN544_ST_COLD) { | |
520 | r = -ENODEV; | |
521 | goto out; | |
522 | } | |
523 | ||
524 | pdata = info->i2c_dev->dev.platform_data; | |
525 | switch (cmd) { | |
526 | case PN544_GET_FW_MODE: | |
527 | dev_dbg(&client->dev, "%s: PN544_GET_FW_MODE\n", __func__); | |
528 | ||
529 | val = (info->state == PN544_ST_FW_READY); | |
530 | if (copy_to_user((void __user *)arg, &val, sizeof(val))) { | |
531 | r = -EFAULT; | |
532 | goto out; | |
533 | } | |
534 | ||
535 | break; | |
536 | ||
537 | case PN544_SET_FW_MODE: | |
538 | dev_dbg(&client->dev, "%s: PN544_SET_FW_MODE\n", __func__); | |
539 | ||
540 | if (copy_from_user(&val, (void __user *)arg, sizeof(val))) { | |
541 | r = -EFAULT; | |
542 | goto out; | |
543 | } | |
544 | ||
545 | if (val) { | |
546 | if (info->state == PN544_ST_FW_READY) | |
547 | break; | |
548 | ||
549 | pn544_disable(info); | |
550 | r = pn544_enable(info, FW_MODE); | |
551 | if (r < 0) | |
552 | goto out; | |
553 | } else { | |
554 | if (info->state == PN544_ST_READY) | |
555 | break; | |
556 | pn544_disable(info); | |
557 | r = pn544_enable(info, HCI_MODE); | |
558 | if (r < 0) | |
559 | goto out; | |
560 | } | |
561 | file->f_pos = info->read_offset; | |
562 | break; | |
563 | ||
564 | case TCGETS: | |
565 | dev_dbg(&client->dev, "%s: TCGETS\n", __func__); | |
566 | ||
567 | r = -ENOIOCTLCMD; | |
568 | break; | |
569 | ||
570 | default: | |
571 | dev_err(&client->dev, "Unknown ioctl 0x%x\n", cmd); | |
572 | r = -ENOIOCTLCMD; | |
573 | break; | |
574 | } | |
575 | ||
576 | out: | |
577 | mutex_unlock(&info->mutex); | |
578 | ||
579 | return r; | |
580 | } | |
581 | ||
582 | static int pn544_open(struct inode *inode, struct file *file) | |
583 | { | |
584 | struct pn544_info *info = container_of(file->private_data, | |
585 | struct pn544_info, miscdev); | |
586 | struct i2c_client *client = info->i2c_dev; | |
587 | int r = 0; | |
588 | ||
589 | dev_dbg(&client->dev, "%s: info: %p, client %p\n", __func__, | |
590 | info, info->i2c_dev); | |
591 | ||
592 | mutex_lock(&info->mutex); | |
593 | ||
594 | /* | |
595 | * Only 1 at a time. | |
596 | * XXX: maybe user (counter) would work better | |
597 | */ | |
598 | if (info->state != PN544_ST_COLD) { | |
599 | r = -EBUSY; | |
600 | goto out; | |
601 | } | |
602 | ||
603 | file->f_pos = info->read_offset; | |
604 | r = pn544_enable(info, HCI_MODE); | |
605 | ||
606 | out: | |
607 | mutex_unlock(&info->mutex); | |
608 | return r; | |
609 | } | |
610 | ||
611 | static int pn544_close(struct inode *inode, struct file *file) | |
612 | { | |
613 | struct pn544_info *info = container_of(file->private_data, | |
614 | struct pn544_info, miscdev); | |
615 | struct i2c_client *client = info->i2c_dev; | |
616 | ||
617 | dev_dbg(&client->dev, "%s: info: %p, client %p\n", | |
618 | __func__, info, info->i2c_dev); | |
619 | ||
620 | mutex_lock(&info->mutex); | |
621 | pn544_disable(info); | |
622 | mutex_unlock(&info->mutex); | |
623 | ||
624 | return 0; | |
625 | } | |
626 | ||
627 | static const struct file_operations pn544_fops = { | |
628 | .owner = THIS_MODULE, | |
629 | .llseek = no_llseek, | |
630 | .read = pn544_read, | |
631 | .write = pn544_write, | |
632 | .poll = pn544_poll, | |
633 | .open = pn544_open, | |
634 | .release = pn544_close, | |
635 | .unlocked_ioctl = pn544_ioctl, | |
636 | }; | |
637 | ||
638 | #ifdef CONFIG_PM | |
639 | static int pn544_suspend(struct device *dev) | |
640 | { | |
641 | struct i2c_client *client = to_i2c_client(dev); | |
642 | struct pn544_info *info; | |
643 | int r = 0; | |
644 | ||
645 | dev_info(&client->dev, "***\n%s: client %p\n***\n", __func__, client); | |
646 | ||
647 | info = i2c_get_clientdata(client); | |
648 | dev_info(&client->dev, "%s: info: %p, client %p\n", __func__, | |
649 | info, client); | |
650 | ||
651 | mutex_lock(&info->mutex); | |
652 | ||
653 | switch (info->state) { | |
654 | case PN544_ST_FW_READY: | |
655 | /* Do not suspend while upgrading FW, please! */ | |
656 | r = -EPERM; | |
657 | break; | |
658 | ||
659 | case PN544_ST_READY: | |
660 | /* | |
661 | * CHECK: Device should be in standby-mode. No way to check? | |
662 | * Allowing low power mode for the regulator is potentially | |
663 | * dangerous if pn544 does not go to suspension. | |
664 | */ | |
665 | break; | |
666 | ||
667 | case PN544_ST_COLD: | |
668 | break; | |
669 | }; | |
670 | ||
671 | mutex_unlock(&info->mutex); | |
672 | return r; | |
673 | } | |
674 | ||
675 | static int pn544_resume(struct device *dev) | |
676 | { | |
677 | struct i2c_client *client = to_i2c_client(dev); | |
678 | struct pn544_info *info = i2c_get_clientdata(client); | |
679 | int r = 0; | |
680 | ||
681 | dev_dbg(&client->dev, "%s: info: %p, client %p\n", __func__, | |
682 | info, client); | |
683 | ||
684 | mutex_lock(&info->mutex); | |
685 | ||
686 | switch (info->state) { | |
687 | case PN544_ST_READY: | |
688 | /* | |
689 | * CHECK: If regulator low power mode is allowed in | |
690 | * pn544_suspend, we should go back to normal mode | |
691 | * here. | |
692 | */ | |
693 | break; | |
694 | ||
695 | case PN544_ST_COLD: | |
696 | break; | |
697 | ||
698 | case PN544_ST_FW_READY: | |
699 | break; | |
700 | }; | |
701 | ||
702 | mutex_unlock(&info->mutex); | |
703 | ||
704 | return r; | |
705 | } | |
706 | ||
707 | static SIMPLE_DEV_PM_OPS(pn544_pm_ops, pn544_suspend, pn544_resume); | |
708 | #endif | |
709 | ||
710 | static struct device_attribute pn544_attr = | |
711 | __ATTR(nfc_test, S_IRUGO, pn544_test, NULL); | |
712 | ||
713 | static int __devinit pn544_probe(struct i2c_client *client, | |
714 | const struct i2c_device_id *id) | |
715 | { | |
716 | struct pn544_info *info; | |
717 | struct pn544_nfc_platform_data *pdata; | |
718 | int r = 0; | |
719 | ||
720 | dev_dbg(&client->dev, "%s\n", __func__); | |
721 | dev_dbg(&client->dev, "IRQ: %d\n", client->irq); | |
722 | ||
723 | /* private data allocation */ | |
724 | info = kzalloc(sizeof(struct pn544_info), GFP_KERNEL); | |
725 | if (!info) { | |
726 | dev_err(&client->dev, | |
727 | "Cannot allocate memory for pn544_info.\n"); | |
728 | r = -ENOMEM; | |
729 | goto err_info_alloc; | |
730 | } | |
731 | ||
732 | info->buflen = max(PN544_MSG_MAX_SIZE, PN544_MAX_I2C_TRANSFER); | |
733 | info->buf = kzalloc(info->buflen, GFP_KERNEL); | |
734 | if (!info->buf) { | |
735 | dev_err(&client->dev, | |
736 | "Cannot allocate memory for pn544_info->buf.\n"); | |
737 | r = -ENOMEM; | |
738 | goto err_buf_alloc; | |
739 | } | |
740 | ||
741 | info->regs[0].supply = reg_vdd_io; | |
742 | info->regs[1].supply = reg_vbat; | |
743 | r = regulator_bulk_get(&client->dev, ARRAY_SIZE(info->regs), | |
744 | info->regs); | |
745 | if (r < 0) | |
746 | goto err_kmalloc; | |
747 | ||
748 | info->i2c_dev = client; | |
749 | info->state = PN544_ST_COLD; | |
750 | info->read_irq = PN544_NONE; | |
751 | mutex_init(&info->read_mutex); | |
752 | mutex_init(&info->mutex); | |
753 | init_waitqueue_head(&info->read_wait); | |
754 | i2c_set_clientdata(client, info); | |
755 | pdata = client->dev.platform_data; | |
756 | if (!pdata) { | |
757 | dev_err(&client->dev, "No platform data\n"); | |
758 | r = -EINVAL; | |
759 | goto err_reg; | |
760 | } | |
761 | ||
762 | if (!pdata->request_resources) { | |
763 | dev_err(&client->dev, "request_resources() missing\n"); | |
764 | r = -EINVAL; | |
765 | goto err_reg; | |
766 | } | |
767 | ||
768 | r = pdata->request_resources(client); | |
769 | if (r) { | |
770 | dev_err(&client->dev, "Cannot get platform resources\n"); | |
771 | goto err_reg; | |
772 | } | |
773 | ||
774 | r = request_threaded_irq(client->irq, NULL, pn544_irq_thread_fn, | |
775 | IRQF_TRIGGER_RISING, PN544_DRIVER_NAME, | |
776 | info); | |
777 | if (r < 0) { | |
778 | dev_err(&client->dev, "Unable to register IRQ handler\n"); | |
779 | goto err_res; | |
780 | } | |
781 | ||
782 | /* If we don't have the test we don't need the sysfs file */ | |
783 | if (pdata->test) { | |
784 | r = device_create_file(&client->dev, &pn544_attr); | |
785 | if (r) { | |
786 | dev_err(&client->dev, | |
787 | "sysfs registration failed, error %d\n", r); | |
788 | goto err_irq; | |
789 | } | |
790 | } | |
791 | ||
792 | info->miscdev.minor = MISC_DYNAMIC_MINOR; | |
793 | info->miscdev.name = PN544_DRIVER_NAME; | |
794 | info->miscdev.fops = &pn544_fops; | |
795 | info->miscdev.parent = &client->dev; | |
796 | r = misc_register(&info->miscdev); | |
797 | if (r < 0) { | |
798 | dev_err(&client->dev, "Device registration failed\n"); | |
799 | goto err_sysfs; | |
800 | } | |
801 | ||
802 | dev_dbg(&client->dev, "%s: info: %p, pdata %p, client %p\n", | |
803 | __func__, info, pdata, client); | |
804 | ||
805 | return 0; | |
806 | ||
807 | err_sysfs: | |
808 | if (pdata->test) | |
809 | device_remove_file(&client->dev, &pn544_attr); | |
810 | err_irq: | |
811 | free_irq(client->irq, info); | |
812 | err_res: | |
813 | if (pdata->free_resources) | |
814 | pdata->free_resources(); | |
815 | err_reg: | |
816 | regulator_bulk_free(ARRAY_SIZE(info->regs), info->regs); | |
817 | err_kmalloc: | |
818 | kfree(info->buf); | |
819 | err_buf_alloc: | |
820 | kfree(info); | |
821 | err_info_alloc: | |
822 | return r; | |
823 | } | |
824 | ||
825 | static __devexit int pn544_remove(struct i2c_client *client) | |
826 | { | |
827 | struct pn544_info *info = i2c_get_clientdata(client); | |
828 | struct pn544_nfc_platform_data *pdata = client->dev.platform_data; | |
829 | ||
830 | dev_dbg(&client->dev, "%s\n", __func__); | |
831 | ||
832 | misc_deregister(&info->miscdev); | |
833 | if (pdata->test) | |
834 | device_remove_file(&client->dev, &pn544_attr); | |
835 | ||
836 | if (info->state != PN544_ST_COLD) { | |
837 | if (pdata->disable) | |
838 | pdata->disable(); | |
839 | ||
840 | info->read_irq = PN544_NONE; | |
841 | } | |
842 | ||
843 | free_irq(client->irq, info); | |
844 | if (pdata->free_resources) | |
845 | pdata->free_resources(); | |
846 | ||
847 | regulator_bulk_free(ARRAY_SIZE(info->regs), info->regs); | |
848 | kfree(info->buf); | |
849 | kfree(info); | |
850 | ||
851 | return 0; | |
852 | } | |
853 | ||
854 | static struct i2c_driver pn544_driver = { | |
855 | .driver = { | |
856 | .name = PN544_DRIVER_NAME, | |
857 | #ifdef CONFIG_PM | |
858 | .pm = &pn544_pm_ops, | |
859 | #endif | |
860 | }, | |
861 | .probe = pn544_probe, | |
862 | .id_table = pn544_id_table, | |
863 | .remove = __devexit_p(pn544_remove), | |
864 | }; | |
865 | ||
866 | static int __init pn544_init(void) | |
867 | { | |
868 | int r; | |
869 | ||
870 | pr_debug(DRIVER_DESC ": %s\n", __func__); | |
871 | ||
872 | r = i2c_add_driver(&pn544_driver); | |
873 | if (r) { | |
874 | pr_err(PN544_DRIVER_NAME ": driver registration failed\n"); | |
875 | return r; | |
876 | } | |
877 | ||
878 | return 0; | |
879 | } | |
880 | ||
881 | static void __exit pn544_exit(void) | |
882 | { | |
883 | i2c_del_driver(&pn544_driver); | |
884 | pr_info(DRIVER_DESC ", Exiting.\n"); | |
885 | } | |
886 | ||
887 | module_init(pn544_init); | |
888 | module_exit(pn544_exit); | |
889 | ||
890 | MODULE_LICENSE("GPL"); | |
891 | MODULE_DESCRIPTION(DRIVER_DESC); |