aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/input/keyboard/gpio_keys.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/input/keyboard/gpio_keys.c')
-rw-r--r--drivers/input/keyboard/gpio_keys.c133
1 files changed, 130 insertions, 3 deletions
diff --git a/drivers/input/keyboard/gpio_keys.c b/drivers/input/keyboard/gpio_keys.c
index b8d2a93..bf75ef5 100644
--- a/drivers/input/keyboard/gpio_keys.c
+++ b/drivers/input/keyboard/gpio_keys.c
@@ -389,6 +389,59 @@ static struct attribute_group sec_key_attr_group = {
.attrs = sec_key_attrs,
};
+#ifdef CONFIG_MACH_GC1
+void gpio_keys_check_zoom_exception(unsigned int code,
+ bool *zoomkey, unsigned int *hotkey, unsigned int *index)
+{
+ switch (code) {
+ case KEY_CAMERA_ZOOMIN:
+ *hotkey = 0x221;
+ *index = 5;
+ break;
+ case KEY_CAMERA_ZOOMOUT:
+ *hotkey = 0x222;
+ *index = 6;
+ break;
+ case 0x221:
+ *hotkey = KEY_CAMERA_ZOOMIN;
+ *index = 3;
+ break;
+ case 0x222:
+ *hotkey = KEY_CAMERA_ZOOMOUT;
+ *index = 4;
+ break;
+ default:
+ *zoomkey = false;
+ return;
+ }
+ *zoomkey = true;
+}
+#endif
+
+#ifdef CONFIG_FAST_BOOT
+extern bool fake_shut_down;
+
+struct timer_list fake_timer;
+bool fake_pressed;
+
+static void gpio_keys_fake_off_check(unsigned long _data)
+{
+ struct input_dev *input = (struct input_dev *)_data;
+ unsigned int type = EV_KEY;
+
+ if (fake_pressed == false)
+ return ;
+
+ printk(KERN_DEBUG"[Keys] make event\n");
+
+ input_event(input, type, KEY_FAKE_PWR, 1);
+ input_sync(input);
+
+ input_event(input, type, KEY_FAKE_PWR, 0);
+ input_sync(input);
+}
+#endif
+
static void gpio_keys_report_event(struct gpio_button_data *bdata)
{
struct gpio_keys_button *button = bdata->button;
@@ -396,13 +449,61 @@ static void gpio_keys_report_event(struct gpio_button_data *bdata)
unsigned int type = button->type ?: EV_KEY;
int state = (gpio_get_value_cansleep(button->gpio) ? 1 : 0)
^ button->active_low;
+#ifdef CONFIG_MACH_GC1
+ struct gpio_keys_drvdata *ddata = input_get_drvdata(input);
+ struct gpio_button_data *tmp_bdata;
+ static bool overlapped;
+ static unsigned int hotkey;
+ unsigned int index_hotkey = 0;
+ bool zoomkey = false;
+
+#ifdef CONFIG_FAST_BOOT
+ /*Fake pwr off control*/
+ if (fake_shut_down) {
+ if (button->code == KEY_POWER) {
+ if (!!state) {
+ printk(KERN_DEBUG"[Keys] start fake check\n");
+ fake_pressed = true;
+ mod_timer(&fake_timer,
+ jiffies + msecs_to_jiffies(1000));
+ } else {
+ printk(KERN_DEBUG"[Keys] end fake checkPwr 0\n");
+ fake_pressed = false;
+ }
+ }
+ return ;
+ }
+#endif
+ if (system_rev < 6 && system_rev >= 2) {
+ if (overlapped) {
+ if (hotkey == button->code && !state) {
+ bdata->key_state = !!state;
+ bdata->wakeup = false;
+ overlapped = false;
+#ifdef CONFIG_SAMSUNG_PRODUCT_SHIP
+ printk(KERN_DEBUG"[KEYS] Ignored\n");
+#else
+ printk(KERN_DEBUG"[KEYS] Ignore %d %d\n",
+ hotkey, state);
+#endif
+ return;
+ }
+ }
+
+ gpio_keys_check_zoom_exception(button->code, &zoomkey,
+ &hotkey, &index_hotkey);
+ }
+#endif
if (type == EV_ABS) {
- if (state)
+ if (state) {
input_event(input, type, button->code, button->value);
+ input_sync(input);
+ }
} else {
if (bdata->wakeup && !state) {
input_event(input, type, button->code, !state);
+ input_sync(input);
if (button->code == KEY_POWER)
printk(KERN_DEBUG"[keys] f PWR %d\n", !state);
}
@@ -410,12 +511,32 @@ static void gpio_keys_report_event(struct gpio_button_data *bdata)
bdata->key_state = !!state;
bdata->wakeup = false;
+
+#ifdef CONFIG_MACH_GC1
+ if (system_rev < 6 && system_rev >= 2
+ && zoomkey && state) {
+ tmp_bdata = &ddata->data[index_hotkey];
+
+ if (tmp_bdata->key_state) {
+#ifdef CONFIG_SAMSUNG_PRODUCT_SHIP
+ printk(KERN_DEBUG"[KEYS] overlapped\n");
+#else
+ printk(KERN_DEBUG"[KEYS] overlapped. Forced release c %d h %d\n",
+ tmp_bdata->button->code, hotkey);
+#endif
+ input_event(input, type, hotkey, 0);
+ input_sync(input);
+
+ overlapped = true;
+ }
+ }
+#endif
input_event(input, type, button->code, !!state);
+ input_sync(input);
+
if (button->code == KEY_POWER)
printk(KERN_DEBUG"[keys]PWR %d\n", !!state);
}
-
- input_sync(input);
}
static void gpio_keys_work_func(struct work_struct *work)
@@ -638,6 +759,12 @@ static int __devinit gpio_keys_probe(struct platform_device *pdev)
gpio_keys_report_event(&ddata->data[i]);
input_sync(input);
+#ifdef CONFIG_FAST_BOOT
+ /*Fake power off*/
+ input_set_capability(input, EV_KEY, KEY_FAKE_PWR);
+ setup_timer(&fake_timer, gpio_keys_fake_off_check,
+ (unsigned long)input);
+#endif
device_init_wakeup(&pdev->dev, wakeup);
return 0;