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;
}
Пример #3
0
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;
}
Пример #4
0
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
}