blob: d5c059b7603f3c24eb43ba00a36624ce5b0fc060 [file] [log] [blame]
Tirupathi Reddye5b54272017-09-25 12:21:03 +05301/* Copyright (c) 2017 The Linux Foundation. All rights reserved.
2 *
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#define pr_fmt(fmt) "%s: " fmt, __func__
14
15#include <linux/alarmtimer.h>
16#include <linux/debugfs.h>
17#include <linux/device.h>
18#include <linux/errno.h>
19#include <linux/i2c.h>
20#include <linux/module.h>
21#include <linux/mutex.h>
22#include <linux/of.h>
23#include <linux/of_gpio.h>
24#include <linux/platform_device.h>
25#include <linux/pm_wakeup.h>
26#include <linux/power_supply.h>
27#include <linux/regmap.h>
28#include <linux/rtc.h>
29
30#define NX30P6093_ID_REG 0x0
31#define NX30P6093_VENDOR_ID_MASK GENMASK(7, 3)
32#define NX30P6093_VENDOR_ID_SHIFT 3
33#define NX30P6093_VERSION_ID_MASK GENMASK(2, 0)
34
35#define NX30P6093_ENABLE_REG 0x01
36#define NX30P6093_DETECT_EN BIT(6)
37
38#define NX30P6093_STATUS_REG 0x02
39#define NX30P6093_PWRON_STS BIT(7)
40#define NX30P6093_IMPEDANCE_MASK GENMASK(6, 5)
41#define NX30P6093_IMPEDANCE_SHIFT 5
42#define NX30P6093_IMPEDANCE_GOOD_VAL 1
43#define NX30P6093_IMPEDANCE_BAD_VAL 3
44
45#define NX30P6093_INTR_MASK_REG 0x04
46#define NX30P6093_OVER_TAG_STS_INTR_MASK BIT(6)
47#define NX30P6093_TMR_OUT_STS_INTR_MASK BIT(5)
48
49#define NX30P6093_VIN_ISOURCE_REG 0x06
50#define NX30P6093_VIN_ISOURCE_MASK GENMASK(3, 0)
51
52#define NX30P6093_ISOURCE_TIMING_REG 0x07
53#define NX30P6093_ISOURCE_TDET_MASK GENMASK(7, 4)
54#define NX30P6093_ISOURCE_TDET_SHIFT 4
55#define NX30P6093_ISOURCE_TDUTY_MASK GENMASK(3, 0)
56
57#define NX30P6093_VIN_VOLTAGE_TAG_REG 0x09
58#define NX30P6093_VIN_VOLTAGE_TAG_MASK GENMASK(7, 0)
59
60#define NX30P6093_SLEW_RATE_TUNE_REG 0x0f
61
62/* short duration is 5sec and long duration is 5hrs */
63#define NX30P6093_LONG_WAKEUP_SEC 18000
64#define NX30P6093_SHORT_WAKEUP_MS 5000
65
66/* Default Tduty = 5mins when always-on detection is configured */
67#define NX30P6093_ISOURCE_ALWAYS_ON_TDUTY_MS 300000
68
69/* configuration data */
70#define NX30P6093_VIN_ISOURCE_VAL 0xd
71#define NX30P6093_VIN_VOLTAGE_TAG_VAL 0xad
72#define NX30P6093_ISOURCE_TDET_VAL 0x5
73#define NX30P6093_ISOURCE_TDUTY_VAL 0x0
74#define NX30P6093_ISOURCE_TDET_MS 10
75
76struct nx30p6093_info {
77 struct device *dev;
78 struct regmap *regmap;
79 struct power_supply *usb_psy;
80 struct alarm alarm_timer;
81 struct delayed_work config_impedance_detect;
82 struct mutex lock;
83 struct dentry *debugfs;
84 u8 tduty_val;
85 int irq;
86
87 /* status data */
88 bool irq_waiting;
89 bool high_impedance;
90 bool detection_on;
91 bool always_on;
92 bool use_alarm;
93 bool suspended;
94
95 /* timer configuration */
96 u64 long_wakeup_ms;
97 u64 short_wakeup_ms;
98};
99
100static const int nx30p6093_tduty_ms[] = {0, 10, 20, 50, 100, 200, 500, 1000,
101 2000, 3000, 6000, 12000, 30000, 60000,
102 120000, 300000};
103
104static const struct regmap_config nx30p6093_regmap_config = {
105 .reg_bits = 8,
106 .val_bits = 8,
107 .max_register = NX30P6093_SLEW_RATE_TUNE_REG,
108};
109
110static int nx30p6093_dump_regs(struct nx30p6093_info *info)
111{
112 unsigned int val;
113 int i, rc = 0;
114
115 for (i = 0; i <= NX30P6093_SLEW_RATE_TUNE_REG; ++i) {
116 rc = regmap_read(info->regmap, i, &val);
117 if (rc < 0)
118 return rc;
119 pr_debug("NX30P6093(0x%02x) = 0x%02x\n", i, (uint8_t)val);
120 }
121
122 return rc;
123}
124
125static inline void nx30p6093_config_alarm(struct nx30p6093_info *info,
126 u64 wakeup_ms)
127{
128 if (!info->use_alarm)
129 return;
130
131 alarm_start_relative(&info->alarm_timer, ms_to_ktime(wakeup_ms));
132}
133
134static int nx30p6093_impedance_detect(struct nx30p6093_info *info, bool enable)
135{
136 int rc = 0;
137
138 if (enable == info->detection_on)
139 return rc;
140
141 rc = regmap_update_bits(info->regmap, NX30P6093_ENABLE_REG,
142 NX30P6093_DETECT_EN,
143 enable ? NX30P6093_DETECT_EN : 0);
144 if (rc < 0) {
145 pr_err("failed to %s VIN impedance detection, rc=%d\n",
146 enable ? "enable" : "disable", rc);
147 return rc;
148 }
149
150 /* wait for 3ms for HW activation and enters detection standby mode */
151 usleep_range(3000, 3100);
152
153 /* config Isource to VIN */
154 rc = regmap_update_bits(info->regmap, NX30P6093_VIN_ISOURCE_REG,
155 NX30P6093_VIN_ISOURCE_MASK,
156 enable ? NX30P6093_VIN_ISOURCE_VAL : 0);
157 if (rc < 0) {
158 pr_err("failed to configure Vin Isource register, rc=%d\n", rc);
159 return rc;
160 }
161
162 info->detection_on = enable;
163 nx30p6093_dump_regs(info);
164
165 return rc;
166}
167
168static int nx30p6093_read_impedance_status(struct nx30p6093_info *info)
169{
170 union power_supply_propval psp_val;
171 unsigned int val;
172 u8 impedance;
173 int rc;
174
175 /* Read status register */
176 rc = regmap_read(info->regmap, NX30P6093_STATUS_REG, &val);
177 if (rc < 0) {
178 pr_err("failed to read status register, rc=%d\n", rc);
179 return rc;
180 }
181
182 if (val & NX30P6093_PWRON_STS) {
183 /* VBUS present */
184 return rc;
185 }
186
187 impedance = (val & NX30P6093_IMPEDANCE_MASK)
188 >> NX30P6093_IMPEDANCE_SHIFT;
189 if (impedance == NX30P6093_IMPEDANCE_GOOD_VAL && info->high_impedance) {
190 info->high_impedance = false;
191
192 /* enable the type-C CC detection */
193 psp_val.intval = 0;
194 rc = power_supply_set_property(info->usb_psy,
195 POWER_SUPPLY_PROP_MOISTURE_DETECTED,
196 &psp_val);
197 } else if (impedance == NX30P6093_IMPEDANCE_BAD_VAL) {
198 info->high_impedance = true;
199
200 /* disable the type-C CC detection */
201 psp_val.intval = 1;
202 rc = power_supply_set_property(info->usb_psy,
203 POWER_SUPPLY_PROP_MOISTURE_DETECTED,
204 &psp_val);
205 }
206
207 return rc;
208}
209
210static irqreturn_t nx30p6093_irq_handler(int irq, void *data)
211{
212 struct nx30p6093_info *info = data;
213
214 mutex_lock(&info->lock);
215
216 info->irq_waiting = true;
217 if (info->suspended) {
218 pr_debug("IRQ triggered before device-resume\n");
219 disable_irq_nosync(irq);
220 mutex_unlock(&info->lock);
221 return IRQ_HANDLED;
222 }
223 info->irq_waiting = false;
224 mutex_unlock(&info->lock);
225
226 nx30p6093_read_impedance_status(info);
227
228 if (info->high_impedance) {
229 disable_irq_nosync(irq);
230 /* set up next detection event */
231 nx30p6093_config_alarm(info,
232 NX30P6093_ISOURCE_ALWAYS_ON_TDUTY_MS);
233 }
234
235 return IRQ_HANDLED;
236}
237
238static int nx30p6093_trigger_impedance_detect(struct nx30p6093_info *info)
239{
240 int rc;
241
242 if (!info->always_on) {
243 rc = nx30p6093_impedance_detect(info, true);
244 if (rc < 0) {
245 pr_err("start impedance detection failed, rc=%d\n", rc);
246 return rc;
247 }
248
249 /* wait for the detection complete(Tdet time). */
250 usleep_range(NX30P6093_ISOURCE_TDET_MS * USEC_PER_MSEC,
251 NX30P6093_ISOURCE_TDET_MS * USEC_PER_MSEC + 100);
252 }
253
254 /* Read and process the detection result. */
255 rc = nx30p6093_read_impedance_status(info);
256 if (rc < 0)
257 pr_err("impedance status read failed, rc=%d\n", rc);
258
259 if (!info->always_on) {
260 rc = nx30p6093_impedance_detect(info, false);
261 if (rc < 0)
262 pr_err("stop impedance detection failed, rc=%d\n", rc);
263 }
264
265 return rc;
266}
267
268static void nx30p6093_config_impedance_detect(struct work_struct *work)
269{
270 struct nx30p6093_info *info = container_of(work, struct nx30p6093_info,
271 config_impedance_detect.work);
272 u64 wakeup_ms = 0;
273
274 mutex_lock(&info->lock);
275 if (info->suspended) {
276 /*
277 * Defer the work as the device is still in suspend state and
278 * not yet resumed.
279 */
280 schedule_delayed_work(&info->config_impedance_detect,
281 msecs_to_jiffies(500));
282 mutex_unlock(&info->lock);
283 return;
284 }
285
286 nx30p6093_trigger_impedance_detect(info);
287
288 if (info->always_on) {
289 if (info->high_impedance) {
290 /*
291 * Bad impedance is not cleared yet.
292 * Set up a next detection event.
293 */
294 nx30p6093_config_alarm(info,
295 NX30P6093_ISOURCE_ALWAYS_ON_TDUTY_MS);
296 } else {
297 /* Bad impedance is cleared. Enable detection IRQ */
298 enable_irq(info->irq);
299 }
300 } else {
301 wakeup_ms = info->high_impedance ? info->short_wakeup_ms
302 : info->long_wakeup_ms;
303
304 /* Set up a next detection event */
305 nx30p6093_config_alarm(info, wakeup_ms);
306 }
307
308 mutex_unlock(&info->lock);
309 pm_relax(info->dev);
310}
311
312static enum alarmtimer_restart
313 nx30p6093_process_alarm_event(struct alarm *alarm, ktime_t now)
314{
315 struct nx30p6093_info *info = container_of(alarm, struct nx30p6093_info,
316 alarm_timer);
317 union power_supply_propval val;
318 int rc;
319
320 /* Read USB plugged-in */
321 rc = power_supply_get_property(info->usb_psy, POWER_SUPPLY_PROP_PRESENT,
322 &val);
323 if (rc < 0) {
324 pr_err("read usb present failed, rc=%d\n", rc);
325 return ALARMTIMER_RESTART;
326 }
327
328 if (val.intval) {
329 /*
330 * usb present - skip impedance detection and set up
331 * next detection event.
332 */
333 nx30p6093_config_alarm(info, info->long_wakeup_ms);
334 } else {
335 pm_stay_awake(info->dev);
336 schedule_delayed_work(&info->config_impedance_detect, 0);
337 }
338
339 return ALARMTIMER_NORESTART;
340}
341
342static int nx30p6093_init_config(struct nx30p6093_info *info)
343{
344 int rc;
345 u8 val;
346
347 /* Enable OVER_TAG_STATUS interrupt if always-on detection enabled */
348 rc = regmap_write(info->regmap, NX30P6093_INTR_MASK_REG,
349 info->always_on ? NX30P6093_OVER_TAG_STS_INTR_MASK
350 : 0);
351 if (rc < 0) {
352 pr_err("failed to enable timer out status interrupt, rc=%d\n",
353 rc);
354 return rc;
355 }
356
357 /* config Isource timing (Default: 10ms) */
358 val = NX30P6093_ISOURCE_TDET_VAL << NX30P6093_ISOURCE_TDET_SHIFT;
359 rc = regmap_update_bits(info->regmap, NX30P6093_ISOURCE_TIMING_REG,
360 NX30P6093_ISOURCE_TDET_MASK, val);
361 if (rc < 0) {
362 pr_err("failed to configure Isource timing, rc=%d\n", rc);
363 return rc;
364 }
365
366 /*
367 * config Isource Tduty timing;
368 * Default value:
369 * 1) One shot - if Periodic detection enabled
370 * 2) 5 mins - if Always-on detection enabled
371 */
372 rc = regmap_update_bits(info->regmap, NX30P6093_ISOURCE_TIMING_REG,
373 NX30P6093_ISOURCE_TDUTY_MASK,
374 info->always_on ? info->tduty_val
375 : NX30P6093_ISOURCE_TDUTY_VAL);
376 if (rc < 0) {
377 pr_err("failed to configure Isource Tduty timing, rc=%d\n", rc);
378 return rc;
379 }
380
381 /* config VIN voltage tag (Default: 0xad) */
382 rc = regmap_update_bits(info->regmap, NX30P6093_VIN_VOLTAGE_TAG_REG,
383 NX30P6093_VIN_VOLTAGE_TAG_MASK,
384 NX30P6093_VIN_VOLTAGE_TAG_VAL);
385 if (rc < 0) {
386 pr_err("failed to configure Vin voltage tag register, rc=%d\n",
387 rc);
388 return rc;
389 }
390
391 return 0;
392}
393
394static int nx30p6093_dt_init(struct i2c_client *client,
395 struct nx30p6093_info *info)
396{
397 struct device_node *of_node = client->dev.of_node;
398 int i, tduty_ms;
399 u32 long_wakeup_sec, short_wakeup_ms;
400
401 if (of_property_read_bool(of_node, "nxp,always-on-detect")) {
402 info->always_on = true;
403 tduty_ms = NX30P6093_ISOURCE_ALWAYS_ON_TDUTY_MS;
404 of_property_read_u32(of_node, "nxp,always-on-tduty-ms",
405 &tduty_ms);
406 for (i = 0; i < ARRAY_SIZE(nx30p6093_tduty_ms); i++) {
407 if (tduty_ms <= nx30p6093_tduty_ms[i]) {
408 info->tduty_val = (uint8_t)i;
409 break;
410 }
411 }
412
413 if (!info->tduty_val) {
414 pr_err("invalid nxp,always-on-tduty-ms = %d\n",
415 tduty_ms);
416 return -EINVAL;
417 }
418 } else {
419 long_wakeup_sec = NX30P6093_LONG_WAKEUP_SEC;
420 short_wakeup_ms = NX30P6093_SHORT_WAKEUP_MS;
421
422 of_property_read_u32(of_node, "nxp,long-wakeup-sec",
423 &long_wakeup_sec);
424 of_property_read_u32(of_node, "nxp,short-wakeup-ms",
425 &short_wakeup_ms);
426 if (!long_wakeup_sec || !short_wakeup_ms) {
427 pr_err("Invalid wakeup timings are configured\n");
428 return -EINVAL;
429 }
430
431 info->long_wakeup_ms = long_wakeup_sec * MSEC_PER_SEC;
432 info->short_wakeup_ms = short_wakeup_ms;
433 }
434
435 return 0;
436}
437
438static int nx30p6093_trigger_detect(struct seq_file *file, void *data)
439{
440 struct nx30p6093_info *info = file->private;
441
442 if (info->always_on)
443 return 0;
444
445 mutex_lock(&info->lock);
446 nx30p6093_trigger_impedance_detect(info);
447 seq_printf(file, "%s impedance detected\n",
448 info->high_impedance ? "BAD" : "GOOD");
449 mutex_unlock(&info->lock);
450
451 return 0;
452}
453
454static int nx30p6093_trigger_detect_open(struct inode *inode, struct file *file)
455{
456 return single_open(file, nx30p6093_trigger_detect, inode->i_private);
457}
458
459static const struct file_operations nx30p6093_trigger_detect_fops = {
460 .owner = THIS_MODULE,
461 .open = nx30p6093_trigger_detect_open,
462 .read = seq_read,
463 .llseek = seq_lseek,
464 .release = single_release,
465};
466
467static void nx30p6093_debugfs_init(struct nx30p6093_info *info)
468{
469 struct dentry *temp;
470
471 /* debugfs */
472 info->debugfs = debugfs_create_dir("nx30p6093", NULL);
473 if (!info->debugfs) {
474 pr_err("Couldn't create debug dir\n");
475 return;
476 }
477
478 temp = debugfs_create_file("trigger_detection", 0644, info->debugfs,
479 info, &nx30p6093_trigger_detect_fops);
480 if (IS_ERR_OR_NULL(temp)) {
481 pr_err("debugfs_nx30p6093_reg_addr_fops debugfs file creation failed\n");
482 debugfs_remove_recursive(info->debugfs);
483 }
484}
485
486#if CONFIG_PM
487static int nx30p6093_suspend(struct device *dev)
488{
489 struct i2c_client *client = to_i2c_client(dev);
490 struct nx30p6093_info *info = i2c_get_clientdata(client);
491
492 cancel_delayed_work_sync(&info->config_impedance_detect);
493
494 mutex_lock(&info->lock);
495 info->suspended = true;
496 mutex_unlock(&info->lock);
497
498 return 0;
499}
500
501static int nx30p6093_suspend_noirq(struct device *dev)
502{
503 struct i2c_client *client = to_i2c_client(dev);
504 struct nx30p6093_info *info = i2c_get_clientdata(client);
505
506 if (info->irq_waiting) {
507 pr_err_ratelimited("Aborting suspend, an interrupt was detected while suspending\n");
508 return -EBUSY;
509 }
510 return 0;
511}
512
513static int nx30p6093_resume(struct device *dev)
514{
515 struct i2c_client *client = to_i2c_client(dev);
516 struct nx30p6093_info *info = i2c_get_clientdata(client);
517
518 mutex_lock(&info->lock);
519 info->suspended = false;
520 if (info->irq_waiting) {
521 mutex_unlock(&info->lock);
522 nx30p6093_irq_handler(client->irq, info);
523 enable_irq(client->irq);
524 } else {
525 mutex_unlock(&info->lock);
526 }
527
528 return 0;
529}
530#else
531static int nx30p6093_suspend(struct device *dev)
532{
533 return 0;
534}
535
536static int nx30p6093_resume(struct device *dev)
537{
538 return 0;
539}
540#endif
541
542static const struct dev_pm_ops nx30p6093_pm_ops = {
543 .suspend = nx30p6093_suspend,
544 .suspend_noirq = nx30p6093_suspend_noirq,
545 .resume = nx30p6093_resume,
546};
547
548static int nx30p6093_probe(struct i2c_client *client,
549 const struct i2c_device_id *id)
550{
551 struct nx30p6093_info *info;
552 unsigned int val;
553 int vendor_id, version_id, rc = 0;
554
555 info = devm_kzalloc(&client->dev, sizeof(*info), GFP_KERNEL);
556 if (!info)
557 return -ENOMEM;
558
559 info->dev = &client->dev;
560 info->regmap = devm_regmap_init_i2c(client, &nx30p6093_regmap_config);
561 if (IS_ERR(info->regmap)) {
562 pr_err("Error in allocating regmap, rc=%ld\n",
563 PTR_ERR(info->regmap));
564 return PTR_ERR(info->regmap);
565 }
566
567 rc = regmap_read(info->regmap, NX30P6093_ID_REG, &val);
568 if (rc < 0) {
569 pr_err("Unable to identify NX30P6093, rc=%d\n", rc);
570 return rc;
571 }
572 vendor_id = (val & NX30P6093_VENDOR_ID_MASK)
573 >> NX30P6093_VENDOR_ID_SHIFT;
574 version_id = val & NX30P6093_VERSION_ID_MASK;
575
576 info->usb_psy = power_supply_get_by_name("usb");
577 if (!info->usb_psy) {
578 pr_err("USB psy not found\n");
579 return -EPROBE_DEFER;
580 }
581
582 i2c_set_clientdata(client, info);
583 mutex_init(&info->lock);
584 INIT_DELAYED_WORK(&info->config_impedance_detect,
585 nx30p6093_config_impedance_detect);
586
587 rc = nx30p6093_dt_init(client, info);
588 if (rc < 0) {
589 pr_err("device tree parsing failed, rc=%d\n", rc);
590 return rc;
591 }
592
593 rc = nx30p6093_init_config(info);
594 if (rc < 0) {
595 pr_err("initial configuration programming failed, rc=%d\n", rc);
596 return rc;
597 }
598
599 if (alarmtimer_get_rtcdev()) {
600 /* Initialize alarm timer */
601 info->use_alarm = true;
602 alarm_init(&info->alarm_timer, ALARM_BOOTTIME,
603 nx30p6093_process_alarm_event);
604 } else {
605 pr_err("alarm initialization failed\n");
606 return -ENODEV;
607 }
608
609 if (info->always_on) {
610 /* Moisture detect irq configuration */
611 if (client->irq) {
612 info->irq = client->irq;
613 rc = devm_request_threaded_irq(&client->dev,
614 client->irq, NULL,
615 nx30p6093_irq_handler,
616 IRQF_ONESHOT | IRQF_TRIGGER_FALLING,
617 client->name, info);
618 if (rc < 0) {
619 pr_err("Failed Moisture detect irq(%d) request, rc=%d\n",
620 client->irq, rc);
621 return rc;
622 }
623 enable_irq_wake(client->irq);
624 } else {
625 pr_err("Moisture detect irq not defined\n");
626 return -EINVAL;
627 }
628
629 nx30p6093_impedance_detect(info, true);
630 } else {
631 /* Run impedance detection for first time */
632 pm_stay_awake(info->dev);
633 schedule_delayed_work(&info->config_impedance_detect, 0);
634 }
635
636 nx30p6093_debugfs_init(info);
637
638 if (info->always_on)
639 pr_info("NXP NX30P6093 Vendor(%d), Version(%d), configured to Always-on detection\n",
640 vendor_id, version_id);
641 else
642 pr_info("NXP NX30P6093 Vendor(%d), Version(%d), configured to periodic detection with Short_wakeup = %llu ms and Long_wakeup = %llu sec\n",
643 vendor_id, version_id, info->short_wakeup_ms,
644 info->long_wakeup_ms / MSEC_PER_SEC);
645
646 return 0;
647}
648
649static int nx30p6093_remove(struct i2c_client *client)
650{
651 struct nx30p6093_info *info = i2c_get_clientdata(client);
652
653 debugfs_remove_recursive(info->debugfs);
654 cancel_delayed_work_sync(&info->config_impedance_detect);
655
656 if (info->use_alarm)
657 alarm_cancel(&info->alarm_timer);
658
659 return 0;
660}
661
662static const struct of_device_id nx30p6093_table[] = {
663 { .compatible = "nxp,nx30p6093" },
664 { },
665};
666MODULE_DEVICE_TABLE(of, nx30p6093_table);
667
668static const struct i2c_device_id nx30p6093_id[] = {
669 {"nx30p6093", -1},
670 { },
671};
672MODULE_DEVICE_TABLE(i2c, nx30p6093_id);
673
674static struct i2c_driver nx30p6093_driver = {
675 .driver = {
676 .name = "nxp,nx30p6093",
677 .owner = THIS_MODULE,
678 .of_match_table = nx30p6093_table,
679 .pm = &nx30p6093_pm_ops,
680 },
681 .probe = nx30p6093_probe,
682 .remove = nx30p6093_remove,
683 .id_table = nx30p6093_id,
684};
685module_i2c_driver(nx30p6093_driver);
686
687MODULE_DESCRIPTION("NX30P6093 driver");
688MODULE_LICENSE("GPL v2");