input: keyboard: rk_keys: add rk_keys.h
[firefly-linux-kernel-4.4.55.git] / drivers / input / keyboard / rk_keys.c
old mode 100755 (executable)
new mode 100644 (file)
index 3df60b4..fed5ced
@@ -23,6 +23,7 @@
 #include <linux/input.h>
 #include <linux/adc.h>
 #include <linux/slab.h>
+#include <linux/wakelock.h>
 
 #include <linux/iio/iio.h>
 #include <linux/iio/machine.h>
 #include <linux/of_irq.h>
 #include <linux/of_gpio.h>
 #include <linux/of_platform.h>
+#include <linux/rk_keys.h>
 
-#define EMPTY_ADVALUE                  950
-#define DRIFT_ADVALUE                  70
+#define EMPTY_DEFAULT_ADVALUE          1024
+#define DRIFT_DEFAULT_ADVALUE          70
 #define INVALID_ADVALUE                        -1
-#define EV_ENCALL                       KEY_F4
-#define EV_MENU                         KEY_F1
+#define EV_ENCALL                      KEY_F4
+#define EV_MENU                                KEY_F1
 
 #if 0
 #define key_dbg(bdata, format, arg...)         \
@@ -48,8 +50,9 @@
 #define key_dbg(bdata, format, arg...)
 #endif
 
-#define DEFAULT_DEBOUNCE_INTERVAL      10  /* 10ms */
-#define ADC_SAMPLE_TIME                        100
+#define DEBOUNCE_JIFFIES       (10 / (MSEC_PER_SEC / HZ))      /* 10ms */
+#define ADC_SAMPLE_JIFFIES     (100 / (MSEC_PER_SEC / HZ))     /* 100ms */
+#define WAKE_LOCK_JIFFIES      (1 * HZ)                        /* 1s */
 
 enum rk_key_type {
        TYPE_GPIO = 1,
@@ -57,6 +60,7 @@ enum rk_key_type {
 };
 
 struct rk_keys_button {
+       struct device *dev;
        u32 type;               /* TYPE_GPIO, TYPE_ADC */
        u32 code;               /* key code */
        const char *desc;       /* key label */
@@ -75,6 +79,8 @@ struct rk_keys_drvdata {
        bool in_suspend;
        int result;
        int rep;
+       int drift_advalue;
+       struct wake_lock wake_lock;
        struct input_dev *input;
        struct delayed_work adc_poll_work;
        struct iio_channel *chan;
@@ -82,13 +88,6 @@ struct rk_keys_drvdata {
 };
 
 static struct input_dev *sinput_dev;
-static struct rk_keys_drvdata *spdata;
-
-static void *rk_key_get_drvdata(void)
-{
-       BUG_ON(!spdata);
-       return spdata;
-}
 
 void rk_send_power_key(int state)
 {
@@ -118,8 +117,8 @@ EXPORT_SYMBOL(rk_send_wakeup_key);
 
 static void keys_timer(unsigned long _data)
 {
-       struct rk_keys_drvdata *pdata = rk_key_get_drvdata();
        struct rk_keys_button *button = (struct rk_keys_button *)_data;
+       struct rk_keys_drvdata *pdata = dev_get_drvdata(button->dev);
        struct input_dev *input = pdata->input;
        int state;
 
@@ -140,18 +139,18 @@ static void keys_timer(unsigned long _data)
        }
 
        if (state)
-               mod_timer(&button->timer, jiffies + msecs_to_jiffies(DEFAULT_DEBOUNCE_INTERVAL));
+               mod_timer(&button->timer, jiffies + DEBOUNCE_JIFFIES);
 }
 
 static irqreturn_t keys_isr(int irq, void *dev_id)
 {
-       struct rk_keys_drvdata *pdata = rk_key_get_drvdata();
        struct rk_keys_button *button = (struct rk_keys_button *)dev_id;
+       struct rk_keys_drvdata *pdata = dev_get_drvdata(button->dev);
        struct input_dev *input = pdata->input;
 
        BUG_ON(irq != gpio_to_irq(button->gpio));
 
-       if (button->wakeup == 1 && pdata->in_suspend == true) {
+       if (button->wakeup && pdata->in_suspend) {
                button->state = 1;
                key_dbg(pdata,
                        "wakeup: %skey[%s]: report event[%d] state[%d]\n",
@@ -160,7 +159,9 @@ static irqreturn_t keys_isr(int irq, void *dev_id)
                input_event(input, EV_KEY, button->code, button->state);
                input_sync(input);
        }
-       mod_timer(&button->timer, jiffies + msecs_to_jiffies(DEFAULT_DEBOUNCE_INTERVAL));
+       if (button->wakeup)
+               wake_lock_timeout(&pdata->wake_lock, WAKE_LOCK_JIFFIES);
+       mod_timer(&button->timer, jiffies + DEBOUNCE_JIFFIES);
 
        return IRQ_HANDLED;
 }
@@ -205,25 +206,26 @@ static void adc_key_poll(struct work_struct *work)
        ddata = container_of(work, struct rk_keys_drvdata, adc_poll_work.work);
        if (!ddata->in_suspend) {
                result = rk_key_adc_iio_read(ddata);
-               if (result > INVALID_ADVALUE && result < EMPTY_ADVALUE)
+               if (result > INVALID_ADVALUE &&
+                   result < (EMPTY_DEFAULT_ADVALUE - ddata->drift_advalue))
                        ddata->result = result;
                for (i = 0; i < ddata->nbuttons; i++) {
                        struct rk_keys_button *button = &ddata->button[i];
 
                        if (!button->adc_value)
                                continue;
-                       if (result < button->adc_value + DRIFT_ADVALUE &&
-                           result > button->adc_value - DRIFT_ADVALUE)
+                       if (result < button->adc_value + ddata->drift_advalue &&
+                           result > button->adc_value - ddata->drift_advalue)
                                button->adc_state = 1;
                        else
                                button->adc_state = 0;
                        if (button->state != button->adc_state)
                                mod_timer(&button->timer,
-                                         jiffies + msecs_to_jiffies(DEFAULT_DEBOUNCE_INTERVAL));
+                                         jiffies + DEBOUNCE_JIFFIES);
                }
        }
 
-       schedule_delayed_work(&ddata->adc_poll_work, msecs_to_jiffies(ADC_SAMPLE_TIME));
+       schedule_delayed_work(&ddata->adc_poll_work, ADC_SAMPLE_JIFFIES);
 }
 
 static int rk_key_type_get(struct device_node *node,
@@ -246,7 +248,12 @@ static int rk_keys_parse_dt(struct rk_keys_drvdata *pdata,
        struct device_node *child_node;
        struct iio_channel *chan;
        int ret, gpio, i = 0;
-       u32 code, adc_value, flags;
+       u32 code, adc_value, flags, drift;
+
+       if (of_property_read_u32(node, "adc-drift", &drift))
+               pdata->drift_advalue = DRIFT_DEFAULT_ADVALUE;
+       else
+               pdata->drift_advalue = (int)drift;
 
        chan = iio_channel_get(&pdev->dev, NULL);
        if (IS_ERR(chan)) {
@@ -336,6 +343,7 @@ static int keys_probe(struct platform_device *pdev)
                return error;
        }
        platform_set_drvdata(pdev, ddata);
+       dev_set_drvdata(&pdev->dev, ddata);
 
        input->name = "rk29-keypad";    /* pdev->name; */
        input->phys = "gpio-keys/input0";
@@ -357,6 +365,14 @@ static int keys_probe(struct platform_device *pdev)
        if (ddata->rep)
                __set_bit(EV_REP, input->evbit);
 
+       error = input_register_device(input);
+       if (error) {
+               pr_err("gpio-keys: Unable to register input device, error: %d\n",
+                      error);
+               goto fail0;
+       }
+       sinput_dev = input;
+
        for (i = 0; i < ddata->nbuttons; i++) {
                struct rk_keys_button *button = &ddata->button[i];
 
@@ -371,9 +387,13 @@ static int keys_probe(struct platform_device *pdev)
                input_set_capability(input, EV_KEY, button->code);
        }
 
+       wake_lock_init(&ddata->wake_lock, WAKE_LOCK_SUSPEND, input->name);
+       device_init_wakeup(dev, wakeup);
+
        for (i = 0; i < ddata->nbuttons; i++) {
                struct rk_keys_button *button = &ddata->button[i];
 
+               button->dev = &pdev->dev;
                if (button->type == TYPE_GPIO) {
                        int irq;
 
@@ -420,31 +440,20 @@ static int keys_probe(struct platform_device *pdev)
        }
 
        input_set_capability(input, EV_KEY, KEY_WAKEUP);
-       device_init_wakeup(dev, wakeup);
-
-       error = input_register_device(input);
-       if (error) {
-               pr_err("gpio-keys: Unable to register input device, error: %d\n",
-                      error);
-               goto fail2;
-       }
-
        /* adc polling work */
        if (ddata->chan) {
                INIT_DELAYED_WORK(&ddata->adc_poll_work, adc_key_poll);
                schedule_delayed_work(&ddata->adc_poll_work,
-                                     msecs_to_jiffies(ADC_SAMPLE_TIME));
+                                     ADC_SAMPLE_JIFFIES);
        }
 
-       spdata = ddata;
-       sinput_dev = input;
        return error;
 
-fail2:
-       device_init_wakeup(dev, 0);
 fail1:
        while (--i >= 0)
                del_timer_sync(&ddata->button[i].timer);
+       device_init_wakeup(dev, 0);
+       wake_lock_destroy(&ddata->wake_lock);
 fail0:
        platform_set_drvdata(pdev, NULL);
 
@@ -464,9 +473,9 @@ static int keys_remove(struct platform_device *pdev)
        if (ddata->chan)
                cancel_delayed_work_sync(&ddata->adc_poll_work);
        input_unregister_device(input);
+       wake_lock_destroy(&ddata->wake_lock);
 
        sinput_dev = NULL;
-       spdata = NULL;
 
        return 0;
 }
@@ -533,4 +542,15 @@ static struct platform_driver keys_device_driver = {
        }
 };
 
-module_platform_driver(keys_device_driver);
+static int __init rk_keys_driver_init(void)
+{
+       return platform_driver_register(&keys_device_driver);
+}
+
+static void __exit rk_keys_driver_exit(void)
+{
+       platform_driver_unregister(&keys_device_driver);
+}
+
+late_initcall_sync(rk_keys_driver_init);
+module_exit(rk_keys_driver_exit);