diff options
| author | Davide Garberi <dade.garberi@gmail.com> | 2019-03-19 21:58:36 +0100 |
|---|---|---|
| committer | Davide Garberi <dade.garberi@gmail.com> | 2022-07-27 18:59:03 +0200 |
| commit | b3a8b48a0697e6399980857da113d3881b3ee322 (patch) | |
| tree | 27c342427e921b326d117a3a73b8e41abc13e067 | |
| parent | cccc81038a9a86fc90e2e15d536770307ed6ac6a (diff) | |
fpc1020: Add wakeup option
* Import from Xiaomi msm8996 driver
* Remove the sysfs node and the dts entry as we don't need it
| -rw-r--r-- | drivers/fingerprint/fpc1020_ree.c | 27 |
1 files changed, 23 insertions, 4 deletions
diff --git a/drivers/fingerprint/fpc1020_ree.c b/drivers/fingerprint/fpc1020_ree.c index 8f7afe9eb379..8d363fc65599 100644 --- a/drivers/fingerprint/fpc1020_ree.c +++ b/drivers/fingerprint/fpc1020_ree.c @@ -46,6 +46,7 @@ struct fpc1020_data { int irq_gpio; int irq; bool irq_enabled; + int wakeup_enabled; struct notifier_block fb_notif; /*Input device*/ struct input_dev *input_dev; @@ -169,8 +170,9 @@ static ssize_t proximity_state_set(struct device *dev, if (fpc1020->proximity_state == 1) { /* Disable IRQ when screen is off and proximity sensor is covered */ config_irq(fpc1020, false); - } else if (fpc1020->proximity_state == 0) { - /* Enable IRQ when screen is off and proximity sensor is uncovered */ + } else if (fpc1020->wakeup_enabled) { + /* Enable IRQ when screen is off and proximity sensor is uncovered, + but only if fingerprint wake up is enabled */ config_irq(fpc1020, true); } } @@ -254,8 +256,10 @@ static irqreturn_t fpc1020_irq_handler(int irq, void *_fpc1020) struct fpc1020_data *fpc1020 = _fpc1020; pr_info("fpc1020 IRQ interrupt\n"); + /* Make sure 'wakeup_enabled' is updated before using it + ** since this is interrupt context (other thread...) */ smp_rmb(); - if (fpc1020->screen_on == 0) { + if (fpc1020->wakeup_enabled && !fpc1020->screen_on) { pm_wakeup_event(fpc1020->dev, 5000); } sysfs_notify(&fpc1020->dev->kobj, NULL, dev_attr_irq.attr.name); @@ -289,16 +293,27 @@ static int fpc1020_initial_irq(struct fpc1020_data *fpc1020) return -EINVAL; } + device_init_wakeup(fpc1020->dev, 1); + fpc1020->wakeup_enabled = 1; + retval = devm_request_threaded_irq(fpc1020->dev, fpc1020->irq, NULL, fpc1020_irq_handler, - IRQF_TRIGGER_RISING | IRQF_ONESHOT, + IRQF_TRIGGER_RISING | IRQF_ONESHOT | IRQF_NO_SUSPEND, dev_name(fpc1020->dev), fpc1020); + if (retval) { pr_err("request irq %i failed.\n", fpc1020->irq); fpc1020->irq = -EINVAL; return -EINVAL; } + dev_info(fpc1020->dev, "requested irq %d\n", fpc1020->irq); + /* Request that the interrupt should be wakeable*/ + if (fpc1020->wakeup_enabled) { + enable_irq_wake(fpc1020->irq); + } + fpc1020->irq_enabled = true; + return 0; } @@ -392,6 +407,8 @@ static int fb_notifier_callback(struct notifier_block *self, } else if (*blank == FB_BLANK_POWERDOWN) { pr_err("ScreenOff\n"); fpc1020->screen_on = 0; + if (!fpc1020->wakeup_enabled) + config_irq(fpc1020, false); queue_work(fpc1020->fpc1020_wq, &fpc1020->pm_work); } } @@ -420,6 +437,8 @@ static int fpc1020_probe(struct platform_device *pdev) goto error; } + fpc1020->wakeup_enabled = 0; + /*create sfs nodes*/ retval = fpc1020_manage_sysfs(fpc1020); if (retval != 0) { |
