2 * For CYPRESS CY8C20236-24LKX1 TouchSensor driver
4 * Copyright (C) 2010 Samsung Electronics Co.Ltd
5 * Author: Junkyeong Kim <jk0430.kim@samsung.com>
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation.
13 #include <linux/module.h>
14 #include <linux/firmware.h>
15 #include <linux/init.h>
16 #include <linux/i2c.h>
17 #include <linux/i2c/cypress_touchkey.h>
18 #include <linux/interrupt.h>
19 #include <linux/input.h>
20 #include <linux/irq.h>
21 #include <linux/workqueue.h>
22 #include <linux/delay.h>
23 #include <linux/gpio.h>
24 #include <linux/slab.h>
25 #include <linux/pm_runtime.h>
27 #include <plat/gpio-cfg.h>
33 #define CYPRESS_TK_CONTROL_REG 0x00
34 #define CYPRESS_TK_KEYCODE_REG 0x00
35 #define CYPRESS_TK_FW_VERSION 0x01
36 #define CYPRESS_TK_MD_VERSION 0x02
39 #define KEYCODE_VALUE 0x07
40 #define UPDOWN_EVENT 0x08
41 #define ESD_STATE_BIT 0x10
44 #define PRESS_LED_TIME 500
45 #define WAKEUP_LED_TIME 5000
48 struct i2c_client *client;
49 struct input_dev *input_dev;
50 struct work_struct event_work;
51 struct cypress_platform_data *pdata;
55 unsigned char last_key;
57 /* The framebuffer notifier block */
58 struct notifier_block fb_notif;
61 static struct i2c_driver cypress_tk_driver;
62 struct cypress_data *global_cypress_data;
64 static struct timer_list cypress_led_off_timer;
65 struct work_struct cypress_led_onoff_work;
67 int cypress_key_onoff;
68 int cypress_key_debug;
70 int cypress_led_onoff;
71 int cypress_led_timer_start;
72 u8 cypress_fw_ver, cypress_md_ver;
74 static void cypress_hardware_reset(struct i2c_client *client)
76 struct cypress_data *data = i2c_get_clientdata(client);
78 if (cypress_key_onoff == 0)
81 disable_irq(client->irq);
83 s3c_gpio_cfgpin(data->pdata->pin->gpio_sda, S3C_GPIO_OUTPUT);
84 s3c_gpio_cfgpin(data->pdata->pin->gpio_scl, S3C_GPIO_OUTPUT);
85 s3c_gpio_cfgpin(data->pdata->pin->gpio_int, S3C_GPIO_OUTPUT);
87 s3c_gpio_setpull(data->pdata->pin->gpio_sda, S3C_GPIO_PULL_NONE);
88 s3c_gpio_setpull(data->pdata->pin->gpio_scl, S3C_GPIO_PULL_NONE);
89 s3c_gpio_setpull(data->pdata->pin->gpio_int, S3C_GPIO_PULL_NONE);
91 gpio_direction_output(data->pdata->pin->gpio_sda, 0);
92 gpio_direction_output(data->pdata->pin->gpio_scl, 0);
93 gpio_direction_output(data->pdata->pin->gpio_int, 0);
95 data->pdata->power_pin(0);
97 /* i2c pin pull up controled by touch chip */
98 s3c_gpio_setpull(data->pdata->pin->gpio_int, S3C_GPIO_PULL_UP);
100 s3c_gpio_cfgpin(data->pdata->pin->gpio_sda, S3C_GPIO_SFN(2));
101 s3c_gpio_cfgpin(data->pdata->pin->gpio_scl, S3C_GPIO_SFN(2));
102 s3c_gpio_cfgpin(data->pdata->pin->gpio_int, S3C_GPIO_SFN(0xf));
105 data->pdata->power_pin(1);
107 enable_irq(client->irq);
109 printk(KERN_INFO "[TK] %s excute\n", __func__);
112 static int cypress_i2c_read(struct i2c_client *client, u8 reg, u8 *val, int len)
114 struct i2c_msg msg[1];
117 msg->addr = client->addr;
118 msg->flags = client->flags | I2C_M_RD;
120 msg->buf = (char *)val;
122 ret = i2c_transfer(client->adapter, msg, 1);
124 dev_err(&client->dev, "[TK][R] i2c transfer failed. ret:%d, reg:%02x, val:%02x\n",
127 /* if failed, try one moer time */
128 ret = i2c_transfer(client->adapter, msg, 1);
130 dev_err(&client->dev, "[TK][R] i2c transfer failed 2. ret:%d, reg:%02x, val:%02x\n",
133 cypress_hardware_reset(client);
140 static int cypress_i2c_write(struct i2c_client *client, u8 reg, u8 *val, int len)
142 struct i2c_msg msg[1];
145 msg->addr = client->addr;
146 msg->flags = I2C_M_WR;
148 msg->buf = (char *)val;
150 ret = i2c_transfer(client->adapter, msg, 1);
152 dev_err(&client->dev, "[TK][W] i2c transfer failed. ret:%d, reg:%02x, val:%02x\n",
155 /* if failed, try one moer time */
156 ret = i2c_transfer(client->adapter, msg, 1);
158 dev_err(&client->dev, "[TK][W] i2c transfer failed 2. ret:%d, reg:%02x, val:%02x\n",
161 cypress_hardware_reset(client);
168 int cypress_debug_on(struct i2c_client *client)
171 unsigned char buf = 0x40;
173 ret = cypress_i2c_write(client, CYPRESS_TK_CONTROL_REG, &buf, 1);
175 dev_err(&client->dev, "[TK] %s: error\n", __func__);
181 void cypress_tk_led_on(struct i2c_client *client)
184 unsigned char buf = 0x1;
186 ret = cypress_i2c_write(client, CYPRESS_TK_CONTROL_REG, &buf, 1);
188 dev_err(&client->dev, "[TK] %s: error\n", __func__);
191 void cypress_tk_led_off(struct i2c_client *client)
194 unsigned char buf = 0x2;
196 ret = cypress_i2c_write(client, CYPRESS_TK_CONTROL_REG, &buf, 1);
198 dev_err(&client->dev, "[TK] %s: error\n", __func__);
202 static void cypress_led_onoff_worker(struct work_struct *work)
204 struct i2c_client *client = global_cypress_data->client;
207 if (cypress_led_onoff == 1) {
209 cypress_tk_led_on(client);
210 if (cypress_led_timer_start != 1) {
211 cypress_led_off_timer.expires = (jiffies + (400)); /* 2sec */
212 add_timer(&cypress_led_off_timer);
213 cypress_led_timer_start = 1;
217 cypress_tk_led_off(client);
221 static void cypress_led_off_timer_handler(unsigned long timer_data)
223 if ((cypress_key_onoff == 1) && (cypress_led_onoff == 1)) {
224 cypress_led_onoff = 0;
225 if (!work_pending(&cypress_led_onoff_work))
226 schedule_work(&cypress_led_onoff_work);
228 cypress_led_timer_start = 0;
231 void cypress_tk_led_onoff_function(int flag)
233 struct i2c_client *client;
235 if (global_cypress_data == NULL)
238 client = global_cypress_data->client;
240 if (cypress_key_onoff == 0)
243 if (cypress_irq_flag == 0)
246 if (cypress_led_onoff == 0) {
248 cypress_led_onoff = 1;
249 if (!work_pending(&cypress_led_onoff_work))
250 schedule_work(&cypress_led_onoff_work);
252 } else if (cypress_led_onoff == 1) {
254 if (cypress_led_timer_start == 1) {
255 del_timer(&cypress_led_off_timer);
256 cypress_led_off_timer.expires = (jiffies + (400)); /* 2sec */
257 add_timer(&cypress_led_off_timer);
259 } else if (flag == 0) {
260 cypress_led_onoff = 0;
261 del_timer(&cypress_led_off_timer);
262 cypress_led_timer_start = 0;
263 if (!work_pending(&cypress_led_onoff_work))
264 schedule_work(&cypress_led_onoff_work);
268 EXPORT_SYMBOL(cypress_tk_led_onoff_function);
270 void cypress_touchkey_irq_flag_function(int flag)
272 if (global_cypress_data == NULL)
276 if (global_cypress_data->pdata->led_pin)
277 global_cypress_data->pdata->led_pin(0);
278 cypress_tk_led_onoff_function(0);
279 cypress_irq_flag = 0;
280 } else if (flag == 1) {
281 cypress_irq_flag = 1;
282 if (global_cypress_data->pdata->led_pin)
283 global_cypress_data->pdata->led_pin(1);
284 cypress_tk_led_onoff_function(1);
288 EXPORT_SYMBOL(cypress_touchkey_irq_flag_function);
290 static void cypress_tk_input_read(struct cypress_data *data)
292 struct i2c_client *client = data->client;
293 const struct cypress_platform_data *pdata = data->pdata;
294 struct input_dev *input = data->input_dev;
295 unsigned int value, updown;
301 ret = cypress_i2c_read(client, CYPRESS_TK_KEYCODE_REG, &buffer, 1);
303 dev_err(&client->dev, "[TK] %s: error\n", __func__);
307 if (cypress_irq_flag == 0) {
308 if (cypress_key_debug) {
309 printk(KERN_INFO "[TK] %s excute. But do not report (cypress_irq_flag = %d)\n",
310 __func__, cypress_irq_flag);
315 if (buffer & ESD_STATE_BIT) {
316 if (cypress_key_debug)
317 printk(KERN_INFO "[TK] ESD_STATE_BIT setting.(buffer = 0x%x)\n", buffer);
318 /* release if pressed */
319 cypress_hardware_reset(client);
320 /* read and confirm it's good or bad - jk */
324 value = buffer & KEYCODE_VALUE;
325 updown = (buffer & UPDOWN_EVENT) >> 3; /* 0 = press, 1 = release */
326 key = pdata->keycode[value];
328 if (updown) { /* release */
330 key = data->last_key;
333 data->last_key = key;
336 input_report_key(input, key, pushed);
339 cypress_tk_led_onoff_function(1);
341 if (cypress_key_debug) {
342 printk(KERN_INFO "[TK] value:%02x, key:%d, updown:%02x,pushed:%d\n",
343 value, key, updown, pushed);
347 static void cypress_tk_irq_worker(struct work_struct *work)
349 struct cypress_data *data = container_of(work, struct cypress_data, event_work);
351 cypress_tk_input_read(data);
354 static irqreturn_t cypress_tk_interrupt(int irq, void *dev_id)
356 struct cypress_data *data = dev_id;
358 if (!work_pending(&data->event_work))
359 schedule_work(&data->event_work);
364 void cypress_tk_on(struct cypress_data *data)
367 cypress_key_onoff = 1;
369 s3c_gpio_setpull(data->pdata->pin->gpio_int, S3C_GPIO_PULL_UP);
371 s3c_gpio_cfgpin(data->pdata->pin->gpio_sda, S3C_GPIO_SFN(2));
372 s3c_gpio_cfgpin(data->pdata->pin->gpio_scl, S3C_GPIO_SFN(2));
373 s3c_gpio_cfgpin(data->pdata->pin->gpio_int, S3C_GPIO_SFN(0xf));
376 data->pdata->power_pin(1);
379 void cypress_tk_off(struct cypress_data *data)
382 cypress_key_onoff = 0;
384 s3c_gpio_cfgpin(data->pdata->pin->gpio_sda, S3C_GPIO_OUTPUT);
385 s3c_gpio_cfgpin(data->pdata->pin->gpio_scl, S3C_GPIO_OUTPUT);
386 s3c_gpio_cfgpin(data->pdata->pin->gpio_int, S3C_GPIO_OUTPUT);
388 s3c_gpio_setpull(data->pdata->pin->gpio_sda, S3C_GPIO_PULL_NONE);
389 s3c_gpio_setpull(data->pdata->pin->gpio_scl, S3C_GPIO_PULL_NONE);
390 s3c_gpio_setpull(data->pdata->pin->gpio_int, S3C_GPIO_PULL_NONE);
392 gpio_direction_output(data->pdata->pin->gpio_sda, 0);
393 gpio_direction_output(data->pdata->pin->gpio_scl, 0);
394 gpio_direction_output(data->pdata->pin->gpio_int, 0);
395 data->pdata->power_pin(0);
399 static void cypress_tk_power_up(struct cypress_data *data)
401 if (data->pdata->power_pin)
402 data->pdata->power_pin(0);
405 if (data->pdata->cfg_pin)
406 data->pdata->cfg_pin();
411 if (data->pdata->power_pin)
412 data->pdata->power_pin(1);
414 if (data->pdata->led_pin)
415 data->pdata->led_pin(1);
418 cypress_key_onoff = 1;
421 static ssize_t cypress_firmware_show(struct device *dev,
422 struct device_attribute *attr, char *buf)
424 struct cypress_data *data = dev_get_drvdata(dev);
425 struct i2c_client *client = data->client;
429 err = cypress_i2c_read(client, CYPRESS_TK_KEYCODE_REG, buffer, 3);
431 dev_err(&client->dev, "%s: error\n", __func__);
433 printk(KERN_INFO "[TK] MCS-5080 TK Firmware version = 0x%x, Module version = 0x%x\n",
434 buffer[CYPRESS_TK_FW_VERSION], buffer[CYPRESS_TK_MD_VERSION]);
440 void cypress_tk_fw_pin_setting(struct cypress_data *data, int flag)
442 struct i2c_client *client = data->client;
444 struct cypress_platform_data *pdata = data->pdata;
446 int gpio_intr = pdata->pin->gpio_int;
447 int gpio_sda = pdata->pin->gpio_sda;
448 int gpio_scl = pdata->pin->gpio_scl;
451 s3c_gpio_cfgpin(gpio_sda, S3C_GPIO_OUTPUT);
452 s3c_gpio_cfgpin(gpio_scl, S3C_GPIO_OUTPUT);
453 s3c_gpio_cfgpin(gpio_intr, S3C_GPIO_OUTPUT);
455 s3c_gpio_setpull(gpio_sda, S3C_GPIO_PULL_NONE);
456 s3c_gpio_setpull(gpio_scl, S3C_GPIO_PULL_NONE);
457 s3c_gpio_setpull(gpio_intr, S3C_GPIO_PULL_NONE);
459 data->pdata->power_pin(0);
461 gpio_direction_output(gpio_sda, 0);
462 gpio_direction_output(gpio_scl, 0);
463 gpio_direction_output(gpio_intr, 0);
465 s3c_gpio_cfgpin(gpio_sda, S3C_GPIO_OUTPUT);
466 s3c_gpio_cfgpin(gpio_scl, S3C_GPIO_OUTPUT);
467 s3c_gpio_cfgpin(gpio_intr, S3C_GPIO_OUTPUT);
469 s3c_gpio_setpull(gpio_sda, S3C_GPIO_PULL_NONE);
470 s3c_gpio_setpull(gpio_scl, S3C_GPIO_PULL_NONE);
471 s3c_gpio_setpull(gpio_intr, S3C_GPIO_PULL_NONE);
473 data->pdata->power_pin(0);
475 gpio_direction_output(gpio_sda, 0);
476 gpio_direction_output(gpio_scl, 0);
477 gpio_direction_output(gpio_intr, 0);
482 s3c_gpio_setpull(gpio_sda, S3C_GPIO_PULL_UP);
483 s3c_gpio_setpull(gpio_scl, S3C_GPIO_PULL_UP);
484 s3c_gpio_setpull(gpio_intr, S3C_GPIO_PULL_UP);
486 s3c_gpio_cfgpin(gpio_sda, S3C_GPIO_SFN(2));
487 s3c_gpio_cfgpin(gpio_scl, S3C_GPIO_SFN(2));
488 s3c_gpio_cfgpin(gpio_intr, S3C_GPIO_SFN(0xf));
492 data->pdata->power_pin(1);
496 static ssize_t cypress_firmware_store(struct device *dev,
497 struct device_attribute *attr, const char *buf, size_t count)
499 struct cypress_data *data = dev_get_drvdata(dev);
500 struct i2c_client *client = data->client;
505 sscanf(buf, "%d", &type);
508 printk(KERN_INFO "[TK] cypress touch key firmware update start\n");
509 disable_irq(client->irq);
510 cypress_key_onoff = 0;
511 cypress_tk_fw_pin_setting(data, 1);
513 cypress_tk_fw_pin_setting(data, 0);
514 cypress_key_onoff = 1;
515 enable_irq(client->irq);
517 printk(KERN_INFO "[TK] cypress touch key firmware update success\n");
519 printk(KERN_INFO "[TK] cypress touch key firmware update fail(ret = %d)\n", ret);
521 printk(KERN_INFO "[TK] wrong command\n");
526 static ssize_t sysfs_cypress_test_show(struct device *dev,
527 struct device_attribute *attr, char *buf)
529 printk(KERN_INFO "[TK] cypress_key_onoff = %d\n", cypress_key_onoff);
530 printk(KERN_INFO "[TK] cypress_led_onoff = %d\n", cypress_led_onoff);
531 printk(KERN_INFO "[TK] cypress_key_debug = %d\n", cypress_key_debug);
532 printk(KERN_INFO "[TK] cypress_irq_flag = %d\n", cypress_irq_flag);
533 printk(KERN_INFO "[TK] fw_ver = %d, md_ver = %d\n", cypress_fw_ver, cypress_md_ver);
537 static ssize_t sysfs_cypress_test(struct device *dev,
538 struct device_attribute *attr, const char *buf, size_t count)
540 struct cypress_data *data = dev_get_drvdata(dev);
541 struct i2c_client *client = data->client;
544 sscanf(buf, "%d", &type);
546 if (type == 0) { /* touch_key off */
547 printk(KERN_INFO "[TK] touch key off\n");
549 data->pdata->power_pin(0);
550 cypress_key_onoff = 0;
552 } else if (type == 1) { /* touch_key on */
553 printk(KERN_INFO "[TK] touch key on\n");
555 data->pdata->power_pin(1);
556 cypress_key_onoff = 1;
558 } else if (type == 2) { /* key led_off */
559 printk(KERN_INFO "[TK] key led off\n");
561 if (cypress_led_onoff == 1) {
562 cypress_tk_led_off(client);
563 cypress_led_onoff = 0;
565 printk(KERN_INFO "[TK] key led already off\n");
567 } else if (type == 3) { /* key led_on */
568 printk(KERN_INFO "[TK] key led on\n");
570 if (cypress_led_onoff == 0) {
571 cypress_tk_led_on(client);
572 cypress_led_onoff = 1;
574 printk(KERN_INFO "[TK] key led already on\n");
576 } else if (type == 4) { /* key led_off by workqueue */
577 printk(KERN_INFO "[TK] key led off\n");
579 if (cypress_led_onoff == 1) {
580 cypress_led_onoff = 0;
581 if (!work_pending(&cypress_led_onoff_work))
582 schedule_work(&cypress_led_onoff_work);
584 printk(KERN_INFO "[TK] key led already off\n");
586 } else if (type == 5) { /* key led_on by workqueue */
587 printk(KERN_INFO "[TK] key led on\n");
589 if (cypress_led_onoff == 0) {
590 cypress_led_onoff = 1;
591 if (!work_pending(&cypress_led_onoff_work))
592 schedule_work(&cypress_led_onoff_work);
594 printk(KERN_INFO "[TK] key led already on\n");
596 } else if (type == 6) { /* key led_power off */
597 printk(KERN_INFO "[TK] key led power off\n");
598 if (data->pdata->led_pin)
599 data->pdata->led_pin(0);
600 } else if (type == 7) { /* key led_power on */
601 printk(KERN_INFO "[TK] key led power on\n");
602 if (data->pdata->led_pin)
603 data->pdata->led_pin(1);
605 printk(KERN_INFO "[TSP] sysfs_qt602240_debug wrong command\n");
610 static ssize_t cypress_debug_store(struct device *dev,
611 struct device_attribute *attr, const char *buf, size_t count)
615 sscanf(buf, "%d", &type);
618 printk(KERN_INFO "[TK] cypress_key_debug off\n");
619 cypress_key_debug = 0;
620 } else if (type == 1) {
621 printk(KERN_INFO "[TK] cypress_key_debug on\n");
622 cypress_key_debug = 1;
627 static ssize_t cypress_debug_show(struct device *dev,
628 struct device_attribute *attr, char *buf)
630 printk(KERN_INFO "[TK] cypress_key_debug = %d\n", cypress_key_debug);
635 static DEVICE_ATTR(fw_update, 0664, cypress_firmware_show, cypress_firmware_store);
636 static DEVICE_ATTR(test, 0664, sysfs_cypress_test_show, sysfs_cypress_test);
637 static DEVICE_ATTR(debug, 0664, cypress_debug_show, cypress_debug_store);
639 static struct attribute *cypress_attrs[] = {
640 &dev_attr_fw_update.attr,
642 &dev_attr_debug.attr,
646 static const struct attribute_group cypress_attr_group = {
647 .attrs = cypress_attrs,
650 static void cypress_tk_enable(struct i2c_client *client)
652 struct cypress_data *data = i2c_get_clientdata(client);
654 if (cypress_key_onoff == 1)
657 /* Enable the device first */
658 if (data->pdata->power_pin)
659 data->pdata->power_pin(1);
661 /* Enable irq again */
662 enable_irq(client->irq);
664 /* Set touchkey state as enable */
665 cypress_key_onoff = 1;
667 /* LED On with power */
668 cypress_touchkey_irq_flag_function(1);
672 static void cypress_tk_disable(struct i2c_client *client)
674 struct cypress_data *data = i2c_get_clientdata(client);
676 if (cypress_key_onoff == 0)
679 /* LED Off with power */
680 cypress_touchkey_irq_flag_function(0);
683 disable_irq(client->irq);
685 /* Disable the work */
686 cancel_work_sync(&data->event_work);
687 cancel_work_sync(&cypress_led_onoff_work);
688 if (cypress_led_onoff == 1)
689 del_timer(&cypress_led_off_timer);
690 cypress_led_onoff = 0;
692 /* Finally turn off the power */
693 if (data->pdata->power_pin)
694 data->pdata->power_pin(0);
696 /* Set touchkey state as diable */
697 cypress_key_onoff = 0;
701 static int cypress_tk_fb_notifier_callback(struct notifier_block *self,
702 unsigned long event, void *fb_evdata)
704 struct cypress_data *data = container_of(self, struct cypress_data, fb_notif);
705 struct i2c_client *client = data->client;
706 struct fb_event *evdata = fb_evdata;
709 /* If we aren't interested in this event, skip it immediately ... */
710 if (event != FB_EVENT_BLANK)
713 blank = *(int *)evdata->data;
717 cypress_tk_enable(client);
720 cypress_tk_disable(client);
729 static int __devinit cypress_tk_probe(struct i2c_client *client, const struct i2c_device_id *id)
731 struct cypress_data *data;
732 struct cypress_platform_data *pdata = client->dev.platform_data;
733 struct input_dev *input_dev;
736 if (!client->dev.platform_data)
739 data = kzalloc(sizeof(struct cypress_data), GFP_KERNEL);
740 global_cypress_data = data;
742 input_dev = input_allocate_device();
743 if (!data || !input_dev) {
744 dev_err(&client->dev, "[TK] Failed to allocate memory\n");
749 INIT_WORK(&data->event_work, cypress_tk_irq_worker);
750 data->client = client;
751 data->input_dev = input_dev;
753 data->irq = client->irq;
754 data->type = id->driver_data;
756 INIT_WORK(&cypress_led_onoff_work, cypress_led_onoff_worker);
758 /* set up input device driver configuration */
759 __set_bit(EV_ABS, input_dev->evbit);
760 __set_bit(EV_KEY, input_dev->evbit);
761 for (i = 0; i < pdata->keycode_size; i++) {
762 if (pdata->keycode_setbit[i] == 1)
763 __set_bit(pdata->keycode[i], input_dev->keybit);
766 input_dev->name = "CYPRESS Touchkey"; /* CY8C20236-24LKX1 */
767 input_dev->id.bustype = BUS_I2C;
768 input_dev->dev.parent = &client->dev;
769 input_set_drvdata(input_dev, data);
772 ret = request_irq(client->irq, cypress_tk_interrupt, IRQF_TRIGGER_FALLING,
773 "cypress_tk_input", data);
775 dev_err(&client->dev, "[TK] Failed to register interrupt\n");
779 /* register input device driver */
780 ret = input_register_device(data->input_dev);
782 dev_err(&client->dev, "[TK] Failed to input_register_device\n");
785 /* set i2c client driver data */
786 i2c_set_clientdata(client, data);
788 /* set up physical characteristics */
789 cypress_tk_power_up(data);
791 cypress_key_onoff = 1;
792 cypress_tk_disable(client);
793 /* To turn off touchkey when LCD turns off */
794 data->fb_notif.notifier_call = cypress_tk_fb_notifier_callback;
795 fb_register_client(&data->fb_notif);
797 init_timer(&cypress_led_off_timer);
798 cypress_led_off_timer.function = cypress_led_off_timer_handler;
800 ret = sysfs_create_group(&client->dev.kobj, &cypress_attr_group);
802 printk(KERN_INFO "[TK] make sysfs_create_group error\n");
804 cypress_irq_flag = 1;
808 ret = cypress_i2c_read(client, CYPRESS_TK_KEYCODE_REG, buffer, 3);
810 dev_err(&client->dev, "%s: error\n", __func__);
812 printk(KERN_INFO "[TK] CYPRESS TK Firmware version = 0x%x, Module version = 0x%x\n",\
813 buffer[CYPRESS_TK_FW_VERSION], buffer[CYPRESS_TK_MD_VERSION]);
814 cypress_fw_ver = buffer[CYPRESS_TK_FW_VERSION];
815 cypress_md_ver = buffer[CYPRESS_TK_MD_VERSION];
822 free_irq(client->irq, data);
824 input_free_device(input_dev);
829 static int __devexit cypress_tk_remove(struct i2c_client *client)
831 struct cypress_data *data = i2c_get_clientdata(client);
833 free_irq(data->irq, data);
834 cancel_work_sync(&data->event_work);
836 input_unregister_device(data->input_dev);
839 i2c_set_clientdata(client, NULL);
844 static const struct i2c_device_id cypress_tk_id[] = {
848 MODULE_DEVICE_TABLE(i2c, cypress_tk_id);
850 static struct i2c_driver cypress_tk_driver = {
852 .name = "cypress_tk",
854 .probe = cypress_tk_probe,
855 .remove = __devexit_p(cypress_tk_remove),
856 .id_table = cypress_tk_id,
859 static int __init cypress_tk_init(void)
861 return i2c_add_driver(&cypress_tk_driver);
864 static void __exit cypress_tk_exit(void)
866 i2c_del_driver(&cypress_tk_driver);
869 module_init(cypress_tk_init);
870 module_exit(cypress_tk_exit);
872 /* Module information */
873 MODULE_AUTHOR("Samsung Electronics");
874 MODULE_DESCRIPTION("touch key driver for CYPRESS CY8C20236-24LKX1");
875 MODULE_LICENSE("GPL");