static void cypress_touchkey_work(struct work_struct *work)
{
	struct cypress_touchkey_info *info = container_of(work,
		struct cypress_touchkey_info, key_work);
	struct timeval diff;
	int code;
	int press;

	if (info->keybuf == 0xFF) {
		dev_err(&info->client->dev, "keybuf: 0x%2X\n", info->keybuf);
		goto out;
	}

	press = !(info->keybuf & PRESS_BIT_MASK);
	code = (int)(info->keybuf & KEYCODE_BIT_MASK) - 1;

	if (code < 0) {
		dev_err(&info->client->dev, "not proper interrupt 0x%2X.\n",
			info->keybuf);
		if (info->press == 0)
			goto out;
		dev_err(&info->client->dev, "forced key released.\n");
		code = info->code;
		press = 0;
	}

	/* ignore invalid keycode, keypress value */
	if (code > 1 || press > 1) {
		dev_err(&info->client->dev, "invalid keycode or keypress 0x%2X.\n", info->keybuf);
		goto out;
	}

#if !defined(CONFIG_SAMSUNG_PRODUCT_SHIP)
	TOUCHKEY_LOG(info->keycode[code], press);
#endif

	if (touch_is_pressed && press) {
#if !defined(CONFIG_SAMSUNG_PRODUCT_SHIP)
		printk(KERN_DEBUG "[TouchKey]touchkey pressed but don't send event because touch is pressed.\n");
#endif
		goto out;
	}
	if (code == 0 && press == 1) {
		do_gettimeofday(&info->end);
		diff.tv_sec = info->end.tv_sec - info->start.tv_sec;
		diff.tv_usec = info->end.tv_usec - info->start.tv_usec;

		if (diff.tv_sec >= 0) {
			if (diff.tv_usec < 0) {
				(diff.tv_sec)--;
				diff.tv_usec = (info->end.tv_usec + 1000000L) - info->start.tv_usec;
			}

			/* If the interval of pressed menu-key is below 100msec */
			if (diff.tv_sec == 0 && diff.tv_usec < 100000) {
				dev_err(&info->client->dev, "Interval below 100msec:%ldusec\n", diff.tv_usec);
				info->start.tv_sec = info->end.tv_sec;
				info->start.tv_usec = info->end.tv_usec;
				goto out;
			}
		}
		/* refresh timeval */
		info->start.tv_sec = info->end.tv_sec;
		info->start.tv_usec = info->end.tv_usec;
	}

	info->code = code;
	info->press = press;
	input_report_key(info->input_dev, info->keycode[code], press);
	input_sync(info->input_dev);

out:
	enable_irq(info->irq);
	return;
}
static irqreturn_t cypress_touchkey_interrupt(int irq, void *dev_id)
{
	struct cypress_touchkey_info *info = dev_id;
	u8 buf[10] = {0,};
	int code;
	int press;
	int ret;

	if (!atomic_read(&info->keypad_enable)) {
		goto out;
	}

	ret = gpio_get_value(info->pdata->gpio_int);
	if (ret) {
		dev_err(&info->client->dev, "not real interrupt (%d).\n", ret);
		goto out;
	}

	if (info->is_powering_on) {
		dev_err(&info->client->dev, "%s: ignoring spurious boot "
					"interrupt\n", __func__);
		return IRQ_HANDLED;
	}

#if defined(SEC_TOUCHKEY_VERBOSE_DEBUG)
	ret = i2c_smbus_read_i2c_block_data(info->client,
			CYPRESS_GEN, ARRAY_SIZE(buf), buf);
	if (ret != ARRAY_SIZE(buf)) {
		dev_err(&info->client->dev, "interrupt failed with %d.\n", ret);
		goto out;
	}
	print_hex_dump(KERN_DEBUG, "cypress_touchkey: ",
			DUMP_PREFIX_OFFSET, 32, 1, buf, 10, false);
#else
	buf[0] = i2c_smbus_read_byte_data(info->client, CYPRESS_GEN);
	if (buf[0] < 0) {
		dev_err(&info->client->dev, "interrupt failed with %d.\n", ret);
		goto out;
	}
#endif
	press = !(buf[0] & PRESS_BIT_MASK);
	code = (int)(buf[0] & KEYCODE_BIT_MASK) - 1;
	dev_dbg(&info->client->dev,
		"[TouchKey]press=%d, code=%d\n", press, code);

	if (code < 0) {
		dev_err(&info->client->dev,
				"not profer interrupt 0x%2X.\n", buf[0]);
		goto out;
	}

#if defined(SEC_TOUCHKEY_DEBUG)
	TOUCHKEY_LOG(info->keycode[code], press);
#endif

//	if (touch_is_pressed && press) {
//		printk(KERN_ERR "[TouchKey] don't send event because touch is pressed.\n");
//		printk(KERN_ERR "[TouchKey] touch_pressed = %d\n",
//							touch_is_pressed);
//	} else {
		input_report_key(info->input_dev, info->keycode[code], press);
		input_sync(info->input_dev);
//	}

out:
	return IRQ_HANDLED;
}