static void handle_power_key_state(unsigned int code, int value)
{
	int ret = 0;
	if (code == KEY_POWER && value == 1) {
		KEY_LOGI("[PWR][STATE]try to schedule power key pressed due\n");
		ret = schedule_delayed_work(&power_key_state_disable_work, PWRKEY_PRESS_DUE);
		if (!ret) {
			KEY_LOGI("[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)) {
					KEY_LOGI("[PWR][STATE]Re-schedule power key pressed due SCCUESS.\n");
					KEY_LOGI("[PWR][STATE] start count for power key pressed due\n");
					setPowerKeyState(1);
				} else
					KEY_LOGI("[PWR][STATE]Re-schedule power key pressed due FAILED, reason unknown, give up.\n");
			} else {
				KEY_LOGI("[PWR][STATE]Cancel scheduled power key due success, now re-schedule.\n");
				if (schedule_delayed_work(&power_key_state_disable_work, PWRKEY_PRESS_DUE)) {
					KEY_LOGI("[PWR][STATE]Re-schedule power key pressed due SCCUESS.\n");
					KEY_LOGI("[PWR][STATE] start count for power key pressed due\n");
					setPowerKeyState(1);
				} else
					KEY_LOGI("[PWR][STATE]Re-schedule power key pressed due FAILED, reason unknown, give up.\n");
			}
		} else {
			KEY_LOGI("[PWR][STATE] start count for power key pressed due\n");
			setPowerKeyState(1);
		}
	}
}
Beispiel #2
0
static ssize_t vol_wakeup_store(struct device *dev,
					 struct device_attribute *attr,
					 const char *buf, size_t count)
{
	unsigned char bitmask = 0;
	bitmask = simple_strtoull(buf, NULL, 10);
	mutex_lock(&wakeup_mutex);
	if (bitmask) {
		if (bitmask == 127)
			wakeup_bitmask &= bitmask;
		else if (bitmask > 128)
			wakeup_bitmask &= bitmask;
		else
			wakeup_bitmask |= bitmask;
	}

	if (wakeup_bitmask && (!set_wakeup)) {
		enable_irq_wake(vol_up_irq);
		enable_irq_wake(vol_down_irq);
		set_wakeup = 1;
		KEY_LOGI("%s:change to wake up function(%d, %d)\n", __func__, vol_up_irq, vol_down_irq);
	} else if ((!wakeup_bitmask) && set_wakeup){
		disable_irq_wake(vol_up_irq);
		disable_irq_wake(vol_down_irq);
		set_wakeup = 0;
		KEY_LOGI("%s:change to non-wake up function(%d, %d)\n", __func__, vol_up_irq, vol_down_irq);
	}
	mutex_unlock(&wakeup_mutex);
	return count;
}
static void power_key_led_off_work_func(struct work_struct *dummy)
{
	if (power_key_led_requested) {
		if (cancel_delayed_work_sync(&power_key_led_on_work)) {
			KEY_LOGI("[PWR] cancel power key led work successfully(%x)\n", power_key_led_requested);
		} else
			KEY_LOGI("[PWR] cancel power key led work unsuccessfully (%x)\n", power_key_led_requested);

		power_key_led_requested = 0;
	}
	if (pre_power_key_led_status == 1) {
#ifdef CONFIG_POWER_KEY_CLR_RESET
		cancel_delayed_work_sync(&power_key_restart_work);
#endif
		KEY_LOGI("[PWR] change power key led off\n");
#ifdef CONFIG_QPNP_PWM
#ifdef CONFIG_VK_LED
		qpnp_led_set_for_key(0);
#endif
#else
		pm8xxx_led_current_set_for_key(0);
#endif
		pre_power_key_led_status = 0;
#ifdef CONFIG_POWER_KEY_CLR_RESET
		if(!is_rrm1_mode())
#endif
			set_hw_reason(0);
	}
}
static int gpio_event_input_request_irqs(struct gpio_input_state *ds)
{
	int i;
	int err;
	int value;
	unsigned int irq;
	unsigned long req_flags = IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING;

	for (i = 0; i < ds->info->keymap_size; i++) {
		err = irq = gpio_to_irq(ds->info->keymap[i].gpio);
		if (err < 0)
			goto err_gpio_get_irq_num_failed;
		if (ds->info->keymap[i].code == KEY_POWER) {
#ifdef CONFIG_PWRKEY_WAKESRC_LOG
			power_key_gpio = ds->info->keymap[i].gpio;
			KEY_LOGI("Power Key gpio = %d", power_key_gpio);
#endif
			power_key_intr_flag = 0;
			value = gpio_get_value(ds->info->keymap[i].gpio);
			req_flags = value ? IRQF_TRIGGER_FALLING: IRQF_TRIGGER_RISING;
			KEY_LOGI("keycode = %d, gpio = %d, type = %lx", ds->info->keymap[i].code, value, req_flags);
		}
		else
			req_flags = IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING;
#ifdef CONFIG_MFD_MAX8957
		INIT_WORK(&ds->key_state[i].work, keypad_do_work);
		queue_work(ki_queue, &ds->key_state[i].work);
#endif
		err = request_any_context_irq(irq, gpio_event_input_irq_handler,
				  req_flags, "gpio_keys", &ds->key_state[i]);
		if (err < 0) {
			KEY_LOGE("KEY_ERR: %s: request_irq "
				"failed for input %d, irq %d, err %d\n", __func__,
				ds->info->keymap[i].gpio, irq, err);
			goto err_request_irq_failed;
		}
		if (ds->info->keymap[i].code == KEY_VOLUMEUP ||
			ds->info->keymap[i].code == KEY_VOLUMEDOWN || ds->info->keymap[i].code == KEY_HP ) {
			KEY_LOGI("keycode = %d, gpio = %d, irq = %d", ds->info->keymap[i].code, ds->info->keymap[i].gpio, irq);
			if (ds->info->keymap[i].code == KEY_VOLUMEUP)
				vol_up_irq = irq;
			else if (ds->info->keymap[i].code == KEY_VOLUMEDOWN)
				vol_down_irq = irq;
		} else
			enable_irq_wake(irq);
	}
#ifdef CONFIG_PWRKEY_STATUS_API
	init_power_key_api();
#endif
	return 0;

	for (i = ds->info->keymap_size - 1; i >= 0; i--) {
		free_irq(gpio_to_irq(ds->info->keymap[i].gpio),
			 &ds->key_state[i]);
err_request_irq_failed:
err_gpio_get_irq_num_failed:
		;
	}
	return err;
}
Beispiel #5
0
static void power_key_led_on_work_func(struct work_struct *dummy)
{
	KEY_LOGI("[PWR] %s in (%x)\n", __func__, power_key_led_requested);
	if (power_key_led_requested == 1) {
		pre_power_key_led_status = 1;
		KEY_LOGI("[PWR] change power key led on\n");
		button_backlight_flash(1);
	}
}
static void power_key_clr_check_work_func(struct work_struct *dummy)
{
    if (cancel_delayed_work_sync(&power_key_check_reset_work))
        KEY_LOGI("[PWR] cancel power key check reset work successfully\n");
    else
        KEY_LOGI("[PWR] cancel power key check reset work unsuccessfully\n");

    wake_unlock(&key_reset_clr_wake_lock);
}
Beispiel #7
0
static void power_key_led_on_work_func(struct work_struct *dummy)
{
	KEY_LOGI("[PWR] %s in (%x)\n", __func__, power_key_led_requested);
	if (power_key_led_requested == 1) {
		pre_power_key_led_status = 1;
		KEY_LOGI("[PWR] change power key led on\n");
		pm8xxx_led_current_set_for_key(1);
	}
}
Beispiel #8
0
static void power_key_led_on_work_func(struct work_struct *dummy)
{
	KEY_LOGI("[PWR] %s in (%x)\n", __func__, power_key_led_requested);
	if (power_key_led_requested == 1) {
		pre_power_key_led_status = 1;
		KEY_LOGI("[PWR] change power key led on\n");
		pm8xxx_led_current_set_for_key(1);
		set_hw_reason(HW_RESET_REASON);
		KEY_LOGI("[PWR] Show Blocked State -- long press power key\n");
		show_state_filter(TASK_UNINTERRUPTIBLE);
	}
}
Beispiel #9
0
static int gpio_event_input_request_irqs(struct gpio_input_state *ds)
{
	int i;
	int err;
	int value;
	unsigned int irq;
	unsigned long req_flags = IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING;

	for (i = 0; i < ds->info->keymap_size; i++) {
		err = irq = gpio_to_irq(ds->info->keymap[i].gpio);
		if (err < 0)
			goto err_gpio_get_irq_num_failed;

		if (ds->info->keymap[i].code == KEY_POWER) {
			power_key_intr_flag = 0;
			value = gpio_get_value(ds->info->keymap[i].gpio);
			req_flags = value ? IRQF_TRIGGER_FALLING: IRQF_TRIGGER_RISING;
			KEY_LOGI("keycode = %d, gpio = %d, type = %lx", ds->info->keymap[i].code, value, req_flags);
		}
		else
			req_flags = IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING;

		err = request_any_context_irq(irq, gpio_event_input_irq_handler,
				  req_flags, "gpio_keys", &ds->key_state[i]);
		if (err < 0) {
			KEY_LOGE("KEY_ERR: %s: request_irq "
				"failed for input %d, irq %d, err %d\n", __func__,
				ds->info->keymap[i].gpio, irq, err);
			goto err_request_irq_failed;
		}
		if (ds->info->keymap[i].code == KEY_VOLUMEUP ||
			ds->info->keymap[i].code == KEY_VOLUMEDOWN) {
			KEY_LOGI("keycode = %d, gpio = %d, irq = %d", ds->info->keymap[i].code, ds->info->keymap[i].gpio, irq);
			if (ds->info->keymap[i].code == KEY_VOLUMEUP)
				vol_up_irq = irq;
			else
				vol_down_irq = irq;
		} else
			enable_irq_wake(irq);
	}
	return 0;

	for (i = ds->info->keymap_size - 1; i >= 0; i--) {
		free_irq(gpio_to_irq(ds->info->keymap[i].gpio),
			 &ds->key_state[i]);
err_request_irq_failed:
err_gpio_get_irq_num_failed:
		;
	}
	return err;
}
Beispiel #10
0
static void do_reset_fn(void *priv)
{
	struct keyreset_state *state = priv;
	if (state->restart_requested)
		panic("[KEY] keyboard reset failed, %d", state->restart_requested);
	if (state->reset_fn) {
		KEY_LOGI("keyboard reset\n");
		state->restart_requested = state->reset_fn();
	} else {
		KEY_LOGI("keyboard reset (default)\n");
		do_restart();
		state->restart_requested = 1;
	}
}
static void handle_transition_according_to_power_key(int value)
{
	struct gpio_input_state *ds = gb_ddata;

#ifdef CONFIG_KPDPWR_S2_DVDD_RESET
	clear_kpdpwr_s2_rst_flag = 0;
	if (hrtimer_is_queued(&clr_kpd_reset_timer))
		hrtimer_cancel(&clr_kpd_reset_timer);
	if (hrtimer_is_queued(&enable_kpd_s2_timer))
		hrtimer_cancel(&enable_kpd_s2_timer);
#endif 

	if (ds->disable_reset_flag == 0 && value) {
		
#ifdef CONFIG_POWER_VOLUP_RESET
		wake_lock_timeout(&key_reset_clr_wake_lock, msecs_to_jiffies(1000));
		if (!schedule_delayed_work(&power_key_check_reset_work, msecs_to_jiffies(0)))
#else
		wake_lock_timeout(&key_reset_clr_wake_lock, PWRKEYCHKRST_WAKELOCK_TIMEOUT);
		if (!schedule_delayed_work(&power_key_check_reset_work, PWRKEYCHKRST_DELAY))
#endif
			KEY_LOGI("[PWR] the reset work in already in the queue\n");
	} else if (ds->disable_reset_flag != 0) {
		
		handle_only_power_key(KEY_POWER, value);
	}
}
Beispiel #12
0
static void power_key_led_off_work_func(struct work_struct *dummy)
{
	if (power_key_led_requested) {
		if (cancel_delayed_work_sync(&power_key_led_on_work)) {
			KEY_LOGI("[PWR] cancel power key led work successfully(%x)\n", power_key_led_requested);
		} else
			KEY_LOGI("[PWR] cancel power key led work unsuccessfully (%x)\n", power_key_led_requested);

		power_key_led_requested = 0;
	}
	if (pre_power_key_led_status == 1) {
		KEY_LOGI("[PWR] change power key led off\n");
		button_backlight_flash(0);
		pre_power_key_led_status = 0;
	}
}
Beispiel #13
0
static void handle_power_key_reset(unsigned int code, int value)
{
	if (code == KEY_POWER) {
		if (value) {
			wake_lock_timeout(&key_reset_clr_wake_lock, PWRKEYCHKRST_WAKELOCK_TIMEOUT);
			KEY_LOGI("[PWR] start count for power key check reset\n");
			if (!schedule_delayed_work(&power_key_check_reset_work, PWRKEYCHKRST_DELAY))
				KEY_LOGI("[PWR] the reset work in already in the queue\n");
		} else {
			KEY_LOGI("[PWR] start count for power key clear check\n");

			if (!schedule_delayed_work(&power_key_clr_check_work, PWRKEYCLRCHK_DELAY))
				KEY_LOGI("[PWR] the clear work in already in the queue\n");
		}
	}
}
Beispiel #14
0
static void handle_power_key_led(unsigned int code, int value)
{
	if (code == KEY_POWER) {
		if (pre_power_key_status == value)
			return;
		pre_power_key_status = value;
		if (value) {
			KEY_LOGI("[PWR] start count for power key led on\n");
			schedule_delayed_work(&power_key_led_on_work, PWRKEYLEDON_DELAY);
			power_key_led_requested = 1;
		} else {
			KEY_LOGI("[PWR] start count for power key led off\n");
			schedule_delayed_work(&power_key_led_off_work, PWRKEYLEDOFF_DELAY);
		}
	}
}
static void disable_reset_func(struct work_struct *work)
{
	struct delayed_work *dwork = container_of(work, struct delayed_work,
									work);
	struct gpio_input_state *ds = container_of(dwork,
			struct gpio_input_state, disable_reset_work);
	const struct gpio_event_direct_entry *key_entry = ds->info->keymap;
	unsigned long irqflags;
	unsigned gpio_flags = ds->info->flags;
	unsigned npolarity;
	uint8_t idx_pwr = 0;
	int i = 0;
	int pressed;

	spin_lock_irqsave(&ds->irq_lock, irqflags);
	ds->disable_reset_flag = 0;
	__cancel_delayed_work(&ds->clear_hw_reset_work);

	for (i = 0; i < ds->info->keymap_size; i++, key_entry++)
		if (key_entry->code == KEY_POWER)
			idx_pwr = i;
	key_entry = ds->info->keymap;
	npolarity = !(gpio_flags & GPIOEDF_ACTIVE_HIGH);
	pressed = gpio_get_value((key_entry + idx_pwr)->gpio) ^ npolarity;
	handle_transition_according_to_power_key(pressed);

	wake_unlock(&disable_reset_wake_lock);
	spin_unlock_irqrestore(&ds->irq_lock, irqflags);

	KEY_LOGI("%s, %d\n", __func__, ds->disable_reset_flag);
}
Beispiel #16
0
static void power_key_led_off_work_func(struct work_struct *dummy)
{
	if (power_key_led_requested) {
		if (cancel_delayed_work_sync(&power_key_led_on_work)) {
			KEY_LOGI("[PWR] cancel power key led work successfully(%x)\n", power_key_led_requested);
		} else
			KEY_LOGI("[PWR] cancel power key led work unsuccessfully (%x)\n", power_key_led_requested);

		power_key_led_requested = 0;
	}
	if (pre_power_key_led_status == 1) {
		pr_info("[PWR] change power key led off\n");
		pm8xxx_led_current_set_for_key(0);
		pre_power_key_led_status = 0;
	}
}
Beispiel #17
0
static void power_key_state_disable_work_func(struct work_struct *dummy)
{
	setPowerKeyState(0);
#ifdef CONFIG_CIR_ALWAYS
	power_key_pressed = 0;
#endif
	KEY_LOGI("[PWR][STATE]power key pressed outdated\n");
}
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 ssize_t fm_radio_store(struct device *dev,
					 struct device_attribute *attr,
					 const char *buf, size_t count)
{
	fm_radio_status = simple_strtoull(buf, NULL, 10);
	KEY_LOGI("GPIO_EVENT:: fm_radio_status=%d\n", fm_radio_status);

	return count;
}
static void power_key_check_reset_work_func(struct work_struct *dummy)
{
    struct gpio_event_input_info *aa = gis;
    int pocket_mode = 0;
    KEY_LOGI("[PWR] %s\n", __func__);
    if ((aa->clear_hw_reset)) {
        /* Check P/L sensor status */
        pocket_mode = power_key_check_in_pocket();
        if (pocket_mode) {
            printk(KERN_INFO "[KEY] power_key_check_in_pocket = %d\n", pocket_mode);
            aa->clear_hw_reset();
        }
    }
    else {
        KEY_LOGI("[PWR] No reset  clear function\n");
    }
    handle_power_key_reset(KEY_POWER, 1);
}
static void clear_hw_reset(void)
{
	struct gpio_event_input_info *aa = gis;
	KEY_LOGI("[PWR] %s\n", __func__);
#ifdef CONFIG_OF
	if ((aa->dt_clear_hw_reset)) {
		printk(KERN_INFO "[KEY] clear hw reset\n");
		aa->dt_clear_hw_reset(aa->clr_gpio);
	}
#else
	if ((aa->clear_hw_reset)) {
		printk(KERN_INFO "[KEY] clear hw reset\n");
		aa->clear_hw_reset();
	}
#endif
	else {
		KEY_LOGI("[PWR] No reset  clear function\n");
	}
}
Beispiel #22
0
static void do_restart(struct work_struct *unused)
{
#if defined(CONFIG_POWER_KEY_CLR_RESET)
	clear_hw_reset();
#endif
	sys_sync();
	KEY_LOGI("[PWR] Show Blocked State -- long press power key\n");
	show_state_filter(TASK_UNINTERRUPTIBLE);
	machine_restart("power-key-force-hard");
}
Beispiel #23
0
static void report_key(struct gpio_kp *kp, int key_index, int out, int in)
{
	struct gpio_event_matrix_info *mi = kp->keypad_info;
	int pressed = test_bit(key_index, kp->keys_pressed);
	unsigned short keyentry = mi->keymap[key_index];
	unsigned short keycode = keyentry & MATRIX_KEY_MASK;
	unsigned short dev = keyentry >> MATRIX_CODE_BITS;
#ifdef CONFIG_OPTICALJOYSTICK_CRUCIAL
	static unsigned need_send_spec_key = 1;
#endif

	if (pressed != test_bit(keycode, kp->input_devs->dev[dev]->key)) {
		if (keycode == KEY_RESERVED) {
			KEY_LOGI("gpiomatrix: unmapped key, %d-%d "
					"(%d-%d) changed to %d\n",
					out, in, mi->output_gpios[out],
					mi->input_gpios[in], pressed);
		} else {
			KEY_LOGI("gpiomatrix: key %d, %d-%d (%d-%d) "
					"changed to %d\n", keycode,
					out, in, mi->output_gpios[out],
					mi->input_gpios[in], pressed);
#ifdef CONFIG_OPTICALJOYSTICK_CRUCIAL
			if (mi->info.oj_btn && keycode == BTN_MOUSE)
				;
			else
#endif
				input_report_key(kp->input_devs->dev[dev],
							keycode, pressed);
		}
	}
#ifdef CONFIG_OPTICALJOYSTICK_CRUCIAL
	if (mi->info.oj_btn && keycode == BTN_MOUSE) {
		if (need_send_spec_key == pressed) {
			curcial_oj_send_key(keycode, pressed);
			need_send_spec_key = !pressed;
			KEY_LOGI("%s: send OJ action key, pressed: %d\n",
				__func__, pressed);
		}
	}
#endif
}
Beispiel #24
0
static void clear_phantom_key(struct gpio_kp *kp, int out, int in)
{
	struct gpio_event_matrix_info *mi = kp->keypad_info;
	int key_index = out * mi->ninputs + in;
	unsigned short keyentry = mi->keymap[key_index];
	unsigned short keycode = keyentry & MATRIX_KEY_MASK;
	unsigned short dev = keyentry >> MATRIX_CODE_BITS;

	if (!test_bit(keycode, kp->input_devs->dev[dev]->key)) {
		if (mi->flags & GPIOKPF_PRINT_PHANTOM_KEYS)
			KEY_LOGI("gpiomatrix: phantom key %d, %d-%d (%d-%d) "
				"cleared\n", keycode, out, in,
				mi->output_gpios[out], mi->input_gpios[in]);
		__clear_bit(key_index, kp->keys_pressed);
	} else {
		if (mi->flags & GPIOKPF_PRINT_PHANTOM_KEYS)
			KEY_LOGI("gpiomatrix: phantom key %d, %d-%d (%d-%d) "
				"not cleared\n", keycode, out, in,
				mi->output_gpios[out], mi->input_gpios[in]);
	}
}
Beispiel #25
0
static void power_key_check_reset_work_func(struct work_struct *dummy)
{
	struct gpio_event_input_info *aa = gis;
	int pocket_mode = 0;
	KEY_LOGI("[PWR] %s\n", __func__);
	if ((aa->clear_hw_reset)) {
		if (aa->info.rrm1_mode) {
			printk(KERN_INFO "[KEY] Power key check in Lab Test RRM1 mode.\n");
			aa->clear_hw_reset();
		}
		else {
			
			pocket_mode = power_key_check_in_pocket();
			if (pocket_mode) {
				printk(KERN_INFO "[KEY] power_key_check_in_pocket = %d\n", pocket_mode);
				aa->clear_hw_reset();
			}
		}
	}
	else {
		KEY_LOGI("[PWR] No reset  clear function\n");
	}
	handle_power_key_reset(KEY_POWER, 1);
}
static void doubleshot_set_qty_irq(uint8_t disable)
{
	uint32_t i;
	static uint8_t already_disabled;
	KEY_LOGI("%s disable=%d, already_disabled=%d\n",
			__func__, disable, already_disabled);

	if (!(disable ^ already_disabled))
		return;

	already_disabled = disable;
	for (i = 0; i < KEYMAP_NUM_COLS; i++) {
		if (disable)
			disable_irq(gpio_to_irq(doubleshot_pmic_col_gpios[i]));
		else
			enable_irq(gpio_to_irq(doubleshot_pmic_col_gpios[i]));
	}
}
Beispiel #27
0
int gpio_event_input_func(struct gpio_event_input_devs *input_devs,
			struct gpio_event_info *info, void **data, int func)
{
	int ret;
	int i;
	unsigned long irqflags;
	struct gpio_event_input_info *di;
	struct gpio_input_state *ds = *data;
	struct kobject *keyboard_kobj;

	di = container_of(info, struct gpio_event_input_info, info);

	if (func == GPIO_EVENT_FUNC_SUSPEND) {
		if (ds->use_irq)
			for (i = 0; i < di->keymap_size; i++)
				disable_irq(gpio_to_irq(di->keymap[i].gpio));
		hrtimer_cancel(&ds->timer);
		return 0;
	}
	if (func == GPIO_EVENT_FUNC_RESUME) {
		spin_lock_irqsave(&ds->irq_lock, irqflags);
		if (ds->use_irq)
			for (i = 0; i < di->keymap_size; i++)
				enable_irq(gpio_to_irq(di->keymap[i].gpio));
		hrtimer_start(&ds->timer, ktime_set(0, 0), HRTIMER_MODE_REL);
		spin_unlock_irqrestore(&ds->irq_lock, irqflags);
		return 0;
	}

	if (func == GPIO_EVENT_FUNC_INIT) {
		if (ktime_to_ns(di->poll_time) <= 0)
			di->poll_time = ktime_set(0, 20 * NSEC_PER_MSEC);

		*data = ds = kzalloc(sizeof(*ds) + sizeof(ds->key_state[0]) *
					di->keymap_size, GFP_KERNEL);
		if (ds == NULL) {
			ret = -ENOMEM;
			KEY_LOGE("gpio_event_input_func: "
				"Failed to allocate private data\n");
			goto err_ds_alloc_failed;
		}
		ds->debounce_count = di->keymap_size;
		ds->input_devs = input_devs;
		ds->info = di;
		wake_lock_init(&ds->wake_lock, WAKE_LOCK_SUSPEND, "gpio_input");
		spin_lock_init(&ds->irq_lock);
		if (board_build_flag() == 0)
			ds->debug_log = 0;
		else
			ds->debug_log = 1;

		for (i = 0; i < di->keymap_size; i++) {
			int dev = di->keymap[i].dev;
			if (dev >= input_devs->count) {
				KEY_LOGE("gpio_event_input_func: bad device "
					"index %d >= %d for key code %d\n",
					dev, input_devs->count,
					di->keymap[i].code);
				ret = -EINVAL;
				goto err_bad_keymap;
			}
			input_set_capability(input_devs->dev[dev], di->type,
					     di->keymap[i].code);
			ds->key_state[i].ds = ds;
			ds->key_state[i].debounce = DEBOUNCE_UNKNOWN;
		}

		for (i = 0; i < di->keymap_size; i++) {
			ret = gpio_request(di->keymap[i].gpio, "gpio_kp_in");
			if (ret) {
				KEY_LOGE("gpio_event_input_func: gpio_request "
					"failed for %d\n", di->keymap[i].gpio);
				goto err_gpio_request_failed;
			}
			ret = gpio_direction_input(di->keymap[i].gpio);
			if (ret) {
				KEY_LOGE("gpio_event_input_func: "
					"gpio_direction_input failed for %d\n",
					di->keymap[i].gpio);
				goto err_gpio_configure_failed;
			}
		}

		if (di->setup_input_gpio)
			di->setup_input_gpio();

		ret = gpio_event_input_request_irqs(ds);

		keyboard_kobj = kobject_create_and_add("keyboard", NULL);
		if (keyboard_kobj == NULL) {
			KEY_LOGE("KEY_ERR: %s: subsystem_register failed\n", __func__);
			ret = -ENOMEM;
			return ret;
		}
		if (sysfs_create_file(keyboard_kobj, &dev_attr_vol_wakeup.attr))
			KEY_LOGE("gpio_event_input_func: sysfs_create_file "
					"return %d\n", ret);
		wakeup_bitmask = 0;
		set_wakeup = 0;

		spin_lock_irqsave(&ds->irq_lock, irqflags);
		ds->use_irq = ret == 0;

		KEY_LOGI("GPIO Input Driver: Start gpio inputs for %s%s in %s "
			"mode\n", input_devs->dev[0]->name,
			(input_devs->count > 1) ? "..." : "",
			ret == 0 ? "interrupt" : "polling");

		hrtimer_init(&ds->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
		ds->timer.function = gpio_event_input_timer_func;
		hrtimer_start(&ds->timer, ktime_set(0, 0), HRTIMER_MODE_REL);
		spin_unlock_irqrestore(&ds->irq_lock, irqflags);
		return 0;
	}

	ret = 0;
	spin_lock_irqsave(&ds->irq_lock, irqflags);
	hrtimer_cancel(&ds->timer);
	if (ds->use_irq) {
		for (i = di->keymap_size - 1; i >= 0; i--) {
			free_irq(gpio_to_irq(di->keymap[i].gpio),
				 &ds->key_state[i]);
		}
	}
	spin_unlock_irqrestore(&ds->irq_lock, irqflags);

	for (i = di->keymap_size - 1; i >= 0; i--) {
err_gpio_configure_failed:
		gpio_free(di->keymap[i].gpio);
err_gpio_request_failed:
		;
	}
err_bad_keymap:
	wake_lock_destroy(&ds->wake_lock);
	kfree(ds);
err_ds_alloc_failed:
	return ret;
}
Beispiel #28
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
}
Beispiel #29
0
int gpio_event_input_func(struct gpio_event_input_devs *input_devs,
			struct gpio_event_info *info, void **data, int func)
{
	int ret;
	int i;
	unsigned long irqflags;
	struct gpio_event_input_info *di;
	struct gpio_input_state *ds = *data;

	di = container_of(info, struct gpio_event_input_info, info);

	if (func == GPIO_EVENT_FUNC_SUSPEND) {
		if (ds->use_irq)
			for (i = 0; i < di->keymap_size; i++)
				disable_irq(gpio_to_irq(di->keymap[i].gpio));
#ifndef CONFIG_MFD_MAX8957
		hrtimer_cancel(&ds->timer);
#else
		for (i = 0; i < di->keymap_size; i++) {
			if (cancel_delayed_work_sync(&(ds->key_state[i].key_work)))
				KEY_LOGI("Cancel delayed debounce function of keycode:0x%X success.\n", ds->info->keymap[i].code);
			else
				KEY_LOGI("Cancel delayed debounce function of keycode:0x%X fail.\n", ds->info->keymap[i].code);
		}
#endif
		return 0;
	}
	if (func == GPIO_EVENT_FUNC_RESUME) {
		spin_lock_irqsave(&ds->irq_lock, irqflags);
		if (ds->use_irq)
			for (i = 0; i < di->keymap_size; i++)
				enable_irq(gpio_to_irq(di->keymap[i].gpio));
#ifndef CONFIG_MFD_MAX8957
		hrtimer_start(&ds->timer, ktime_set(0, 0), HRTIMER_MODE_REL);
#else
		queue_delayed_work(ki_queue, &(ds->key_state[0].key_work), 0);
#endif
		spin_unlock_irqrestore(&ds->irq_lock, irqflags);
		return 0;
	}

	if (func == GPIO_EVENT_FUNC_INIT) {
		if (ktime_to_ns(di->poll_time) <= 0)
			di->poll_time = ktime_set(0, 20 * NSEC_PER_MSEC);

		*data = ds = kzalloc(sizeof(*ds) + sizeof(ds->key_state[0]) *
					di->keymap_size, GFP_KERNEL);
		if (ds == NULL) {
			ret = -ENOMEM;
			KEY_LOGE("KEY_ERR: %s: "
				"Failed to allocate private data\n", __func__);
			goto err_ds_alloc_failed;
		}
		ds->debounce_count = di->keymap_size;
		ds->input_devs = input_devs;
		ds->info = di;
		wake_lock_init(&ds->wake_lock, WAKE_LOCK_SUSPEND, "gpio_input");

		spin_lock_init(&ds->irq_lock);
		if (board_build_flag() == 0)
			ds->debug_log = 0;
		else
			ds->debug_log = 1;

		for (i = 0; i < di->keymap_size; i++) {
			int dev = di->keymap[i].dev;
			if (dev >= input_devs->count) {
				KEY_LOGE("KEY_ERR: %s: bad device "
					"index %d >= %d for key code %d\n",
					__func__, dev, input_devs->count,
					di->keymap[i].code);
				ret = -EINVAL;
				goto err_bad_keymap;
			}
			input_set_capability(input_devs->dev[dev], di->type,
					     di->keymap[i].code);
			ds->key_state[i].ds = ds;
			ds->key_state[i].debounce = DEBOUNCE_UNKNOWN;
		}

		for (i = 0; i < di->keymap_size; i++) {
			ret = gpio_request(di->keymap[i].gpio, "gpio_kp_in");
			if (ret) {
				KEY_LOGE("KEY_ERR: %s: gpio_request "
					"failed for %d\n", __func__, di->keymap[i].gpio);
				goto err_gpio_request_failed;
			}
			ret = gpio_direction_input(di->keymap[i].gpio);
			if (ret) {
				KEY_LOGE("KEY_ERR: %s: "
					"gpio_direction_input failed for %d\n",
					__func__, di->keymap[i].gpio);
				goto err_gpio_configure_failed;
			}
		}

		if (di->setup_input_gpio)
			di->setup_input_gpio();
#ifdef CONFIG_MFD_MAX8957
		ki_queue = create_singlethread_workqueue("ki_queue");
#endif

		ret = gpio_event_input_request_irqs(ds);

		spin_lock_irqsave(&ds->irq_lock, irqflags);
		ds->use_irq = ret == 0;

		KEY_LOGI("GPIO Input Driver: Start gpio inputs for %s%s in %s "
			"mode\n", input_devs->dev[0]->name,
			(input_devs->count > 1) ? "..." : "",
			ret == 0 ? "interrupt" : "polling");

#ifndef CONFIG_MFD_MAX8957
		hrtimer_init(&ds->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
		ds->timer.function = gpio_event_input_timer_func;
		hrtimer_start(&ds->timer, ktime_set(0, 0), HRTIMER_MODE_REL);
#else
		for (i = 0; i < di->keymap_size; i++)
			INIT_DELAYED_WORK(&(ds->key_state[i].key_work), gpio_event_input_delayed_func);

		queue_delayed_work(ki_queue, &(ds->key_state[0].key_work), 0);
#endif
		spin_unlock_irqrestore(&ds->irq_lock, irqflags);
		return 0;
	}

	ret = 0;
	spin_lock_irqsave(&ds->irq_lock, irqflags);
#ifndef CONFIG_MFD_MAX8957
	hrtimer_cancel(&ds->timer);
#else
	for (i = 0; i < di->keymap_size; i++) {
		if (cancel_delayed_work_sync(&(ds->key_state[i].key_work)))
			KEY_LOGI("Cancel delayed debounce function of keycode:0x%X success.\n", ds->info->keymap[i].code);
		else
			KEY_LOGI("Cancel delayed debounce function of keycode:0x%X fail.\n", ds->info->keymap[i].code);
	}
#endif
	if (ds->use_irq) {
		for (i = di->keymap_size - 1; i >= 0; i--) {
			free_irq(gpio_to_irq(di->keymap[i].gpio),
				 &ds->key_state[i]);
		}
	}
	spin_unlock_irqrestore(&ds->irq_lock, irqflags);

	for (i = di->keymap_size - 1; i >= 0; i--) {
err_gpio_configure_failed:
		gpio_free(di->keymap[i].gpio);
err_gpio_request_failed:
		;
	}
err_bad_keymap:
	wake_lock_destroy(&ds->wake_lock);
	kfree(ds);
err_ds_alloc_failed:
	return ret;
}
Beispiel #30
0
static irqreturn_t gpio_event_input_irq_handler(int irq, void *dev_id)
{
	struct gpio_key_state *ks = dev_id;
	struct gpio_input_state *ds = ks->ds;
	int keymap_index = ks - ds->key_state;
	const struct gpio_event_direct_entry *key_entry;
	unsigned long irqflags;
	int pressed;

	KEY_LOGD("%s, irq=%d, use_irq=%d, keycode=0x%X\n", __func__, irq, ds->use_irq, ds->info->keymap[keymap_index].code);

	if (!ds->use_irq)
		return IRQ_HANDLED;

	key_entry = &ds->info->keymap[keymap_index];

	if (ds->info->debounce_time.tv64) {
		spin_lock_irqsave(&ds->irq_lock, irqflags);
		if (ks->debounce & DEBOUNCE_WAIT_IRQ) {
			ks->debounce = DEBOUNCE_UNKNOWN;
			if (ds->debounce_count++ == 0) {
				wake_lock(&ds->wake_lock);
#ifndef CONFIG_MFD_MAX8957
				hrtimer_start(
					&ds->timer, ds->info->debounce_time,
					HRTIMER_MODE_REL);
#else
				if (!queue_delayed_work(ki_queue, &(ks->key_work), KTIME_TO_JIFFIES(ds->info->debounce_time)))
					KEY_LOGI("Keycode: 0x%X has been queued already.\n", key_entry->code);
#endif
			}
			if (ds->info->flags & GPIOEDF_PRINT_KEY_DEBOUNCE)
				KEY_LOGD("gpio_event_input_irq_handler: "
					"key %x-%x, %d (%d) start debounce\n",
					ds->info->type, key_entry->code,
					keymap_index, key_entry->gpio);
		} else {
#ifndef CONFIG_MFD_MAX8957
			disable_irq_nosync(irq);
#endif
#ifdef KEYPAD_DEBUG
			if (ds->info->flags & GPIOEDF_PRINT_KEY_UNSTABLE)
				KEY_LOGD("Disable IRQ because of bouncing.");
#endif
			ks->debounce = DEBOUNCE_UNSTABLE;
		}
		spin_unlock_irqrestore(&ds->irq_lock, irqflags);
	} else {
		pressed = gpio_get_value(key_entry->gpio) ^
			!(ds->info->flags & GPIOEDF_ACTIVE_HIGH);
		if (ds->info->flags & GPIOEDF_PRINT_KEYS)
			KEY_LOGD("gpio_event_input_irq_handler: key %x-%x, %d "
				"(%d) changed to %d\n",
				ds->info->type, key_entry->code, keymap_index,
				key_entry->gpio, pressed);
		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]);
	}
	return IRQ_HANDLED;
}