summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavide Garberi <dade.garberi@gmail.com>2019-03-19 21:58:36 +0100
committerDavide Garberi <dade.garberi@gmail.com>2022-07-27 18:59:03 +0200
commitb3a8b48a0697e6399980857da113d3881b3ee322 (patch)
tree27c342427e921b326d117a3a73b8e41abc13e067
parentcccc81038a9a86fc90e2e15d536770307ed6ac6a (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.c27
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) {