blob: 0d9b6f0e49b05f04ee9da9c7b4b2c07a0026b28a [file] [log] [blame]
Tapas Deyb5e69602019-05-07 11:33:00 +05301/* Copyright (c) 2015-2019, The Linux Foundation. All rights reserved.
Gaurav Singhalc53bc292017-02-16 16:35:39 +05302 *
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License version 2 and
5 * only version 2 as published by the Free Software Foundation.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 */
12
13#include <linux/kernel.h>
14#include <linux/module.h>
15#include <linux/fs.h>
16#include <linux/reboot.h>
17#include <linux/slab.h>
18#include <linux/irq.h>
19#include <linux/delay.h>
20#include <linux/interrupt.h>
21#include <linux/gpio.h>
22#include <linux/spinlock.h>
23#include <linux/of_gpio.h>
24#include <linux/of_device.h>
25#include <linux/uaccess.h>
26#include "nq-nci.h"
27#include <linux/clk.h>
28#ifdef CONFIG_COMPAT
29#include <linux/compat.h>
30#endif
31
32struct nqx_platform_data {
33 unsigned int irq_gpio;
34 unsigned int en_gpio;
35 unsigned int clkreq_gpio;
36 unsigned int firm_gpio;
37 unsigned int ese_gpio;
38 const char *clk_src_name;
Gaurav Singhal71661102018-01-30 16:34:37 +053039 /* NFC_CLK pin voting state */
40 bool clk_pin_voting;
Gaurav Singhalc53bc292017-02-16 16:35:39 +053041};
42
43static const struct of_device_id msm_match_table[] = {
44 {.compatible = "qcom,nq-nci"},
45 {}
46};
47
48MODULE_DEVICE_TABLE(of, msm_match_table);
49
50#define MAX_BUFFER_SIZE (320)
51#define WAKEUP_SRC_TIMEOUT (2000)
52#define MAX_RETRY_COUNT 3
53
54struct nqx_dev {
55 wait_queue_head_t read_wq;
56 struct mutex read_mutex;
57 struct i2c_client *client;
58 struct miscdevice nqx_device;
59 union nqx_uinfo nqx_info;
60 /* NFC GPIO variables */
61 unsigned int irq_gpio;
62 unsigned int en_gpio;
63 unsigned int firm_gpio;
64 unsigned int clkreq_gpio;
65 unsigned int ese_gpio;
66 /* NFC VEN pin state powered by Nfc */
67 bool nfc_ven_enabled;
68 /* NFC_IRQ state */
69 bool irq_enabled;
70 /* NFC_IRQ wake-up state */
71 bool irq_wake_up;
72 spinlock_t irq_enabled_lock;
73 unsigned int count_irq;
74 /* Initial CORE RESET notification */
75 unsigned int core_reset_ntf;
76 /* CLK control */
77 bool clk_run;
78 struct clk *s_clk;
79 /* read buffer*/
80 size_t kbuflen;
81 u8 *kbuf;
82 struct nqx_platform_data *pdata;
83};
84
85static int nfcc_reboot(struct notifier_block *notifier, unsigned long val,
86 void *v);
87/*clock enable function*/
88static int nqx_clock_select(struct nqx_dev *nqx_dev);
89/*clock disable function*/
90static int nqx_clock_deselect(struct nqx_dev *nqx_dev);
91static struct notifier_block nfcc_notifier = {
92 .notifier_call = nfcc_reboot,
93 .next = NULL,
94 .priority = 0
95};
96
97unsigned int disable_ctrl;
98
99static void nqx_init_stat(struct nqx_dev *nqx_dev)
100{
101 nqx_dev->count_irq = 0;
102}
103
104static void nqx_disable_irq(struct nqx_dev *nqx_dev)
105{
106 unsigned long flags;
107
108 spin_lock_irqsave(&nqx_dev->irq_enabled_lock, flags);
109 if (nqx_dev->irq_enabled) {
110 disable_irq_nosync(nqx_dev->client->irq);
111 nqx_dev->irq_enabled = false;
112 }
113 spin_unlock_irqrestore(&nqx_dev->irq_enabled_lock, flags);
114}
115
116/**
117 * nqx_enable_irq()
118 *
119 * Check if interrupt is enabled or not
120 * and enable interrupt
121 *
122 * Return: void
123 */
124static void nqx_enable_irq(struct nqx_dev *nqx_dev)
125{
126 unsigned long flags;
127
128 spin_lock_irqsave(&nqx_dev->irq_enabled_lock, flags);
129 if (!nqx_dev->irq_enabled) {
130 nqx_dev->irq_enabled = true;
131 enable_irq(nqx_dev->client->irq);
132 }
133 spin_unlock_irqrestore(&nqx_dev->irq_enabled_lock, flags);
134}
135
136static irqreturn_t nqx_dev_irq_handler(int irq, void *dev_id)
137{
138 struct nqx_dev *nqx_dev = dev_id;
139 unsigned long flags;
140
141 if (device_may_wakeup(&nqx_dev->client->dev))
142 pm_wakeup_event(&nqx_dev->client->dev, WAKEUP_SRC_TIMEOUT);
143
144 nqx_disable_irq(nqx_dev);
145 spin_lock_irqsave(&nqx_dev->irq_enabled_lock, flags);
146 nqx_dev->count_irq++;
147 spin_unlock_irqrestore(&nqx_dev->irq_enabled_lock, flags);
148 wake_up(&nqx_dev->read_wq);
149
150 return IRQ_HANDLED;
151}
152
153static ssize_t nfc_read(struct file *filp, char __user *buf,
154 size_t count, loff_t *offset)
155{
156 struct nqx_dev *nqx_dev = filp->private_data;
157 unsigned char *tmp = NULL;
158 int ret;
159 int irq_gpio_val = 0;
160
161 if (!nqx_dev) {
162 ret = -ENODEV;
163 goto out;
164 }
165
166 if (count > nqx_dev->kbuflen)
167 count = nqx_dev->kbuflen;
168
169 dev_dbg(&nqx_dev->client->dev, "%s : reading %zu bytes.\n",
170 __func__, count);
171
172 mutex_lock(&nqx_dev->read_mutex);
173
174 irq_gpio_val = gpio_get_value(nqx_dev->irq_gpio);
175 if (irq_gpio_val == 0) {
176 if (filp->f_flags & O_NONBLOCK) {
177 dev_err(&nqx_dev->client->dev,
178 ":f_falg has O_NONBLOCK. EAGAIN\n");
179 ret = -EAGAIN;
180 goto err;
181 }
182 while (1) {
183 ret = 0;
184 if (!nqx_dev->irq_enabled) {
185 nqx_dev->irq_enabled = true;
186 enable_irq(nqx_dev->client->irq);
187 }
188 if (!gpio_get_value(nqx_dev->irq_gpio)) {
189 ret = wait_event_interruptible(nqx_dev->read_wq,
190 !nqx_dev->irq_enabled);
191 }
192 if (ret)
193 goto err;
194 nqx_disable_irq(nqx_dev);
195
196 if (gpio_get_value(nqx_dev->irq_gpio))
197 break;
198 dev_err_ratelimited(&nqx_dev->client->dev,
199 "gpio is low, no need to read data\n");
200 }
201 }
202
203 tmp = nqx_dev->kbuf;
204 if (!tmp) {
205 dev_err(&nqx_dev->client->dev,
206 "%s: device doesn't exist anymore\n", __func__);
207 ret = -ENODEV;
208 goto err;
209 }
210 memset(tmp, 0x00, count);
211
212 /* Read data */
213 ret = i2c_master_recv(nqx_dev->client, tmp, count);
214 if (ret < 0) {
215 dev_err(&nqx_dev->client->dev,
216 "%s: i2c_master_recv returned %d\n", __func__, ret);
217 goto err;
218 }
219 if (ret > count) {
220 dev_err(&nqx_dev->client->dev,
221 "%s: received too many bytes from i2c (%d)\n",
222 __func__, ret);
223 ret = -EIO;
224 goto err;
225 }
226#ifdef NFC_KERNEL_BU
227 dev_dbg(&nqx_dev->client->dev, "%s : NfcNciRx %x %x %x\n",
228 __func__, tmp[0], tmp[1], tmp[2]);
229#endif
230 if (copy_to_user(buf, tmp, ret)) {
231 dev_warn(&nqx_dev->client->dev,
232 "%s : failed to copy to user space\n", __func__);
233 ret = -EFAULT;
234 goto err;
235 }
236 mutex_unlock(&nqx_dev->read_mutex);
237 return ret;
238
239err:
240 mutex_unlock(&nqx_dev->read_mutex);
241out:
242 return ret;
243}
244
245static ssize_t nfc_write(struct file *filp, const char __user *buf,
246 size_t count, loff_t *offset)
247{
248 struct nqx_dev *nqx_dev = filp->private_data;
249 char *tmp = NULL;
250 int ret = 0;
251
252 if (!nqx_dev) {
253 ret = -ENODEV;
254 goto out;
255 }
256 if (count > nqx_dev->kbuflen) {
257 dev_err(&nqx_dev->client->dev, "%s: out of memory\n",
258 __func__);
259 ret = -ENOMEM;
260 goto out;
261 }
262
263 tmp = memdup_user(buf, count);
264 if (IS_ERR(tmp)) {
265 dev_err(&nqx_dev->client->dev, "%s: memdup_user failed\n",
266 __func__);
267 ret = PTR_ERR(tmp);
268 goto out;
269 }
270
271 ret = i2c_master_send(nqx_dev->client, tmp, count);
272 if (ret != count) {
273 dev_err(&nqx_dev->client->dev,
274 "%s: failed to write %d\n", __func__, ret);
275 ret = -EIO;
276 goto out_free;
277 }
278#ifdef NFC_KERNEL_BU
279 dev_dbg(&nqx_dev->client->dev,
280 "%s : i2c-%d: NfcNciTx %x %x %x\n",
281 __func__, iminor(file_inode(filp)),
282 tmp[0], tmp[1], tmp[2]);
283#endif
284 usleep_range(1000, 1100);
285out_free:
286 kfree(tmp);
287out:
288 return ret;
289}
290
291/**
292 * nqx_standby_write()
293 * @buf: pointer to data buffer
294 * @len: # of bytes need to transfer
295 *
296 * write data buffer over I2C and retry
297 * if NFCC is in stand by mode
298 *
299 * Return: # of bytes written or -ve value in case of error
300 */
301static int nqx_standby_write(struct nqx_dev *nqx_dev,
302 const unsigned char *buf, size_t len)
303{
304 int ret = -EINVAL;
305 int retry_cnt;
306
307 for (retry_cnt = 1; retry_cnt <= MAX_RETRY_COUNT; retry_cnt++) {
308 ret = i2c_master_send(nqx_dev->client, buf, len);
309 if (ret < 0) {
310 dev_err(&nqx_dev->client->dev,
311 "%s: write failed, Maybe in Standby Mode - Retry(%d)\n",
312 __func__, retry_cnt);
313 usleep_range(1000, 1100);
314 } else if (ret == len)
315 break;
316 }
317 return ret;
318}
319
320/*
321 * Power management of the eSE
322 * NFC & eSE ON : NFC_EN high and eSE_pwr_req high.
323 * NFC OFF & eSE ON : NFC_EN high and eSE_pwr_req high.
324 * NFC OFF & eSE OFF : NFC_EN low and eSE_pwr_req low.
325 */
326static int nqx_ese_pwr(struct nqx_dev *nqx_dev, unsigned long int arg)
327{
328 int r = -1;
329 const unsigned char svdd_off_cmd_warn[] = {0x2F, 0x31, 0x01, 0x01};
330 const unsigned char svdd_off_cmd_done[] = {0x2F, 0x31, 0x01, 0x00};
331
332 if (!gpio_is_valid(nqx_dev->ese_gpio)) {
333 dev_err(&nqx_dev->client->dev,
334 "%s: ese_gpio is not valid\n", __func__);
335 return -EINVAL;
336 }
337
338 if (arg == 0) {
339 /*
340 * We want to power on the eSE and to do so we need the
341 * eSE_pwr_req pin and the NFC_EN pin to be high
342 */
343 if (gpio_get_value(nqx_dev->ese_gpio)) {
344 dev_dbg(&nqx_dev->client->dev, "ese_gpio is already high\n");
345 r = 0;
346 } else {
347 /**
348 * Let's store the NFC_EN pin state
349 * only if the eSE is not yet on
350 */
351 nqx_dev->nfc_ven_enabled =
352 gpio_get_value(nqx_dev->en_gpio);
353 if (!nqx_dev->nfc_ven_enabled) {
354 gpio_set_value(nqx_dev->en_gpio, 1);
355 /* hardware dependent delay */
356 usleep_range(1000, 1100);
357 }
358 gpio_set_value(nqx_dev->ese_gpio, 1);
Gaurav Singhalcfb64802017-08-30 17:03:58 +0530359 usleep_range(1000, 1100);
Gaurav Singhalc53bc292017-02-16 16:35:39 +0530360 if (gpio_get_value(nqx_dev->ese_gpio)) {
361 dev_dbg(&nqx_dev->client->dev, "ese_gpio is enabled\n");
362 r = 0;
363 }
364 }
365 } else if (arg == 1) {
366 if (nqx_dev->nfc_ven_enabled &&
367 ((nqx_dev->nqx_info.info.chip_type == NFCC_NQ_220) ||
368 (nqx_dev->nqx_info.info.chip_type == NFCC_PN66T))) {
369 /**
370 * Let's inform the CLF we're
371 * powering off the eSE
372 */
373 r = nqx_standby_write(nqx_dev, svdd_off_cmd_warn,
374 sizeof(svdd_off_cmd_warn));
375 if (r < 0) {
376 dev_err(&nqx_dev->client->dev,
377 "%s: write failed after max retry\n",
378 __func__);
379 return -ENXIO;
380 }
381 dev_dbg(&nqx_dev->client->dev,
382 "%s: svdd_off_cmd_warn sent\n", __func__);
383
384 /* let's power down the eSE */
385 gpio_set_value(nqx_dev->ese_gpio, 0);
386 dev_dbg(&nqx_dev->client->dev,
387 "%s: nqx_dev->ese_gpio set to 0\n", __func__);
388
389 /**
390 * Time needed for the SVDD capacitor
391 * to get discharged
392 */
393 usleep_range(8000, 8100);
394
395 /* Let's inform the CLF the eSE is now off */
396 r = nqx_standby_write(nqx_dev, svdd_off_cmd_done,
397 sizeof(svdd_off_cmd_done));
398 if (r < 0) {
399 dev_err(&nqx_dev->client->dev,
400 "%s: write failed after max retry\n",
401 __func__);
402 return -ENXIO;
403 }
404 dev_dbg(&nqx_dev->client->dev,
405 "%s: svdd_off_cmd_done sent\n", __func__);
406 } else {
407 /**
408 * In case the NFC is off,
409 * there's no need to send the i2c commands
410 */
411 gpio_set_value(nqx_dev->ese_gpio, 0);
Gaurav Singhalcfb64802017-08-30 17:03:58 +0530412 usleep_range(1000, 1100);
Gaurav Singhalc53bc292017-02-16 16:35:39 +0530413 }
414
415 if (!gpio_get_value(nqx_dev->ese_gpio)) {
416 dev_dbg(&nqx_dev->client->dev, "ese_gpio is disabled\n");
417 r = 0;
418 }
419
420 if (!nqx_dev->nfc_ven_enabled) {
421 /* hardware dependent delay */
422 usleep_range(1000, 1100);
423 dev_dbg(&nqx_dev->client->dev, "disabling en_gpio\n");
424 gpio_set_value(nqx_dev->en_gpio, 0);
425 }
426 } else if (arg == 3) {
427 r = gpio_get_value(nqx_dev->ese_gpio);
428 }
429 return r;
430}
431
432static int nfc_open(struct inode *inode, struct file *filp)
433{
434 int ret = 0;
435 struct nqx_dev *nqx_dev = container_of(filp->private_data,
436 struct nqx_dev, nqx_device);
437
438 filp->private_data = nqx_dev;
439 nqx_init_stat(nqx_dev);
440
441 dev_dbg(&nqx_dev->client->dev,
442 "%s: %d,%d\n", __func__, imajor(inode), iminor(inode));
443 return ret;
444}
445
446/*
447 * nfc_ioctl_power_states() - power control
448 * @filp: pointer to the file descriptor
449 * @arg: mode that we want to move to
450 *
451 * Device power control. Depending on the arg value, device moves to
452 * different states
453 * (arg = 0): NFC_ENABLE GPIO = 0, FW_DL GPIO = 0
454 * (arg = 1): NFC_ENABLE GPIO = 1, FW_DL GPIO = 0
455 * (arg = 2): FW_DL GPIO = 1
456 *
457 * Return: -ENOIOCTLCMD if arg is not supported, 0 in any other case
458 */
459int nfc_ioctl_power_states(struct file *filp, unsigned long arg)
460{
461 int r = 0;
462 struct nqx_dev *nqx_dev = filp->private_data;
463
464 if (arg == 0) {
465 /*
466 * We are attempting a hardware reset so let us disable
467 * interrupts to avoid spurious notifications to upper
468 * layers.
469 */
470 nqx_disable_irq(nqx_dev);
471 dev_dbg(&nqx_dev->client->dev,
472 "gpio_set_value disable: %s: info: %p\n",
473 __func__, nqx_dev);
Gaurav Singhal165add72017-10-13 17:17:58 +0530474 if (gpio_is_valid(nqx_dev->firm_gpio)) {
Gaurav Singhalc53bc292017-02-16 16:35:39 +0530475 gpio_set_value(nqx_dev->firm_gpio, 0);
Gaurav Singhal165add72017-10-13 17:17:58 +0530476 usleep_range(10000, 10100);
477 }
Gaurav Singhalc53bc292017-02-16 16:35:39 +0530478
479 if (gpio_is_valid(nqx_dev->ese_gpio)) {
480 if (!gpio_get_value(nqx_dev->ese_gpio)) {
481 dev_dbg(&nqx_dev->client->dev, "disabling en_gpio\n");
482 gpio_set_value(nqx_dev->en_gpio, 0);
Gaurav Singhal165add72017-10-13 17:17:58 +0530483 usleep_range(10000, 10100);
Gaurav Singhalc53bc292017-02-16 16:35:39 +0530484 } else {
485 dev_dbg(&nqx_dev->client->dev, "keeping en_gpio high\n");
486 }
487 } else {
488 dev_dbg(&nqx_dev->client->dev, "ese_gpio invalid, set en_gpio to low\n");
489 gpio_set_value(nqx_dev->en_gpio, 0);
Gaurav Singhal165add72017-10-13 17:17:58 +0530490 usleep_range(10000, 10100);
Gaurav Singhalc53bc292017-02-16 16:35:39 +0530491 }
Gaurav Singhal71661102018-01-30 16:34:37 +0530492 if (nqx_dev->pdata->clk_pin_voting) {
493 r = nqx_clock_deselect(nqx_dev);
494 if (r < 0)
495 dev_err(&nqx_dev->client->dev, "unable to disable clock\n");
496 }
Gaurav Singhalc53bc292017-02-16 16:35:39 +0530497 nqx_dev->nfc_ven_enabled = false;
Gaurav Singhalc53bc292017-02-16 16:35:39 +0530498 } else if (arg == 1) {
499 nqx_enable_irq(nqx_dev);
500 dev_dbg(&nqx_dev->client->dev,
501 "gpio_set_value enable: %s: info: %p\n",
502 __func__, nqx_dev);
Gaurav Singhal165add72017-10-13 17:17:58 +0530503 if (gpio_is_valid(nqx_dev->firm_gpio)) {
Gaurav Singhalc53bc292017-02-16 16:35:39 +0530504 gpio_set_value(nqx_dev->firm_gpio, 0);
Gaurav Singhal165add72017-10-13 17:17:58 +0530505 usleep_range(10000, 10100);
506 }
Gaurav Singhalc53bc292017-02-16 16:35:39 +0530507 gpio_set_value(nqx_dev->en_gpio, 1);
Gaurav Singhal165add72017-10-13 17:17:58 +0530508 usleep_range(10000, 10100);
Gaurav Singhal71661102018-01-30 16:34:37 +0530509 if (nqx_dev->pdata->clk_pin_voting) {
510 r = nqx_clock_select(nqx_dev);
511 if (r < 0)
512 dev_err(&nqx_dev->client->dev, "unable to enable clock\n");
513 }
Gaurav Singhalc53bc292017-02-16 16:35:39 +0530514 nqx_dev->nfc_ven_enabled = true;
Gaurav Singhalc53bc292017-02-16 16:35:39 +0530515 } else if (arg == 2) {
516 /*
517 * We are switching to Dowload Mode, toggle the enable pin
518 * in order to set the NFCC in the new mode
519 */
520 if (gpio_is_valid(nqx_dev->ese_gpio)) {
521 if (gpio_get_value(nqx_dev->ese_gpio)) {
522 dev_err(&nqx_dev->client->dev,
523 "FW download forbidden while ese is on\n");
524 return -EBUSY; /* Device or resource busy */
525 }
526 }
527 gpio_set_value(nqx_dev->en_gpio, 1);
Gaurav Singhal165add72017-10-13 17:17:58 +0530528 usleep_range(10000, 10100);
529 if (gpio_is_valid(nqx_dev->firm_gpio)) {
Gaurav Singhalc53bc292017-02-16 16:35:39 +0530530 gpio_set_value(nqx_dev->firm_gpio, 1);
Gaurav Singhal165add72017-10-13 17:17:58 +0530531 usleep_range(10000, 10100);
532 }
Gaurav Singhalc53bc292017-02-16 16:35:39 +0530533 gpio_set_value(nqx_dev->en_gpio, 0);
Gaurav Singhal165add72017-10-13 17:17:58 +0530534 usleep_range(10000, 10100);
Gaurav Singhalc53bc292017-02-16 16:35:39 +0530535 gpio_set_value(nqx_dev->en_gpio, 1);
Gaurav Singhal165add72017-10-13 17:17:58 +0530536 usleep_range(10000, 10100);
Bhuvan Varshneyae67c4e2018-11-23 15:15:27 +0530537 } else if (arg == 4) {
538 /*
539 * Setting firmware download gpio to HIGH for SN100U
540 * before FW download start
541 */
542 dev_dbg(&nqx_dev->client->dev, "SN100 fw gpio HIGH\n");
543 if (gpio_is_valid(nqx_dev->firm_gpio)) {
544 gpio_set_value(nqx_dev->firm_gpio, 1);
545 usleep_range(10000, 10100);
546 } else {
547 dev_err(&nqx_dev->client->dev,
548 "firm_gpio is invalid\n");
549 }
550 } else if (arg == 6) {
551 /*
552 * Setting firmware download gpio to LOW for SN100U
553 * FW download finished
554 */
555 dev_dbg(&nqx_dev->client->dev, "SN100 fw gpio LOW\n");
556 if (gpio_is_valid(nqx_dev->firm_gpio)) {
557 gpio_set_value(nqx_dev->firm_gpio, 0);
558 usleep_range(10000, 10100);
559 } else {
560 dev_err(&nqx_dev->client->dev,
561 "firm_gpio is invalid\n");
562 }
Gaurav Singhalc53bc292017-02-16 16:35:39 +0530563 } else {
564 r = -ENOIOCTLCMD;
565 }
566
567 return r;
568}
569
570#ifdef CONFIG_COMPAT
571static long nfc_compat_ioctl(struct file *pfile, unsigned int cmd,
572 unsigned long arg)
573{
574 long r = 0;
575
576 arg = (compat_u64)arg;
577 switch (cmd) {
578 case NFC_SET_PWR:
579 nfc_ioctl_power_states(pfile, arg);
580 break;
581 case ESE_SET_PWR:
582 nqx_ese_pwr(pfile->private_data, arg);
583 break;
584 case ESE_GET_PWR:
585 nqx_ese_pwr(pfile->private_data, 3);
586 break;
587 case SET_RX_BLOCK:
588 break;
589 case SET_EMULATOR_TEST_POINT:
590 break;
591 default:
592 r = -ENOTTY;
593 }
594 return r;
595}
596#endif
597
598/*
599 * nfc_ioctl_core_reset_ntf()
600 * @filp: pointer to the file descriptor
601 *
602 * Allows callers to determine if a CORE_RESET_NTF has arrived
603 *
604 * Return: the value of variable core_reset_ntf
605 */
606int nfc_ioctl_core_reset_ntf(struct file *filp)
607{
608 struct nqx_dev *nqx_dev = filp->private_data;
609
610 dev_dbg(&nqx_dev->client->dev, "%s: returning = %d\n", __func__,
611 nqx_dev->core_reset_ntf);
612 return nqx_dev->core_reset_ntf;
613}
614
615/*
616 * Inside nfc_ioctl_nfcc_info
617 *
618 * @brief nfc_ioctl_nfcc_info
619 *
620 * Check the NQ Chipset and firmware version details
621 */
622unsigned int nfc_ioctl_nfcc_info(struct file *filp, unsigned long arg)
623{
624 unsigned int r = 0;
625 struct nqx_dev *nqx_dev = filp->private_data;
626
627 r = nqx_dev->nqx_info.i;
628 dev_dbg(&nqx_dev->client->dev,
629 "nqx nfc : nfc_ioctl_nfcc_info r = %d\n", r);
630
631 return r;
632}
633
634static long nfc_ioctl(struct file *pfile, unsigned int cmd,
635 unsigned long arg)
636{
637 int r = 0;
638
639 switch (cmd) {
640 case NFC_SET_PWR:
641 r = nfc_ioctl_power_states(pfile, arg);
642 break;
643 case ESE_SET_PWR:
644 r = nqx_ese_pwr(pfile->private_data, arg);
645 break;
646 case ESE_GET_PWR:
647 r = nqx_ese_pwr(pfile->private_data, 3);
648 break;
649 case SET_RX_BLOCK:
650 break;
651 case SET_EMULATOR_TEST_POINT:
652 break;
653 case NFCC_INITIAL_CORE_RESET_NTF:
654 r = nfc_ioctl_core_reset_ntf(pfile);
655 break;
656 case NFCC_GET_INFO:
657 r = nfc_ioctl_nfcc_info(pfile, arg);
658 break;
659 default:
660 r = -ENOIOCTLCMD;
661 }
662 return r;
663}
664
665static const struct file_operations nfc_dev_fops = {
666 .owner = THIS_MODULE,
667 .llseek = no_llseek,
668 .read = nfc_read,
669 .write = nfc_write,
670 .open = nfc_open,
671 .unlocked_ioctl = nfc_ioctl,
672#ifdef CONFIG_COMPAT
673 .compat_ioctl = nfc_compat_ioctl
674#endif
675};
676
677/* Check for availability of NQ_ NFC controller hardware */
678static int nfcc_hw_check(struct i2c_client *client, struct nqx_dev *nqx_dev)
679{
680 int ret = 0;
681
Bhuvan Varshneybd019372018-11-23 15:57:10 +0530682 int gpio_retry_count = 0;
Gaurav Singhalc53bc292017-02-16 16:35:39 +0530683 unsigned char raw_nci_reset_cmd[] = {0x20, 0x00, 0x01, 0x00};
684 unsigned char raw_nci_init_cmd[] = {0x20, 0x01, 0x00};
Tapas Deyb5e69602019-05-07 11:33:00 +0530685 unsigned char nci_get_version_cmd[] = {0x00, 0x04, 0xF1,
686 0x00, 0x00, 0x00, 0x6E, 0xEF};
Gaurav Singhalc53bc292017-02-16 16:35:39 +0530687 unsigned char nci_init_rsp[28];
688 unsigned char nci_reset_rsp[6];
Tapas Deyb5e69602019-05-07 11:33:00 +0530689 unsigned char nci_get_version_rsp[12];
Gaurav Singhalc53bc292017-02-16 16:35:39 +0530690 unsigned char init_rsp_len = 0;
691 unsigned int enable_gpio = nqx_dev->en_gpio;
Gaurav Singhal165add72017-10-13 17:17:58 +0530692
Bhuvan Varshneybd019372018-11-23 15:57:10 +0530693reset_enable_gpio:
Gaurav Singhalc53bc292017-02-16 16:35:39 +0530694 /* making sure that the NFCC starts in a clean state. */
695 gpio_set_value(enable_gpio, 0);/* ULPM: Disable */
696 /* hardware dependent delay */
Gaurav Singhal165add72017-10-13 17:17:58 +0530697 usleep_range(10000, 10100);
Gaurav Singhalc53bc292017-02-16 16:35:39 +0530698 gpio_set_value(enable_gpio, 1);/* HPD : Enable*/
699 /* hardware dependent delay */
Gaurav Singhal165add72017-10-13 17:17:58 +0530700 usleep_range(10000, 10100);
Gaurav Singhalc53bc292017-02-16 16:35:39 +0530701
702 /* send NCI CORE RESET CMD with Keep Config parameters */
703 ret = i2c_master_send(client, raw_nci_reset_cmd,
704 sizeof(raw_nci_reset_cmd));
705 if (ret < 0) {
706 dev_err(&client->dev,
Tapas Deyb5e69602019-05-07 11:33:00 +0530707 "%s: - i2c_master_send core reset Error\n", __func__);
708
709 if (gpio_is_valid(nqx_dev->firm_gpio)) {
710 gpio_set_value(nqx_dev->firm_gpio, 1);
711 usleep_range(10000, 10100);
712 }
713 gpio_set_value(nqx_dev->en_gpio, 0);
714 usleep_range(10000, 10100);
715 gpio_set_value(nqx_dev->en_gpio, 1);
716 usleep_range(10000, 10100);
717
718 ret = i2c_master_send(client, nci_get_version_cmd,
719 sizeof(nci_get_version_cmd));
720
721 if (ret < 0) {
722 dev_err(&client->dev,
723 "%s: - i2c_master_send get version cmd Error\n",
724 __func__);
725 goto err_nfcc_hw_check;
726 }
727 /* hardware dependent delay */
728 usleep_range(10000, 10100);
729
730 ret = i2c_master_recv(client, nci_get_version_rsp,
731 sizeof(nci_get_version_rsp));
732 if (ret < 0) {
733 dev_err(&client->dev,
734 "%s: - i2c_master_recv get version rsp Error\n",
735 __func__);
736 goto err_nfcc_hw_check;
737 } else {
738 nqx_dev->nqx_info.info.chip_type =
739 nci_get_version_rsp[3];
740 nqx_dev->nqx_info.info.rom_version =
741 nci_get_version_rsp[4];
742 nqx_dev->nqx_info.info.fw_minor =
743 nci_get_version_rsp[10];
744 nqx_dev->nqx_info.info.fw_major =
745 nci_get_version_rsp[11];
746 }
747 goto err_nfcc_reset_failed;
Gaurav Singhalc53bc292017-02-16 16:35:39 +0530748 }
749 /* hardware dependent delay */
750 msleep(30);
751
752 /* Read Response of RESET command */
753 ret = i2c_master_recv(client, nci_reset_rsp,
754 sizeof(nci_reset_rsp));
Gaurav Singhalc53bc292017-02-16 16:35:39 +0530755 if (ret < 0) {
756 dev_err(&client->dev,
757 "%s: - i2c_master_recv Error\n", __func__);
Bhuvan Varshneybd019372018-11-23 15:57:10 +0530758 gpio_retry_count = gpio_retry_count + 1;
759 if (gpio_retry_count < MAX_RETRY_COUNT)
760 goto reset_enable_gpio;
Gaurav Singhalc53bc292017-02-16 16:35:39 +0530761 goto err_nfcc_hw_check;
762 }
Gaurav Singhal165add72017-10-13 17:17:58 +0530763 ret = nqx_standby_write(nqx_dev, raw_nci_init_cmd,
764 sizeof(raw_nci_init_cmd));
Gaurav Singhalc53bc292017-02-16 16:35:39 +0530765 if (ret < 0) {
766 dev_err(&client->dev,
Tapas Deyb5e69602019-05-07 11:33:00 +0530767 "%s: - i2c_master_send failed for Core INIT\n", __func__);
Gaurav Singhal165add72017-10-13 17:17:58 +0530768 goto err_nfcc_core_init_fail;
Gaurav Singhalc53bc292017-02-16 16:35:39 +0530769 }
770 /* hardware dependent delay */
771 msleep(30);
772 /* Read Response of INIT command */
773 ret = i2c_master_recv(client, nci_init_rsp,
774 sizeof(nci_init_rsp));
775 if (ret < 0) {
776 dev_err(&client->dev,
777 "%s: - i2c_master_recv Error\n", __func__);
Gaurav Singhal165add72017-10-13 17:17:58 +0530778 goto err_nfcc_core_init_fail;
Gaurav Singhalc53bc292017-02-16 16:35:39 +0530779 }
780 init_rsp_len = 2 + nci_init_rsp[2]; /*payload + len*/
781 if (init_rsp_len > PAYLOAD_HEADER_LENGTH) {
782 nqx_dev->nqx_info.info.chip_type =
783 nci_init_rsp[init_rsp_len - 3];
784 nqx_dev->nqx_info.info.rom_version =
785 nci_init_rsp[init_rsp_len - 2];
786 nqx_dev->nqx_info.info.fw_major =
787 nci_init_rsp[init_rsp_len - 1];
788 nqx_dev->nqx_info.info.fw_minor =
789 nci_init_rsp[init_rsp_len];
790 }
Gaurav Singhal165add72017-10-13 17:17:58 +0530791 dev_dbg(&client->dev,
792 "%s: - nq - reset cmd answer : NfcNciRx %x %x %x\n",
793 __func__, nci_reset_rsp[0],
794 nci_reset_rsp[1], nci_reset_rsp[2]);
795
Tapas Deyb5e69602019-05-07 11:33:00 +0530796err_nfcc_reset_failed:
Gaurav Singhalc53bc292017-02-16 16:35:39 +0530797 dev_dbg(&nqx_dev->client->dev, "NQ NFCC chip_type = %x\n",
798 nqx_dev->nqx_info.info.chip_type);
799 dev_dbg(&nqx_dev->client->dev, "NQ fw version = %x.%x.%x\n",
800 nqx_dev->nqx_info.info.rom_version,
801 nqx_dev->nqx_info.info.fw_major,
802 nqx_dev->nqx_info.info.fw_minor);
803
804 switch (nqx_dev->nqx_info.info.chip_type) {
805 case NFCC_NQ_210:
806 dev_dbg(&client->dev,
807 "%s: ## NFCC == NQ210 ##\n", __func__);
808 break;
809 case NFCC_NQ_220:
810 dev_dbg(&client->dev,
811 "%s: ## NFCC == NQ220 ##\n", __func__);
812 break;
813 case NFCC_NQ_310:
814 dev_dbg(&client->dev,
815 "%s: ## NFCC == NQ310 ##\n", __func__);
816 break;
817 case NFCC_NQ_330:
818 dev_dbg(&client->dev,
819 "%s: ## NFCC == NQ330 ##\n", __func__);
820 break;
821 case NFCC_PN66T:
822 dev_dbg(&client->dev,
823 "%s: ## NFCC == PN66T ##\n", __func__);
824 break;
825 default:
826 dev_err(&client->dev,
827 "%s: - NFCC HW not Supported\n", __func__);
828 break;
829 }
830
831 /*Disable NFC by default to save power on boot*/
832 gpio_set_value(enable_gpio, 0);/* ULPM: Disable */
833 ret = 0;
834 goto done;
835
Gaurav Singhal165add72017-10-13 17:17:58 +0530836err_nfcc_core_init_fail:
837 dev_err(&client->dev,
838 "%s: - nq - reset cmd answer : NfcNciRx %x %x %x\n",
839 __func__, nci_reset_rsp[0],
840 nci_reset_rsp[1], nci_reset_rsp[2]);
841
Gaurav Singhalc53bc292017-02-16 16:35:39 +0530842err_nfcc_hw_check:
843 ret = -ENXIO;
844 dev_err(&client->dev,
845 "%s: - NFCC HW not available\n", __func__);
846done:
847 return ret;
848}
849
850/*
851 * Routine to enable clock.
852 * this routine can be extended to select from multiple
853 * sources based on clk_src_name.
854 */
855static int nqx_clock_select(struct nqx_dev *nqx_dev)
856{
857 int r = 0;
858
859 nqx_dev->s_clk = clk_get(&nqx_dev->client->dev, "ref_clk");
860
861 if (nqx_dev->s_clk == NULL)
862 goto err_clk;
863
864 if (nqx_dev->clk_run == false)
865 r = clk_prepare_enable(nqx_dev->s_clk);
866
867 if (r)
868 goto err_clk;
869
870 nqx_dev->clk_run = true;
871
872 return r;
873
874err_clk:
875 r = -1;
876 return r;
877}
878
879/*
880 * Routine to disable clocks
881 */
882static int nqx_clock_deselect(struct nqx_dev *nqx_dev)
883{
884 int r = -1;
885
886 if (nqx_dev->s_clk != NULL) {
887 if (nqx_dev->clk_run == true) {
888 clk_disable_unprepare(nqx_dev->s_clk);
889 nqx_dev->clk_run = false;
890 }
891 return 0;
892 }
893 return r;
894}
895
896static int nfc_parse_dt(struct device *dev, struct nqx_platform_data *pdata)
897{
898 int r = 0;
899 struct device_node *np = dev->of_node;
900
901 pdata->en_gpio = of_get_named_gpio(np, "qcom,nq-ven", 0);
902 if ((!gpio_is_valid(pdata->en_gpio)))
903 return -EINVAL;
904 disable_ctrl = pdata->en_gpio;
905
906 pdata->irq_gpio = of_get_named_gpio(np, "qcom,nq-irq", 0);
907 if ((!gpio_is_valid(pdata->irq_gpio)))
908 return -EINVAL;
909
910 pdata->firm_gpio = of_get_named_gpio(np, "qcom,nq-firm", 0);
911 if (!gpio_is_valid(pdata->firm_gpio)) {
912 dev_warn(dev,
913 "FIRM GPIO <OPTIONAL> error getting from OF node\n");
914 pdata->firm_gpio = -EINVAL;
915 }
916
917 pdata->ese_gpio = of_get_named_gpio(np, "qcom,nq-esepwr", 0);
918 if (!gpio_is_valid(pdata->ese_gpio)) {
919 dev_warn(dev,
920 "ese GPIO <OPTIONAL> error getting from OF node\n");
921 pdata->ese_gpio = -EINVAL;
922 }
923
Gaurav Singhal71661102018-01-30 16:34:37 +0530924 if (of_property_read_string(np, "qcom,clk-src", &pdata->clk_src_name))
925 pdata->clk_pin_voting = false;
926 else
927 pdata->clk_pin_voting = true;
Gaurav Singhalc53bc292017-02-16 16:35:39 +0530928
929 pdata->clkreq_gpio = of_get_named_gpio(np, "qcom,nq-clkreq", 0);
930
Gaurav Singhalc53bc292017-02-16 16:35:39 +0530931 return r;
932}
933
934static inline int gpio_input_init(const struct device * const dev,
935 const int gpio, const char * const gpio_name)
936{
937 int r = gpio_request(gpio, gpio_name);
938
939 if (r) {
940 dev_err(dev, "unable to request gpio [%d]\n", gpio);
941 return r;
942 }
943
944 r = gpio_direction_input(gpio);
945 if (r)
946 dev_err(dev, "unable to set direction for gpio [%d]\n", gpio);
947
948 return r;
949}
950
951static int nqx_probe(struct i2c_client *client,
952 const struct i2c_device_id *id)
953{
954 int r = 0;
955 int irqn = 0;
956 struct nqx_platform_data *platform_data;
957 struct nqx_dev *nqx_dev;
958
959 dev_dbg(&client->dev, "%s: enter\n", __func__);
960 if (client->dev.of_node) {
961 platform_data = devm_kzalloc(&client->dev,
962 sizeof(struct nqx_platform_data), GFP_KERNEL);
963 if (!platform_data) {
964 r = -ENOMEM;
965 goto err_platform_data;
966 }
967 r = nfc_parse_dt(&client->dev, platform_data);
968 if (r)
969 goto err_free_data;
970 } else
971 platform_data = client->dev.platform_data;
972
973 dev_dbg(&client->dev,
974 "%s, inside nfc-nci flags = %x\n",
975 __func__, client->flags);
976
977 if (platform_data == NULL) {
978 dev_err(&client->dev, "%s: failed\n", __func__);
979 r = -ENODEV;
980 goto err_platform_data;
981 }
982 if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
983 dev_err(&client->dev, "%s: need I2C_FUNC_I2C\n", __func__);
984 r = -ENODEV;
985 goto err_free_data;
986 }
987 nqx_dev = kzalloc(sizeof(*nqx_dev), GFP_KERNEL);
988 if (nqx_dev == NULL) {
989 r = -ENOMEM;
990 goto err_free_data;
991 }
992 nqx_dev->client = client;
993 nqx_dev->kbuflen = MAX_BUFFER_SIZE;
994 nqx_dev->kbuf = kzalloc(MAX_BUFFER_SIZE, GFP_KERNEL);
995 if (!nqx_dev->kbuf) {
996 dev_err(&client->dev,
997 "failed to allocate memory for nqx_dev->kbuf\n");
998 r = -ENOMEM;
999 goto err_free_dev;
1000 }
1001
1002 if (gpio_is_valid(platform_data->en_gpio)) {
1003 r = gpio_request(platform_data->en_gpio, "nfc_reset_gpio");
1004 if (r) {
1005 dev_err(&client->dev,
1006 "%s: unable to request nfc reset gpio [%d]\n",
1007 __func__,
1008 platform_data->en_gpio);
1009 goto err_mem;
1010 }
1011 r = gpio_direction_output(platform_data->en_gpio, 0);
1012 if (r) {
1013 dev_err(&client->dev,
1014 "%s: unable to set direction for nfc reset gpio [%d]\n",
1015 __func__,
1016 platform_data->en_gpio);
1017 goto err_en_gpio;
1018 }
1019 } else {
1020 dev_err(&client->dev,
1021 "%s: nfc reset gpio not provided\n", __func__);
1022 goto err_mem;
1023 }
1024
1025 if (gpio_is_valid(platform_data->irq_gpio)) {
1026 r = gpio_request(platform_data->irq_gpio, "nfc_irq_gpio");
1027 if (r) {
1028 dev_err(&client->dev, "%s: unable to request nfc irq gpio [%d]\n",
1029 __func__, platform_data->irq_gpio);
1030 goto err_en_gpio;
1031 }
1032 r = gpio_direction_input(platform_data->irq_gpio);
1033 if (r) {
1034 dev_err(&client->dev,
1035 "%s: unable to set direction for nfc irq gpio [%d]\n",
1036 __func__,
1037 platform_data->irq_gpio);
1038 goto err_irq_gpio;
1039 }
1040 irqn = gpio_to_irq(platform_data->irq_gpio);
1041 if (irqn < 0) {
1042 r = irqn;
1043 goto err_irq_gpio;
1044 }
1045 client->irq = irqn;
1046 } else {
1047 dev_err(&client->dev, "%s: irq gpio not provided\n", __func__);
1048 goto err_en_gpio;
1049 }
1050 if (gpio_is_valid(platform_data->firm_gpio)) {
1051 r = gpio_request(platform_data->firm_gpio,
1052 "nfc_firm_gpio");
1053 if (r) {
1054 dev_err(&client->dev,
1055 "%s: unable to request nfc firmware gpio [%d]\n",
1056 __func__, platform_data->firm_gpio);
1057 goto err_irq_gpio;
1058 }
1059 r = gpio_direction_output(platform_data->firm_gpio, 0);
1060 if (r) {
1061 dev_err(&client->dev,
1062 "%s: cannot set direction for nfc firmware gpio [%d]\n",
1063 __func__, platform_data->firm_gpio);
1064 goto err_firm_gpio;
1065 }
1066 } else {
1067 dev_err(&client->dev,
1068 "%s: firm gpio not provided\n", __func__);
1069 goto err_irq_gpio;
1070 }
1071 if (gpio_is_valid(platform_data->ese_gpio)) {
1072 r = gpio_request(platform_data->ese_gpio,
1073 "nfc-ese_pwr");
1074 if (r) {
1075 nqx_dev->ese_gpio = -EINVAL;
1076 dev_err(&client->dev,
1077 "%s: unable to request nfc ese gpio [%d]\n",
1078 __func__, platform_data->ese_gpio);
1079 /* ese gpio optional so we should continue */
1080 } else {
1081 nqx_dev->ese_gpio = platform_data->ese_gpio;
1082 r = gpio_direction_output(platform_data->ese_gpio, 0);
1083 if (r) {
1084 /*
1085 * free ese gpio and set invalid
1086 * to avoid further use
1087 */
1088 gpio_free(platform_data->ese_gpio);
1089 nqx_dev->ese_gpio = -EINVAL;
1090 dev_err(&client->dev,
1091 "%s: cannot set direction for nfc ese gpio [%d]\n",
1092 __func__, platform_data->ese_gpio);
1093 /* ese gpio optional so we should continue */
1094 }
1095 }
1096 } else {
1097 nqx_dev->ese_gpio = -EINVAL;
1098 dev_err(&client->dev,
1099 "%s: ese gpio not provided\n", __func__);
1100 /* ese gpio optional so we should continue */
1101 }
1102 if (gpio_is_valid(platform_data->clkreq_gpio)) {
1103 r = gpio_request(platform_data->clkreq_gpio,
1104 "nfc_clkreq_gpio");
1105 if (r) {
1106 dev_err(&client->dev,
1107 "%s: unable to request nfc clkreq gpio [%d]\n",
1108 __func__, platform_data->clkreq_gpio);
1109 goto err_ese_gpio;
1110 }
1111 r = gpio_direction_input(platform_data->clkreq_gpio);
1112 if (r) {
1113 dev_err(&client->dev,
1114 "%s: cannot set direction for nfc clkreq gpio [%d]\n",
1115 __func__, platform_data->clkreq_gpio);
1116 goto err_clkreq_gpio;
1117 }
1118 } else {
1119 dev_err(&client->dev,
1120 "%s: clkreq gpio not provided\n", __func__);
1121 goto err_ese_gpio;
1122 }
1123
1124 nqx_dev->en_gpio = platform_data->en_gpio;
1125 nqx_dev->irq_gpio = platform_data->irq_gpio;
1126 nqx_dev->firm_gpio = platform_data->firm_gpio;
1127 nqx_dev->clkreq_gpio = platform_data->clkreq_gpio;
1128 nqx_dev->pdata = platform_data;
1129
1130 /* init mutex and queues */
1131 init_waitqueue_head(&nqx_dev->read_wq);
1132 mutex_init(&nqx_dev->read_mutex);
1133 spin_lock_init(&nqx_dev->irq_enabled_lock);
1134
1135 nqx_dev->nqx_device.minor = MISC_DYNAMIC_MINOR;
1136 nqx_dev->nqx_device.name = "nq-nci";
1137 nqx_dev->nqx_device.fops = &nfc_dev_fops;
1138
1139 r = misc_register(&nqx_dev->nqx_device);
1140 if (r) {
1141 dev_err(&client->dev, "%s: misc_register failed\n", __func__);
1142 goto err_misc_register;
1143 }
1144
1145 /* NFC_INT IRQ */
1146 nqx_dev->irq_enabled = true;
1147 r = request_irq(client->irq, nqx_dev_irq_handler,
1148 IRQF_TRIGGER_HIGH, client->name, nqx_dev);
1149 if (r) {
1150 dev_err(&client->dev, "%s: request_irq failed\n", __func__);
1151 goto err_request_irq_failed;
1152 }
1153 nqx_disable_irq(nqx_dev);
1154
1155 /*
1156 * To be efficient we need to test whether nfcc hardware is physically
1157 * present before attempting further hardware initialisation.
1158 *
1159 */
1160 r = nfcc_hw_check(client, nqx_dev);
1161 if (r) {
1162 /* make sure NFCC is not enabled */
1163 gpio_set_value(platform_data->en_gpio, 0);
1164 /* We don't think there is hardware switch NFC OFF */
1165 goto err_request_hw_check_failed;
1166 }
1167
1168 /* Register reboot notifier here */
1169 r = register_reboot_notifier(&nfcc_notifier);
1170 if (r) {
1171 dev_err(&client->dev,
1172 "%s: cannot register reboot notifier(err = %d)\n",
1173 __func__, r);
1174 /*
1175 * nfcc_hw_check function not doing memory
1176 * allocation so using same goto target here
1177 */
1178 goto err_request_hw_check_failed;
1179 }
1180
1181#ifdef NFC_KERNEL_BU
1182 r = nqx_clock_select(nqx_dev);
1183 if (r < 0) {
1184 dev_err(&client->dev,
1185 "%s: nqx_clock_select failed\n", __func__);
1186 goto err_clock_en_failed;
1187 }
1188 gpio_set_value(platform_data->en_gpio, 1);
1189#endif
1190 device_init_wakeup(&client->dev, true);
1191 device_set_wakeup_capable(&client->dev, true);
1192 i2c_set_clientdata(client, nqx_dev);
1193 nqx_dev->irq_wake_up = false;
1194
1195 dev_err(&client->dev,
1196 "%s: probing NFCC NQxxx exited successfully\n",
1197 __func__);
1198 return 0;
1199
1200#ifdef NFC_KERNEL_BU
1201err_clock_en_failed:
1202 unregister_reboot_notifier(&nfcc_notifier);
1203#endif
1204err_request_hw_check_failed:
1205 free_irq(client->irq, nqx_dev);
1206err_request_irq_failed:
1207 misc_deregister(&nqx_dev->nqx_device);
1208err_misc_register:
1209 mutex_destroy(&nqx_dev->read_mutex);
1210err_clkreq_gpio:
1211 gpio_free(platform_data->clkreq_gpio);
1212err_ese_gpio:
1213 /* optional gpio, not sure was configured in probe */
1214 if (nqx_dev->ese_gpio > 0)
1215 gpio_free(platform_data->ese_gpio);
1216err_firm_gpio:
1217 gpio_free(platform_data->firm_gpio);
1218err_irq_gpio:
1219 gpio_free(platform_data->irq_gpio);
1220err_en_gpio:
1221 gpio_free(platform_data->en_gpio);
1222err_mem:
1223 kfree(nqx_dev->kbuf);
1224err_free_dev:
1225 kfree(nqx_dev);
1226err_free_data:
1227 if (client->dev.of_node)
1228 devm_kfree(&client->dev, platform_data);
1229err_platform_data:
1230 dev_err(&client->dev,
1231 "%s: probing nqxx failed, check hardware\n",
1232 __func__);
1233 return r;
1234}
1235
1236static int nqx_remove(struct i2c_client *client)
1237{
1238 int ret = 0;
1239 struct nqx_dev *nqx_dev;
1240
1241 nqx_dev = i2c_get_clientdata(client);
1242 if (!nqx_dev) {
1243 dev_err(&client->dev,
1244 "%s: device doesn't exist anymore\n", __func__);
1245 ret = -ENODEV;
1246 goto err;
1247 }
1248
1249 unregister_reboot_notifier(&nfcc_notifier);
1250 free_irq(client->irq, nqx_dev);
1251 misc_deregister(&nqx_dev->nqx_device);
1252 mutex_destroy(&nqx_dev->read_mutex);
1253 gpio_free(nqx_dev->clkreq_gpio);
1254 /* optional gpio, not sure was configured in probe */
1255 if (nqx_dev->ese_gpio > 0)
1256 gpio_free(nqx_dev->ese_gpio);
1257 gpio_free(nqx_dev->firm_gpio);
1258 gpio_free(nqx_dev->irq_gpio);
1259 gpio_free(nqx_dev->en_gpio);
1260 kfree(nqx_dev->kbuf);
1261 if (client->dev.of_node)
1262 devm_kfree(&client->dev, nqx_dev->pdata);
1263
1264 kfree(nqx_dev);
1265err:
1266 return ret;
1267}
1268
1269static int nqx_suspend(struct device *device)
1270{
1271 struct i2c_client *client = to_i2c_client(device);
1272 struct nqx_dev *nqx_dev = i2c_get_clientdata(client);
1273
1274 if (device_may_wakeup(&client->dev) && nqx_dev->irq_enabled) {
1275 if (!enable_irq_wake(client->irq))
1276 nqx_dev->irq_wake_up = true;
1277 }
1278 return 0;
1279}
1280
1281static int nqx_resume(struct device *device)
1282{
1283 struct i2c_client *client = to_i2c_client(device);
1284 struct nqx_dev *nqx_dev = i2c_get_clientdata(client);
1285
1286 if (device_may_wakeup(&client->dev) && nqx_dev->irq_wake_up) {
1287 if (!disable_irq_wake(client->irq))
1288 nqx_dev->irq_wake_up = false;
1289 }
1290 return 0;
1291}
1292
1293static const struct i2c_device_id nqx_id[] = {
1294 {"nqx-i2c", 0},
1295 {}
1296};
1297
1298static const struct dev_pm_ops nfc_pm_ops = {
1299 SET_SYSTEM_SLEEP_PM_OPS(nqx_suspend, nqx_resume)
1300};
1301
1302static struct i2c_driver nqx = {
1303 .id_table = nqx_id,
1304 .probe = nqx_probe,
1305 .remove = nqx_remove,
1306 .driver = {
1307 .owner = THIS_MODULE,
1308 .name = "nq-nci",
1309 .of_match_table = msm_match_table,
Lingutla Chandrasekhar788cb1c2016-09-12 11:10:27 +05301310 .probe_type = PROBE_PREFER_ASYNCHRONOUS,
Gaurav Singhalc53bc292017-02-16 16:35:39 +05301311 .pm = &nfc_pm_ops,
1312 },
1313};
1314
1315static int nfcc_reboot(struct notifier_block *notifier, unsigned long val,
1316 void *v)
1317{
1318 gpio_set_value(disable_ctrl, 1);
1319 return NOTIFY_OK;
1320}
1321
1322/*
1323 * module load/unload record keeping
1324 */
1325static int __init nqx_dev_init(void)
1326{
1327 return i2c_add_driver(&nqx);
1328}
1329module_init(nqx_dev_init);
1330
1331static void __exit nqx_dev_exit(void)
1332{
1333 unregister_reboot_notifier(&nfcc_notifier);
1334 i2c_del_driver(&nqx);
1335}
1336module_exit(nqx_dev_exit);
1337
1338MODULE_DESCRIPTION("NFC nqx");
1339MODULE_LICENSE("GPL v2");