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