blob: bae7f5b8d5ccb90477f4dba98d13f9ec80b1a18e [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
Bhuvan Varshney8e2ca882019-09-09 19:20:37 +0530153static int is_data_available_for_read(struct nqx_dev *nqx_dev)
154{
155 int ret;
156
157 nqx_enable_irq(nqx_dev);
158 ret = wait_event_interruptible(nqx_dev->read_wq, !nqx_dev->irq_enabled);
159 return ret;
160}
161
Gaurav Singhalc53bc292017-02-16 16:35:39 +0530162static ssize_t nfc_read(struct file *filp, char __user *buf,
163 size_t count, loff_t *offset)
164{
165 struct nqx_dev *nqx_dev = filp->private_data;
166 unsigned char *tmp = NULL;
167 int ret;
168 int irq_gpio_val = 0;
169
170 if (!nqx_dev) {
171 ret = -ENODEV;
172 goto out;
173 }
174
175 if (count > nqx_dev->kbuflen)
176 count = nqx_dev->kbuflen;
177
178 dev_dbg(&nqx_dev->client->dev, "%s : reading %zu bytes.\n",
179 __func__, count);
180
181 mutex_lock(&nqx_dev->read_mutex);
182
183 irq_gpio_val = gpio_get_value(nqx_dev->irq_gpio);
184 if (irq_gpio_val == 0) {
185 if (filp->f_flags & O_NONBLOCK) {
186 dev_err(&nqx_dev->client->dev,
187 ":f_falg has O_NONBLOCK. EAGAIN\n");
188 ret = -EAGAIN;
189 goto err;
190 }
191 while (1) {
192 ret = 0;
193 if (!nqx_dev->irq_enabled) {
194 nqx_dev->irq_enabled = true;
195 enable_irq(nqx_dev->client->irq);
196 }
197 if (!gpio_get_value(nqx_dev->irq_gpio)) {
198 ret = wait_event_interruptible(nqx_dev->read_wq,
199 !nqx_dev->irq_enabled);
200 }
201 if (ret)
202 goto err;
203 nqx_disable_irq(nqx_dev);
204
205 if (gpio_get_value(nqx_dev->irq_gpio))
206 break;
207 dev_err_ratelimited(&nqx_dev->client->dev,
208 "gpio is low, no need to read data\n");
209 }
210 }
211
212 tmp = nqx_dev->kbuf;
213 if (!tmp) {
214 dev_err(&nqx_dev->client->dev,
215 "%s: device doesn't exist anymore\n", __func__);
216 ret = -ENODEV;
217 goto err;
218 }
219 memset(tmp, 0x00, count);
220
221 /* Read data */
222 ret = i2c_master_recv(nqx_dev->client, tmp, count);
223 if (ret < 0) {
224 dev_err(&nqx_dev->client->dev,
225 "%s: i2c_master_recv returned %d\n", __func__, ret);
226 goto err;
227 }
228 if (ret > count) {
229 dev_err(&nqx_dev->client->dev,
230 "%s: received too many bytes from i2c (%d)\n",
231 __func__, ret);
232 ret = -EIO;
233 goto err;
234 }
235#ifdef NFC_KERNEL_BU
236 dev_dbg(&nqx_dev->client->dev, "%s : NfcNciRx %x %x %x\n",
237 __func__, tmp[0], tmp[1], tmp[2]);
238#endif
239 if (copy_to_user(buf, tmp, ret)) {
240 dev_warn(&nqx_dev->client->dev,
241 "%s : failed to copy to user space\n", __func__);
242 ret = -EFAULT;
243 goto err;
244 }
245 mutex_unlock(&nqx_dev->read_mutex);
246 return ret;
247
248err:
249 mutex_unlock(&nqx_dev->read_mutex);
250out:
251 return ret;
252}
253
254static ssize_t nfc_write(struct file *filp, const char __user *buf,
255 size_t count, loff_t *offset)
256{
257 struct nqx_dev *nqx_dev = filp->private_data;
258 char *tmp = NULL;
259 int ret = 0;
260
261 if (!nqx_dev) {
262 ret = -ENODEV;
263 goto out;
264 }
265 if (count > nqx_dev->kbuflen) {
266 dev_err(&nqx_dev->client->dev, "%s: out of memory\n",
267 __func__);
268 ret = -ENOMEM;
269 goto out;
270 }
271
272 tmp = memdup_user(buf, count);
273 if (IS_ERR(tmp)) {
274 dev_err(&nqx_dev->client->dev, "%s: memdup_user failed\n",
275 __func__);
276 ret = PTR_ERR(tmp);
277 goto out;
278 }
279
280 ret = i2c_master_send(nqx_dev->client, tmp, count);
281 if (ret != count) {
282 dev_err(&nqx_dev->client->dev,
283 "%s: failed to write %d\n", __func__, ret);
284 ret = -EIO;
285 goto out_free;
286 }
287#ifdef NFC_KERNEL_BU
288 dev_dbg(&nqx_dev->client->dev,
289 "%s : i2c-%d: NfcNciTx %x %x %x\n",
290 __func__, iminor(file_inode(filp)),
291 tmp[0], tmp[1], tmp[2]);
292#endif
293 usleep_range(1000, 1100);
294out_free:
295 kfree(tmp);
296out:
297 return ret;
298}
299
300/**
301 * nqx_standby_write()
302 * @buf: pointer to data buffer
303 * @len: # of bytes need to transfer
304 *
305 * write data buffer over I2C and retry
306 * if NFCC is in stand by mode
307 *
308 * Return: # of bytes written or -ve value in case of error
309 */
310static int nqx_standby_write(struct nqx_dev *nqx_dev,
311 const unsigned char *buf, size_t len)
312{
313 int ret = -EINVAL;
314 int retry_cnt;
315
316 for (retry_cnt = 1; retry_cnt <= MAX_RETRY_COUNT; retry_cnt++) {
317 ret = i2c_master_send(nqx_dev->client, buf, len);
318 if (ret < 0) {
319 dev_err(&nqx_dev->client->dev,
320 "%s: write failed, Maybe in Standby Mode - Retry(%d)\n",
321 __func__, retry_cnt);
322 usleep_range(1000, 1100);
323 } else if (ret == len)
324 break;
325 }
326 return ret;
327}
328
329/*
330 * Power management of the eSE
331 * NFC & eSE ON : NFC_EN high and eSE_pwr_req high.
332 * NFC OFF & eSE ON : NFC_EN high and eSE_pwr_req high.
333 * NFC OFF & eSE OFF : NFC_EN low and eSE_pwr_req low.
334 */
335static int nqx_ese_pwr(struct nqx_dev *nqx_dev, unsigned long int arg)
336{
337 int r = -1;
338 const unsigned char svdd_off_cmd_warn[] = {0x2F, 0x31, 0x01, 0x01};
339 const unsigned char svdd_off_cmd_done[] = {0x2F, 0x31, 0x01, 0x00};
340
341 if (!gpio_is_valid(nqx_dev->ese_gpio)) {
342 dev_err(&nqx_dev->client->dev,
343 "%s: ese_gpio is not valid\n", __func__);
344 return -EINVAL;
345 }
346
347 if (arg == 0) {
348 /*
349 * We want to power on the eSE and to do so we need the
350 * eSE_pwr_req pin and the NFC_EN pin to be high
351 */
352 if (gpio_get_value(nqx_dev->ese_gpio)) {
353 dev_dbg(&nqx_dev->client->dev, "ese_gpio is already high\n");
354 r = 0;
355 } else {
356 /**
357 * Let's store the NFC_EN pin state
358 * only if the eSE is not yet on
359 */
360 nqx_dev->nfc_ven_enabled =
361 gpio_get_value(nqx_dev->en_gpio);
362 if (!nqx_dev->nfc_ven_enabled) {
363 gpio_set_value(nqx_dev->en_gpio, 1);
364 /* hardware dependent delay */
365 usleep_range(1000, 1100);
366 }
367 gpio_set_value(nqx_dev->ese_gpio, 1);
Gaurav Singhalcfb64802017-08-30 17:03:58 +0530368 usleep_range(1000, 1100);
Gaurav Singhalc53bc292017-02-16 16:35:39 +0530369 if (gpio_get_value(nqx_dev->ese_gpio)) {
370 dev_dbg(&nqx_dev->client->dev, "ese_gpio is enabled\n");
371 r = 0;
372 }
373 }
374 } else if (arg == 1) {
375 if (nqx_dev->nfc_ven_enabled &&
376 ((nqx_dev->nqx_info.info.chip_type == NFCC_NQ_220) ||
377 (nqx_dev->nqx_info.info.chip_type == NFCC_PN66T))) {
378 /**
379 * Let's inform the CLF we're
380 * powering off the eSE
381 */
382 r = nqx_standby_write(nqx_dev, svdd_off_cmd_warn,
383 sizeof(svdd_off_cmd_warn));
384 if (r < 0) {
385 dev_err(&nqx_dev->client->dev,
386 "%s: write failed after max retry\n",
387 __func__);
388 return -ENXIO;
389 }
390 dev_dbg(&nqx_dev->client->dev,
391 "%s: svdd_off_cmd_warn sent\n", __func__);
392
393 /* let's power down the eSE */
394 gpio_set_value(nqx_dev->ese_gpio, 0);
395 dev_dbg(&nqx_dev->client->dev,
396 "%s: nqx_dev->ese_gpio set to 0\n", __func__);
397
398 /**
399 * Time needed for the SVDD capacitor
400 * to get discharged
401 */
402 usleep_range(8000, 8100);
403
404 /* Let's inform the CLF the eSE is now off */
405 r = nqx_standby_write(nqx_dev, svdd_off_cmd_done,
406 sizeof(svdd_off_cmd_done));
407 if (r < 0) {
408 dev_err(&nqx_dev->client->dev,
409 "%s: write failed after max retry\n",
410 __func__);
411 return -ENXIO;
412 }
413 dev_dbg(&nqx_dev->client->dev,
414 "%s: svdd_off_cmd_done sent\n", __func__);
415 } else {
416 /**
417 * In case the NFC is off,
418 * there's no need to send the i2c commands
419 */
420 gpio_set_value(nqx_dev->ese_gpio, 0);
Gaurav Singhalcfb64802017-08-30 17:03:58 +0530421 usleep_range(1000, 1100);
Gaurav Singhalc53bc292017-02-16 16:35:39 +0530422 }
423
424 if (!gpio_get_value(nqx_dev->ese_gpio)) {
425 dev_dbg(&nqx_dev->client->dev, "ese_gpio is disabled\n");
426 r = 0;
427 }
428
429 if (!nqx_dev->nfc_ven_enabled) {
430 /* hardware dependent delay */
431 usleep_range(1000, 1100);
432 dev_dbg(&nqx_dev->client->dev, "disabling en_gpio\n");
433 gpio_set_value(nqx_dev->en_gpio, 0);
434 }
435 } else if (arg == 3) {
436 r = gpio_get_value(nqx_dev->ese_gpio);
437 }
438 return r;
439}
440
441static int nfc_open(struct inode *inode, struct file *filp)
442{
443 int ret = 0;
444 struct nqx_dev *nqx_dev = container_of(filp->private_data,
445 struct nqx_dev, nqx_device);
446
447 filp->private_data = nqx_dev;
448 nqx_init_stat(nqx_dev);
449
450 dev_dbg(&nqx_dev->client->dev,
451 "%s: %d,%d\n", __func__, imajor(inode), iminor(inode));
452 return ret;
453}
454
455/*
456 * nfc_ioctl_power_states() - power control
457 * @filp: pointer to the file descriptor
458 * @arg: mode that we want to move to
459 *
460 * Device power control. Depending on the arg value, device moves to
461 * different states
462 * (arg = 0): NFC_ENABLE GPIO = 0, FW_DL GPIO = 0
463 * (arg = 1): NFC_ENABLE GPIO = 1, FW_DL GPIO = 0
464 * (arg = 2): FW_DL GPIO = 1
465 *
466 * Return: -ENOIOCTLCMD if arg is not supported, 0 in any other case
467 */
468int nfc_ioctl_power_states(struct file *filp, unsigned long arg)
469{
470 int r = 0;
471 struct nqx_dev *nqx_dev = filp->private_data;
472
473 if (arg == 0) {
474 /*
475 * We are attempting a hardware reset so let us disable
476 * interrupts to avoid spurious notifications to upper
477 * layers.
478 */
479 nqx_disable_irq(nqx_dev);
480 dev_dbg(&nqx_dev->client->dev,
481 "gpio_set_value disable: %s: info: %p\n",
482 __func__, nqx_dev);
Gaurav Singhal165add72017-10-13 17:17:58 +0530483 if (gpio_is_valid(nqx_dev->firm_gpio)) {
Gaurav Singhalc53bc292017-02-16 16:35:39 +0530484 gpio_set_value(nqx_dev->firm_gpio, 0);
Gaurav Singhal165add72017-10-13 17:17:58 +0530485 usleep_range(10000, 10100);
486 }
Gaurav Singhalc53bc292017-02-16 16:35:39 +0530487
488 if (gpio_is_valid(nqx_dev->ese_gpio)) {
489 if (!gpio_get_value(nqx_dev->ese_gpio)) {
490 dev_dbg(&nqx_dev->client->dev, "disabling en_gpio\n");
491 gpio_set_value(nqx_dev->en_gpio, 0);
Gaurav Singhal165add72017-10-13 17:17:58 +0530492 usleep_range(10000, 10100);
Gaurav Singhalc53bc292017-02-16 16:35:39 +0530493 } else {
494 dev_dbg(&nqx_dev->client->dev, "keeping en_gpio high\n");
495 }
496 } else {
497 dev_dbg(&nqx_dev->client->dev, "ese_gpio invalid, set en_gpio to low\n");
498 gpio_set_value(nqx_dev->en_gpio, 0);
Gaurav Singhal165add72017-10-13 17:17:58 +0530499 usleep_range(10000, 10100);
Gaurav Singhalc53bc292017-02-16 16:35:39 +0530500 }
Gaurav Singhal71661102018-01-30 16:34:37 +0530501 if (nqx_dev->pdata->clk_pin_voting) {
502 r = nqx_clock_deselect(nqx_dev);
503 if (r < 0)
504 dev_err(&nqx_dev->client->dev, "unable to disable clock\n");
505 }
Gaurav Singhalc53bc292017-02-16 16:35:39 +0530506 nqx_dev->nfc_ven_enabled = false;
Gaurav Singhalc53bc292017-02-16 16:35:39 +0530507 } else if (arg == 1) {
508 nqx_enable_irq(nqx_dev);
509 dev_dbg(&nqx_dev->client->dev,
510 "gpio_set_value enable: %s: info: %p\n",
511 __func__, nqx_dev);
Gaurav Singhal165add72017-10-13 17:17:58 +0530512 if (gpio_is_valid(nqx_dev->firm_gpio)) {
Gaurav Singhalc53bc292017-02-16 16:35:39 +0530513 gpio_set_value(nqx_dev->firm_gpio, 0);
Gaurav Singhal165add72017-10-13 17:17:58 +0530514 usleep_range(10000, 10100);
515 }
Gaurav Singhalc53bc292017-02-16 16:35:39 +0530516 gpio_set_value(nqx_dev->en_gpio, 1);
Gaurav Singhal165add72017-10-13 17:17:58 +0530517 usleep_range(10000, 10100);
Gaurav Singhal71661102018-01-30 16:34:37 +0530518 if (nqx_dev->pdata->clk_pin_voting) {
519 r = nqx_clock_select(nqx_dev);
520 if (r < 0)
521 dev_err(&nqx_dev->client->dev, "unable to enable clock\n");
522 }
Gaurav Singhalc53bc292017-02-16 16:35:39 +0530523 nqx_dev->nfc_ven_enabled = true;
Gaurav Singhalc53bc292017-02-16 16:35:39 +0530524 } else if (arg == 2) {
525 /*
526 * We are switching to Dowload Mode, toggle the enable pin
527 * in order to set the NFCC in the new mode
528 */
529 if (gpio_is_valid(nqx_dev->ese_gpio)) {
530 if (gpio_get_value(nqx_dev->ese_gpio)) {
531 dev_err(&nqx_dev->client->dev,
532 "FW download forbidden while ese is on\n");
533 return -EBUSY; /* Device or resource busy */
534 }
535 }
536 gpio_set_value(nqx_dev->en_gpio, 1);
Gaurav Singhal165add72017-10-13 17:17:58 +0530537 usleep_range(10000, 10100);
538 if (gpio_is_valid(nqx_dev->firm_gpio)) {
Gaurav Singhalc53bc292017-02-16 16:35:39 +0530539 gpio_set_value(nqx_dev->firm_gpio, 1);
Gaurav Singhal165add72017-10-13 17:17:58 +0530540 usleep_range(10000, 10100);
541 }
Gaurav Singhalc53bc292017-02-16 16:35:39 +0530542 gpio_set_value(nqx_dev->en_gpio, 0);
Gaurav Singhal165add72017-10-13 17:17:58 +0530543 usleep_range(10000, 10100);
Gaurav Singhalc53bc292017-02-16 16:35:39 +0530544 gpio_set_value(nqx_dev->en_gpio, 1);
Gaurav Singhal165add72017-10-13 17:17:58 +0530545 usleep_range(10000, 10100);
Bhuvan Varshneyae67c4e2018-11-23 15:15:27 +0530546 } else if (arg == 4) {
547 /*
548 * Setting firmware download gpio to HIGH for SN100U
549 * before FW download start
550 */
551 dev_dbg(&nqx_dev->client->dev, "SN100 fw gpio HIGH\n");
552 if (gpio_is_valid(nqx_dev->firm_gpio)) {
553 gpio_set_value(nqx_dev->firm_gpio, 1);
554 usleep_range(10000, 10100);
555 } else {
556 dev_err(&nqx_dev->client->dev,
557 "firm_gpio is invalid\n");
558 }
559 } else if (arg == 6) {
560 /*
561 * Setting firmware download gpio to LOW for SN100U
562 * FW download finished
563 */
564 dev_dbg(&nqx_dev->client->dev, "SN100 fw gpio LOW\n");
565 if (gpio_is_valid(nqx_dev->firm_gpio)) {
566 gpio_set_value(nqx_dev->firm_gpio, 0);
567 usleep_range(10000, 10100);
568 } else {
569 dev_err(&nqx_dev->client->dev,
570 "firm_gpio is invalid\n");
571 }
Gaurav Singhalc53bc292017-02-16 16:35:39 +0530572 } else {
573 r = -ENOIOCTLCMD;
574 }
575
576 return r;
577}
578
579#ifdef CONFIG_COMPAT
580static long nfc_compat_ioctl(struct file *pfile, unsigned int cmd,
581 unsigned long arg)
582{
583 long r = 0;
584
585 arg = (compat_u64)arg;
586 switch (cmd) {
587 case NFC_SET_PWR:
588 nfc_ioctl_power_states(pfile, arg);
589 break;
590 case ESE_SET_PWR:
591 nqx_ese_pwr(pfile->private_data, arg);
592 break;
593 case ESE_GET_PWR:
594 nqx_ese_pwr(pfile->private_data, 3);
595 break;
596 case SET_RX_BLOCK:
597 break;
598 case SET_EMULATOR_TEST_POINT:
599 break;
600 default:
601 r = -ENOTTY;
602 }
603 return r;
604}
605#endif
606
607/*
608 * nfc_ioctl_core_reset_ntf()
609 * @filp: pointer to the file descriptor
610 *
611 * Allows callers to determine if a CORE_RESET_NTF has arrived
612 *
613 * Return: the value of variable core_reset_ntf
614 */
615int nfc_ioctl_core_reset_ntf(struct file *filp)
616{
617 struct nqx_dev *nqx_dev = filp->private_data;
618
619 dev_dbg(&nqx_dev->client->dev, "%s: returning = %d\n", __func__,
620 nqx_dev->core_reset_ntf);
621 return nqx_dev->core_reset_ntf;
622}
623
624/*
625 * Inside nfc_ioctl_nfcc_info
626 *
627 * @brief nfc_ioctl_nfcc_info
628 *
629 * Check the NQ Chipset and firmware version details
630 */
631unsigned int nfc_ioctl_nfcc_info(struct file *filp, unsigned long arg)
632{
633 unsigned int r = 0;
634 struct nqx_dev *nqx_dev = filp->private_data;
635
636 r = nqx_dev->nqx_info.i;
637 dev_dbg(&nqx_dev->client->dev,
638 "nqx nfc : nfc_ioctl_nfcc_info r = %d\n", r);
639
640 return r;
641}
642
643static long nfc_ioctl(struct file *pfile, unsigned int cmd,
644 unsigned long arg)
645{
646 int r = 0;
647
648 switch (cmd) {
649 case NFC_SET_PWR:
650 r = nfc_ioctl_power_states(pfile, arg);
651 break;
652 case ESE_SET_PWR:
653 r = nqx_ese_pwr(pfile->private_data, arg);
654 break;
655 case ESE_GET_PWR:
656 r = nqx_ese_pwr(pfile->private_data, 3);
657 break;
658 case SET_RX_BLOCK:
659 break;
660 case SET_EMULATOR_TEST_POINT:
661 break;
662 case NFCC_INITIAL_CORE_RESET_NTF:
663 r = nfc_ioctl_core_reset_ntf(pfile);
664 break;
665 case NFCC_GET_INFO:
666 r = nfc_ioctl_nfcc_info(pfile, arg);
667 break;
668 default:
669 r = -ENOIOCTLCMD;
670 }
671 return r;
672}
673
674static const struct file_operations nfc_dev_fops = {
675 .owner = THIS_MODULE,
676 .llseek = no_llseek,
677 .read = nfc_read,
678 .write = nfc_write,
679 .open = nfc_open,
680 .unlocked_ioctl = nfc_ioctl,
681#ifdef CONFIG_COMPAT
682 .compat_ioctl = nfc_compat_ioctl
683#endif
684};
685
686/* Check for availability of NQ_ NFC controller hardware */
687static int nfcc_hw_check(struct i2c_client *client, struct nqx_dev *nqx_dev)
688{
689 int ret = 0;
690
691 unsigned char raw_nci_reset_cmd[] = {0x20, 0x00, 0x01, 0x00};
692 unsigned char raw_nci_init_cmd[] = {0x20, 0x01, 0x00};
Tapas Deyb5e69602019-05-07 11:33:00 +0530693 unsigned char nci_get_version_cmd[] = {0x00, 0x04, 0xF1,
694 0x00, 0x00, 0x00, 0x6E, 0xEF};
Gaurav Singhalc53bc292017-02-16 16:35:39 +0530695 unsigned char nci_init_rsp[28];
696 unsigned char nci_reset_rsp[6];
Tapas Deyb5e69602019-05-07 11:33:00 +0530697 unsigned char nci_get_version_rsp[12];
Gaurav Singhalc53bc292017-02-16 16:35:39 +0530698 unsigned char init_rsp_len = 0;
699 unsigned int enable_gpio = nqx_dev->en_gpio;
Gaurav Singhal165add72017-10-13 17:17:58 +0530700
Gaurav Singhalc53bc292017-02-16 16:35:39 +0530701 /* making sure that the NFCC starts in a clean state. */
702 gpio_set_value(enable_gpio, 0);/* ULPM: Disable */
703 /* hardware dependent delay */
Gaurav Singhal165add72017-10-13 17:17:58 +0530704 usleep_range(10000, 10100);
Gaurav Singhalc53bc292017-02-16 16:35:39 +0530705 gpio_set_value(enable_gpio, 1);/* HPD : Enable*/
706 /* hardware dependent delay */
Gaurav Singhal165add72017-10-13 17:17:58 +0530707 usleep_range(10000, 10100);
Gaurav Singhalc53bc292017-02-16 16:35:39 +0530708
709 /* send NCI CORE RESET CMD with Keep Config parameters */
710 ret = i2c_master_send(client, raw_nci_reset_cmd,
711 sizeof(raw_nci_reset_cmd));
712 if (ret < 0) {
713 dev_err(&client->dev,
Tapas Deyb5e69602019-05-07 11:33:00 +0530714 "%s: - i2c_master_send core reset Error\n", __func__);
715
716 if (gpio_is_valid(nqx_dev->firm_gpio)) {
717 gpio_set_value(nqx_dev->firm_gpio, 1);
718 usleep_range(10000, 10100);
719 }
720 gpio_set_value(nqx_dev->en_gpio, 0);
721 usleep_range(10000, 10100);
722 gpio_set_value(nqx_dev->en_gpio, 1);
723 usleep_range(10000, 10100);
724
725 ret = i2c_master_send(client, nci_get_version_cmd,
726 sizeof(nci_get_version_cmd));
727
728 if (ret < 0) {
729 dev_err(&client->dev,
730 "%s: - i2c_master_send get version cmd Error\n",
731 __func__);
732 goto err_nfcc_hw_check;
733 }
734 /* hardware dependent delay */
735 usleep_range(10000, 10100);
736
737 ret = i2c_master_recv(client, nci_get_version_rsp,
738 sizeof(nci_get_version_rsp));
739 if (ret < 0) {
740 dev_err(&client->dev,
741 "%s: - i2c_master_recv get version rsp Error\n",
742 __func__);
743 goto err_nfcc_hw_check;
744 } else {
745 nqx_dev->nqx_info.info.chip_type =
746 nci_get_version_rsp[3];
747 nqx_dev->nqx_info.info.rom_version =
748 nci_get_version_rsp[4];
Tapas Dey48613f82019-11-21 16:18:42 +0530749 if ((nci_get_version_rsp[3] == NFCC_SN100_A)
750 || (nci_get_version_rsp[3] == NFCC_SN100_B)) {
751 nqx_dev->nqx_info.info.fw_minor =
752 nci_get_version_rsp[6];
753 nqx_dev->nqx_info.info.fw_major =
754 nci_get_version_rsp[7];
755 } else {
756 nqx_dev->nqx_info.info.fw_minor =
757 nci_get_version_rsp[10];
758 nqx_dev->nqx_info.info.fw_major =
759 nci_get_version_rsp[11];
760 }
Tapas Deyb5e69602019-05-07 11:33:00 +0530761 }
762 goto err_nfcc_reset_failed;
Gaurav Singhalc53bc292017-02-16 16:35:39 +0530763 }
Bhuvan Varshney8e2ca882019-09-09 19:20:37 +0530764 ret = is_data_available_for_read(nqx_dev);
765 if (ret < 0) {
766 nqx_disable_irq(nqx_dev);
767 goto err_nfcc_hw_check;
768 }
Gaurav Singhalc53bc292017-02-16 16:35:39 +0530769
770 /* Read Response of RESET command */
771 ret = i2c_master_recv(client, nci_reset_rsp,
772 sizeof(nci_reset_rsp));
Gaurav Singhalc53bc292017-02-16 16:35:39 +0530773 if (ret < 0) {
774 dev_err(&client->dev,
775 "%s: - i2c_master_recv Error\n", __func__);
776 goto err_nfcc_hw_check;
777 }
Bhuvan Varshney8e2ca882019-09-09 19:20:37 +0530778
779 /* send NCI CORE INIT CMD */
Gaurav Singhal165add72017-10-13 17:17:58 +0530780 ret = nqx_standby_write(nqx_dev, raw_nci_init_cmd,
781 sizeof(raw_nci_init_cmd));
Gaurav Singhalc53bc292017-02-16 16:35:39 +0530782 if (ret < 0) {
783 dev_err(&client->dev,
Tapas Deyb5e69602019-05-07 11:33:00 +0530784 "%s: - i2c_master_send failed for Core INIT\n", __func__);
Gaurav Singhal165add72017-10-13 17:17:58 +0530785 goto err_nfcc_core_init_fail;
Gaurav Singhalc53bc292017-02-16 16:35:39 +0530786 }
Bhuvan Varshney8e2ca882019-09-09 19:20:37 +0530787 ret = is_data_available_for_read(nqx_dev);
788 if (ret < 0) {
789 nqx_disable_irq(nqx_dev);
790 goto err_nfcc_hw_check;
791 }
792
Gaurav Singhalc53bc292017-02-16 16:35:39 +0530793 /* Read Response of INIT command */
794 ret = i2c_master_recv(client, nci_init_rsp,
795 sizeof(nci_init_rsp));
796 if (ret < 0) {
797 dev_err(&client->dev,
798 "%s: - i2c_master_recv Error\n", __func__);
Gaurav Singhal165add72017-10-13 17:17:58 +0530799 goto err_nfcc_core_init_fail;
Gaurav Singhalc53bc292017-02-16 16:35:39 +0530800 }
801 init_rsp_len = 2 + nci_init_rsp[2]; /*payload + len*/
802 if (init_rsp_len > PAYLOAD_HEADER_LENGTH) {
803 nqx_dev->nqx_info.info.chip_type =
804 nci_init_rsp[init_rsp_len - 3];
805 nqx_dev->nqx_info.info.rom_version =
806 nci_init_rsp[init_rsp_len - 2];
807 nqx_dev->nqx_info.info.fw_major =
808 nci_init_rsp[init_rsp_len - 1];
809 nqx_dev->nqx_info.info.fw_minor =
810 nci_init_rsp[init_rsp_len];
811 }
Gaurav Singhal165add72017-10-13 17:17:58 +0530812 dev_dbg(&client->dev,
813 "%s: - nq - reset cmd answer : NfcNciRx %x %x %x\n",
814 __func__, nci_reset_rsp[0],
815 nci_reset_rsp[1], nci_reset_rsp[2]);
816
Tapas Deyb5e69602019-05-07 11:33:00 +0530817err_nfcc_reset_failed:
Gaurav Singhalc53bc292017-02-16 16:35:39 +0530818 dev_dbg(&nqx_dev->client->dev, "NQ NFCC chip_type = %x\n",
819 nqx_dev->nqx_info.info.chip_type);
820 dev_dbg(&nqx_dev->client->dev, "NQ fw version = %x.%x.%x\n",
821 nqx_dev->nqx_info.info.rom_version,
822 nqx_dev->nqx_info.info.fw_major,
823 nqx_dev->nqx_info.info.fw_minor);
824
825 switch (nqx_dev->nqx_info.info.chip_type) {
826 case NFCC_NQ_210:
827 dev_dbg(&client->dev,
828 "%s: ## NFCC == NQ210 ##\n", __func__);
829 break;
830 case NFCC_NQ_220:
831 dev_dbg(&client->dev,
832 "%s: ## NFCC == NQ220 ##\n", __func__);
833 break;
834 case NFCC_NQ_310:
835 dev_dbg(&client->dev,
836 "%s: ## NFCC == NQ310 ##\n", __func__);
837 break;
838 case NFCC_NQ_330:
839 dev_dbg(&client->dev,
840 "%s: ## NFCC == NQ330 ##\n", __func__);
841 break;
842 case NFCC_PN66T:
843 dev_dbg(&client->dev,
844 "%s: ## NFCC == PN66T ##\n", __func__);
845 break;
Bhuvan Varshney8e2ca882019-09-09 19:20:37 +0530846 case NFCC_SN100_A:
847 case NFCC_SN100_B:
848 dev_dbg(&client->dev,
849 "%s: ## NFCC == SN100x ##\n", __func__);
850 break;
Gaurav Singhalc53bc292017-02-16 16:35:39 +0530851 default:
852 dev_err(&client->dev,
853 "%s: - NFCC HW not Supported\n", __func__);
854 break;
855 }
856
857 /*Disable NFC by default to save power on boot*/
858 gpio_set_value(enable_gpio, 0);/* ULPM: Disable */
859 ret = 0;
860 goto done;
861
Gaurav Singhal165add72017-10-13 17:17:58 +0530862err_nfcc_core_init_fail:
863 dev_err(&client->dev,
864 "%s: - nq - reset cmd answer : NfcNciRx %x %x %x\n",
865 __func__, nci_reset_rsp[0],
866 nci_reset_rsp[1], nci_reset_rsp[2]);
867
Gaurav Singhalc53bc292017-02-16 16:35:39 +0530868err_nfcc_hw_check:
869 ret = -ENXIO;
870 dev_err(&client->dev,
871 "%s: - NFCC HW not available\n", __func__);
872done:
873 return ret;
874}
875
876/*
877 * Routine to enable clock.
878 * this routine can be extended to select from multiple
879 * sources based on clk_src_name.
880 */
881static int nqx_clock_select(struct nqx_dev *nqx_dev)
882{
883 int r = 0;
884
885 nqx_dev->s_clk = clk_get(&nqx_dev->client->dev, "ref_clk");
886
887 if (nqx_dev->s_clk == NULL)
888 goto err_clk;
889
890 if (nqx_dev->clk_run == false)
891 r = clk_prepare_enable(nqx_dev->s_clk);
892
893 if (r)
894 goto err_clk;
895
896 nqx_dev->clk_run = true;
897
898 return r;
899
900err_clk:
901 r = -1;
902 return r;
903}
904
905/*
906 * Routine to disable clocks
907 */
908static int nqx_clock_deselect(struct nqx_dev *nqx_dev)
909{
910 int r = -1;
911
912 if (nqx_dev->s_clk != NULL) {
913 if (nqx_dev->clk_run == true) {
914 clk_disable_unprepare(nqx_dev->s_clk);
915 nqx_dev->clk_run = false;
916 }
917 return 0;
918 }
919 return r;
920}
921
922static int nfc_parse_dt(struct device *dev, struct nqx_platform_data *pdata)
923{
924 int r = 0;
925 struct device_node *np = dev->of_node;
926
927 pdata->en_gpio = of_get_named_gpio(np, "qcom,nq-ven", 0);
928 if ((!gpio_is_valid(pdata->en_gpio)))
929 return -EINVAL;
930 disable_ctrl = pdata->en_gpio;
931
932 pdata->irq_gpio = of_get_named_gpio(np, "qcom,nq-irq", 0);
933 if ((!gpio_is_valid(pdata->irq_gpio)))
934 return -EINVAL;
935
936 pdata->firm_gpio = of_get_named_gpio(np, "qcom,nq-firm", 0);
937 if (!gpio_is_valid(pdata->firm_gpio)) {
938 dev_warn(dev,
939 "FIRM GPIO <OPTIONAL> error getting from OF node\n");
940 pdata->firm_gpio = -EINVAL;
941 }
942
943 pdata->ese_gpio = of_get_named_gpio(np, "qcom,nq-esepwr", 0);
944 if (!gpio_is_valid(pdata->ese_gpio)) {
945 dev_warn(dev,
946 "ese GPIO <OPTIONAL> error getting from OF node\n");
947 pdata->ese_gpio = -EINVAL;
948 }
949
Gaurav Singhal71661102018-01-30 16:34:37 +0530950 if (of_property_read_string(np, "qcom,clk-src", &pdata->clk_src_name))
951 pdata->clk_pin_voting = false;
952 else
953 pdata->clk_pin_voting = true;
Gaurav Singhalc53bc292017-02-16 16:35:39 +0530954
955 pdata->clkreq_gpio = of_get_named_gpio(np, "qcom,nq-clkreq", 0);
956
Gaurav Singhalc53bc292017-02-16 16:35:39 +0530957 return r;
958}
959
960static inline int gpio_input_init(const struct device * const dev,
961 const int gpio, const char * const gpio_name)
962{
963 int r = gpio_request(gpio, gpio_name);
964
965 if (r) {
966 dev_err(dev, "unable to request gpio [%d]\n", gpio);
967 return r;
968 }
969
970 r = gpio_direction_input(gpio);
971 if (r)
972 dev_err(dev, "unable to set direction for gpio [%d]\n", gpio);
973
974 return r;
975}
976
977static int nqx_probe(struct i2c_client *client,
978 const struct i2c_device_id *id)
979{
980 int r = 0;
981 int irqn = 0;
982 struct nqx_platform_data *platform_data;
983 struct nqx_dev *nqx_dev;
984
985 dev_dbg(&client->dev, "%s: enter\n", __func__);
986 if (client->dev.of_node) {
987 platform_data = devm_kzalloc(&client->dev,
988 sizeof(struct nqx_platform_data), GFP_KERNEL);
989 if (!platform_data) {
990 r = -ENOMEM;
991 goto err_platform_data;
992 }
993 r = nfc_parse_dt(&client->dev, platform_data);
994 if (r)
995 goto err_free_data;
996 } else
997 platform_data = client->dev.platform_data;
998
999 dev_dbg(&client->dev,
1000 "%s, inside nfc-nci flags = %x\n",
1001 __func__, client->flags);
1002
1003 if (platform_data == NULL) {
1004 dev_err(&client->dev, "%s: failed\n", __func__);
1005 r = -ENODEV;
1006 goto err_platform_data;
1007 }
1008 if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
1009 dev_err(&client->dev, "%s: need I2C_FUNC_I2C\n", __func__);
1010 r = -ENODEV;
1011 goto err_free_data;
1012 }
1013 nqx_dev = kzalloc(sizeof(*nqx_dev), GFP_KERNEL);
1014 if (nqx_dev == NULL) {
1015 r = -ENOMEM;
1016 goto err_free_data;
1017 }
1018 nqx_dev->client = client;
1019 nqx_dev->kbuflen = MAX_BUFFER_SIZE;
1020 nqx_dev->kbuf = kzalloc(MAX_BUFFER_SIZE, GFP_KERNEL);
1021 if (!nqx_dev->kbuf) {
1022 dev_err(&client->dev,
1023 "failed to allocate memory for nqx_dev->kbuf\n");
1024 r = -ENOMEM;
1025 goto err_free_dev;
1026 }
1027
1028 if (gpio_is_valid(platform_data->en_gpio)) {
1029 r = gpio_request(platform_data->en_gpio, "nfc_reset_gpio");
1030 if (r) {
1031 dev_err(&client->dev,
1032 "%s: unable to request nfc reset gpio [%d]\n",
1033 __func__,
1034 platform_data->en_gpio);
1035 goto err_mem;
1036 }
1037 r = gpio_direction_output(platform_data->en_gpio, 0);
1038 if (r) {
1039 dev_err(&client->dev,
1040 "%s: unable to set direction for nfc reset gpio [%d]\n",
1041 __func__,
1042 platform_data->en_gpio);
1043 goto err_en_gpio;
1044 }
1045 } else {
1046 dev_err(&client->dev,
1047 "%s: nfc reset gpio not provided\n", __func__);
1048 goto err_mem;
1049 }
1050
1051 if (gpio_is_valid(platform_data->irq_gpio)) {
1052 r = gpio_request(platform_data->irq_gpio, "nfc_irq_gpio");
1053 if (r) {
1054 dev_err(&client->dev, "%s: unable to request nfc irq gpio [%d]\n",
1055 __func__, platform_data->irq_gpio);
1056 goto err_en_gpio;
1057 }
1058 r = gpio_direction_input(platform_data->irq_gpio);
1059 if (r) {
1060 dev_err(&client->dev,
1061 "%s: unable to set direction for nfc irq gpio [%d]\n",
1062 __func__,
1063 platform_data->irq_gpio);
1064 goto err_irq_gpio;
1065 }
1066 irqn = gpio_to_irq(platform_data->irq_gpio);
1067 if (irqn < 0) {
1068 r = irqn;
1069 goto err_irq_gpio;
1070 }
1071 client->irq = irqn;
1072 } else {
1073 dev_err(&client->dev, "%s: irq gpio not provided\n", __func__);
1074 goto err_en_gpio;
1075 }
1076 if (gpio_is_valid(platform_data->firm_gpio)) {
1077 r = gpio_request(platform_data->firm_gpio,
1078 "nfc_firm_gpio");
1079 if (r) {
1080 dev_err(&client->dev,
1081 "%s: unable to request nfc firmware gpio [%d]\n",
1082 __func__, platform_data->firm_gpio);
1083 goto err_irq_gpio;
1084 }
1085 r = gpio_direction_output(platform_data->firm_gpio, 0);
1086 if (r) {
1087 dev_err(&client->dev,
1088 "%s: cannot set direction for nfc firmware gpio [%d]\n",
1089 __func__, platform_data->firm_gpio);
1090 goto err_firm_gpio;
1091 }
1092 } else {
1093 dev_err(&client->dev,
1094 "%s: firm gpio not provided\n", __func__);
1095 goto err_irq_gpio;
1096 }
1097 if (gpio_is_valid(platform_data->ese_gpio)) {
1098 r = gpio_request(platform_data->ese_gpio,
1099 "nfc-ese_pwr");
1100 if (r) {
1101 nqx_dev->ese_gpio = -EINVAL;
1102 dev_err(&client->dev,
1103 "%s: unable to request nfc ese gpio [%d]\n",
1104 __func__, platform_data->ese_gpio);
1105 /* ese gpio optional so we should continue */
1106 } else {
1107 nqx_dev->ese_gpio = platform_data->ese_gpio;
1108 r = gpio_direction_output(platform_data->ese_gpio, 0);
1109 if (r) {
1110 /*
1111 * free ese gpio and set invalid
1112 * to avoid further use
1113 */
1114 gpio_free(platform_data->ese_gpio);
1115 nqx_dev->ese_gpio = -EINVAL;
1116 dev_err(&client->dev,
1117 "%s: cannot set direction for nfc ese gpio [%d]\n",
1118 __func__, platform_data->ese_gpio);
1119 /* ese gpio optional so we should continue */
1120 }
1121 }
1122 } else {
1123 nqx_dev->ese_gpio = -EINVAL;
1124 dev_err(&client->dev,
1125 "%s: ese gpio not provided\n", __func__);
1126 /* ese gpio optional so we should continue */
1127 }
1128 if (gpio_is_valid(platform_data->clkreq_gpio)) {
1129 r = gpio_request(platform_data->clkreq_gpio,
1130 "nfc_clkreq_gpio");
1131 if (r) {
1132 dev_err(&client->dev,
1133 "%s: unable to request nfc clkreq gpio [%d]\n",
1134 __func__, platform_data->clkreq_gpio);
1135 goto err_ese_gpio;
1136 }
1137 r = gpio_direction_input(platform_data->clkreq_gpio);
1138 if (r) {
1139 dev_err(&client->dev,
1140 "%s: cannot set direction for nfc clkreq gpio [%d]\n",
1141 __func__, platform_data->clkreq_gpio);
1142 goto err_clkreq_gpio;
1143 }
1144 } else {
1145 dev_err(&client->dev,
1146 "%s: clkreq gpio not provided\n", __func__);
1147 goto err_ese_gpio;
1148 }
1149
1150 nqx_dev->en_gpio = platform_data->en_gpio;
1151 nqx_dev->irq_gpio = platform_data->irq_gpio;
1152 nqx_dev->firm_gpio = platform_data->firm_gpio;
1153 nqx_dev->clkreq_gpio = platform_data->clkreq_gpio;
1154 nqx_dev->pdata = platform_data;
1155
1156 /* init mutex and queues */
1157 init_waitqueue_head(&nqx_dev->read_wq);
1158 mutex_init(&nqx_dev->read_mutex);
1159 spin_lock_init(&nqx_dev->irq_enabled_lock);
1160
1161 nqx_dev->nqx_device.minor = MISC_DYNAMIC_MINOR;
1162 nqx_dev->nqx_device.name = "nq-nci";
1163 nqx_dev->nqx_device.fops = &nfc_dev_fops;
1164
1165 r = misc_register(&nqx_dev->nqx_device);
1166 if (r) {
1167 dev_err(&client->dev, "%s: misc_register failed\n", __func__);
1168 goto err_misc_register;
1169 }
1170
1171 /* NFC_INT IRQ */
1172 nqx_dev->irq_enabled = true;
1173 r = request_irq(client->irq, nqx_dev_irq_handler,
1174 IRQF_TRIGGER_HIGH, client->name, nqx_dev);
1175 if (r) {
1176 dev_err(&client->dev, "%s: request_irq failed\n", __func__);
1177 goto err_request_irq_failed;
1178 }
1179 nqx_disable_irq(nqx_dev);
1180
1181 /*
1182 * To be efficient we need to test whether nfcc hardware is physically
1183 * present before attempting further hardware initialisation.
1184 *
1185 */
1186 r = nfcc_hw_check(client, nqx_dev);
1187 if (r) {
1188 /* make sure NFCC is not enabled */
1189 gpio_set_value(platform_data->en_gpio, 0);
1190 /* We don't think there is hardware switch NFC OFF */
1191 goto err_request_hw_check_failed;
1192 }
1193
1194 /* Register reboot notifier here */
1195 r = register_reboot_notifier(&nfcc_notifier);
1196 if (r) {
1197 dev_err(&client->dev,
1198 "%s: cannot register reboot notifier(err = %d)\n",
1199 __func__, r);
1200 /*
1201 * nfcc_hw_check function not doing memory
1202 * allocation so using same goto target here
1203 */
1204 goto err_request_hw_check_failed;
1205 }
1206
1207#ifdef NFC_KERNEL_BU
1208 r = nqx_clock_select(nqx_dev);
1209 if (r < 0) {
1210 dev_err(&client->dev,
1211 "%s: nqx_clock_select failed\n", __func__);
1212 goto err_clock_en_failed;
1213 }
1214 gpio_set_value(platform_data->en_gpio, 1);
1215#endif
1216 device_init_wakeup(&client->dev, true);
1217 device_set_wakeup_capable(&client->dev, true);
1218 i2c_set_clientdata(client, nqx_dev);
1219 nqx_dev->irq_wake_up = false;
1220
1221 dev_err(&client->dev,
1222 "%s: probing NFCC NQxxx exited successfully\n",
1223 __func__);
1224 return 0;
1225
1226#ifdef NFC_KERNEL_BU
1227err_clock_en_failed:
1228 unregister_reboot_notifier(&nfcc_notifier);
1229#endif
1230err_request_hw_check_failed:
1231 free_irq(client->irq, nqx_dev);
1232err_request_irq_failed:
1233 misc_deregister(&nqx_dev->nqx_device);
1234err_misc_register:
1235 mutex_destroy(&nqx_dev->read_mutex);
1236err_clkreq_gpio:
1237 gpio_free(platform_data->clkreq_gpio);
1238err_ese_gpio:
1239 /* optional gpio, not sure was configured in probe */
Bhuvan Varshneybf32b4a2019-03-20 13:26:27 +05301240 if (gpio_is_valid(platform_data->ese_gpio))
Gaurav Singhalc53bc292017-02-16 16:35:39 +05301241 gpio_free(platform_data->ese_gpio);
1242err_firm_gpio:
1243 gpio_free(platform_data->firm_gpio);
1244err_irq_gpio:
1245 gpio_free(platform_data->irq_gpio);
1246err_en_gpio:
1247 gpio_free(platform_data->en_gpio);
1248err_mem:
1249 kfree(nqx_dev->kbuf);
1250err_free_dev:
1251 kfree(nqx_dev);
1252err_free_data:
1253 if (client->dev.of_node)
1254 devm_kfree(&client->dev, platform_data);
1255err_platform_data:
1256 dev_err(&client->dev,
1257 "%s: probing nqxx failed, check hardware\n",
1258 __func__);
1259 return r;
1260}
1261
1262static int nqx_remove(struct i2c_client *client)
1263{
1264 int ret = 0;
1265 struct nqx_dev *nqx_dev;
1266
1267 nqx_dev = i2c_get_clientdata(client);
1268 if (!nqx_dev) {
1269 dev_err(&client->dev,
1270 "%s: device doesn't exist anymore\n", __func__);
1271 ret = -ENODEV;
1272 goto err;
1273 }
1274
1275 unregister_reboot_notifier(&nfcc_notifier);
1276 free_irq(client->irq, nqx_dev);
1277 misc_deregister(&nqx_dev->nqx_device);
1278 mutex_destroy(&nqx_dev->read_mutex);
1279 gpio_free(nqx_dev->clkreq_gpio);
1280 /* optional gpio, not sure was configured in probe */
1281 if (nqx_dev->ese_gpio > 0)
1282 gpio_free(nqx_dev->ese_gpio);
1283 gpio_free(nqx_dev->firm_gpio);
1284 gpio_free(nqx_dev->irq_gpio);
1285 gpio_free(nqx_dev->en_gpio);
1286 kfree(nqx_dev->kbuf);
1287 if (client->dev.of_node)
1288 devm_kfree(&client->dev, nqx_dev->pdata);
1289
1290 kfree(nqx_dev);
1291err:
1292 return ret;
1293}
1294
1295static int nqx_suspend(struct device *device)
1296{
1297 struct i2c_client *client = to_i2c_client(device);
1298 struct nqx_dev *nqx_dev = i2c_get_clientdata(client);
1299
1300 if (device_may_wakeup(&client->dev) && nqx_dev->irq_enabled) {
1301 if (!enable_irq_wake(client->irq))
1302 nqx_dev->irq_wake_up = true;
1303 }
1304 return 0;
1305}
1306
1307static int nqx_resume(struct device *device)
1308{
1309 struct i2c_client *client = to_i2c_client(device);
1310 struct nqx_dev *nqx_dev = i2c_get_clientdata(client);
1311
1312 if (device_may_wakeup(&client->dev) && nqx_dev->irq_wake_up) {
1313 if (!disable_irq_wake(client->irq))
1314 nqx_dev->irq_wake_up = false;
1315 }
1316 return 0;
1317}
1318
1319static const struct i2c_device_id nqx_id[] = {
1320 {"nqx-i2c", 0},
1321 {}
1322};
1323
1324static const struct dev_pm_ops nfc_pm_ops = {
1325 SET_SYSTEM_SLEEP_PM_OPS(nqx_suspend, nqx_resume)
1326};
1327
1328static struct i2c_driver nqx = {
1329 .id_table = nqx_id,
1330 .probe = nqx_probe,
1331 .remove = nqx_remove,
1332 .driver = {
1333 .owner = THIS_MODULE,
1334 .name = "nq-nci",
1335 .of_match_table = msm_match_table,
Lingutla Chandrasekhar788cb1c2016-09-12 11:10:27 +05301336 .probe_type = PROBE_PREFER_ASYNCHRONOUS,
Gaurav Singhalc53bc292017-02-16 16:35:39 +05301337 .pm = &nfc_pm_ops,
1338 },
1339};
1340
1341static int nfcc_reboot(struct notifier_block *notifier, unsigned long val,
1342 void *v)
1343{
1344 gpio_set_value(disable_ctrl, 1);
1345 return NOTIFY_OK;
1346}
1347
1348/*
1349 * module load/unload record keeping
1350 */
1351static int __init nqx_dev_init(void)
1352{
1353 return i2c_add_driver(&nqx);
1354}
1355module_init(nqx_dev_init);
1356
1357static void __exit nqx_dev_exit(void)
1358{
1359 unregister_reboot_notifier(&nfcc_notifier);
1360 i2c_del_driver(&nqx);
1361}
1362module_exit(nqx_dev_exit);
1363
1364MODULE_DESCRIPTION("NFC nqx");
1365MODULE_LICENSE("GPL v2");