void cypress_touchkey_change_thd(bool vbus_status)
{
#if !defined(CONFIG_SAMSUNG_PRODUCT_SHIP)
	printk(KERN_DEBUG "[Touchkey] VBUS_STATUS %d\n", vbus_status);
	printk(KERN_DEBUG "[Touchkey] CYPRESS_VBUS_STATUS %d\n", vbus_status);
#endif
	if (info)
		cypress_thd_change(vbus_status);
}
Пример #2
0
static void touch_FW_update_func(struct work_struct *work)
{
	int count = 0;
	int retry = NUM_OF_RETRY_UPDATE;
	u8 data;

	touchkey_update_status = 1;
#ifdef CONFIG_DEBUG_PRINTK
	printk(KERN_DEBUG "[TouchKey] %s start... !\n", __func__);
#else
	;
#endif

	disable_irq(info->irq);
	while (retry--) {
		if (ISSP_main() == 0) {
#ifdef CONFIG_DEBUG_PRINTK
			printk(KERN_DEBUG "[TOUCHKEY] Update success!\n");
#else
			;
#endif
			cypress_touchkey_con_hw(info, true);
			msleep(200);
			enable_irq(info->irq);

			data = i2c_smbus_read_byte_data(info->client, CYPRESS_FW_VER);
			info->fw_ver = data;
#ifdef CONFIG_DEBUG_PRINTK
			printk(KERN_DEBUG "[TouchKey] %s : FW Ver 0x%02x\n", __func__,
			data);
#else
			;
#endif

			cypress_thd_change(vbus_state);
			cypress_touchkey_auto_cal(info);
			touchkey_update_status = 0;
			count = i2c_smbus_write_byte_data(info->client,
					CYPRESS_GEN, CYPRESS_DATA_UPDATE);
			return;
		}
		cypress_touchkey_con_hw(info, false);
		msleep(300);
		cypress_touchkey_con_hw(info, true);
		msleep(200);
	}

	touchkey_update_status = -1;
#ifdef CONFIG_DEBUG_PRINTK
	printk(KERN_DEBUG "[TOUCHKEY]Touchkey_update fail\n");
#else
	;
#endif
	return;
}
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_touchkey_con_hw(info, true);
	msleep(110);
	cypress_thd_change(vbus_state);
	cypress_touchkey_auto_cal(info);

	FUNC_CALLED;
	enable_irq(info->irq);

	return ret;
}
/*
static int cypress_touchkey_led_on(struct cypress_touchkey_info *info)
{
	u8 buf = CYPRESS_LED_ON;

	int ret;
	ret = i2c_smbus_write_byte_data(info->client, CYPRESS_GEN, buf);

	return ret;
}

static int cypress_touchkey_led_off(struct cypress_touchkey_info *info)
{
	u8 buf = CYPRESS_LED_OFF;

	int ret;
	ret = i2c_smbus_write_byte_data(info->client, CYPRESS_GEN, buf);

	return ret;
}
*/
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 input_dev *input_dev;
	int ret = 0;
	int i;
	u8 buf[2] = {0,};
#ifdef TOUCHKEY_UPDATE_ONBOOT
	u8 mod_ver;
	u8 fw_ver;
#endif

	if (!i2c_check_functionality(adapter, I2C_FUNC_I2C))
		return -EIO;

	info = kzalloc(sizeof(struct cypress_touchkey_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;
	}

	info->client = client;
	info->input_dev = input_dev;
	info->pdata = client->dev.platform_data;
	info->irq = client->irq;

	memcpy(info->keycode, cypress_touchkey_keycode, ARRAY_SIZE(cypress_touchkey_keycode));
	snprintf(info->phys, sizeof(info->phys), "%s/input0", dev_name(&client->dev));
	input_dev->name = "sec_touchkey";
	input_dev->phys = info->phys;
	input_dev->id.bustype = BUS_I2C;
	input_dev->dev.parent = &client->dev;

	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);

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

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

	do_gettimeofday(&info->start);

	i2c_set_clientdata(client, info);
	cypress_touchkey_con_hw(info, true);

#ifdef TOUCHKEY_UPDATE_ONBOOT
	if (system_rev >= JANICE_R0_3) {
		mod_ver = JANICE_TOUCHKEY_HW03_MOD_VER;
		fw_ver = JANICE_TOUCHKEY_M_04_FW_VER;
	} else {
		mod_ver = JANICE_TOUCHKEY_HW02_MOD_VER;
		fw_ver = JANICE_TOUCHKEY_M_03_FW_VER;
	}
#endif

	ret = i2c_smbus_read_i2c_block_data(info->client, CYPRESS_FW_VER,
					ARRAY_SIZE(buf), buf);

	if (ret != ARRAY_SIZE(buf))
		dev_err(&client->dev, "failed to check FW ver.\n");

	else {
		info->fw_ver = buf[0];
		info->mod_ver = buf[1];
#if !defined(CONFIG_SAMSUNG_PRODUCT_SHIP)
		printk(KERN_DEBUG "[TouchKey] %s : Mod Ver 0x%02x\n", __func__,
			info->mod_ver);
		printk(KERN_DEBUG "[TouchKey] FW mod 0x%02x\n",
			info->fw_ver);
#endif
#ifdef TOUCHKEY_UPDATE_ONBOOT
		if ((info->mod_ver == mod_ver) && (info->fw_ver < fw_ver))
			touch_FW_update();
#endif
	}
	cypress_thd_change(vbus_state);
	cypress_touchkey_auto_cal(info);

#ifdef CONFIG_HAS_EARLYSUSPEND
	info->early_suspend.level = EARLY_SUSPEND_LEVEL_BLANK_SCREEN + 1;
	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->key_wq = create_singlethread_workqueue("cypress_key_wq");
	INIT_WORK(&info->key_work, cypress_touchkey_work);
	touchkey_wq = create_singlethread_workqueue("cypress_tsk_update_wq");

#ifdef CONFIG_LEDS_CLASS
	mutex_init(&info->touchkey_mutex);
	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;
	info->current_status = 1;
	ret = led_classdev_register(&client->dev, &info->leds);
	if (ret) {
		goto err_req_irq;
	}
#endif

	ret = request_threaded_irq(client->irq, NULL, cypress_touchkey_interrupt,
				   IRQF_TRIGGER_RISING, 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;
	}

	FUNC_CALLED;
	return 0;

err_req_irq:
#ifdef CONFIG_LEDS_CLASS
	destroy_workqueue(info->led_wq);
#endif
	destroy_workqueue(info->key_wq);
	destroy_workqueue(touchkey_wq);
	input_unregister_device(input_dev);
	input_dev = NULL;
err_reg_input_dev:
err_input_dev_alloc:
	input_free_device(input_dev);
	kfree(info);
err_mem_alloc:
	return ret;
}