summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/fingerprint/fpc1020_ree.c143
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,