static int cypress_touchkey_resume(struct device *dev)
{
	struct i2c_client *client = to_i2c_client(dev);
	struct cypress_touchkey_info *info = i2c_get_clientdata(client);
	int ret = 0;
	cypress_power_onoff(info, 1);
	if (info->pdata->gpio_led_en)
		cypress_touchkey_con_hw(info, true);
	msleep(50);

	cypress_touchkey_auto_cal(info);

	if (touchled_cmd_reversed) {
			touchled_cmd_reversed = 0;
			i2c_smbus_write_byte_data(info->client,
					CYPRESS_GEN, touchkey_led_status);
			printk(KERN_DEBUG "LED returned on\n");
		}


	enable_irq(info->irq);


	info->is_powering_on = false;
	return ret;
}
void ApplyTargetVDD(struct cypress_touchkey_info *info)
{
#if defined(CONFIG_MACH_KS01SKT) || defined(CONFIG_MACH_KS01KTT) || defined(CONFIG_MACH_KS01LGT)
	if (system_rev < 11)
		gpio_direction_input(GPIO_TOUCHKEY_SDA);
	else
		gpio_direction_input(GPIO_TOUCHKEY_SDA_2);
#elif defined(CONFIG_MACH_JACTIVESKT)
    gpio_direction_input(GPIO_TOUCHKEY_SDA_2);
#else /* CONFIG_SEC_H_PROJECT */
	gpio_direction_input(GPIO_TOUCHKEY_SDA_2);
#endif

#if defined(CONFIG_MACH_JF_ATT) || defined(CONFIG_MACH_JF_TMO) || defined(CONFIG_MACH_JF_EUR)
	if (system_rev < 9)
		gpio_direction_input(GPIO_TOUCHKEY_SCL);
	else
		gpio_direction_input(GPIO_TOUCHKEY_SCL_2);
#elif defined(CONFIG_MACH_KS01SKT) || defined(CONFIG_MACH_KS01KTT) || defined(CONFIG_MACH_KS01LGT)
	if (system_rev < 11)
		gpio_direction_input(GPIO_TOUCHKEY_SCL);
	else
		gpio_direction_input(GPIO_TOUCHKEY_SCL_2);
#elif defined(CONFIG_MACH_JACTIVESKT)
	gpio_direction_input(GPIO_TOUCHKEY_SCL_2);
#else /* CONFIG_SEC_H_PROJECT */
	gpio_direction_input(GPIO_TOUCHKEY_SCL_2);
#endif

	cypress_power_onoff(info, 1);
}
/*
 ********************* LOW-LEVEL ISSP SUBROUTINE SECTION ********************
 ****************************************************************************
 ****                        PROCESSOR SPECIFIC                          ****
 ****************************************************************************
 ****                      USER ATTENTION REQUIRED                       ****
 ****************************************************************************
 ApplyTargetVDD()
 Provide power to the target PSoC's Vdd pin through a GPIO.
 ****************************************************************************
*/
void ApplyTargetVDD(struct cypress_touchkey_info *info)
{

	gpio_direction_input(GPIO_TOUCHKEY_SDA);

	gpio_direction_input(GPIO_TOUCHKEY_SCL);

	cypress_power_onoff(info, 1);
}
static int cypress_touchkey_suspend(struct device *dev)
{
	struct i2c_client *client = to_i2c_client(dev);
	struct cypress_touchkey_info *info = i2c_get_clientdata(client);
	int ret = 0;

	info->is_powering_on = true;
	disable_irq(info->irq);
	if (info->pdata->gpio_led_en)
		cypress_touchkey_con_hw(info, false);
	cypress_power_onoff(info, 0);
	return ret;
}
void ApplyTargetVDD(void)
{
	gpio_direction_input(GPIO_TOUCHKEY_SDA);
#if defined(CONFIG_MACH_JF_ATT) || defined(CONFIG_MACH_JF_TMO) || defined(CONFIG_MACH_JF_EUR)
	if (system_rev < 9)
		gpio_direction_input(GPIO_TOUCHKEY_SCL);
	else
		gpio_direction_input(GPIO_TOUCHKEY_SCL_2);
#else
	if (system_rev < 10)
		gpio_direction_input(GPIO_TOUCHKEY_SCL);
	else
		gpio_direction_input(GPIO_TOUCHKEY_SCL_2);
#endif

	cypress_power_onoff(1);
}
void __init input_touchkey_init(void)
{
	tkey_int_request_gpio();

	gpio_tlmm_config(GPIO_CFG(GPIO_TOUCHKEY_I2C_SDA,
			0, GPIO_CFG_INPUT,
			GPIO_CFG_PULL_DOWN, GPIO_CFG_2MA), 1);
	gpio_tlmm_config(GPIO_CFG(GPIO_TOUCHKEY_I2C_SCL,
			0, GPIO_CFG_INPUT,
			GPIO_CFG_PULL_DOWN, GPIO_CFG_2MA), 1);
	gpio_tlmm_config(GPIO_CFG(GPIO_TKEY_INT, 0,
			GPIO_CFG_INPUT, GPIO_CFG_NO_PULL, GPIO_CFG_2MA), 1);
#ifdef CONFIG_KEYBOARD_CYPRESS_TOUCH
#if defined(CONFIG_MACH_SERRANO_ATT) ||defined(CONFIG_MACH_SERRANO_VZW) \
	||defined(CONFIG_MACH_SERRANO_SPR) ||defined(CONFIG_MACH_SERRANO_LRA)
		if (system_rev < BOARD_REV07)
	#elif defined(CONFIG_MACH_SERRANO_USC)
		if (system_rev < BOARD_REV05)
	#else
		if (system_rev >= BOARD_REV00)
	#endif
		{
			tkey_led_power(1);
			tc360_power(1);
			i2c_register_board_info(MSM_TOUCHKEY_I2C_BUS_ID,
						touchkey_i2c_devices_info,
						ARRAY_SIZE(touchkey_i2c_devices_info));
		} else {
			cypress_power_onoff(1);
			i2c_register_board_info(MSM_TOUCHKEY_I2C_BUS_ID,
						cypress_touchkey_i2c_devices_info,
						ARRAY_SIZE(cypress_touchkey_i2c_devices_info));
		}
#else
	tkey_led_power(1);
	tc360_power(1);
	i2c_register_board_info(MSM_TOUCHKEY_I2C_BUS_ID,
				touchkey_i2c_devices_info,
				ARRAY_SIZE(touchkey_i2c_devices_info));
	
#endif
	platform_add_devices(input_touchkey_devices,
				ARRAY_SIZE(input_touchkey_devices));	
}
/*
 ********************* LOW-LEVEL ISSP SUBROUTINE SECTION ********************
 ****************************************************************************
 ****                        PROCESSOR SPECIFIC                          ****
 ****************************************************************************
 ****                      USER ATTENTION REQUIRED                       ****
 ****************************************************************************
 RemoveTargetVDD()
 Remove power from the target PSoC's Vdd pin.
 ****************************************************************************
*/
void RemoveTargetVDD(struct cypress_touchkey_info *info)
{
	cypress_power_onoff(info, 0);
}
Example #8
0
/*
 ********************* LOW-LEVEL ISSP SUBROUTINE SECTION ********************
 ****************************************************************************
 ****                        PROCESSOR SPECIFIC                          ****
 ****************************************************************************
 ****                      USER ATTENTION REQUIRED                       ****
 ****************************************************************************
 RemoveTargetVDD()
 Remove power from the target PSoC's Vdd pin.
 ****************************************************************************
*/
void RemoveTargetVDD(void)
{
	cypress_power_onoff(0);
}
Example #9
0
void ApplyTargetVDD(void)
{
	gpio_direction_input(GPIO_TOUCHKEY_SDA);
	gpio_direction_input(GPIO_TOUCHKEY_SCL);
	cypress_power_onoff(1);
}
static int __devinit cypress_touchkey_probe(struct i2c_client *client,
				  const struct i2c_device_id *id)
{
	struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent);
	struct cypress_touchkey_platform_data *pdata =
					client->dev.platform_data;
	struct cypress_touchkey_info *info;
	struct input_dev *input_dev;
	int ret = 0;
	int i;
//	int retry = NUM_OF_RETRY_UPDATE;
	int ic_fw_ver;
	int error;

	struct device *sec_touchkey;

printk("[TKEY] %s _ %d\n",__func__,__LINE__);

	if (!i2c_check_functionality(adapter, I2C_FUNC_I2C))
		return -EIO;
#ifdef CONFIG_OF
	if (client->dev.of_node) {
		pdata = devm_kzalloc(&client->dev,
			sizeof(struct cypress_touchkey_platform_data),
				GFP_KERNEL);
		if (!pdata) {
			dev_info(&client->dev, "Failed to allocate memory\n");
			return -ENOMEM;
		}

		error = cypress_parse_dt(&client->dev, pdata);
		if (error)
			return error;
	} else
		pdata = client->dev.platform_data;

	cypress_request_gpio(pdata);
#endif

	info = kzalloc(sizeof(*info), GFP_KERNEL);
	if (!info) {
		dev_err(&client->dev, "fail to memory allocation.\n");
		goto err_mem_alloc;
	}

	input_dev = input_allocate_device();
	if (!input_dev) {
		dev_err(&client->dev, "fail to allocate input device.\n");
		goto err_input_dev_alloc;
	}

	client->irq = gpio_to_irq(pdata->gpio_int);

	info->client = client;
	info->input_dev = input_dev;
	info->pdata = pdata;
	info->irq = client->irq;
	info->touchkey_update_status = 0;
	
	input_dev->name = "sec_touchkey";
	input_dev->phys = info->phys;
	input_dev->id.bustype = BUS_I2C;
	input_dev->dev.parent = &client->dev;

	info->is_powering_on = true;
	cypress_power_onoff(info, 1);
	msleep(50);
	set_bit(EV_SYN, input_dev->evbit);
	set_bit(EV_KEY, input_dev->evbit);
	set_bit(EV_LED, input_dev->evbit);
	set_bit(LED_MISC, input_dev->ledbit);

	atomic_set(&info->keypad_enable, 1);

	for (i = 0; i < pdata->keycodes_size; i++) {
		info->keycode[i] = pdata->touchkey_keycode[i];
		set_bit(info->keycode[i], input_dev->keybit);
	}

	input_set_drvdata(input_dev, info);
	mutex_init(&info->touchkey_mutex);
	ret = input_register_device(input_dev);
	if (ret) {
		dev_err(&client->dev, "[TOUCHKEY] failed to register input dev (%d).\n",
			ret);
		goto err_reg_input_dev;
	}

	i2c_set_clientdata(client, info);

	if (info->pdata->gpio_led_en) {
		ret = gpio_request(info->pdata->gpio_led_en,
						"gpio_touchkey_led");
		if (ret < 0) {
			dev_err(&client->dev,
				"gpio_touchkey_led gpio_request is failed\n");
			goto err_gpio_request;
		}
		gpio_tlmm_config(GPIO_CFG(info->pdata->gpio_led_en, 0,
			GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL, GPIO_CFG_2MA), 1);

		cypress_touchkey_con_hw(info, true);
	}

	#ifdef USE_OPEN_CLOSE
	input_dev->open = cypress_input_open;
	input_dev->close = cypress_input_close;
	#endif

	dev_info(&info->client->dev, "gpio_to_irq IRQ %d\n",
			client->irq);

	ret = request_threaded_irq(client->irq, NULL,
			cypress_touchkey_interrupt,
			IRQF_TRIGGER_FALLING, client->dev.driver->name, info);
	if (ret < 0) {
		dev_err(&client->dev, "Failed to request IRQ %d (err: %d).\n",
				client->irq, ret);
		goto err_req_irq;
	}

#ifdef CONFIG_HAS_EARLYSUSPEND
		info->early_suspend.suspend = cypress_touchkey_early_suspend;
		info->early_suspend.resume = cypress_touchkey_late_resume;
		register_early_suspend(&info->early_suspend);
#endif /* CONFIG_HAS_EARLYSUSPEND */

	info->led_wq = create_singlethread_workqueue("cypress_touchkey");
	INIT_WORK(&info->led_work, cypress_touchkey_led_work);

	info->leds.name = TOUCHKEY_BACKLIGHT;
	info->leds.brightness = LED_FULL;
	info->leds.max_brightness = LED_FULL;
	info->leds.brightness_set = cypress_touchkey_brightness_set;

	ret = led_classdev_register(&client->dev, &info->leds);
	if (ret)
		goto err_req_irq;

#if defined(CONFIG_LCD_CONNECTION_CHECK)	//for SMD test
	if (is_lcd_attached() == 0) {
		disable_irq(client->irq);
		printk("[TSK] %s : is_lcd_attached()=0 \n",__func__);
	
	}
	else{
#endif
	msleep(20);
	ic_fw_ver = i2c_smbus_read_byte_data(client, CYPRESS_FW_VER);
	dev_err(&client->dev, "Touchkey FW Version: 0x%02x\n", ic_fw_ver);

#if defined(CONFIG_MACH_M2_ATT) || defined(CONFIG_MACH_M2_DCM) \
	|| defined(CONFIG_MACH_M2_SKT) || defined(CONFIG_MACH_M2_KDI)
	dev_err(&client->dev, "Touchkey FW Version: 0x%02x, system_rev: %x\n",
						ic_fw_ver, system_rev);
	if (0 /* ic_fw_ver < BIN_FW_VERSION */) {
		dev_err(&client->dev, "[TOUCHKEY] touchkey_update Start!!\n");
		disable_irq(client->irq);

		while (retry--) {
			if (ISSP_main() == 0) {
				dev_err(&client->dev, "[TOUCHKEY] Update success!\n");
				enable_irq(client->irq);
				break;
			}
			dev_err(&client->dev,
				"[TOUCHKEY] Touchkey_update failed... retry...\n");
		}

		if (retry <= 0) {
			if (info->pdata->gpio_led_en)
				cypress_touchkey_con_hw(info, false);
			msleep(300);
			dev_err(&client->dev, "[TOUCHKEY]Touchkey_update fail\n");
		}

		msleep(500);

		ic_fw_ver = i2c_smbus_read_byte_data(info->client,
				CYPRESS_FW_VER);
		dev_err(&client->dev,
			"[TouchKey] %s : FW Ver 0x%02x\n", __func__, ic_fw_ver);
	} else {
		dev_err(&client->dev, "[TouchKey] FW update does not need!\n");
	}
#endif
	cypress_touchkey_auto_cal(info);
#if defined(CONFIG_LCD_CONNECTION_CHECK)	//for SMD test
	}
#endif	
	sec_touchkey = device_create(sec_class, NULL, 0, NULL, "sec_touchkey");
	if (IS_ERR(sec_touchkey)) {
		pr_err("Failed to create device(sec_touchkey)!\n");
		goto err_sysfs;
	}
	dev_set_drvdata(sec_touchkey, info);


	if (device_create_file(sec_touchkey,
			&dev_attr_keypad_enable) < 0) {
		pr_err("Failed to create device file(%s)!\n",
			dev_attr_keypad_enable.attr.name);
		goto err_sysfs;
	}

	if (device_create_file(sec_touchkey,
			&dev_attr_touchkey_firm_update_status) < 0) {
		pr_err("Failed to create device file(%s)!\n",
			dev_attr_touchkey_firm_update.attr.name);
		goto err_sysfs;
	}

	if (device_create_file(sec_touchkey,
			&dev_attr_touchkey_firm_update) < 0) {
		pr_err("Failed to create device file(%s)!\n",
			dev_attr_touchkey_firm_update.attr.name);
		goto err_sysfs;
	}

	if (device_create_file(sec_touchkey,
			&dev_attr_touchkey_firm_version_panel) < 0) {
		pr_err("Failed to create device file(%s)!\n",
			dev_attr_touchkey_firm_version_panel.attr.name);
		goto err_sysfs;
	}

	if (device_create_file(sec_touchkey,
			&dev_attr_touchkey_firm_version_phone) < 0) {
		pr_err("Failed to create device file(%s)!\n",
			dev_attr_touchkey_firm_version_phone.attr.name);
		goto err_sysfs;
	}

	if (device_create_file(sec_touchkey,
			&dev_attr_touchkey_brightness) < 0) {
		pr_err("Failed to create device file(%s)!\n",
			dev_attr_touchkey_brightness.attr.name);
		goto err_sysfs;
	}

	if (device_create_file(sec_touchkey,
			&dev_attr_touch_sensitivity) < 0) {
		pr_err("Failed to create device file(%s)!\n",
			dev_attr_touch_sensitivity.attr.name);
		goto err_sysfs;
	}

	if (device_create_file(sec_touchkey,
			&dev_attr_touchkey_menu) < 0) {
		pr_err("Failed to create device file(%s)!\n",
			dev_attr_touchkey_menu.attr.name);
		goto err_sysfs;
	}

	if (device_create_file(sec_touchkey,
			&dev_attr_touchkey_back) < 0) {
		pr_err("Failed to create device file(%s)!\n",
			dev_attr_touchkey_back.attr.name);
		goto err_sysfs;
	}
#ifdef HOME_KEY_USE
	if (device_create_file(sec_touchkey,
			&dev_attr_touchkey_home) < 0) {
		pr_err("Failed to create device file(%s)!\n",
			dev_attr_touchkey_home.attr.name);
		goto err_sysfs;
	}
#endif

	if (device_create_file(sec_touchkey,
			&dev_attr_touchkey_raw_data0) < 0) {
		pr_err("Failed to create device file(%s)!\n",
			dev_attr_touchkey_raw_data0.attr.name);
		goto err_sysfs;
	}

	if (device_create_file(sec_touchkey,
			&dev_attr_touchkey_raw_data1) < 0) {
		pr_err("Failed to create device file(%s)!\n",
			dev_attr_touchkey_raw_data1.attr.name);
		goto err_sysfs;
	}
#ifdef HOME_KEY_USE
	if (device_create_file(sec_touchkey,
			&dev_attr_touchkey_raw_data2) < 0) {
		pr_err("Failed to create device file(%s)!\n",
			dev_attr_touchkey_raw_data2.attr.name);
		goto err_sysfs;
	}
#endif
	if (device_create_file(sec_touchkey, &dev_attr_touchkey_idac0) < 0) {
		pr_err("Failed to create device file(%s)!\n",
			dev_attr_touchkey_idac0.attr.name);
		goto err_sysfs;
	}

	if (device_create_file(sec_touchkey, &dev_attr_touchkey_idac1) < 0) {
		pr_err("Failed to create device file(%s)!\n",
			dev_attr_touchkey_idac1.attr.name);
		goto err_sysfs;
	}
#ifdef HOME_KEY_USE
	if (device_create_file(sec_touchkey, &dev_attr_touchkey_idac2) < 0) {
		pr_err("Failed to create device file(%s)!\n",
			dev_attr_touchkey_idac2.attr.name);
		goto err_sysfs;
	}
#endif
	if (device_create_file(sec_touchkey,
			&dev_attr_touchkey_threshold) < 0) {
		pr_err("Failed to create device file(%s)!\n",
			dev_attr_touchkey_threshold.attr.name);
		goto err_sysfs;
	}

	if (device_create_file(sec_touchkey,
			&dev_attr_touchkey_autocal_start) < 0) {
		pr_err("Failed to create device file(%s)!\n",
			dev_attr_touchkey_autocal_start.attr.name);
		goto err_sysfs;
	}

	if (device_create_file(sec_touchkey,
			&dev_attr_autocal_enable) < 0) {
		pr_err("Failed to create device file(%s)!\n",
			dev_attr_autocal_enable.attr.name);
		goto err_sysfs;
	}

	if (device_create_file(sec_touchkey,
			&dev_attr_autocal_stat) < 0) {
		pr_err("Failed to create device file(%s)!\n",
			dev_attr_autocal_stat.attr.name);
		goto err_sysfs;
	}

	if (device_create_file(sec_touchkey,
		&dev_attr_touchkey_brightness_level) < 0) {
		printk(KERN_ERR "Failed to create device file(%s)!\n",
		dev_attr_touchkey_brightness_level.attr.name);
		goto err_sysfs;
	}
	info->is_powering_on = false;
	return 0;

err_req_irq:
err_gpio_request:
	input_unregister_device(input_dev);
err_reg_input_dev:
	input_free_device(input_dev);
	input_dev = NULL;
	mutex_destroy(&info->touchkey_mutex);
err_input_dev_alloc:
	kfree(info);
err_sysfs:
	return -ENXIO;
err_mem_alloc:
	return ret;

}
/*
 ********************* LOW-LEVEL ISSP SUBROUTINE SECTION ********************
 ****************************************************************************
 ****                        PROCESSOR SPECIFIC                          ****
 ****************************************************************************
 ****                      USER ATTENTION REQUIRED                       ****
 ****************************************************************************
 RemoveTargetVDD()
 Remove power from the target PSoC's Vdd pin.
 ****************************************************************************
*/
void RemoveTargetVDD(struct cypress_touchkey_info *info)
{
	cypress_power_onoff(info, 0);
    msleep(1000); // 1 sec - can reduce time after measuring the VDD signal
}
void cypress_power_onoff(int onoff)
{
	printk(KERN_ERR "%s: power %s\n", __func__, onoff ? "on" : "off");

	#if defined(CONFIG_MACH_EXPRESS)
		if (system_rev > BOARD_REV02) {
	#else
		if (system_rev >= BOARD_REV00) {
	#endif
	static struct regulator *reg_l30;
	static struct regulator *reg_lvs5;
	int ret = 0;
		if (!reg_lvs5) {
			reg_lvs5 = regulator_get(NULL, "8917_lvs5");
			if (IS_ERR(reg_lvs5)) {
				pr_err("%s: could not get 8917_lvs5, rc = %ld\n",
					__func__, PTR_ERR(reg_lvs5));
				return;
			}
		}

		if (onoff) {
			ret = regulator_enable(reg_lvs5);
			if (ret) {
				pr_err("%s: enable lvs5 failed, rc=%d\n",
					__func__, ret);
				return;
			}
			pr_info("%s: tsp 1.8V on is finished.\n", __func__);
		} else {
			if (regulator_is_enabled(reg_lvs5))
				ret = regulator_disable(reg_lvs5);
			else
				printk(KERN_ERR
					"%s: rugulator LVS5(1.8V) is disabled\n",
						__func__);
			if (ret) {
				pr_err("%s: enable lvs5 failed, rc=%d\n",
					__func__, ret);
				return;
			}
			pr_info("%s: tsp 1.8V off is finished.\n", __func__);
		}


		if (!reg_l30) {
			reg_l30 = regulator_get(NULL, "8917_l30");
			if (IS_ERR(reg_l30)) {
				pr_err("%s: could not get 8917_l30, rc = %ld\n",
					__func__, PTR_ERR(reg_l30));
				return;
			}
			ret = regulator_set_voltage(reg_l30, 2800000, 2800000);
			if (ret) {
				pr_err("%s: unable to set l30 voltage to 3.3V\n",
					__func__);
				return;
			}
		}

		if (onoff) {
			ret = regulator_enable(reg_l30);
			if (ret) {
				pr_err("%s: enable l30 failed, rc=%d\n",
					__func__, ret);
				return;
			}
			pr_info("%s: tsp 3.3V on is finished.\n", __func__);
		} else {
			if (regulator_is_enabled(reg_l30))
				ret = regulator_disable(reg_l30);
			else
				printk(KERN_ERR
					"%s: rugulator L30(3.3V) is disabled\n",
						__func__);
			if (ret) {
				pr_err("%s: disable l30 failed, rc=%d\n",
					__func__, ret);
				return;
			}
			pr_info("%s: tsp 3.3V off is finished.\n", __func__);
		}

	} else {

		gpio_direction_output(GPIO_TKEY_LDO_EN, onoff);

	}

	if (onoff)
		msleep(40);
}

void cypress_touchkey_led_en(bool onoff)
{
	printk(KERN_ERR "%s: %s\n", __func__, onoff ? "on" : "off");

	#if defined(CONFIG_MACH_EXPRESS)
		if (system_rev > BOARD_REV01) {
	#else
		if (system_rev >= BOARD_REV00) {
	#endif
		int ret;
		static struct regulator *reg_l33;
		reg_l33 = regulator_get(NULL, "8917_l33");
		if (IS_ERR(reg_l33))
			pr_err("%s: could not get 8917_l33, rc = %ld\n",
				__func__, PTR_ERR(reg_l33));

		ret = regulator_set_voltage(reg_l33, 3300000, 3300000);
		if (ret) {
			pr_err("%s: unable to set l33 voltage to 3.3V\n",
			__func__);
		}

		if (onoff) {
			ret = regulator_enable(reg_l33);
			if (ret)
				pr_err("%s: enable l33 failed, rc=%d\n",
					__func__, ret);

			pr_info("TKEY_LED 3.3V on is finished.\n");
		} else {
			if (regulator_is_enabled(reg_l33))
				ret = regulator_disable(reg_l33);

			if (ret)
				pr_err("%s: disable l33 failed, rc=%d\n",
					__func__, ret);

			pr_info("TKEY_LED 3.3V off is finished.\n");
		}

	} else {
		if (onoff)
			gpio_set_value(GPIO_TKEY_LED, onoff ? 1 : 0);
	}

}

static u8 touchkey_keycode[] = {KEY_MENU, KEY_BACK};

static struct cypress_touchkey_platform_data cypress_touchkey_pdata = {
	.gpio_int = GPIO_TKEY_INT,
	.touchkey_led_en = cypress_touchkey_led_en,
	.touchkey_keycode = touchkey_keycode,
	.power_onoff = cypress_power_onoff,
};

static struct i2c_board_info touchkey_i2c_devices_info[] __initdata = {
	{
		I2C_BOARD_INFO("cypress_touchkey", 0x20),
		.platform_data = &cypress_touchkey_pdata,
		.irq			= MSM_GPIO_TO_INT(GPIO_TKEY_INT),
	},
};

static struct i2c_gpio_platform_data  cypress_touchkey_i2c_gpio_data = {
	.udelay			= 2,
	.sda_is_open_drain	= 0,
	.scl_is_open_drain	= 0,
	.scl_is_output_only	= 0,
};

static struct platform_device touchkey_i2c_gpio_device = {
	.name			= "i2c-gpio",
	.id			= MSM_TOUCHKEY_I2C_BUS_ID,
	.dev.platform_data	= &cypress_touchkey_i2c_gpio_data,
};

static struct platform_device *input_touchkey_devices[] __initdata = {
	&touchkey_i2c_gpio_device,
};

void __init input_touchkey_init(void)
{
	int ret;
	#if defined(CONFIG_MACH_EXPRESS)
		if (system_rev > BOARD_REV01) {
	#else
		if (system_rev >= BOARD_REV00) {
	#endif
		ret = gpio_request(GPIO_TKEY_LDO_EN, "touch_ldo_en");
		if (ret)
			printk(KERN_ERR "%s: err request LDO_EN: %d\n",
					__func__, ret);
	}

	#if defined(CONFIG_MACH_EXPRESS)
		if (system_rev > BOARD_REV01) {
	#else
		if (system_rev >= BOARD_REV00) {
	#endif
		gpio_tlmm_config(GPIO_CFG(GPIO_TKEY_I2C_SDA_REV02,
				0, GPIO_CFG_INPUT,
				GPIO_CFG_PULL_DOWN, GPIO_CFG_2MA), 1);
		gpio_tlmm_config(GPIO_CFG(GPIO_TKEY_I2C_SCL_REV02,
				0, GPIO_CFG_INPUT,
				GPIO_CFG_PULL_DOWN, GPIO_CFG_2MA), 1);

		cypress_touchkey_i2c_gpio_data.sda_pin =
					GPIO_TKEY_I2C_SDA_REV02;
		cypress_touchkey_i2c_gpio_data.scl_pin =
					GPIO_TKEY_I2C_SCL_REV02;


	} else {
		gpio_tlmm_config(GPIO_CFG(GPIO_TKEY_I2C_SDA,
				0, GPIO_CFG_INPUT,
				GPIO_CFG_PULL_DOWN, GPIO_CFG_2MA), 1);
		gpio_tlmm_config(GPIO_CFG(GPIO_TKEY_I2C_SCL,
				0, GPIO_CFG_INPUT,
				GPIO_CFG_PULL_DOWN, GPIO_CFG_2MA), 1);

		cypress_touchkey_i2c_gpio_data.sda_pin =
					GPIO_TKEY_I2C_SDA;
		cypress_touchkey_i2c_gpio_data.scl_pin =
					GPIO_TKEY_I2C_SCL;
	}

	ret = gpio_request(GPIO_TKEY_INT, "gpio_tkey_int");

	if (ret) {
		printk(KERN_ERR "%s: err request Tkey_int: %d\n",
				__func__, ret);
	}

	gpio_tlmm_config(GPIO_CFG(GPIO_TKEY_INT, 0,
			GPIO_CFG_INPUT, GPIO_CFG_NO_PULL, GPIO_CFG_2MA), 1);

	gpio_tlmm_config(GPIO_CFG(GPIO_TKEY_LDO_EN, 0, GPIO_CFG_OUTPUT,
				GPIO_CFG_NO_PULL, GPIO_CFG_2MA), 1);

	cypress_power_onoff(1);

	i2c_register_board_info(MSM_TOUCHKEY_I2C_BUS_ID,
				touchkey_i2c_devices_info,
				ARRAY_SIZE(touchkey_i2c_devices_info));

	platform_add_devices(input_touchkey_devices,
				ARRAY_SIZE(input_touchkey_devices));
}