input: touchscreen: synaptics_3200: Add Synaptics 3200 driver
HTC kernel version: evitaul-jb-crc-3.4.10-ec474a3
Change-Id: I4acac53e40e4b47f249f631e7b92d9dfe7cb9e79
diff --git a/drivers/input/misc/gpio_input.c b/drivers/input/misc/gpio_input.c
index 6a0c315..f4b9a5a 100644
--- a/drivers/input/misc/gpio_input.c
+++ b/drivers/input/misc/gpio_input.c
@@ -22,6 +22,78 @@
#include <linux/slab.h>
#include <linux/wakelock.h>
+#ifdef CONFIG_TOUCHSCREEN_SYNAPTICS_3K
+static uint8_t power_key_state;
+static spinlock_t power_key_state_lock;
+
+#define PWRKEY_PRESS_DUE 1*HZ
+#include <linux/module.h>
+static void init_power_key_api(void)
+{
+ spin_lock_init(&power_key_state_lock);
+ power_key_state = 0;
+}
+
+static void setPowerKeyState(uint8_t flag)
+{
+ spin_lock(&power_key_state_lock);
+ power_key_state = flag;
+ spin_unlock(&power_key_state_lock);
+}
+
+uint8_t getPowerKeyState(void)
+{
+ uint8_t value;
+
+ spin_lock(&power_key_state_lock);
+ value = power_key_state;
+ spin_unlock(&power_key_state_lock);
+
+ return value;
+}
+EXPORT_SYMBOL(getPowerKeyState);
+
+static void power_key_state_disable_work_func(struct work_struct *dummy)
+{
+ setPowerKeyState(0);
+ printk(KERN_INFO "[KEY][PWR][STATE]power key pressed outdated\n");
+}
+static DECLARE_DELAYED_WORK(power_key_state_disable_work, power_key_state_disable_work_func);
+
+static void handle_power_key_state(unsigned int code, int value)
+{
+ int ret = 0;
+ if (code == KEY_POWER && value == 1) {
+ printk(KERN_INFO "[PWR][STATE]try to schedule power key pressed due\n");
+ ret = schedule_delayed_work(&power_key_state_disable_work, PWRKEY_PRESS_DUE);
+ if (!ret) {
+ printk(KERN_INFO "[PWR][STATE]Schedule power key pressed due failed, seems already have one, try to cancel...\n");
+ ret = cancel_delayed_work(&power_key_state_disable_work);
+ if (!ret) {
+ setPowerKeyState(1);
+ if (schedule_delayed_work(&power_key_state_disable_work, PWRKEY_PRESS_DUE)) {
+ printk(KERN_INFO "[PWR][STATE]Re-schedule power key pressed due SCCUESS.\n");
+ printk(KERN_INFO "[PWR][STATE] start count for power key pressed due\n");
+ setPowerKeyState(1);
+ } else
+ printk(KERN_INFO "[PWR][STATE]Re-schedule power key pressed due FAILED, reason unknown, give up.\n");
+ } else {
+ printk(KERN_INFO "[PWR][STATE]Cancel scheduled power key due success, now re-schedule.\n");
+ if (schedule_delayed_work(&power_key_state_disable_work, PWRKEY_PRESS_DUE)) {
+ printk(KERN_INFO "[PWR][STATE]Re-schedule power key pressed due SCCUESS.\n");
+ printk(KERN_INFO "[PWR][STATE] start count for power key pressed due\n");
+ setPowerKeyState(1);
+ } else
+ printk(KERN_INFO "[PWR][STATE]Re-schedule power key pressed due FAILED, reason unknown, give up.\n");
+ }
+ } else {
+ printk(KERN_INFO "[PWR][STATE] start count for power key pressed due\n");
+ setPowerKeyState(1);
+ }
+ }
+}
+#endif /* CONFIG_TOUCHSCREEN_SYNAPTICS_3K */
+
enum {
DEBOUNCE_UNSTABLE = BIT(0), /* Got irq, while debouncing */
DEBOUNCE_PRESSED = BIT(1),
@@ -130,6 +202,9 @@
pr_info("gpio_keys_scan_keys: key %x-%x, %d (%d) "
"changed to %d\n", ds->info->type,
key_entry->code, i, key_entry->gpio, pressed);
+#ifdef CONFIG_TOUCHSCREEN_SYNAPTICS_3K
+ handle_power_key_state(key_entry->code, pressed);
+#endif
input_event(ds->input_devs->dev[key_entry->dev], ds->info->type,
key_entry->code, pressed);
sync_needed = true;
@@ -239,6 +314,9 @@
}
}
}
+#ifdef CONFIG_TOUCHSCREEN_SYNAPTICS_3K
+ init_power_key_api();
+#endif
return 0;
for (i = ds->info->keymap_size - 1; i >= 0; i--) {