diff options
| -rw-r--r-- | drivers/fingerprint/fpc1020_ree.c | 143 |
1 files changed, 39 insertions, 104 deletions
diff --git a/drivers/fingerprint/fpc1020_ree.c b/drivers/fingerprint/fpc1020_ree.c index e5e0015c44fb..8fcadaf0d8b4 100644 --- a/drivers/fingerprint/fpc1020_ree.c +++ b/drivers/fingerprint/fpc1020_ree.c @@ -35,7 +35,7 @@ #define FPC1020_RESET_LOW_US 1000 #define FPC1020_RESET_HIGH1_US 100 #define FPC1020_RESET_HIGH2_US 1250 -#define FPC_TTW_HOLD_TIME 1000 +#define FPC_TTW_HOLD_TIME 1500 struct fpc1020_data { struct device *dev; @@ -48,12 +48,10 @@ struct fpc1020_data { struct notifier_block fb_notif; /*Input device*/ struct input_dev *input_dev; + struct work_struct pm_work; struct work_struct input_report_work; struct workqueue_struct *fpc1020_wq; u8 report_key; - struct wake_lock wake_lock; - struct wake_lock fp_wl; - int wakeup_status; int screen_on; }; @@ -96,68 +94,6 @@ static ssize_t irq_set(struct device *device, static DEVICE_ATTR(irq, S_IRUSR | S_IWUSR, irq_get, irq_set); -static ssize_t fp_wl_get(struct device *device, - struct device_attribute *attribute, - char *buffer) -{ - /* struct fpc1020_data* fpc1020 = dev_get_drvdata(device); */ - return 0; -} - -static ssize_t fp_wl_set(struct device *device, - struct device_attribute *attribute, - const char *buffer, size_t count) -{ - int retval = 0; - u64 val; - struct fpc1020_data *fpc1020 = dev_get_drvdata(device); - - retval = kstrtou64(buffer, 0, &val); - if (val == 1 && !wake_lock_active(&fpc1020->fp_wl)) - wake_lock(&fpc1020->fp_wl); - else if (val == 0 && wake_lock_active(&fpc1020->fp_wl)) - wake_unlock(&fpc1020->fp_wl); - else - pr_err("HAL wakelock request fail, val = %d\n", (int)val); - return strnlen(buffer, count); -} - -static DEVICE_ATTR(wl, S_IRUSR | S_IWUSR, fp_wl_get, fp_wl_set); - -static ssize_t get_wakeup_status(struct device *device, - struct device_attribute *attribute, - char *buffer) -{ - struct fpc1020_data *fpc1020 = dev_get_drvdata(device); - - return scnprintf(buffer, PAGE_SIZE, "%i\n", fpc1020->wakeup_status); -} - -static ssize_t set_wakeup_status(struct device *device, - struct device_attribute *attribute, - const char *buffer, size_t count) -{ - int retval = 0; - u64 val; - struct fpc1020_data *fpc1020 = dev_get_drvdata(device); - - retval = kstrtou64(buffer, 0, &val); - pr_info("val === %d\n", (int)val); - if (val == 1) { - enable_irq_wake(fpc1020->irq); - fpc1020->wakeup_status = 1; - } else if (val == 0) { - disable_irq_wake(fpc1020->irq); - fpc1020->wakeup_status = 0; - } else - return -ENOENT; - - return strnlen(buffer, count); -} - -static DEVICE_ATTR(wakeup, S_IRUSR | S_IWUSR, - get_wakeup_status, set_wakeup_status); - static ssize_t get_key(struct device *device, struct device_attribute *attribute, char *buffer) { @@ -201,27 +137,9 @@ static ssize_t set_key(struct device *device, static DEVICE_ATTR(key, S_IRUSR | S_IWUSR, get_key, set_key); -static ssize_t get_screen_stat(struct device* device, struct device_attribute* attribute, char* buffer) -{ - struct fpc1020_data* fpc1020 = dev_get_drvdata(device); - return scnprintf(buffer, PAGE_SIZE, "%i\n", fpc1020->screen_on); -} - -static ssize_t set_screen_stat(struct device* device, - struct device_attribute* attribute, - const char*buffer, size_t count) -{ - return 1; -} - -static DEVICE_ATTR(screen, S_IRUSR | S_IWUSR, get_screen_stat, set_screen_stat); - static struct attribute *attributes[] = { &dev_attr_irq.attr, - &dev_attr_wakeup.attr, &dev_attr_key.attr, - &dev_attr_wl.attr, - &dev_attr_screen.attr, NULL }; @@ -295,7 +213,9 @@ static irqreturn_t fpc1020_irq_handler(int irq, void *_fpc1020) pr_info("fpc1020 IRQ interrupt\n"); smp_rmb(); - wake_lock_timeout(&fpc1020->wake_lock, 300); + if (fpc1020->screen_on == 0) { + pm_wakeup_event(fpc1020->dev, 5000); + } sysfs_notify(&fpc1020->dev->kobj, NULL, dev_attr_irq.attr.name); return IRQ_HANDLED; } @@ -384,6 +304,33 @@ static int fpc1020_alloc_input_dev(struct fpc1020_data *fpc1020) return retval; } +static void set_fingerprintd_nice(int nice) +{ + struct task_struct *p; + + read_lock(&tasklist_lock); + for_each_process(p) { + if (!memcmp(p->comm, "fingerprint@2.1", 16)) { + pr_debug("fingerprint nice changed to %i\n", nice); + set_user_nice(p, nice); + break; + } + } + read_unlock(&tasklist_lock); +} + +static void fpc1020_suspend_resume(struct work_struct *work) +{ + struct fpc1020_data *fpc1020 = + container_of(work, typeof(*fpc1020), pm_work); + + /* Escalate fingerprintd priority when screen is off */ + if (!fpc1020->screen_on) + set_fingerprintd_nice(MIN_NICE); + else + set_fingerprintd_nice(0); +} + static int fb_notifier_callback(struct notifier_block *self, unsigned long event, void *data) { @@ -397,9 +344,11 @@ static int fb_notifier_callback(struct notifier_block *self, if (*blank == FB_BLANK_UNBLANK) { pr_err("ScreenOn\n"); fpc1020->screen_on = 1; + queue_work(fpc1020->fpc1020_wq, &fpc1020->pm_work); } else if (*blank == FB_BLANK_POWERDOWN) { pr_err("ScreenOff\n"); fpc1020->screen_on = 0; + queue_work(fpc1020->fpc1020_wq, &fpc1020->pm_work); } } return 0; @@ -441,13 +390,13 @@ static int fpc1020_probe(struct platform_device *pdev) goto error_remove_sysfs; } - fpc1020->fpc1020_wq = create_workqueue("fpc1020_wq"); + fpc1020->fpc1020_wq = alloc_workqueue("fpc1020_wq", WQ_HIGHPRI, 1); if (!fpc1020->fpc1020_wq) { pr_err("Create input workqueue failed\n"); goto error_unregister_device; } INIT_WORK(&fpc1020->input_report_work, fpc1020_report_work_func); - + INIT_WORK(&fpc1020->pm_work, fpc1020_suspend_resume); gpio_direction_output(fpc1020->reset_gpio, 1); /*Do HW reset*/ fpc1020_hw_reset(fpc1020); @@ -459,8 +408,7 @@ static int fpc1020_probe(struct platform_device *pdev) goto error_destroy_workqueue; } - wake_lock_init(&fpc1020->wake_lock, WAKE_LOCK_SUSPEND, "fpc_wakelock"); - wake_lock_init(&fpc1020->fp_wl, WAKE_LOCK_SUSPEND, "fp_hal_wl"); + device_init_wakeup(dev, true); retval = fpc1020_initial_irq(fpc1020); if (retval != 0) { @@ -470,7 +418,8 @@ static int fpc1020_probe(struct platform_device *pdev) /* Disable IRQ */ disable_irq(fpc1020->irq); - + /* Enable irq wake */ + enable_irq_wake(fpc1020->irq); return 0; error_unregister_client: @@ -492,18 +441,6 @@ error: return retval; } -static int fpc1020_resume(struct platform_device *pdev) -{ - int retval = 0; - return retval; -} - -static int fpc1020_suspend(struct platform_device *pdev, pm_message_t state) -{ - int retval = 0; - return retval; -} - static int fpc1020_remove(struct platform_device *pdev) { int retval = 0; @@ -520,8 +457,6 @@ static struct of_device_id fpc1020_match[] = { static struct platform_driver fpc1020_plat_driver = { .probe = fpc1020_probe, .remove = fpc1020_remove, - .suspend = fpc1020_suspend, - .resume = fpc1020_resume, .driver = { .name = "fpc1020", .owner = THIS_MODULE, |
