void keypad_report_keycode(struct gpio_key_state *ks) { struct gpio_input_state *ds = ks->ds; int keymap_index; const struct gpio_event_direct_entry *key_entry; int pressed; if (ds == NULL) { KEY_LOGE("%s, (ds == NULL) failed\n", __func__); return; } keymap_index = ks - ds->key_state; key_entry = &ds->info->keymap[keymap_index]; if (key_entry == NULL) { KEY_LOGE("%s, (key_entry == NULL) failed\n", __func__); return; } pressed = gpio_get_value(key_entry->gpio) ^ !(ds->info->flags & GPIOEDF_ACTIVE_HIGH); if (key_entry->code == KEY_POWER) { if (pressed) wake_lock(&ds->key_pressed_wake_lock); else wake_unlock(&ds->key_pressed_wake_lock); } if (ds->info->flags & GPIOEDF_PRINT_KEYS) KEY_LOGD("%s: key %d-%d, %d " "(%d) changed to %d\n", __func__, ds->info->type, key_entry->code, keymap_index, key_entry->gpio, pressed); #ifdef CONFIG_POWER_KEY_LED handle_power_key_led(key_entry->code, pressed); #endif #ifdef CONFIG_POWER_KEY_CLR_RESET handle_power_key_reset(key_entry->code, pressed); #endif input_event(ds->input_devs->dev[key_entry->dev], ds->info->type, key_entry->code, pressed); input_sync(ds->input_devs->dev[key_entry->dev]); }
static ssize_t disable_reset_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { unsigned int value; int i = 0; int pressed; struct gpio_input_state *ds = gb_ddata; const struct gpio_event_direct_entry *key_entry = ds->info->keymap; struct gpio_key_state *key_state = ds->key_state; unsigned gpio_flags = ds->info->flags; unsigned npolarity; unsigned long irqflags; uint8_t idx_pwr = 0; if (kstrtouint(buf, 10, &value) < 0) { KEY_LOGI("%s: input out of range\n",__func__); return -EINVAL; } spin_lock_irqsave(&ds->irq_lock, irqflags); wake_lock(&disable_reset_wake_lock); ds->disable_reset_flag = value; queue_delayed_work(ds->disable_reset_wq, &ds->disable_reset_work, msecs_to_jiffies(ds->disable_reset_flag * 1000)); for (i = 0; i < ds->info->keymap_size; i++, key_entry++, key_state++) if (key_entry->code == KEY_POWER) idx_pwr = i; key_entry = ds->info->keymap; npolarity = !(gpio_flags & GPIOEDF_ACTIVE_HIGH); #ifdef CONFIG_POWER_KEY_LED handle_power_key_led(KEY_POWER, 0); #endif if (__cancel_delayed_work(&power_key_check_reset_work)) KEY_LOGI("[PWR] cancel power key check reset work successfully\n"); pressed = gpio_get_value((key_entry + idx_pwr)->gpio) ^ npolarity; handle_transition_according_to_power_key(pressed); spin_unlock_irqrestore(&ds->irq_lock, irqflags); KEY_LOGI("%s, %d\n", __func__, ds->disable_reset_flag); return count; }
static enum hrtimer_restart gpio_event_input_timer_func(struct hrtimer *timer) { int i; int pressed; struct gpio_input_state *ds = container_of(timer, struct gpio_input_state, timer); unsigned gpio_flags = ds->info->flags; unsigned npolarity; int nkeys = ds->info->keymap_size; const struct gpio_event_direct_entry *key_entry; struct gpio_key_state *key_state; unsigned long irqflags; uint8_t debounce; bool sync_needed; #if 0 key_entry = kp->keys_info->keymap; key_state = kp->key_state; for (i = 0; i < nkeys; i++, key_entry++, key_state++) pr_info("gpio_read_detect_status %d %d\n", key_entry->gpio, gpio_read_detect_status(key_entry->gpio)); #endif key_entry = ds->info->keymap; key_state = ds->key_state; sync_needed = false; spin_lock_irqsave(&ds->irq_lock, irqflags); for (i = 0; i < nkeys; i++, key_entry++, key_state++) { debounce = key_state->debounce; if (debounce & DEBOUNCE_WAIT_IRQ) continue; if (key_state->debounce & DEBOUNCE_UNSTABLE) { debounce = key_state->debounce = DEBOUNCE_UNKNOWN; enable_irq(gpio_to_irq(key_entry->gpio)); KEY_LOGD("gpio_keys_scan_keys: key %x-%x, %d " "(%d) continue debounce\n", ds->info->type, key_entry->code, i, key_entry->gpio); } npolarity = !(gpio_flags & GPIOEDF_ACTIVE_HIGH); pressed = gpio_get_value_cansleep(key_entry->gpio) ^ npolarity; if (debounce & DEBOUNCE_POLL) { if (pressed == !(debounce & DEBOUNCE_PRESSED)) { ds->debounce_count++; key_state->debounce = DEBOUNCE_UNKNOWN; if (gpio_flags & GPIOEDF_PRINT_KEY_DEBOUNCE) KEY_LOGD("gpio_keys_scan_keys: key %x-" "%x, %d (%d) start debounce\n", ds->info->type, key_entry->code, i, key_entry->gpio); } continue; } if (pressed && (debounce & DEBOUNCE_NOTPRESSED)) { if (gpio_flags & GPIOEDF_PRINT_KEY_DEBOUNCE) KEY_LOGD("gpio_keys_scan_keys: key %x-%x, %d " "(%d) debounce pressed 1\n", ds->info->type, key_entry->code, i, key_entry->gpio); key_state->debounce = DEBOUNCE_PRESSED; continue; } if (!pressed && (debounce & DEBOUNCE_PRESSED)) { if (gpio_flags & GPIOEDF_PRINT_KEY_DEBOUNCE) KEY_LOGD("gpio_keys_scan_keys: key %x-%x, %d " "(%d) debounce pressed 0\n", ds->info->type, key_entry->code, i, key_entry->gpio); key_state->debounce = DEBOUNCE_NOTPRESSED; continue; } /* key is stable */ ds->debounce_count--; if (ds->use_irq) key_state->debounce |= DEBOUNCE_WAIT_IRQ; else key_state->debounce |= DEBOUNCE_POLL; if (gpio_flags & GPIOEDF_PRINT_KEYS) KEY_LOGD("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_POWER_KEY_LED handle_power_key_led(key_entry->code, pressed); #endif input_event(ds->input_devs->dev[key_entry->dev], ds->info->type, key_entry->code, pressed); sync_needed = true; } if (sync_needed) { for (i = 0; i < ds->input_devs->count; i++) input_sync(ds->input_devs->dev[i]); } #if 0 key_entry = kp->keys_info->keymap; key_state = kp->key_state; for (i = 0; i < nkeys; i++, key_entry++, key_state++) { pr_info("gpio_read_detect_status %d %d\n", key_entry->gpio, gpio_read_detect_status(key_entry->gpio)); } #endif if (ds->debounce_count) hrtimer_start(timer, ds->info->debounce_time, HRTIMER_MODE_REL); else if (!ds->use_irq) hrtimer_start(timer, ds->info->poll_time, HRTIMER_MODE_REL); else wake_unlock(&ds->wake_lock); spin_unlock_irqrestore(&ds->irq_lock, irqflags); return HRTIMER_NORESTART; }
static void gpio_event_input_delayed_func(struct work_struct *key_work) { int i; int pressed; struct gpio_input_state *ds = container_of((struct delayed_work *)key_work, struct gpio_key_state, key_work)->ds; unsigned npolarity; unsigned gpio_flags = ds->info->flags; int nkeys = ds->info->keymap_size; const struct gpio_event_direct_entry *key_entry; struct gpio_key_state *key_state; unsigned long irqflags; uint8_t debounce; bool sync_needed; key_entry = ds->info->keymap; key_state = ds->key_state; npolarity = !(gpio_flags & GPIOEDF_ACTIVE_HIGH); for (i = 0; i < nkeys; i++, key_entry++, key_state++) { key_state->keyValue = gpio_get_value(key_entry->gpio) ^ npolarity; key_state->irq_enable_needed = 0; key_state->need_queue = 0; } #ifdef KEYPAD_DEBUG KEY_LOGD("Before process: \n"); print_key_ds(ds); #endif key_entry = ds->info->keymap; key_state = ds->key_state; sync_needed = false; spin_lock_irqsave(&ds->irq_lock, irqflags); for (i = 0; i < nkeys; i++, key_entry++, key_state++) { debounce = key_state->debounce; if (debounce & DEBOUNCE_WAIT_IRQ) continue; if (key_state->debounce & DEBOUNCE_UNSTABLE) { debounce = key_state->debounce = DEBOUNCE_UNKNOWN; key_state->irq_enable_needed = 1; if (gpio_flags & GPIOEDF_PRINT_KEY_UNSTABLE) KEY_LOGD("gpio_keys_scan_keys: key %x-%x, %d " "(%d) continue debounce," #ifdef KEYPAD_DEBUG " enable irq#%d\n" #endif , ds->info->type, key_entry->code, i, key_entry->gpio #ifdef KEYPAD_DEBUG , gpio_to_irq(key_entry->gpio) #endif ); } pressed = key_state->keyValue; if (debounce & DEBOUNCE_POLL) { if (pressed == !(debounce & DEBOUNCE_PRESSED)) { ds->debounce_count++; key_state->need_queue = 1; key_state->debounce = DEBOUNCE_UNKNOWN; if (gpio_flags & GPIOEDF_PRINT_KEY_DEBOUNCE) KEY_LOGD("gpio_keys_scan_keys: key %x-" "%x, %d (%d) start debounce\n", ds->info->type, key_entry->code, i, key_entry->gpio); } continue; } if (pressed && (debounce & DEBOUNCE_NOTPRESSED)) { if (gpio_flags & GPIOEDF_PRINT_KEY_DEBOUNCE) KEY_LOGD("gpio_keys_scan_keys: key %x-%x, %d " "(%d) debounce pressed 1\n", ds->info->type, key_entry->code, i, key_entry->gpio); key_state->debounce = DEBOUNCE_PRESSED; key_state->need_queue = 1; continue; } if (!pressed && (debounce & DEBOUNCE_PRESSED)) { if (gpio_flags & GPIOEDF_PRINT_KEY_DEBOUNCE) KEY_LOGD("gpio_keys_scan_keys: key %x-%x, %d " "(%d) debounce pressed 0\n", ds->info->type, key_entry->code, i, key_entry->gpio); key_state->debounce = DEBOUNCE_NOTPRESSED; key_state->need_queue = 1; continue; } /* key is stable */ ds->debounce_count--; if (ds->use_irq) key_state->debounce |= DEBOUNCE_WAIT_IRQ; else key_state->debounce |= DEBOUNCE_POLL; if (gpio_flags & GPIOEDF_PRINT_KEYS) KEY_LOGD("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_POWER_KEY_LED handle_power_key_led(key_entry->code, pressed); #endif input_event(ds->input_devs->dev[key_entry->dev], ds->info->type, key_entry->code, pressed); sync_needed = true; } if (sync_needed) { for (i = 0; i < ds->input_devs->count; i++) input_sync(ds->input_devs->dev[i]); } #if 0 key_entry = kp->keys_info->keymap; key_state = kp->key_state; for (i = 0; i < nkeys; i++, key_entry++, key_state++) { pr_info("gpio_read_detect_status %d %d\n", key_entry->gpio, gpio_read_detect_status(key_entry->gpio)); } #endif if (ds->debounce_count) { key_entry = ds->info->keymap; key_state = ds->key_state; for (i = 0; i < nkeys; i++, key_entry++, key_state++) { if (key_state->need_queue) if (!queue_delayed_work(ki_queue, &(key_state->key_work), KTIME_TO_JIFFIES(ds->info->debounce_time))) KEY_LOGI("Keycode: 0x%X has been queued already.\n", key_entry->code); } } else if (!ds->use_irq) { key_entry = ds->info->keymap; key_state = ds->key_state; for (i = 0; i < nkeys; i++, key_entry++, key_state++) { if (key_state->need_queue) if (!queue_delayed_work(ki_queue, &(key_state->key_work), KTIME_TO_JIFFIES(ds->info->poll_time))) KEY_LOGI("Keycode: 0x%X has been queued already.\n", key_entry->code); } } else wake_unlock(&ds->wake_lock); spin_unlock_irqrestore(&ds->irq_lock, irqflags); #if 0 key_entry = ds->info->keymap; key_state = ds->key_state; for (i = 0; i < nkeys; i++, key_entry++, key_state++) if (key_state->irq_enable_needed) enable_irq(gpio_to_irq(key_entry->gpio)); #endif #ifdef KEYPAD_DEBUG KEY_LOGD("After process:\n"); print_key_ds(ds); #endif }