diff options
Diffstat (limited to 'drivers/input/keyboard/gpio_keys.c')
-rw-r--r-- | drivers/input/keyboard/gpio_keys.c | 133 |
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; |