aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/input
diff options
context:
space:
mode:
authorChristopher Kenna <cjk@cs.unc.edu>2012-09-28 13:46:28 -0400
committerChristopher Kenna <cjk@cs.unc.edu>2012-09-28 14:50:15 -0400
commitdaa22703f14c007e93b464c45fa60019a36f546d (patch)
treea1a130b6e128dc9d57c35c026977e1b4953105e1 /drivers/input
parent5aa287dcf1b5879aa0150b0511833c52885f5b4c (diff)
Apply k4412 kernel from HardKernel for ODROID-X.
Diffstat (limited to 'drivers/input')
-rw-r--r--drivers/input/Kconfig9
-rw-r--r--drivers/input/Makefile1
-rw-r--r--drivers/input/evdev.c34
-rw-r--r--drivers/input/keyboard/Kconfig6
-rw-r--r--drivers/input/keyboard/Makefile1
-rw-r--r--drivers/input/keyboard/odroid-keypad.c575
-rw-r--r--drivers/input/keyboard/odroid-keypad.h54
-rw-r--r--drivers/input/keyreset.c239
-rw-r--r--drivers/input/misc/Kconfig22
-rw-r--r--drivers/input/misc/Makefile5
-rw-r--r--drivers/input/misc/gpio_axis.c192
-rw-r--r--drivers/input/misc/gpio_event.c260
-rw-r--r--drivers/input/misc/gpio_input.c376
-rw-r--r--drivers/input/misc/gpio_matrix.c441
-rw-r--r--drivers/input/misc/gpio_output.c97
-rw-r--r--drivers/input/misc/isa1200.c324
-rw-r--r--drivers/input/misc/keychord.c387
-rw-r--r--drivers/input/touchscreen/Kconfig40
-rw-r--r--drivers/input/touchscreen/Makefile7
-rw-r--r--drivers/input/touchscreen/egalax_i2c.c962
-rw-r--r--drivers/input/touchscreen/odroidq-config.h151
-rw-r--r--drivers/input/touchscreen/odroidq-touch.c364
-rw-r--r--drivers/input/touchscreen/pixcir_i2c_ts.c1008
-rw-r--r--drivers/input/touchscreen/s3c2410_ts.c134
-rw-r--r--drivers/input/touchscreen/s5pc210_ts.c488
-rw-r--r--drivers/input/touchscreen/s5pc210_ts.h120
-rw-r--r--drivers/input/touchscreen/s5pc210_ts_gpio_i2c.c366
-rw-r--r--drivers/input/touchscreen/s5pc210_ts_gpio_i2c.h21
-rw-r--r--drivers/input/touchscreen/s5pc210_ts_sysfs.c287
-rw-r--r--drivers/input/touchscreen/s5pc210_ts_sysfs.h19
-rw-r--r--drivers/input/touchscreen/synaptics_i2c_rmi.c675
-rw-r--r--drivers/input/touchscreen/touch-i2c.c170
-rw-r--r--drivers/input/touchscreen/touch-i2c.h23
-rw-r--r--drivers/input/touchscreen/touch-sysfs.c250
-rw-r--r--drivers/input/touchscreen/touch-sysfs.h23
-rw-r--r--drivers/input/touchscreen/touch.c672
-rw-r--r--drivers/input/touchscreen/touch.h25
37 files changed, 8808 insertions, 20 deletions
diff --git a/drivers/input/Kconfig b/drivers/input/Kconfig
index 23e82e46656..c0e639c1b17 100644
--- a/drivers/input/Kconfig
+++ b/drivers/input/Kconfig
@@ -161,6 +161,15 @@ config INPUT_APMPOWER
161 To compile this driver as a module, choose M here: the 161 To compile this driver as a module, choose M here: the
162 module will be called apm-power. 162 module will be called apm-power.
163 163
164config INPUT_KEYRESET
165 tristate "Reset key"
166 depends on INPUT
167 ---help---
168 Say Y here if you want to reboot when some keys are pressed;
169
170 To compile this driver as a module, choose M here: the
171 module will be called keyreset.
172
164comment "Input Device Drivers" 173comment "Input Device Drivers"
165 174
166source "drivers/input/keyboard/Kconfig" 175source "drivers/input/keyboard/Kconfig"
diff --git a/drivers/input/Makefile b/drivers/input/Makefile
index 0c789490e0b..5d4593d3101 100644
--- a/drivers/input/Makefile
+++ b/drivers/input/Makefile
@@ -24,3 +24,4 @@ obj-$(CONFIG_INPUT_TOUCHSCREEN) += touchscreen/
24obj-$(CONFIG_INPUT_MISC) += misc/ 24obj-$(CONFIG_INPUT_MISC) += misc/
25 25
26obj-$(CONFIG_INPUT_APMPOWER) += apm-power.o 26obj-$(CONFIG_INPUT_APMPOWER) += apm-power.o
27obj-$(CONFIG_INPUT_KEYRESET) += keyreset.o
diff --git a/drivers/input/evdev.c b/drivers/input/evdev.c
index 4cf25347b01..5c5f9db2807 100644
--- a/drivers/input/evdev.c
+++ b/drivers/input/evdev.c
@@ -23,6 +23,7 @@
23#include <linux/input.h> 23#include <linux/input.h>
24#include <linux/major.h> 24#include <linux/major.h>
25#include <linux/device.h> 25#include <linux/device.h>
26#include <linux/wakelock.h>
26#include "input-compat.h" 27#include "input-compat.h"
27 28
28struct evdev { 29struct evdev {
@@ -43,6 +44,8 @@ struct evdev_client {
43 unsigned int tail; 44 unsigned int tail;
44 unsigned int packet_head; /* [future] position of the first element of next packet */ 45 unsigned int packet_head; /* [future] position of the first element of next packet */
45 spinlock_t buffer_lock; /* protects access to buffer, head and tail */ 46 spinlock_t buffer_lock; /* protects access to buffer, head and tail */
47 struct wake_lock wake_lock;
48 char name[28];
46 struct fasync_struct *fasync; 49 struct fasync_struct *fasync;
47 struct evdev *evdev; 50 struct evdev *evdev;
48 struct list_head node; 51 struct list_head node;
@@ -59,6 +62,7 @@ static void evdev_pass_event(struct evdev_client *client,
59 /* Interrupts are disabled, just acquire the lock. */ 62 /* Interrupts are disabled, just acquire the lock. */
60 spin_lock(&client->buffer_lock); 63 spin_lock(&client->buffer_lock);
61 64
65 wake_lock_timeout(&client->wake_lock, 5 * HZ);
62 client->buffer[client->head++] = *event; 66 client->buffer[client->head++] = *event;
63 client->head &= client->bufsize - 1; 67 client->head &= client->bufsize - 1;
64 68
@@ -94,8 +98,11 @@ static void evdev_event(struct input_handle *handle,
94 struct evdev *evdev = handle->private; 98 struct evdev *evdev = handle->private;
95 struct evdev_client *client; 99 struct evdev_client *client;
96 struct input_event event; 100 struct input_event event;
101 struct timespec ts;
97 102
98 do_gettimeofday(&event.time); 103 ktime_get_ts(&ts);
104 event.time.tv_sec = ts.tv_sec;
105 event.time.tv_usec = ts.tv_nsec / NSEC_PER_USEC;
99 event.type = type; 106 event.type = type;
100 event.code = code; 107 event.code = code;
101 event.value = value; 108 event.value = value;
@@ -255,6 +262,7 @@ static int evdev_release(struct inode *inode, struct file *file)
255 mutex_unlock(&evdev->mutex); 262 mutex_unlock(&evdev->mutex);
256 263
257 evdev_detach_client(evdev, client); 264 evdev_detach_client(evdev, client);
265 wake_lock_destroy(&client->wake_lock);
258 kfree(client); 266 kfree(client);
259 267
260 evdev_close_device(evdev); 268 evdev_close_device(evdev);
@@ -306,6 +314,9 @@ static int evdev_open(struct inode *inode, struct file *file)
306 314
307 client->bufsize = bufsize; 315 client->bufsize = bufsize;
308 spin_lock_init(&client->buffer_lock); 316 spin_lock_init(&client->buffer_lock);
317 snprintf(client->name, sizeof(client->name), "%s-%d",
318 dev_name(&evdev->dev), task_tgid_vnr(current));
319 wake_lock_init(&client->wake_lock, WAKE_LOCK_SUSPEND, client->name);
309 client->evdev = evdev; 320 client->evdev = evdev;
310 evdev_attach_client(evdev, client); 321 evdev_attach_client(evdev, client);
311 322
@@ -320,6 +331,7 @@ static int evdev_open(struct inode *inode, struct file *file)
320 331
321 err_free_client: 332 err_free_client:
322 evdev_detach_client(evdev, client); 333 evdev_detach_client(evdev, client);
334 wake_lock_destroy(&client->wake_lock);
323 kfree(client); 335 kfree(client);
324 err_put_evdev: 336 err_put_evdev:
325 put_device(&evdev->dev); 337 put_device(&evdev->dev);
@@ -369,10 +381,12 @@ static int evdev_fetch_next_event(struct evdev_client *client,
369 381
370 spin_lock_irq(&client->buffer_lock); 382 spin_lock_irq(&client->buffer_lock);
371 383
372 have_event = client->head != client->tail; 384 have_event = client->packet_head != client->tail;
373 if (have_event) { 385 if (have_event) {
374 *event = client->buffer[client->tail++]; 386 *event = client->buffer[client->tail++];
375 client->tail &= client->bufsize - 1; 387 client->tail &= client->bufsize - 1;
388 if (client->head == client->tail)
389 wake_unlock(&client->wake_lock);
376 } 390 }
377 391
378 spin_unlock_irq(&client->buffer_lock); 392 spin_unlock_irq(&client->buffer_lock);
@@ -391,14 +405,12 @@ static ssize_t evdev_read(struct file *file, char __user *buffer,
391 if (count < input_event_size()) 405 if (count < input_event_size())
392 return -EINVAL; 406 return -EINVAL;
393 407
394 if (client->packet_head == client->tail && evdev->exist && 408 if (!(file->f_flags & O_NONBLOCK)) {
395 (file->f_flags & O_NONBLOCK)) 409 retval = wait_event_interruptible(evdev->wait,
396 return -EAGAIN; 410 client->packet_head != client->tail || !evdev->exist);
397 411 if (retval)
398 retval = wait_event_interruptible(evdev->wait, 412 return retval;
399 client->packet_head != client->tail || !evdev->exist); 413 }
400 if (retval)
401 return retval;
402 414
403 if (!evdev->exist) 415 if (!evdev->exist)
404 return -ENODEV; 416 return -ENODEV;
@@ -412,6 +424,8 @@ static ssize_t evdev_read(struct file *file, char __user *buffer,
412 retval += input_event_size(); 424 retval += input_event_size();
413 } 425 }
414 426
427 if (retval == 0 && file->f_flags & O_NONBLOCK)
428 retval = -EAGAIN;
415 return retval; 429 return retval;
416} 430}
417 431
diff --git a/drivers/input/keyboard/Kconfig b/drivers/input/keyboard/Kconfig
index b4dee9d5a05..2d2201a3f5f 100644
--- a/drivers/input/keyboard/Kconfig
+++ b/drivers/input/keyboard/Kconfig
@@ -563,4 +563,10 @@ config KEYBOARD_W90P910
563 To compile this driver as a module, choose M here: the 563 To compile this driver as a module, choose M here: the
564 module will be called w90p910_keypad. 564 module will be called w90p910_keypad.
565 565
566config KEYBOARD_ODROID
567 bool "ODROID-Q, ODROID-A4 Exynos DEV Keypad support"
568 help
569 Say Y here to enable the gpio keypad on evaluation board
570 based on ODROID-EXYNOS.
571
566endif 572endif
diff --git a/drivers/input/keyboard/Makefile b/drivers/input/keyboard/Makefile
index ddde0fd476f..64700d7899a 100644
--- a/drivers/input/keyboard/Makefile
+++ b/drivers/input/keyboard/Makefile
@@ -51,3 +51,4 @@ obj-$(CONFIG_KEYBOARD_TNETV107X) += tnetv107x-keypad.o
51obj-$(CONFIG_KEYBOARD_TWL4030) += twl4030_keypad.o 51obj-$(CONFIG_KEYBOARD_TWL4030) += twl4030_keypad.o
52obj-$(CONFIG_KEYBOARD_XTKBD) += xtkbd.o 52obj-$(CONFIG_KEYBOARD_XTKBD) += xtkbd.o
53obj-$(CONFIG_KEYBOARD_W90P910) += w90p910_keypad.o 53obj-$(CONFIG_KEYBOARD_W90P910) += w90p910_keypad.o
54obj-$(CONFIG_KEYBOARD_ODROID) += odroid-keypad.o
diff --git a/drivers/input/keyboard/odroid-keypad.c b/drivers/input/keyboard/odroid-keypad.c
new file mode 100644
index 00000000000..b4fdc4129cb
--- /dev/null
+++ b/drivers/input/keyboard/odroid-keypad.c
@@ -0,0 +1,575 @@
1//[*]--------------------------------------------------------------------------------------------------[*]
2/*
3 *
4 * ODROID Dev Board keypad driver (charles.park)
5 *
6 */
7//[*]--------------------------------------------------------------------------------------------------[*]
8#include <linux/module.h>
9#include <linux/kernel.h>
10#include <linux/init.h>
11#include <linux/interrupt.h>
12#include <linux/input.h>
13#include <linux/platform_device.h>
14#include <linux/clk.h>
15#include <linux/hrtimer.h>
16#include <linux/slab.h>
17
18#include <linux/gpio.h>
19#include <linux/delay.h>
20#include <asm/io.h>
21#include <plat/gpio-cfg.h>
22#include <mach/regs-gpio.h>
23#include <mach/regs-pmu.h>
24
25// Debug message enable flag
26#define DEBUG_MSG
27#define DEBUG_PM_MSG
28
29//[*]--------------------------------------------------------------------------------------------------[*]
30#include "odroid-keypad.h"
31
32//[*]--------------------------------------------------------------------------------------------------[*]
33//[*]--------------------------------------------------------------------------------------------------[*]
34static void __exit odroid_keypad_exit (void);
35static int __init odroid_keypad_init (void);
36static int __devexit odroid_keypad_remove (struct platform_device *pdev);
37static int __devinit odroid_keypad_probe (struct platform_device *pdev);
38static void odroid_keypad_config (odroid_keypad_t *keypad);
39static int odroid_keypad_suspend (struct platform_device *pdev, pm_message_t state);
40static int odroid_keypad_resume (struct platform_device *pdev);
41static void odroid_keypad_release_device(struct device *dev);
42static void odroid_keypad_close (struct input_dev *dev);
43static int odroid_keypad_open (struct input_dev *dev);
44static void odroid_keypad_control (odroid_keypad_t *keypad);
45static int odroid_keypad_get_data (void);
46static void generate_keycode (odroid_keypad_t *keypad, unsigned short prev_key, unsigned short cur_key, int *key_table);
47
48static enum hrtimer_restart odroid_keypad_timer (struct hrtimer *timer);
49static enum hrtimer_restart odroid_poweroff_timer (struct hrtimer *timer);
50//[*]--------------------------------------------------------------------------------------------------[*]
51static struct platform_driver odroid_platform_device_driver = {
52 .probe = odroid_keypad_probe,
53 .remove = odroid_keypad_remove,
54 .suspend = odroid_keypad_suspend,
55 .resume = odroid_keypad_resume,
56 .driver = {
57 .owner = THIS_MODULE,
58 .name = DEVICE_NAME,
59 },
60};
61
62//[*]--------------------------------------------------------------------------------------------------[*]
63static struct platform_device odroid_platform_device = {
64 .name = DEVICE_NAME,
65 .id = -1,
66 .num_resources = 0,
67 .dev = {
68 .release = odroid_keypad_release_device,
69 },
70};
71
72//[*]--------------------------------------------------------------------------------------------------[*]
73module_init(odroid_keypad_init);
74module_exit(odroid_keypad_exit);
75
76//[*]--------------------------------------------------------------------------------------------------[*]
77MODULE_AUTHOR("Hard-Kernel");
78MODULE_LICENSE("GPL");
79MODULE_DESCRIPTION("Keypad interface for ODROID-Dev board");
80
81//[*]--------------------------------------------------------------------------------------------------[*]
82// Control GPIO Define
83//[*]--------------------------------------------------------------------------------------------------[*]
84// GPIO Index Define
85enum {
86 // KEY CONTROL
87 KEYPAD_POWER,
88#if !defined(CONFIG_BOARD_ODROID_X)
89#if defined(CONFIG_FB_S5P_S6E8AA1)
90 KEYPAD_MODE,
91 KEYPAD_PLAYPAUSE,
92#else
93 KEYPAD_VOLUME_UP,
94 KEYPAD_VOLUME_DOWN,
95#endif
96 KEYPAD_POWER_LED,
97#endif // #if !defined(CONFIG_BOARD_ODROID_X)
98 GPIO_INDEX_END
99};
100
101static struct {
102 int gpio_index; // Control Index
103 int gpio; // GPIO Number
104 char *name; // GPIO Name == sysfs attr name (must)
105 bool output; // 1 = Output, 0 = Input
106 int value; // Default Value(only for output)
107 int pud; // Pull up/down register setting : S3C_GPIO_PULL_DOWN, UP, NONE
108} sControlGpios[] = {
109 { KEYPAD_POWER, EXYNOS4_GPX1(3), "KEY POWER" , 0, 0, S3C_GPIO_PULL_NONE},
110#if !defined(CONFIG_BOARD_ODROID_X)
111#if defined(CONFIG_FB_S5P_S6E8AA1)
112 { KEYPAD_MODE, EXYNOS4_GPX1(7), "KEY MODE" , 0, 0, S3C_GPIO_PULL_DOWN},
113 { KEYPAD_PLAYPAUSE, EXYNOS4_GPX2(0), "KEY PLAYPAUSE" , 0, 0, S3C_GPIO_PULL_DOWN},
114#else
115 { KEYPAD_VOLUME_UP, EXYNOS4_GPX1(7), "KEY VOLUME UP" , 0, 0, S3C_GPIO_PULL_DOWN},
116 { KEYPAD_VOLUME_DOWN, EXYNOS4_GPX2(0), "KEY VOLUME DOWN" , 0, 0, S3C_GPIO_PULL_DOWN},
117#endif
118 { KEYPAD_POWER_LED, EXYNOS4_GPA1(0), "POWER LED" , 1, 1, S3C_GPIO_PULL_NONE},
119#endif // #if !defined(CONFIG_BOARD_ODROID_X)
120};
121
122//[*]--------------------------------------------------------------------------------------------------[*]
123#define MAX_KEYCODE_CNT 3
124
125int Keycode[MAX_KEYCODE_CNT] = {
126 KEY_POWER,
127#if !defined(CONFIG_BOARD_ODROID_X)
128#if defined(CONFIG_FB_S5P_S6E8AA1)
129 KEY_0,
130 KEY_1,
131#else
132 KEY_VOLUMEUP,
133 KEY_VOLUMEDOWN,
134#endif
135#endif // #if !defined(CONFIG_BOARD_ODROID_X)
136};
137
138#if defined(DEBUG_MSG)
139 const char KeyMapStr[MAX_KEYCODE_CNT][20] = {
140 "KEY_POWER\n",
141#if !defined(CONFIG_BOARD_ODROID_X)
142#if defined(CONFIG_FB_S5P_S6E8AA1)
143 "KEY_MODE\n",
144 "KEY_PLAYPAUSE\n",
145#else
146 "KEY_VOLUME_UP\n",
147 "KEY_VOLUME_DOWN\n",
148#endif
149#endif // #if !defined(CONFIG_BOARD_ODROID_X)
150 };
151#endif // DEBUG_MSG
152
153//[*]--------------------------------------------------------------------------------------------------[*]
154static enum hrtimer_restart odroid_poweroff_timer(struct hrtimer *timer)
155{
156#if defined(CONFIG_BOARD_ODROID_X)
157 odroid_keypad_t *keypad = container_of(timer, odroid_keypad_t, poweroff_timer);
158#endif
159
160#if !defined(CONFIG_BOARD_ODROID_X)
161 gpio_direction_output (sControlGpios[KEYPAD_POWER_LED].gpio, 0); // POWER LED OFF
162#endif
163
164#if defined(CONFIG_BOARD_ODROID_X)
165 hrtimer_cancel(&keypad->led_timer);
166 gpio_direction_output (LED_STATUS_PORT, 1);
167#endif
168 printk(KERN_EMERG "%s : setting GPIO_PDA_PS_HOLD low.\n", __func__);
169 (*(unsigned long *)(S5P_PMUREG(0x330C))) = 0x5200;
170 return HRTIMER_NORESTART;
171}
172
173//[*]--------------------------------------------------------------------------------------------------[*]
174#if defined(CONFIG_FB_S5P_S6E8AA1)
175static enum hrtimer_restart odroid_long_timer(struct hrtimer *timer)
176{
177 odroid_keypad_t *keypad = container_of(timer, odroid_keypad_t, long_timer);
178
179 static unsigned char status = false;
180
181 status = !status;
182
183 if(status) input_report_switch(keypad->input, SW_LID, 1);
184 else input_report_switch(keypad->input, SW_LID, 0);
185 input_sync(keypad->input);
186
187 keypad->long_status = false;
188
189 #if defined(DEBUG_MSG)
190 printk("%s : slide notifiy send (%d)\n", __func__, status);
191 #endif
192
193 return HRTIMER_NORESTART;
194}
195#endif
196//[*]--------------------------------------------------------------------------------------------------[*]
197#if defined(CONFIG_BOARD_ODROID_X)
198static enum hrtimer_restart odroid_led_timer(struct hrtimer *timer)
199{
200 odroid_keypad_t *keypad = container_of(timer, odroid_keypad_t, led_timer);
201
202 static unsigned char status = false;
203
204 status = !status;
205
206 gpio_direction_output (LED_STATUS_PORT, !status);
207
208 hrtimer_start(&keypad->led_timer, ktime_set(LED_STATUS_PERIOD, 0), HRTIMER_MODE_REL);
209
210 return HRTIMER_NORESTART;
211}
212#endif
213//[*]--------------------------------------------------------------------------------------------------[*]
214static void generate_keycode(odroid_keypad_t *keypad, unsigned short prev_key, unsigned short cur_key, int *key_table)
215{
216 unsigned short press_key, release_key, i;
217
218 press_key = (cur_key ^ prev_key) & cur_key;
219 release_key = (cur_key ^ prev_key) & prev_key;
220
221 i = 0;
222 while(press_key) {
223 if(press_key & 0x01) {
224#if defined(CONFIG_FB_S5P_S6E8AA1)
225 if(key_table[i] == KEY_0) {
226 keypad->long_status = true;
227 hrtimer_start(&keypad->long_timer, ktime_set(LONGKEY_CHECK_PERIOD, 0), HRTIMER_MODE_REL);
228 }
229 else if(key_table[i] == KEY_1) {
230 keypad->pause = keypad->pause ? 0 : 1;
231
232 if(keypad->pause)
233 input_report_key(keypad->input, key_table[i], KEY_PRESS);
234 else
235 input_report_key(keypad->input, KEY_2, KEY_PRESS);
236 }
237 else
238#endif
239 input_report_key(keypad->input, key_table[i], KEY_PRESS);
240
241 // POWER OFF PRESS
242 if(key_table[i] == KEY_POWER)
243 hrtimer_start(&keypad->poweroff_timer, ktime_set(POWEROFF_CHECK_PERIOD, 0), HRTIMER_MODE_REL);
244 }
245 i++; press_key >>= 1;
246 }
247
248 i = 0;
249 while(release_key) {
250 if(release_key & 0x01) {
251
252#if defined(CONFIG_FB_S5P_S6E8AA1)
253 if(key_table[i] == KEY_0) {
254 if(keypad->long_status) {
255 keypad->long_status = true;
256 hrtimer_cancel(&keypad->long_timer);
257 input_report_key(keypad->input, key_table[i], KEY_PRESS);
258 input_report_key(keypad->input, key_table[i], KEY_RELEASE);
259 }
260 }
261 else if(key_table[i] == KEY_1) {
262 if(keypad->pause)
263 input_report_key(keypad->input, key_table[i], KEY_RELEASE);
264 else
265 input_report_key(keypad->input, KEY_2, KEY_RELEASE);
266 }
267 else
268#endif
269 input_report_key(keypad->input, key_table[i], KEY_RELEASE);
270
271 // POWER OFF (RELEASE)
272 if(key_table[i] == KEY_POWER)
273 hrtimer_cancel(&keypad->poweroff_timer);
274 }
275 i++; release_key >>= 1;
276 }
277}
278//[*]--------------------------------------------------------------------------------------------------[*]
279#if defined(DEBUG_MSG)
280 static void debug_keycode_printf(unsigned short prev_key, unsigned short cur_key, const char *key_table)
281 {
282 unsigned short press_key, release_key, i;
283
284 press_key = (cur_key ^ prev_key) & cur_key;
285 release_key = (cur_key ^ prev_key) & prev_key;
286
287 i = 0;
288 while(press_key) {
289 if(press_key & 0x01) printk("PRESS KEY : %s", (char *)&key_table[i * 20]);
290 i++; press_key >>= 1;
291 }
292
293 i = 0;
294 while(release_key) {
295 if(release_key & 0x01) printk("RELEASE KEY : %s", (char *)&key_table[i * 20]);
296 i++; release_key >>= 1;
297 }
298 }
299#endif
300
301//[*]--------------------------------------------------------------------------------------------------[*]
302static int odroid_keypad_get_data(void)
303{
304 int key_data = 0;
305
306 key_data |= (gpio_get_value(sControlGpios[KEYPAD_POWER].gpio) ? 0 : 0x01);
307#if !defined(CONFIG_BOARD_ODROID_X)
308#if defined(CONFIG_FB_S5P_S6E8AA1)
309 key_data |= (gpio_get_value(sControlGpios[KEYPAD_MODE].gpio) ? 0x02 : 0);
310 key_data |= (gpio_get_value(sControlGpios[KEYPAD_PLAYPAUSE].gpio) ? 0x04 : 0);
311#else
312 key_data |= (gpio_get_value(sControlGpios[KEYPAD_VOLUME_UP].gpio) ? 0x02 : 0);
313 key_data |= (gpio_get_value(sControlGpios[KEYPAD_VOLUME_DOWN].gpio) ? 0x04 : 0);
314#endif
315#endif // #if !defined(CONFIG_BOARD_ODROID_X)
316 return key_data;
317}
318
319//[*]--------------------------------------------------------------------------------------------------[*]
320static void odroid_keypad_control(odroid_keypad_t *keypad)
321{
322 static unsigned short prev_keypad_data = 0, cur_keypad_data = 0;
323
324 // key data process
325 cur_keypad_data = odroid_keypad_get_data();
326
327 if(prev_keypad_data != cur_keypad_data) {
328
329 generate_keycode(keypad, prev_keypad_data, cur_keypad_data, &Keycode[0]);
330
331 #if defined(DEBUG_MSG)
332 debug_keycode_printf(prev_keypad_data, cur_keypad_data, &KeyMapStr[0][0]);
333 #endif
334
335 prev_keypad_data = cur_keypad_data;
336
337 input_sync(keypad->input);
338 }
339}
340
341//[*]--------------------------------------------------------------------------------------------------[*]
342static enum hrtimer_restart odroid_keypad_timer(struct hrtimer *timer)
343{
344 odroid_keypad_t *keypad = container_of(timer, odroid_keypad_t, timer);
345
346 odroid_keypad_control(keypad);
347 hrtimer_start(&keypad->timer, ktime_set(0, KEYPAD_TIMER_PERIOD), HRTIMER_MODE_REL);
348
349 return HRTIMER_NORESTART;
350}
351
352//[*]--------------------------------------------------------------------------------------------------[*]
353static int odroid_keypad_open(struct input_dev *dev)
354{
355 #if defined(DEBUG_MSG)
356 printk("%s\n", __FUNCTION__);
357 #endif
358
359 return 0;
360}
361
362//[*]--------------------------------------------------------------------------------------------------[*]
363static void odroid_keypad_close(struct input_dev *dev)
364{
365 #if defined(DEBUG_MSG)
366 printk("%s\n", __FUNCTION__);
367 #endif
368}
369
370//[*]--------------------------------------------------------------------------------------------------[*]
371static void odroid_keypad_release_device(struct device *dev)
372{
373 #if defined(DEBUG_MSG)
374 printk("%s\n", __FUNCTION__);
375 #endif
376}
377
378//[*]--------------------------------------------------------------------------------------------------[*]
379static int odroid_keypad_resume(struct platform_device *pdev)
380{
381 odroid_keypad_t *keypad = dev_get_drvdata(&pdev->dev);
382
383 #if defined(DEBUG_PM_MSG)
384 printk("%s\n", __FUNCTION__);
385 #endif
386
387 hrtimer_start(&keypad->timer, ktime_set(0, KEYPAD_TIMER_PERIOD), HRTIMER_MODE_REL);
388
389 return 0;
390}
391
392//[*]--------------------------------------------------------------------------------------------------[*]
393static int odroid_keypad_suspend(struct platform_device *pdev, pm_message_t state)
394{
395 odroid_keypad_t *keypad = dev_get_drvdata(&pdev->dev);
396
397 #if defined(DEBUG_PM_MSG)
398 printk("%s\n", __FUNCTION__);
399 #endif
400
401 hrtimer_cancel(&keypad->timer);
402
403 return 0;
404}
405
406//[*]--------------------------------------------------------------------------------------------------[*]
407static void odroid_keypad_config(odroid_keypad_t *keypad)
408{
409 int i;
410
411 // Control GPIO Init
412 for (i = 0; i < ARRAY_SIZE(sControlGpios); i++) {
413 if(gpio_request(sControlGpios[i].gpio, sControlGpios[i].name)) {
414 printk("--------------------------------------------\n");
415 printk("%s : %s gpio reqest err!\n", __FUNCTION__, sControlGpios[i].name);
416 printk("--------------------------------------------\n");
417 }
418 else {
419 if(sControlGpios[i].output) gpio_direction_output (sControlGpios[i].gpio, sControlGpios[i].value);
420 else gpio_direction_input (sControlGpios[i].gpio);
421
422 s3c_gpio_setpull(sControlGpios[i].gpio, sControlGpios[i].pud);
423 }
424 }
425
426 hrtimer_start(&keypad->timer, ktime_set(0, KEYPAD_TIMER_PERIOD), HRTIMER_MODE_REL);
427}
428
429//[*]--------------------------------------------------------------------------------------------------[*]
430static int __devinit odroid_keypad_probe(struct platform_device *pdev)
431{
432 int key, code;
433 odroid_keypad_t *keypad;
434
435 if(!(keypad = kzalloc(sizeof(*keypad), GFP_KERNEL))) return -ENOMEM;
436
437 dev_set_drvdata(&pdev->dev, keypad);
438
439 if(!(keypad->input = input_allocate_device())) goto err_free_input_mem;
440
441 snprintf(keypad->phys, sizeof(keypad->phys), "%s/input0", DEVICE_NAME);
442
443 keypad->input->name = DEVICE_NAME;
444 keypad->input->phys = keypad->phys;
445 keypad->input->id.bustype = BUS_HOST;
446 keypad->input->id.vendor = 0x16B4;
447 keypad->input->id.product = 0x0701;
448 keypad->input->id.version = 0x0001;
449 keypad->input->keycode = Keycode;
450 keypad->input->open = odroid_keypad_open;
451 keypad->input->close = odroid_keypad_close;
452
453 set_bit(EV_KEY, keypad->input->evbit);
454
455#if defined(CONFIG_FB_S5P_S6E8AA1)
456 set_bit(EV_SW , keypad->input->evbit);
457 set_bit(SW_LID & SW_MAX, keypad->input->swbit);
458#endif
459
460 for(key = 0; key < MAX_KEYCODE_CNT; key++){
461 code = Keycode[key];
462 if(code <= 0) continue;
463 set_bit(code & KEY_MAX, keypad->input->keybit);
464 }
465#if defined(CONFIG_FB_S5P_S6E8AA1)
466 set_bit(KEY_2 & KEY_MAX, keypad->input->keybit);
467#endif
468 if(input_register_device(keypad->input)) {
469 printk("--------------------------------------------------------\n");
470 printk("%s input register device fail!!\n", DEVICE_NAME);
471 printk("--------------------------------------------------------\n");
472 goto err_free_all;
473 }
474
475 hrtimer_init(&keypad->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
476 keypad->timer.function = odroid_keypad_timer;
477
478 hrtimer_init(&keypad->poweroff_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
479 keypad->poweroff_timer.function = odroid_poweroff_timer;
480
481#if defined(CONFIG_FB_S5P_S6E8AA1)
482 hrtimer_init(&keypad->long_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
483 keypad->long_timer.function = odroid_long_timer;
484#endif
485
486 odroid_keypad_config(keypad);
487
488#if defined(CONFIG_BOARD_ODROID_X)
489 if(gpio_request(LED_STATUS_PORT, LED_STATUS_PORT_NAME)) {
490 printk("%s : %s gpio reqest err!\n", __FUNCTION__, LED_STATUS_PORT_NAME);
491 }
492 else {
493 gpio_direction_output (LED_STATUS_PORT, 1);
494 s3c_gpio_setpull (LED_STATUS_PORT, S3C_GPIO_PULL_NONE);
495 }
496
497 hrtimer_init(&keypad->led_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
498 keypad->led_timer.function = odroid_led_timer;
499 hrtimer_start(&keypad->led_timer, ktime_set(LED_STATUS_PERIOD, 0), HRTIMER_MODE_REL);
500#endif
501
502 printk("--------------------------------------------------------\n");
503 printk("%s driver initialized!! Ver 1.0\n", DEVICE_NAME);
504 printk("--------------------------------------------------------\n");
505
506 return 0;
507
508err_free_all:
509 input_free_device(keypad->input);
510err_free_input_mem:
511 kfree(keypad);
512 return -ENODEV;
513}
514
515//[*]--------------------------------------------------------------------------------------------------[*]
516static int __devexit odroid_keypad_remove(struct platform_device *pdev)
517{
518 int i;
519 odroid_keypad_t *keypad = dev_get_drvdata(&pdev->dev);
520
521 input_unregister_device(keypad->input);
522
523 hrtimer_cancel(&keypad->timer);
524
525 dev_set_drvdata(&pdev->dev, NULL);
526
527 for (i = 0; i < ARRAY_SIZE(sControlGpios); i++) gpio_free(sControlGpios[i].gpio);
528
529 #if defined(CONFIG_BOARD_ODROID_X)
530 gpio_free(LED_STATUS_PORT);
531 hrtimer_cancel(&keypad->led_timer);
532 #endif
533
534 #if defined(DEBUG_MSG)
535 printk("%s\n", __FUNCTION__);
536 #endif
537
538 kfree(keypad);
539
540 return 0;
541}
542
543//[*]--------------------------------------------------------------------------------------------------[*]
544static int __init odroid_keypad_init(void)
545{
546 int ret = platform_driver_register(&odroid_platform_device_driver);
547
548 #if defined(DEBUG_MSG)
549 printk("%s\n", __FUNCTION__);
550 #endif
551
552 if(!ret) {
553 ret = platform_device_register(&odroid_platform_device);
554
555 #if defined(DEBUG_MSG)
556 printk("platform_driver_register %d \n", ret);
557 #endif
558
559 if(ret) platform_driver_unregister(&odroid_platform_device_driver);
560 }
561 return ret;
562}
563
564//[*]--------------------------------------------------------------------------------------------------[*]
565static void __exit odroid_keypad_exit(void)
566{
567 #if defined(DEBUG_MSG)
568 printk("%s\n",__FUNCTION__);
569 #endif
570
571 platform_device_unregister(&odroid_platform_device);
572 platform_driver_unregister(&odroid_platform_device_driver);
573}
574
575//[*]--------------------------------------------------------------------------------------------------[*]
diff --git a/drivers/input/keyboard/odroid-keypad.h b/drivers/input/keyboard/odroid-keypad.h
new file mode 100644
index 00000000000..31d126b46f4
--- /dev/null
+++ b/drivers/input/keyboard/odroid-keypad.h
@@ -0,0 +1,54 @@
1//[*]--------------------------------------------------------------------------------------------------[*]
2/*
3 *
4 * ODROID Dev Board key-pad header file (charles.park)
5 *
6 */
7//[*]--------------------------------------------------------------------------------------------------[*]
8#ifndef _ODROID_KEYPAD_H_
9#define _ODROID_KEYPAD_H_
10
11//[*]--------------------------------------------------------------------------------------------------[*]
12#define DEVICE_NAME "odroid-keypad"
13
14//[*]--------------------------------------------------------------------------------------------------[*]
15#define KEY_PRESS 1
16#define KEY_RELEASE 0
17
18#define KEYPAD_TIMER_PERIOD 100000000 // ns : ktime_set(sec, nsec)
19#define POWEROFF_CHECK_PERIOD 5 // sec : ktime_set(sec, nsec)
20
21#if defined(CONFIG_FB_S5P_S6E8AA1)
22 #define LONGKEY_CHECK_PERIOD 3
23#endif
24#if defined(CONFIG_BOARD_ODROID_X)
25 #define LED_STATUS_PERIOD 1
26 #define LED_STATUS_PORT EXYNOS4_GPC1(0)
27 #define LED_STATUS_PORT_NAME "STATUS LED"
28#endif
29
30//[*]--------------------------------------------------------------------------------------------------[*]
31typedef struct odroid_keypad__t {
32
33 // keypad control
34 struct input_dev *input; // input driver
35 char phys[32];
36
37 struct hrtimer timer; // keypad timer
38 struct hrtimer poweroff_timer; // force power off control
39#if defined(CONFIG_FB_S5P_S6E8AA1)
40 char pause;
41 struct hrtimer long_timer; // long key support
42 unsigned char long_status;
43#endif
44
45#if defined(CONFIG_BOARD_ODROID_X)
46 struct hrtimer led_timer; // long key support
47#endif
48
49} odroid_keypad_t;
50
51//[*]--------------------------------------------------------------------------------------------------[*]
52#endif /* _ODROID_KEYPAD_H_*/
53//[*]--------------------------------------------------------------------------------------------------[*]
54//[*]--------------------------------------------------------------------------------------------------[*]
diff --git a/drivers/input/keyreset.c b/drivers/input/keyreset.c
new file mode 100644
index 00000000000..36208fe0baa
--- /dev/null
+++ b/drivers/input/keyreset.c
@@ -0,0 +1,239 @@
1/* drivers/input/keyreset.c
2 *
3 * Copyright (C) 2008 Google, Inc.
4 *
5 * This software is licensed under the terms of the GNU General Public
6 * License version 2, as published by the Free Software Foundation, and
7 * may be copied, distributed, and modified under those terms.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 */
15
16#include <linux/input.h>
17#include <linux/keyreset.h>
18#include <linux/module.h>
19#include <linux/platform_device.h>
20#include <linux/reboot.h>
21#include <linux/sched.h>
22#include <linux/slab.h>
23#include <linux/syscalls.h>
24
25
26struct keyreset_state {
27 struct input_handler input_handler;
28 unsigned long keybit[BITS_TO_LONGS(KEY_CNT)];
29 unsigned long upbit[BITS_TO_LONGS(KEY_CNT)];
30 unsigned long key[BITS_TO_LONGS(KEY_CNT)];
31 spinlock_t lock;
32 int key_down_target;
33 int key_down;
34 int key_up;
35 int restart_disabled;
36 int (*reset_fn)(void);
37};
38
39int restart_requested;
40static void deferred_restart(struct work_struct *dummy)
41{
42 restart_requested = 2;
43 sys_sync();
44 restart_requested = 3;
45 kernel_restart(NULL);
46}
47static DECLARE_WORK(restart_work, deferred_restart);
48
49static void keyreset_event(struct input_handle *handle, unsigned int type,
50 unsigned int code, int value)
51{
52 unsigned long flags;
53 struct keyreset_state *state = handle->private;
54
55 if (type != EV_KEY)
56 return;
57
58 if (code >= KEY_MAX)
59 return;
60
61 if (!test_bit(code, state->keybit))
62 return;
63
64 spin_lock_irqsave(&state->lock, flags);
65 if (!test_bit(code, state->key) == !value)
66 goto done;
67 __change_bit(code, state->key);
68 if (test_bit(code, state->upbit)) {
69 if (value) {
70 state->restart_disabled = 1;
71 state->key_up++;
72 } else
73 state->key_up--;
74 } else {
75 if (value)
76 state->key_down++;
77 else
78 state->key_down--;
79 }
80 if (state->key_down == 0 && state->key_up == 0)
81 state->restart_disabled = 0;
82
83 pr_debug("reset key changed %d %d new state %d-%d-%d\n", code, value,
84 state->key_down, state->key_up, state->restart_disabled);
85
86 if (value && !state->restart_disabled &&
87 state->key_down == state->key_down_target) {
88 state->restart_disabled = 1;
89 if (restart_requested)
90 panic("keyboard reset failed, %d", restart_requested);
91 if (state->reset_fn) {
92 restart_requested = state->reset_fn();
93 } else {
94 pr_info("keyboard reset\n");
95 schedule_work(&restart_work);
96 restart_requested = 1;
97 }
98 }
99done:
100 spin_unlock_irqrestore(&state->lock, flags);
101}
102
103static int keyreset_connect(struct input_handler *handler,
104 struct input_dev *dev,
105 const struct input_device_id *id)
106{
107 int i;
108 int ret;
109 struct input_handle *handle;
110 struct keyreset_state *state =
111 container_of(handler, struct keyreset_state, input_handler);
112
113 for (i = 0; i < KEY_MAX; i++) {
114 if (test_bit(i, state->keybit) && test_bit(i, dev->keybit))
115 break;
116 }
117 if (i == KEY_MAX)
118 return -ENODEV;
119
120 handle = kzalloc(sizeof(*handle), GFP_KERNEL);
121 if (!handle)
122 return -ENOMEM;
123
124 handle->dev = dev;
125 handle->handler = handler;
126 handle->name = "keyreset";
127 handle->private = state;
128
129 ret = input_register_handle(handle);
130 if (ret)
131 goto err_input_register_handle;
132
133 ret = input_open_device(handle);
134 if (ret)
135 goto err_input_open_device;
136
137 pr_info("using input dev %s for key reset\n", dev->name);
138
139 return 0;
140
141err_input_open_device:
142 input_unregister_handle(handle);
143err_input_register_handle:
144 kfree(handle);
145 return ret;
146}
147
148static void keyreset_disconnect(struct input_handle *handle)
149{
150 input_close_device(handle);
151 input_unregister_handle(handle);
152 kfree(handle);
153}
154
155static const struct input_device_id keyreset_ids[] = {
156 {
157 .flags = INPUT_DEVICE_ID_MATCH_EVBIT,
158 .evbit = { BIT_MASK(EV_KEY) },
159 },
160 { },
161};
162MODULE_DEVICE_TABLE(input, keyreset_ids);
163
164static int keyreset_probe(struct platform_device *pdev)
165{
166 int ret;
167 int key, *keyp;
168 struct keyreset_state *state;
169 struct keyreset_platform_data *pdata = pdev->dev.platform_data;
170
171 if (!pdata)
172 return -EINVAL;
173
174 state = kzalloc(sizeof(*state), GFP_KERNEL);
175 if (!state)
176 return -ENOMEM;
177
178 spin_lock_init(&state->lock);
179 keyp = pdata->keys_down;
180 while ((key = *keyp++)) {
181 if (key >= KEY_MAX)
182 continue;
183 state->key_down_target++;
184 __set_bit(key, state->keybit);
185 }
186 if (pdata->keys_up) {
187 keyp = pdata->keys_up;
188 while ((key = *keyp++)) {
189 if (key >= KEY_MAX)
190 continue;
191 __set_bit(key, state->keybit);
192 __set_bit(key, state->upbit);
193 }
194 }
195
196 if (pdata->reset_fn)
197 state->reset_fn = pdata->reset_fn;
198
199 state->input_handler.event = keyreset_event;
200 state->input_handler.connect = keyreset_connect;
201 state->input_handler.disconnect = keyreset_disconnect;
202 state->input_handler.name = KEYRESET_NAME;
203 state->input_handler.id_table = keyreset_ids;
204 ret = input_register_handler(&state->input_handler);
205 if (ret) {
206 kfree(state);
207 return ret;
208 }
209 platform_set_drvdata(pdev, state);
210 return 0;
211}
212
213int keyreset_remove(struct platform_device *pdev)
214{
215 struct keyreset_state *state = platform_get_drvdata(pdev);
216 input_unregister_handler(&state->input_handler);
217 kfree(state);
218 return 0;
219}
220
221
222struct platform_driver keyreset_driver = {
223 .driver.name = KEYRESET_NAME,
224 .probe = keyreset_probe,
225 .remove = keyreset_remove,
226};
227
228static int __init keyreset_init(void)
229{
230 return platform_driver_register(&keyreset_driver);
231}
232
233static void __exit keyreset_exit(void)
234{
235 return platform_driver_unregister(&keyreset_driver);
236}
237
238module_init(keyreset_init);
239module_exit(keyreset_exit);
diff --git a/drivers/input/misc/Kconfig b/drivers/input/misc/Kconfig
index 45dc6aa62ba..e4571056464 100644
--- a/drivers/input/misc/Kconfig
+++ b/drivers/input/misc/Kconfig
@@ -193,6 +193,17 @@ config INPUT_ATI_REMOTE2
193 To compile this driver as a module, choose M here: the module will be 193 To compile this driver as a module, choose M here: the module will be
194 called ati_remote2. 194 called ati_remote2.
195 195
196config INPUT_KEYCHORD
197 tristate "Key chord input driver support"
198 help
199 Say Y here if you want to enable the key chord driver
200 accessible at /dev/keychord. This driver can be used
201 for receiving notifications when client specified key
202 combinations are pressed.
203
204 To compile this driver as a module, choose M here: the
205 module will be called keychord.
206
196config INPUT_KEYSPAN_REMOTE 207config INPUT_KEYSPAN_REMOTE
197 tristate "Keyspan DMR USB remote control (EXPERIMENTAL)" 208 tristate "Keyspan DMR USB remote control (EXPERIMENTAL)"
198 depends on EXPERIMENTAL 209 depends on EXPERIMENTAL
@@ -294,6 +305,11 @@ config INPUT_SGI_BTNS
294 To compile this driver as a module, choose M here: the 305 To compile this driver as a module, choose M here: the
295 module will be called sgi_btns. 306 module will be called sgi_btns.
296 307
308config INPUT_GPIO
309 tristate "GPIO driver support"
310 help
311 Say Y here if you want to support gpio based keys, wheels etc...
312
297config HP_SDC_RTC 313config HP_SDC_RTC
298 tristate "HP SDC Real Time Clock" 314 tristate "HP SDC Real Time Clock"
299 depends on (GSC || HP300) && SERIO 315 depends on (GSC || HP300) && SERIO
@@ -478,4 +494,10 @@ config INPUT_XEN_KBDDEV_FRONTEND
478 To compile this driver as a module, choose M here: the 494 To compile this driver as a module, choose M here: the
479 module will be called xen-kbdfront. 495 module will be called xen-kbdfront.
480 496
497config INPUT_ISA1200
498 tristate "ISA1200 Haptic Driver"
499 depends on I2C && HAVE_PWM
500 help
501 This option enables support for the Imagis ISA1200 Haptic Driver.
502
481endif 503endif
diff --git a/drivers/input/misc/Makefile b/drivers/input/misc/Makefile
index 38efb2cb182..f28a4ffc834 100644
--- a/drivers/input/misc/Makefile
+++ b/drivers/input/misc/Makefile
@@ -22,8 +22,10 @@ obj-$(CONFIG_INPUT_CMA3000) += cma3000_d0x.o
22obj-$(CONFIG_INPUT_CMA3000_I2C) += cma3000_d0x_i2c.o 22obj-$(CONFIG_INPUT_CMA3000_I2C) += cma3000_d0x_i2c.o
23obj-$(CONFIG_INPUT_COBALT_BTNS) += cobalt_btns.o 23obj-$(CONFIG_INPUT_COBALT_BTNS) += cobalt_btns.o
24obj-$(CONFIG_INPUT_DM355EVM) += dm355evm_keys.o 24obj-$(CONFIG_INPUT_DM355EVM) += dm355evm_keys.o
25obj-$(CONFIG_INPUT_GPIO) += gpio_event.o gpio_matrix.o gpio_input.o gpio_output.o gpio_axis.o
25obj-$(CONFIG_HP_SDC_RTC) += hp_sdc_rtc.o 26obj-$(CONFIG_HP_SDC_RTC) += hp_sdc_rtc.o
26obj-$(CONFIG_INPUT_IXP4XX_BEEPER) += ixp4xx-beeper.o 27obj-$(CONFIG_INPUT_IXP4XX_BEEPER) += ixp4xx-beeper.o
28obj-$(CONFIG_INPUT_KEYCHORD) += keychord.o
27obj-$(CONFIG_INPUT_KEYSPAN_REMOTE) += keyspan_remote.o 29obj-$(CONFIG_INPUT_KEYSPAN_REMOTE) += keyspan_remote.o
28obj-$(CONFIG_INPUT_M68K_BEEP) += m68kspkr.o 30obj-$(CONFIG_INPUT_M68K_BEEP) += m68kspkr.o
29obj-$(CONFIG_INPUT_MAX8925_ONKEY) += max8925_onkey.o 31obj-$(CONFIG_INPUT_MAX8925_ONKEY) += max8925_onkey.o
@@ -45,4 +47,5 @@ obj-$(CONFIG_INPUT_WISTRON_BTNS) += wistron_btns.o
45obj-$(CONFIG_INPUT_WM831X_ON) += wm831x-on.o 47obj-$(CONFIG_INPUT_WM831X_ON) += wm831x-on.o
46obj-$(CONFIG_INPUT_XEN_KBDDEV_FRONTEND) += xen-kbdfront.o 48obj-$(CONFIG_INPUT_XEN_KBDDEV_FRONTEND) += xen-kbdfront.o
47obj-$(CONFIG_INPUT_YEALINK) += yealink.o 49obj-$(CONFIG_INPUT_YEALINK) += yealink.o
48 50# for ODROID
51obj-$(CONFIG_INPUT_ISA1200) += isa1200.o
diff --git a/drivers/input/misc/gpio_axis.c b/drivers/input/misc/gpio_axis.c
new file mode 100644
index 00000000000..0acf4a576f5
--- /dev/null
+++ b/drivers/input/misc/gpio_axis.c
@@ -0,0 +1,192 @@
1/* drivers/input/misc/gpio_axis.c
2 *
3 * Copyright (C) 2007 Google, Inc.
4 *
5 * This software is licensed under the terms of the GNU General Public
6 * License version 2, as published by the Free Software Foundation, and
7 * may be copied, distributed, and modified under those terms.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 */
15
16#include <linux/kernel.h>
17#include <linux/gpio.h>
18#include <linux/gpio_event.h>
19#include <linux/interrupt.h>
20#include <linux/slab.h>
21
22struct gpio_axis_state {
23 struct gpio_event_input_devs *input_devs;
24 struct gpio_event_axis_info *info;
25 uint32_t pos;
26};
27
28uint16_t gpio_axis_4bit_gray_map_table[] = {
29 [0x0] = 0x0, [0x1] = 0x1, /* 0000 0001 */
30 [0x3] = 0x2, [0x2] = 0x3, /* 0011 0010 */
31 [0x6] = 0x4, [0x7] = 0x5, /* 0110 0111 */
32 [0x5] = 0x6, [0x4] = 0x7, /* 0101 0100 */
33 [0xc] = 0x8, [0xd] = 0x9, /* 1100 1101 */
34 [0xf] = 0xa, [0xe] = 0xb, /* 1111 1110 */
35 [0xa] = 0xc, [0xb] = 0xd, /* 1010 1011 */
36 [0x9] = 0xe, [0x8] = 0xf, /* 1001 1000 */
37};
38uint16_t gpio_axis_4bit_gray_map(struct gpio_event_axis_info *info, uint16_t in)
39{
40 return gpio_axis_4bit_gray_map_table[in];
41}
42
43uint16_t gpio_axis_5bit_singletrack_map_table[] = {
44 [0x10] = 0x00, [0x14] = 0x01, [0x1c] = 0x02, /* 10000 10100 11100 */
45 [0x1e] = 0x03, [0x1a] = 0x04, [0x18] = 0x05, /* 11110 11010 11000 */
46 [0x08] = 0x06, [0x0a] = 0x07, [0x0e] = 0x08, /* 01000 01010 01110 */
47 [0x0f] = 0x09, [0x0d] = 0x0a, [0x0c] = 0x0b, /* 01111 01101 01100 */
48 [0x04] = 0x0c, [0x05] = 0x0d, [0x07] = 0x0e, /* 00100 00101 00111 */
49 [0x17] = 0x0f, [0x16] = 0x10, [0x06] = 0x11, /* 10111 10110 00110 */
50 [0x02] = 0x12, [0x12] = 0x13, [0x13] = 0x14, /* 00010 10010 10011 */
51 [0x1b] = 0x15, [0x0b] = 0x16, [0x03] = 0x17, /* 11011 01011 00011 */
52 [0x01] = 0x18, [0x09] = 0x19, [0x19] = 0x1a, /* 00001 01001 11001 */
53 [0x1d] = 0x1b, [0x15] = 0x1c, [0x11] = 0x1d, /* 11101 10101 10001 */
54};
55uint16_t gpio_axis_5bit_singletrack_map(
56 struct gpio_event_axis_info *info, uint16_t in)
57{
58 return gpio_axis_5bit_singletrack_map_table[in];
59}
60
61static void gpio_event_update_axis(struct gpio_axis_state *as, int report)
62{
63 struct gpio_event_axis_info *ai = as->info;
64 int i;
65 int change;
66 uint16_t state = 0;
67 uint16_t pos;
68 uint16_t old_pos = as->pos;
69 for (i = ai->count - 1; i >= 0; i--)
70 state = (state << 1) | gpio_get_value(ai->gpio[i]);
71 pos = ai->map(ai, state);
72 if (ai->flags & GPIOEAF_PRINT_RAW)
73 pr_info("axis %d-%d raw %x, pos %d -> %d\n",
74 ai->type, ai->code, state, old_pos, pos);
75 if (report && pos != old_pos) {
76 if (ai->type == EV_REL) {
77 change = (ai->decoded_size + pos - old_pos) %
78 ai->decoded_size;
79 if (change > ai->decoded_size / 2)
80 change -= ai->decoded_size;
81 if (change == ai->decoded_size / 2) {
82 if (ai->flags & GPIOEAF_PRINT_EVENT)
83 pr_info("axis %d-%d unknown direction, "
84 "pos %d -> %d\n", ai->type,
85 ai->code, old_pos, pos);
86 change = 0; /* no closest direction */
87 }
88 if (ai->flags & GPIOEAF_PRINT_EVENT)
89 pr_info("axis %d-%d change %d\n",
90 ai->type, ai->code, change);
91 input_report_rel(as->input_devs->dev[ai->dev],
92 ai->code, change);
93 } else {
94 if (ai->flags & GPIOEAF_PRINT_EVENT)
95 pr_info("axis %d-%d now %d\n",
96 ai->type, ai->code, pos);
97 input_event(as->input_devs->dev[ai->dev],
98 ai->type, ai->code, pos);
99 }
100 input_sync(as->input_devs->dev[ai->dev]);
101 }
102 as->pos = pos;
103}
104
105static irqreturn_t gpio_axis_irq_handler(int irq, void *dev_id)
106{
107 struct gpio_axis_state *as = dev_id;
108 gpio_event_update_axis(as, 1);
109 return IRQ_HANDLED;
110}
111
112int gpio_event_axis_func(struct gpio_event_input_devs *input_devs,
113 struct gpio_event_info *info, void **data, int func)
114{
115 int ret;
116 int i;
117 int irq;
118 struct gpio_event_axis_info *ai;
119 struct gpio_axis_state *as;
120
121 ai = container_of(info, struct gpio_event_axis_info, info);
122 if (func == GPIO_EVENT_FUNC_SUSPEND) {
123 for (i = 0; i < ai->count; i++)
124 disable_irq(gpio_to_irq(ai->gpio[i]));
125 return 0;
126 }
127 if (func == GPIO_EVENT_FUNC_RESUME) {
128 for (i = 0; i < ai->count; i++)
129 enable_irq(gpio_to_irq(ai->gpio[i]));
130 return 0;
131 }
132
133 if (func == GPIO_EVENT_FUNC_INIT) {
134 *data = as = kmalloc(sizeof(*as), GFP_KERNEL);
135 if (as == NULL) {
136 ret = -ENOMEM;
137 goto err_alloc_axis_state_failed;
138 }
139 as->input_devs = input_devs;
140 as->info = ai;
141 if (ai->dev >= input_devs->count) {
142 pr_err("gpio_event_axis: bad device index %d >= %d "
143 "for %d:%d\n", ai->dev, input_devs->count,
144 ai->type, ai->code);
145 ret = -EINVAL;
146 goto err_bad_device_index;
147 }
148
149 input_set_capability(input_devs->dev[ai->dev],
150 ai->type, ai->code);
151 if (ai->type == EV_ABS) {
152 input_set_abs_params(input_devs->dev[ai->dev], ai->code,
153 0, ai->decoded_size - 1, 0, 0);
154 }
155 for (i = 0; i < ai->count; i++) {
156 ret = gpio_request(ai->gpio[i], "gpio_event_axis");
157 if (ret < 0)
158 goto err_request_gpio_failed;
159 ret = gpio_direction_input(ai->gpio[i]);
160 if (ret < 0)
161 goto err_gpio_direction_input_failed;
162 ret = irq = gpio_to_irq(ai->gpio[i]);
163 if (ret < 0)
164 goto err_get_irq_num_failed;
165 ret = request_irq(irq, gpio_axis_irq_handler,
166 IRQF_TRIGGER_RISING |
167 IRQF_TRIGGER_FALLING,
168 "gpio_event_axis", as);
169 if (ret < 0)
170 goto err_request_irq_failed;
171 }
172 gpio_event_update_axis(as, 0);
173 return 0;
174 }
175
176 ret = 0;
177 as = *data;
178 for (i = ai->count - 1; i >= 0; i--) {
179 free_irq(gpio_to_irq(ai->gpio[i]), as);
180err_request_irq_failed:
181err_get_irq_num_failed:
182err_gpio_direction_input_failed:
183 gpio_free(ai->gpio[i]);
184err_request_gpio_failed:
185 ;
186 }
187err_bad_device_index:
188 kfree(as);
189 *data = NULL;
190err_alloc_axis_state_failed:
191 return ret;
192}
diff --git a/drivers/input/misc/gpio_event.c b/drivers/input/misc/gpio_event.c
new file mode 100644
index 00000000000..a98be67d1ab
--- /dev/null
+++ b/drivers/input/misc/gpio_event.c
@@ -0,0 +1,260 @@
1/* drivers/input/misc/gpio_event.c
2 *
3 * Copyright (C) 2007 Google, Inc.
4 *
5 * This software is licensed under the terms of the GNU General Public
6 * License version 2, as published by the Free Software Foundation, and
7 * may be copied, distributed, and modified under those terms.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 */
15
16#include <linux/earlysuspend.h>
17#include <linux/module.h>
18#include <linux/input.h>
19#include <linux/gpio_event.h>
20#include <linux/hrtimer.h>
21#include <linux/platform_device.h>
22#include <linux/slab.h>
23
24struct gpio_event {
25 struct gpio_event_input_devs *input_devs;
26 const struct gpio_event_platform_data *info;
27 struct early_suspend early_suspend;
28 void *state[0];
29};
30
31static int gpio_input_event(
32 struct input_dev *dev, unsigned int type, unsigned int code, int value)
33{
34 int i;
35 int devnr;
36 int ret = 0;
37 int tmp_ret;
38 struct gpio_event_info **ii;
39 struct gpio_event *ip = input_get_drvdata(dev);
40
41 for (devnr = 0; devnr < ip->input_devs->count; devnr++)
42 if (ip->input_devs->dev[devnr] == dev)
43 break;
44 if (devnr == ip->input_devs->count) {
45 pr_err("gpio_input_event: unknown device %p\n", dev);
46 return -EIO;
47 }
48
49 for (i = 0, ii = ip->info->info; i < ip->info->info_count; i++, ii++) {
50 if ((*ii)->event) {
51 tmp_ret = (*ii)->event(ip->input_devs, *ii,
52 &ip->state[i],
53 devnr, type, code, value);
54 if (tmp_ret)
55 ret = tmp_ret;
56 }
57 }
58 return ret;
59}
60
61static int gpio_event_call_all_func(struct gpio_event *ip, int func)
62{
63 int i;
64 int ret;
65 struct gpio_event_info **ii;
66
67 if (func == GPIO_EVENT_FUNC_INIT || func == GPIO_EVENT_FUNC_RESUME) {
68 ii = ip->info->info;
69 for (i = 0; i < ip->info->info_count; i++, ii++) {
70 if ((*ii)->func == NULL) {
71 ret = -ENODEV;
72 pr_err("gpio_event_probe: Incomplete pdata, "
73 "no function\n");
74 goto err_no_func;
75 }
76 if (func == GPIO_EVENT_FUNC_RESUME && (*ii)->no_suspend)
77 continue;
78 ret = (*ii)->func(ip->input_devs, *ii, &ip->state[i],
79 func);
80 if (ret) {
81 pr_err("gpio_event_probe: function failed\n");
82 goto err_func_failed;
83 }
84 }
85 return 0;
86 }
87
88 ret = 0;
89 i = ip->info->info_count;
90 ii = ip->info->info + i;
91 while (i > 0) {
92 i--;
93 ii--;
94 if ((func & ~1) == GPIO_EVENT_FUNC_SUSPEND && (*ii)->no_suspend)
95 continue;
96 (*ii)->func(ip->input_devs, *ii, &ip->state[i], func & ~1);
97err_func_failed:
98err_no_func:
99 ;
100 }
101 return ret;
102}
103
104#ifdef CONFIG_HAS_EARLYSUSPEND
105void gpio_event_suspend(struct early_suspend *h)
106{
107 struct gpio_event *ip;
108 ip = container_of(h, struct gpio_event, early_suspend);
109 gpio_event_call_all_func(ip, GPIO_EVENT_FUNC_SUSPEND);
110 ip->info->power(ip->info, 0);
111}
112
113void gpio_event_resume(struct early_suspend *h)
114{
115 struct gpio_event *ip;
116 ip = container_of(h, struct gpio_event, early_suspend);
117 ip->info->power(ip->info, 1);
118 gpio_event_call_all_func(ip, GPIO_EVENT_FUNC_RESUME);
119}
120#endif
121
122static int gpio_event_probe(struct platform_device *pdev)
123{
124 int err;
125 struct gpio_event *ip;
126 struct gpio_event_platform_data *event_info;
127 int dev_count = 1;
128 int i;
129 int registered = 0;
130
131 event_info = pdev->dev.platform_data;
132 if (event_info == NULL) {
133 pr_err("gpio_event_probe: No pdata\n");
134 return -ENODEV;
135 }
136 if ((!event_info->name && !event_info->names[0]) ||
137 !event_info->info || !event_info->info_count) {
138 pr_err("gpio_event_probe: Incomplete pdata\n");
139 return -ENODEV;
140 }
141 if (!event_info->name)
142 while (event_info->names[dev_count])
143 dev_count++;
144 ip = kzalloc(sizeof(*ip) +
145 sizeof(ip->state[0]) * event_info->info_count +
146 sizeof(*ip->input_devs) +
147 sizeof(ip->input_devs->dev[0]) * dev_count, GFP_KERNEL);
148 if (ip == NULL) {
149 err = -ENOMEM;
150 pr_err("gpio_event_probe: Failed to allocate private data\n");
151 goto err_kp_alloc_failed;
152 }
153 ip->input_devs = (void*)&ip->state[event_info->info_count];
154 platform_set_drvdata(pdev, ip);
155
156 for (i = 0; i < dev_count; i++) {
157 struct input_dev *input_dev = input_allocate_device();
158 if (input_dev == NULL) {
159 err = -ENOMEM;
160 pr_err("gpio_event_probe: "
161 "Failed to allocate input device\n");
162 goto err_input_dev_alloc_failed;
163 }
164 input_set_drvdata(input_dev, ip);
165 input_dev->name = event_info->name ?
166 event_info->name : event_info->names[i];
167 input_dev->event = gpio_input_event;
168 ip->input_devs->dev[i] = input_dev;
169 }
170 ip->input_devs->count = dev_count;
171 ip->info = event_info;
172 if (event_info->power) {
173#ifdef CONFIG_HAS_EARLYSUSPEND
174 ip->early_suspend.level = EARLY_SUSPEND_LEVEL_BLANK_SCREEN + 1;
175 ip->early_suspend.suspend = gpio_event_suspend;
176 ip->early_suspend.resume = gpio_event_resume;
177 register_early_suspend(&ip->early_suspend);
178#endif
179 ip->info->power(ip->info, 1);
180 }
181
182 err = gpio_event_call_all_func(ip, GPIO_EVENT_FUNC_INIT);
183 if (err)
184 goto err_call_all_func_failed;
185
186 for (i = 0; i < dev_count; i++) {
187 err = input_register_device(ip->input_devs->dev[i]);
188 if (err) {
189 pr_err("gpio_event_probe: Unable to register %s "
190 "input device\n", ip->input_devs->dev[i]->name);
191 goto err_input_register_device_failed;
192 }
193 registered++;
194 }
195
196 return 0;
197
198err_input_register_device_failed:
199 gpio_event_call_all_func(ip, GPIO_EVENT_FUNC_UNINIT);
200err_call_all_func_failed:
201 if (event_info->power) {
202#ifdef CONFIG_HAS_EARLYSUSPEND
203 unregister_early_suspend(&ip->early_suspend);
204#endif
205 ip->info->power(ip->info, 0);
206 }
207 for (i = 0; i < registered; i++)
208 input_unregister_device(ip->input_devs->dev[i]);
209 for (i = dev_count - 1; i >= registered; i--) {
210 input_free_device(ip->input_devs->dev[i]);
211err_input_dev_alloc_failed:
212 ;
213 }
214 kfree(ip);
215err_kp_alloc_failed:
216 return err;
217}
218
219static int gpio_event_remove(struct platform_device *pdev)
220{
221 struct gpio_event *ip = platform_get_drvdata(pdev);
222 int i;
223
224 gpio_event_call_all_func(ip, GPIO_EVENT_FUNC_UNINIT);
225 if (ip->info->power) {
226#ifdef CONFIG_HAS_EARLYSUSPEND
227 unregister_early_suspend(&ip->early_suspend);
228#endif
229 ip->info->power(ip->info, 0);
230 }
231 for (i = 0; i < ip->input_devs->count; i++)
232 input_unregister_device(ip->input_devs->dev[i]);
233 kfree(ip);
234 return 0;
235}
236
237static struct platform_driver gpio_event_driver = {
238 .probe = gpio_event_probe,
239 .remove = gpio_event_remove,
240 .driver = {
241 .name = GPIO_EVENT_DEV_NAME,
242 },
243};
244
245static int __devinit gpio_event_init(void)
246{
247 return platform_driver_register(&gpio_event_driver);
248}
249
250static void __exit gpio_event_exit(void)
251{
252 platform_driver_unregister(&gpio_event_driver);
253}
254
255module_init(gpio_event_init);
256module_exit(gpio_event_exit);
257
258MODULE_DESCRIPTION("GPIO Event Driver");
259MODULE_LICENSE("GPL");
260
diff --git a/drivers/input/misc/gpio_input.c b/drivers/input/misc/gpio_input.c
new file mode 100644
index 00000000000..6a0c3151096
--- /dev/null
+++ b/drivers/input/misc/gpio_input.c
@@ -0,0 +1,376 @@
1/* drivers/input/misc/gpio_input.c
2 *
3 * Copyright (C) 2007 Google, Inc.
4 *
5 * This software is licensed under the terms of the GNU General Public
6 * License version 2, as published by the Free Software Foundation, and
7 * may be copied, distributed, and modified under those terms.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 */
15
16#include <linux/kernel.h>
17#include <linux/gpio.h>
18#include <linux/gpio_event.h>
19#include <linux/hrtimer.h>
20#include <linux/input.h>
21#include <linux/interrupt.h>
22#include <linux/slab.h>
23#include <linux/wakelock.h>
24
25enum {
26 DEBOUNCE_UNSTABLE = BIT(0), /* Got irq, while debouncing */
27 DEBOUNCE_PRESSED = BIT(1),
28 DEBOUNCE_NOTPRESSED = BIT(2),
29 DEBOUNCE_WAIT_IRQ = BIT(3), /* Stable irq state */
30 DEBOUNCE_POLL = BIT(4), /* Stable polling state */
31
32 DEBOUNCE_UNKNOWN =
33 DEBOUNCE_PRESSED | DEBOUNCE_NOTPRESSED,
34};
35
36struct gpio_key_state {
37 struct gpio_input_state *ds;
38 uint8_t debounce;
39};
40
41struct gpio_input_state {
42 struct gpio_event_input_devs *input_devs;
43 const struct gpio_event_input_info *info;
44 struct hrtimer timer;
45 int use_irq;
46 int debounce_count;
47 spinlock_t irq_lock;
48 struct wake_lock wake_lock;
49 struct gpio_key_state key_state[0];
50};
51
52static enum hrtimer_restart gpio_event_input_timer_func(struct hrtimer *timer)
53{
54 int i;
55 int pressed;
56 struct gpio_input_state *ds =
57 container_of(timer, struct gpio_input_state, timer);
58 unsigned gpio_flags = ds->info->flags;
59 unsigned npolarity;
60 int nkeys = ds->info->keymap_size;
61 const struct gpio_event_direct_entry *key_entry;
62 struct gpio_key_state *key_state;
63 unsigned long irqflags;
64 uint8_t debounce;
65 bool sync_needed;
66
67#if 0
68 key_entry = kp->keys_info->keymap;
69 key_state = kp->key_state;
70 for (i = 0; i < nkeys; i++, key_entry++, key_state++)
71 pr_info("gpio_read_detect_status %d %d\n", key_entry->gpio,
72 gpio_read_detect_status(key_entry->gpio));
73#endif
74 key_entry = ds->info->keymap;
75 key_state = ds->key_state;
76 sync_needed = false;
77 spin_lock_irqsave(&ds->irq_lock, irqflags);
78 for (i = 0; i < nkeys; i++, key_entry++, key_state++) {
79 debounce = key_state->debounce;
80 if (debounce & DEBOUNCE_WAIT_IRQ)
81 continue;
82 if (key_state->debounce & DEBOUNCE_UNSTABLE) {
83 debounce = key_state->debounce = DEBOUNCE_UNKNOWN;
84 enable_irq(gpio_to_irq(key_entry->gpio));
85 if (gpio_flags & GPIOEDF_PRINT_KEY_UNSTABLE)
86 pr_info("gpio_keys_scan_keys: key %x-%x, %d "
87 "(%d) continue debounce\n",
88 ds->info->type, key_entry->code,
89 i, key_entry->gpio);
90 }
91 npolarity = !(gpio_flags & GPIOEDF_ACTIVE_HIGH);
92 pressed = gpio_get_value(key_entry->gpio) ^ npolarity;
93 if (debounce & DEBOUNCE_POLL) {
94 if (pressed == !(debounce & DEBOUNCE_PRESSED)) {
95 ds->debounce_count++;
96 key_state->debounce = DEBOUNCE_UNKNOWN;
97 if (gpio_flags & GPIOEDF_PRINT_KEY_DEBOUNCE)
98 pr_info("gpio_keys_scan_keys: key %x-"
99 "%x, %d (%d) start debounce\n",
100 ds->info->type, key_entry->code,
101 i, key_entry->gpio);
102 }
103 continue;
104 }
105 if (pressed && (debounce & DEBOUNCE_NOTPRESSED)) {
106 if (gpio_flags & GPIOEDF_PRINT_KEY_DEBOUNCE)
107 pr_info("gpio_keys_scan_keys: key %x-%x, %d "
108 "(%d) debounce pressed 1\n",
109 ds->info->type, key_entry->code,
110 i, key_entry->gpio);
111 key_state->debounce = DEBOUNCE_PRESSED;
112 continue;
113 }
114 if (!pressed && (debounce & DEBOUNCE_PRESSED)) {
115 if (gpio_flags & GPIOEDF_PRINT_KEY_DEBOUNCE)
116 pr_info("gpio_keys_scan_keys: key %x-%x, %d "
117 "(%d) debounce pressed 0\n",
118 ds->info->type, key_entry->code,
119 i, key_entry->gpio);
120 key_state->debounce = DEBOUNCE_NOTPRESSED;
121 continue;
122 }
123 /* key is stable */
124 ds->debounce_count--;
125 if (ds->use_irq)
126 key_state->debounce |= DEBOUNCE_WAIT_IRQ;
127 else
128 key_state->debounce |= DEBOUNCE_POLL;
129 if (gpio_flags & GPIOEDF_PRINT_KEYS)
130 pr_info("gpio_keys_scan_keys: key %x-%x, %d (%d) "
131 "changed to %d\n", ds->info->type,
132 key_entry->code, i, key_entry->gpio, pressed);
133 input_event(ds->input_devs->dev[key_entry->dev], ds->info->type,
134 key_entry->code, pressed);
135 sync_needed = true;
136 }
137 if (sync_needed) {
138 for (i = 0; i < ds->input_devs->count; i++)
139 input_sync(ds->input_devs->dev[i]);
140 }
141
142#if 0
143 key_entry = kp->keys_info->keymap;
144 key_state = kp->key_state;
145 for (i = 0; i < nkeys; i++, key_entry++, key_state++) {
146 pr_info("gpio_read_detect_status %d %d\n", key_entry->gpio,
147 gpio_read_detect_status(key_entry->gpio));
148 }
149#endif
150
151 if (ds->debounce_count)
152 hrtimer_start(timer, ds->info->debounce_time, HRTIMER_MODE_REL);
153 else if (!ds->use_irq)
154 hrtimer_start(timer, ds->info->poll_time, HRTIMER_MODE_REL);
155 else
156 wake_unlock(&ds->wake_lock);
157
158 spin_unlock_irqrestore(&ds->irq_lock, irqflags);
159
160 return HRTIMER_NORESTART;
161}
162
163static irqreturn_t gpio_event_input_irq_handler(int irq, void *dev_id)
164{
165 struct gpio_key_state *ks = dev_id;
166 struct gpio_input_state *ds = ks->ds;
167 int keymap_index = ks - ds->key_state;
168 const struct gpio_event_direct_entry *key_entry;
169 unsigned long irqflags;
170 int pressed;
171
172 if (!ds->use_irq)
173 return IRQ_HANDLED;
174
175 key_entry = &ds->info->keymap[keymap_index];
176
177 if (ds->info->debounce_time.tv64) {
178 spin_lock_irqsave(&ds->irq_lock, irqflags);
179 if (ks->debounce & DEBOUNCE_WAIT_IRQ) {
180 ks->debounce = DEBOUNCE_UNKNOWN;
181 if (ds->debounce_count++ == 0) {
182 wake_lock(&ds->wake_lock);
183 hrtimer_start(
184 &ds->timer, ds->info->debounce_time,
185 HRTIMER_MODE_REL);
186 }
187 if (ds->info->flags & GPIOEDF_PRINT_KEY_DEBOUNCE)
188 pr_info("gpio_event_input_irq_handler: "
189 "key %x-%x, %d (%d) start debounce\n",
190 ds->info->type, key_entry->code,
191 keymap_index, key_entry->gpio);
192 } else {
193 disable_irq_nosync(irq);
194 ks->debounce = DEBOUNCE_UNSTABLE;
195 }
196 spin_unlock_irqrestore(&ds->irq_lock, irqflags);
197 } else {
198 pressed = gpio_get_value(key_entry->gpio) ^
199 !(ds->info->flags & GPIOEDF_ACTIVE_HIGH);
200 if (ds->info->flags & GPIOEDF_PRINT_KEYS)
201 pr_info("gpio_event_input_irq_handler: key %x-%x, %d "
202 "(%d) changed to %d\n",
203 ds->info->type, key_entry->code, keymap_index,
204 key_entry->gpio, pressed);
205 input_event(ds->input_devs->dev[key_entry->dev], ds->info->type,
206 key_entry->code, pressed);
207 input_sync(ds->input_devs->dev[key_entry->dev]);
208 }
209 return IRQ_HANDLED;
210}
211
212static int gpio_event_input_request_irqs(struct gpio_input_state *ds)
213{
214 int i;
215 int err;
216 unsigned int irq;
217 unsigned long req_flags = IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING;
218
219 for (i = 0; i < ds->info->keymap_size; i++) {
220 err = irq = gpio_to_irq(ds->info->keymap[i].gpio);
221 if (err < 0)
222 goto err_gpio_get_irq_num_failed;
223 err = request_irq(irq, gpio_event_input_irq_handler,
224 req_flags, "gpio_keys", &ds->key_state[i]);
225 if (err) {
226 pr_err("gpio_event_input_request_irqs: request_irq "
227 "failed for input %d, irq %d\n",
228 ds->info->keymap[i].gpio, irq);
229 goto err_request_irq_failed;
230 }
231 if (ds->info->info.no_suspend) {
232 err = enable_irq_wake(irq);
233 if (err) {
234 pr_err("gpio_event_input_request_irqs: "
235 "enable_irq_wake failed for input %d, "
236 "irq %d\n",
237 ds->info->keymap[i].gpio, irq);
238 goto err_enable_irq_wake_failed;
239 }
240 }
241 }
242 return 0;
243
244 for (i = ds->info->keymap_size - 1; i >= 0; i--) {
245 irq = gpio_to_irq(ds->info->keymap[i].gpio);
246 if (ds->info->info.no_suspend)
247 disable_irq_wake(irq);
248err_enable_irq_wake_failed:
249 free_irq(irq, &ds->key_state[i]);
250err_request_irq_failed:
251err_gpio_get_irq_num_failed:
252 ;
253 }
254 return err;
255}
256
257int gpio_event_input_func(struct gpio_event_input_devs *input_devs,
258 struct gpio_event_info *info, void **data, int func)
259{
260 int ret;
261 int i;
262 unsigned long irqflags;
263 struct gpio_event_input_info *di;
264 struct gpio_input_state *ds = *data;
265
266 di = container_of(info, struct gpio_event_input_info, info);
267
268 if (func == GPIO_EVENT_FUNC_SUSPEND) {
269 if (ds->use_irq)
270 for (i = 0; i < di->keymap_size; i++)
271 disable_irq(gpio_to_irq(di->keymap[i].gpio));
272 hrtimer_cancel(&ds->timer);
273 return 0;
274 }
275 if (func == GPIO_EVENT_FUNC_RESUME) {
276 spin_lock_irqsave(&ds->irq_lock, irqflags);
277 if (ds->use_irq)
278 for (i = 0; i < di->keymap_size; i++)
279 enable_irq(gpio_to_irq(di->keymap[i].gpio));
280 hrtimer_start(&ds->timer, ktime_set(0, 0), HRTIMER_MODE_REL);
281 spin_unlock_irqrestore(&ds->irq_lock, irqflags);
282 return 0;
283 }
284
285 if (func == GPIO_EVENT_FUNC_INIT) {
286 if (ktime_to_ns(di->poll_time) <= 0)
287 di->poll_time = ktime_set(0, 20 * NSEC_PER_MSEC);
288
289 *data = ds = kzalloc(sizeof(*ds) + sizeof(ds->key_state[0]) *
290 di->keymap_size, GFP_KERNEL);
291 if (ds == NULL) {
292 ret = -ENOMEM;
293 pr_err("gpio_event_input_func: "
294 "Failed to allocate private data\n");
295 goto err_ds_alloc_failed;
296 }
297 ds->debounce_count = di->keymap_size;
298 ds->input_devs = input_devs;
299 ds->info = di;
300 wake_lock_init(&ds->wake_lock, WAKE_LOCK_SUSPEND, "gpio_input");
301 spin_lock_init(&ds->irq_lock);
302
303 for (i = 0; i < di->keymap_size; i++) {
304 int dev = di->keymap[i].dev;
305 if (dev >= input_devs->count) {
306 pr_err("gpio_event_input_func: bad device "
307 "index %d >= %d for key code %d\n",
308 dev, input_devs->count,
309 di->keymap[i].code);
310 ret = -EINVAL;
311 goto err_bad_keymap;
312 }
313 input_set_capability(input_devs->dev[dev], di->type,
314 di->keymap[i].code);
315 ds->key_state[i].ds = ds;
316 ds->key_state[i].debounce = DEBOUNCE_UNKNOWN;
317 }
318
319 for (i = 0; i < di->keymap_size; i++) {
320 ret = gpio_request(di->keymap[i].gpio, "gpio_kp_in");
321 if (ret) {
322 pr_err("gpio_event_input_func: gpio_request "
323 "failed for %d\n", di->keymap[i].gpio);
324 goto err_gpio_request_failed;
325 }
326 ret = gpio_direction_input(di->keymap[i].gpio);
327 if (ret) {
328 pr_err("gpio_event_input_func: "
329 "gpio_direction_input failed for %d\n",
330 di->keymap[i].gpio);
331 goto err_gpio_configure_failed;
332 }
333 }
334
335 ret = gpio_event_input_request_irqs(ds);
336
337 spin_lock_irqsave(&ds->irq_lock, irqflags);
338 ds->use_irq = ret == 0;
339
340 pr_info("GPIO Input Driver: Start gpio inputs for %s%s in %s "
341 "mode\n", input_devs->dev[0]->name,
342 (input_devs->count > 1) ? "..." : "",
343 ret == 0 ? "interrupt" : "polling");
344
345 hrtimer_init(&ds->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
346 ds->timer.function = gpio_event_input_timer_func;
347 hrtimer_start(&ds->timer, ktime_set(0, 0), HRTIMER_MODE_REL);
348 spin_unlock_irqrestore(&ds->irq_lock, irqflags);
349 return 0;
350 }
351
352 ret = 0;
353 spin_lock_irqsave(&ds->irq_lock, irqflags);
354 hrtimer_cancel(&ds->timer);
355 if (ds->use_irq) {
356 for (i = di->keymap_size - 1; i >= 0; i--) {
357 int irq = gpio_to_irq(di->keymap[i].gpio);
358 if (ds->info->info.no_suspend)
359 disable_irq_wake(irq);
360 free_irq(irq, &ds->key_state[i]);
361 }
362 }
363 spin_unlock_irqrestore(&ds->irq_lock, irqflags);
364
365 for (i = di->keymap_size - 1; i >= 0; i--) {
366err_gpio_configure_failed:
367 gpio_free(di->keymap[i].gpio);
368err_gpio_request_failed:
369 ;
370 }
371err_bad_keymap:
372 wake_lock_destroy(&ds->wake_lock);
373 kfree(ds);
374err_ds_alloc_failed:
375 return ret;
376}
diff --git a/drivers/input/misc/gpio_matrix.c b/drivers/input/misc/gpio_matrix.c
new file mode 100644
index 00000000000..eaa9e89d473
--- /dev/null
+++ b/drivers/input/misc/gpio_matrix.c
@@ -0,0 +1,441 @@
1/* drivers/input/misc/gpio_matrix.c
2 *
3 * Copyright (C) 2007 Google, Inc.
4 *
5 * This software is licensed under the terms of the GNU General Public
6 * License version 2, as published by the Free Software Foundation, and
7 * may be copied, distributed, and modified under those terms.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 */
15
16#include <linux/kernel.h>
17#include <linux/gpio.h>
18#include <linux/gpio_event.h>
19#include <linux/hrtimer.h>
20#include <linux/interrupt.h>
21#include <linux/slab.h>
22#include <linux/wakelock.h>
23
24struct gpio_kp {
25 struct gpio_event_input_devs *input_devs;
26 struct gpio_event_matrix_info *keypad_info;
27 struct hrtimer timer;
28 struct wake_lock wake_lock;
29 int current_output;
30 unsigned int use_irq:1;
31 unsigned int key_state_changed:1;
32 unsigned int last_key_state_changed:1;
33 unsigned int some_keys_pressed:2;
34 unsigned int disabled_irq:1;
35 unsigned long keys_pressed[0];
36};
37
38static void clear_phantom_key(struct gpio_kp *kp, int out, int in)
39{
40 struct gpio_event_matrix_info *mi = kp->keypad_info;
41 int key_index = out * mi->ninputs + in;
42 unsigned short keyentry = mi->keymap[key_index];
43 unsigned short keycode = keyentry & MATRIX_KEY_MASK;
44 unsigned short dev = keyentry >> MATRIX_CODE_BITS;
45
46 if (!test_bit(keycode, kp->input_devs->dev[dev]->key)) {
47 if (mi->flags & GPIOKPF_PRINT_PHANTOM_KEYS)
48 pr_info("gpiomatrix: phantom key %x, %d-%d (%d-%d) "
49 "cleared\n", keycode, out, in,
50 mi->output_gpios[out], mi->input_gpios[in]);
51 __clear_bit(key_index, kp->keys_pressed);
52 } else {
53 if (mi->flags & GPIOKPF_PRINT_PHANTOM_KEYS)
54 pr_info("gpiomatrix: phantom key %x, %d-%d (%d-%d) "
55 "not cleared\n", keycode, out, in,
56 mi->output_gpios[out], mi->input_gpios[in]);
57 }
58}
59
60static int restore_keys_for_input(struct gpio_kp *kp, int out, int in)
61{
62 int rv = 0;
63 int key_index;
64
65 key_index = out * kp->keypad_info->ninputs + in;
66 while (out < kp->keypad_info->noutputs) {
67 if (test_bit(key_index, kp->keys_pressed)) {
68 rv = 1;
69 clear_phantom_key(kp, out, in);
70 }
71 key_index += kp->keypad_info->ninputs;
72 out++;
73 }
74 return rv;
75}
76
77static void remove_phantom_keys(struct gpio_kp *kp)
78{
79 int out, in, inp;
80 int key_index;
81
82 if (kp->some_keys_pressed < 3)
83 return;
84
85 for (out = 0; out < kp->keypad_info->noutputs; out++) {
86 inp = -1;
87 key_index = out * kp->keypad_info->ninputs;
88 for (in = 0; in < kp->keypad_info->ninputs; in++, key_index++) {
89 if (test_bit(key_index, kp->keys_pressed)) {
90 if (inp == -1) {
91 inp = in;
92 continue;
93 }
94 if (inp >= 0) {
95 if (!restore_keys_for_input(kp, out + 1,
96 inp))
97 break;
98 clear_phantom_key(kp, out, inp);
99 inp = -2;
100 }
101 restore_keys_for_input(kp, out, in);
102 }
103 }
104 }
105}
106
107static void report_key(struct gpio_kp *kp, int key_index, int out, int in)
108{
109 struct gpio_event_matrix_info *mi = kp->keypad_info;
110 int pressed = test_bit(key_index, kp->keys_pressed);
111 unsigned short keyentry = mi->keymap[key_index];
112 unsigned short keycode = keyentry & MATRIX_KEY_MASK;
113 unsigned short dev = keyentry >> MATRIX_CODE_BITS;
114
115 if (pressed != test_bit(keycode, kp->input_devs->dev[dev]->key)) {
116 if (keycode == KEY_RESERVED) {
117 if (mi->flags & GPIOKPF_PRINT_UNMAPPED_KEYS)
118 pr_info("gpiomatrix: unmapped key, %d-%d "
119 "(%d-%d) changed to %d\n",
120 out, in, mi->output_gpios[out],
121 mi->input_gpios[in], pressed);
122 } else {
123 if (mi->flags & GPIOKPF_PRINT_MAPPED_KEYS)
124 pr_info("gpiomatrix: key %x, %d-%d (%d-%d) "
125 "changed to %d\n", keycode,
126 out, in, mi->output_gpios[out],
127 mi->input_gpios[in], pressed);
128 input_report_key(kp->input_devs->dev[dev], keycode, pressed);
129 }
130 }
131}
132
133static void report_sync(struct gpio_kp *kp)
134{
135 int i;
136
137 for (i = 0; i < kp->input_devs->count; i++)
138 input_sync(kp->input_devs->dev[i]);
139}
140
141static enum hrtimer_restart gpio_keypad_timer_func(struct hrtimer *timer)
142{
143 int out, in;
144 int key_index;
145 int gpio;
146 struct gpio_kp *kp = container_of(timer, struct gpio_kp, timer);
147 struct gpio_event_matrix_info *mi = kp->keypad_info;
148 unsigned gpio_keypad_flags = mi->flags;
149 unsigned polarity = !!(gpio_keypad_flags & GPIOKPF_ACTIVE_HIGH);
150
151 out = kp->current_output;
152 if (out == mi->noutputs) {
153 out = 0;
154 kp->last_key_state_changed = kp->key_state_changed;
155 kp->key_state_changed = 0;
156 kp->some_keys_pressed = 0;
157 } else {
158 key_index = out * mi->ninputs;
159 for (in = 0; in < mi->ninputs; in++, key_index++) {
160 gpio = mi->input_gpios[in];
161 if (gpio_get_value(gpio) ^ !polarity) {
162 if (kp->some_keys_pressed < 3)
163 kp->some_keys_pressed++;
164 kp->key_state_changed |= !__test_and_set_bit(
165 key_index, kp->keys_pressed);
166 } else
167 kp->key_state_changed |= __test_and_clear_bit(
168 key_index, kp->keys_pressed);
169 }
170 gpio = mi->output_gpios[out];
171 if (gpio_keypad_flags & GPIOKPF_DRIVE_INACTIVE)
172 gpio_set_value(gpio, !polarity);
173 else
174 gpio_direction_input(gpio);
175 out++;
176 }
177 kp->current_output = out;
178 if (out < mi->noutputs) {
179 gpio = mi->output_gpios[out];
180 if (gpio_keypad_flags & GPIOKPF_DRIVE_INACTIVE)
181 gpio_set_value(gpio, polarity);
182 else
183 gpio_direction_output(gpio, polarity);
184 hrtimer_start(timer, mi->settle_time, HRTIMER_MODE_REL);
185 return HRTIMER_NORESTART;
186 }
187 if (gpio_keypad_flags & GPIOKPF_DEBOUNCE) {
188 if (kp->key_state_changed) {
189 hrtimer_start(&kp->timer, mi->debounce_delay,
190 HRTIMER_MODE_REL);
191 return HRTIMER_NORESTART;
192 }
193 kp->key_state_changed = kp->last_key_state_changed;
194 }
195 if (kp->key_state_changed) {
196 if (gpio_keypad_flags & GPIOKPF_REMOVE_SOME_PHANTOM_KEYS)
197 remove_phantom_keys(kp);
198 key_index = 0;
199 for (out = 0; out < mi->noutputs; out++)
200 for (in = 0; in < mi->ninputs; in++, key_index++)
201 report_key(kp, key_index, out, in);
202 report_sync(kp);
203 }
204 if (!kp->use_irq || kp->some_keys_pressed) {
205 hrtimer_start(timer, mi->poll_time, HRTIMER_MODE_REL);
206 return HRTIMER_NORESTART;
207 }
208
209 /* No keys are pressed, reenable interrupt */
210 for (out = 0; out < mi->noutputs; out++) {
211 if (gpio_keypad_flags & GPIOKPF_DRIVE_INACTIVE)
212 gpio_set_value(mi->output_gpios[out], polarity);
213 else
214 gpio_direction_output(mi->output_gpios[out], polarity);
215 }
216 for (in = 0; in < mi->ninputs; in++)
217 enable_irq(gpio_to_irq(mi->input_gpios[in]));
218 wake_unlock(&kp->wake_lock);
219 return HRTIMER_NORESTART;
220}
221
222static irqreturn_t gpio_keypad_irq_handler(int irq_in, void *dev_id)
223{
224 int i;
225 struct gpio_kp *kp = dev_id;
226 struct gpio_event_matrix_info *mi = kp->keypad_info;
227 unsigned gpio_keypad_flags = mi->flags;
228
229 if (!kp->use_irq) {
230 /* ignore interrupt while registering the handler */
231 kp->disabled_irq = 1;
232 disable_irq_nosync(irq_in);
233 return IRQ_HANDLED;
234 }
235
236 for (i = 0; i < mi->ninputs; i++)
237 disable_irq_nosync(gpio_to_irq(mi->input_gpios[i]));
238 for (i = 0; i < mi->noutputs; i++) {
239 if (gpio_keypad_flags & GPIOKPF_DRIVE_INACTIVE)
240 gpio_set_value(mi->output_gpios[i],
241 !(gpio_keypad_flags & GPIOKPF_ACTIVE_HIGH));
242 else
243 gpio_direction_input(mi->output_gpios[i]);
244 }
245 wake_lock(&kp->wake_lock);
246 hrtimer_start(&kp->timer, ktime_set(0, 0), HRTIMER_MODE_REL);
247 return IRQ_HANDLED;
248}
249
250static int gpio_keypad_request_irqs(struct gpio_kp *kp)
251{
252 int i;
253 int err;
254 unsigned int irq;
255 unsigned long request_flags;
256 struct gpio_event_matrix_info *mi = kp->keypad_info;
257
258 switch (mi->flags & (GPIOKPF_ACTIVE_HIGH|GPIOKPF_LEVEL_TRIGGERED_IRQ)) {
259 default:
260 request_flags = IRQF_TRIGGER_FALLING;
261 break;
262 case GPIOKPF_ACTIVE_HIGH:
263 request_flags = IRQF_TRIGGER_RISING;
264 break;
265 case GPIOKPF_LEVEL_TRIGGERED_IRQ:
266 request_flags = IRQF_TRIGGER_LOW;
267 break;
268 case GPIOKPF_LEVEL_TRIGGERED_IRQ | GPIOKPF_ACTIVE_HIGH:
269 request_flags = IRQF_TRIGGER_HIGH;
270 break;
271 }
272
273 for (i = 0; i < mi->ninputs; i++) {
274 err = irq = gpio_to_irq(mi->input_gpios[i]);
275 if (err < 0)
276 goto err_gpio_get_irq_num_failed;
277 err = request_irq(irq, gpio_keypad_irq_handler, request_flags,
278 "gpio_kp", kp);
279 if (err) {
280 pr_err("gpiomatrix: request_irq failed for input %d, "
281 "irq %d\n", mi->input_gpios[i], irq);
282 goto err_request_irq_failed;
283 }
284 err = enable_irq_wake(irq);
285 if (err) {
286 pr_err("gpiomatrix: set_irq_wake failed for input %d, "
287 "irq %d\n", mi->input_gpios[i], irq);
288 }
289 disable_irq(irq);
290 if (kp->disabled_irq) {
291 kp->disabled_irq = 0;
292 enable_irq(irq);
293 }
294 }
295 return 0;
296
297 for (i = mi->noutputs - 1; i >= 0; i--) {
298 free_irq(gpio_to_irq(mi->input_gpios[i]), kp);
299err_request_irq_failed:
300err_gpio_get_irq_num_failed:
301 ;
302 }
303 return err;
304}
305
306int gpio_event_matrix_func(struct gpio_event_input_devs *input_devs,
307 struct gpio_event_info *info, void **data, int func)
308{
309 int i;
310 int err;
311 int key_count;
312 struct gpio_kp *kp;
313 struct gpio_event_matrix_info *mi;
314
315 mi = container_of(info, struct gpio_event_matrix_info, info);
316 if (func == GPIO_EVENT_FUNC_SUSPEND || func == GPIO_EVENT_FUNC_RESUME) {
317 /* TODO: disable scanning */
318 return 0;
319 }
320
321 if (func == GPIO_EVENT_FUNC_INIT) {
322 if (mi->keymap == NULL ||
323 mi->input_gpios == NULL ||
324 mi->output_gpios == NULL) {
325 err = -ENODEV;
326 pr_err("gpiomatrix: Incomplete pdata\n");
327 goto err_invalid_platform_data;
328 }
329 key_count = mi->ninputs * mi->noutputs;
330
331 *data = kp = kzalloc(sizeof(*kp) + sizeof(kp->keys_pressed[0]) *
332 BITS_TO_LONGS(key_count), GFP_KERNEL);
333 if (kp == NULL) {
334 err = -ENOMEM;
335 pr_err("gpiomatrix: Failed to allocate private data\n");
336 goto err_kp_alloc_failed;
337 }
338 kp->input_devs = input_devs;
339 kp->keypad_info = mi;
340 for (i = 0; i < key_count; i++) {
341 unsigned short keyentry = mi->keymap[i];
342 unsigned short keycode = keyentry & MATRIX_KEY_MASK;
343 unsigned short dev = keyentry >> MATRIX_CODE_BITS;
344 if (dev >= input_devs->count) {
345 pr_err("gpiomatrix: bad device index %d >= "
346 "%d for key code %d\n",
347 dev, input_devs->count, keycode);
348 err = -EINVAL;
349 goto err_bad_keymap;
350 }
351 if (keycode && keycode <= KEY_MAX)
352 input_set_capability(input_devs->dev[dev],
353 EV_KEY, keycode);
354 }
355
356 for (i = 0; i < mi->noutputs; i++) {
357 err = gpio_request(mi->output_gpios[i], "gpio_kp_out");
358 if (err) {
359 pr_err("gpiomatrix: gpio_request failed for "
360 "output %d\n", mi->output_gpios[i]);
361 goto err_request_output_gpio_failed;
362 }
363 if (gpio_cansleep(mi->output_gpios[i])) {
364 pr_err("gpiomatrix: unsupported output gpio %d,"
365 " can sleep\n", mi->output_gpios[i]);
366 err = -EINVAL;
367 goto err_output_gpio_configure_failed;
368 }
369 if (mi->flags & GPIOKPF_DRIVE_INACTIVE)
370 err = gpio_direction_output(mi->output_gpios[i],
371 !(mi->flags & GPIOKPF_ACTIVE_HIGH));
372 else
373 err = gpio_direction_input(mi->output_gpios[i]);
374 if (err) {
375 pr_err("gpiomatrix: gpio_configure failed for "
376 "output %d\n", mi->output_gpios[i]);
377 goto err_output_gpio_configure_failed;
378 }
379 }
380 for (i = 0; i < mi->ninputs; i++) {
381 err = gpio_request(mi->input_gpios[i], "gpio_kp_in");
382 if (err) {
383 pr_err("gpiomatrix: gpio_request failed for "
384 "input %d\n", mi->input_gpios[i]);
385 goto err_request_input_gpio_failed;
386 }
387 err = gpio_direction_input(mi->input_gpios[i]);
388 if (err) {
389 pr_err("gpiomatrix: gpio_direction_input failed"
390 " for input %d\n", mi->input_gpios[i]);
391 goto err_gpio_direction_input_failed;
392 }
393 }
394 kp->current_output = mi->noutputs;
395 kp->key_state_changed = 1;
396
397 hrtimer_init(&kp->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
398 kp->timer.function = gpio_keypad_timer_func;
399 wake_lock_init(&kp->wake_lock, WAKE_LOCK_SUSPEND, "gpio_kp");
400 err = gpio_keypad_request_irqs(kp);
401 kp->use_irq = err == 0;
402
403 pr_info("GPIO Matrix Keypad Driver: Start keypad matrix for "
404 "%s%s in %s mode\n", input_devs->dev[0]->name,
405 (input_devs->count > 1) ? "..." : "",
406 kp->use_irq ? "interrupt" : "polling");
407
408 if (kp->use_irq)
409 wake_lock(&kp->wake_lock);
410 hrtimer_start(&kp->timer, ktime_set(0, 0), HRTIMER_MODE_REL);
411
412 return 0;
413 }
414
415 err = 0;
416 kp = *data;
417
418 if (kp->use_irq)
419 for (i = mi->noutputs - 1; i >= 0; i--)
420 free_irq(gpio_to_irq(mi->input_gpios[i]), kp);
421
422 hrtimer_cancel(&kp->timer);
423 wake_lock_destroy(&kp->wake_lock);
424 for (i = mi->noutputs - 1; i >= 0; i--) {
425err_gpio_direction_input_failed:
426 gpio_free(mi->input_gpios[i]);
427err_request_input_gpio_failed:
428 ;
429 }
430 for (i = mi->noutputs - 1; i >= 0; i--) {
431err_output_gpio_configure_failed:
432 gpio_free(mi->output_gpios[i]);
433err_request_output_gpio_failed:
434 ;
435 }
436err_bad_keymap:
437 kfree(kp);
438err_kp_alloc_failed:
439err_invalid_platform_data:
440 return err;
441}
diff --git a/drivers/input/misc/gpio_output.c b/drivers/input/misc/gpio_output.c
new file mode 100644
index 00000000000..2aac2fad0a1
--- /dev/null
+++ b/drivers/input/misc/gpio_output.c
@@ -0,0 +1,97 @@
1/* drivers/input/misc/gpio_output.c
2 *
3 * Copyright (C) 2007 Google, Inc.
4 *
5 * This software is licensed under the terms of the GNU General Public
6 * License version 2, as published by the Free Software Foundation, and
7 * may be copied, distributed, and modified under those terms.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 */
15
16#include <linux/kernel.h>
17#include <linux/gpio.h>
18#include <linux/gpio_event.h>
19
20int gpio_event_output_event(
21 struct gpio_event_input_devs *input_devs, struct gpio_event_info *info,
22 void **data, unsigned int dev, unsigned int type,
23 unsigned int code, int value)
24{
25 int i;
26 struct gpio_event_output_info *oi;
27 oi = container_of(info, struct gpio_event_output_info, info);
28 if (type != oi->type)
29 return 0;
30 if (!(oi->flags & GPIOEDF_ACTIVE_HIGH))
31 value = !value;
32 for (i = 0; i < oi->keymap_size; i++)
33 if (dev == oi->keymap[i].dev && code == oi->keymap[i].code)
34 gpio_set_value(oi->keymap[i].gpio, value);
35 return 0;
36}
37
38int gpio_event_output_func(
39 struct gpio_event_input_devs *input_devs, struct gpio_event_info *info,
40 void **data, int func)
41{
42 int ret;
43 int i;
44 struct gpio_event_output_info *oi;
45 oi = container_of(info, struct gpio_event_output_info, info);
46
47 if (func == GPIO_EVENT_FUNC_SUSPEND || func == GPIO_EVENT_FUNC_RESUME)
48 return 0;
49
50 if (func == GPIO_EVENT_FUNC_INIT) {
51 int output_level = !(oi->flags & GPIOEDF_ACTIVE_HIGH);
52
53 for (i = 0; i < oi->keymap_size; i++) {
54 int dev = oi->keymap[i].dev;
55 if (dev >= input_devs->count) {
56 pr_err("gpio_event_output_func: bad device "
57 "index %d >= %d for key code %d\n",
58 dev, input_devs->count,
59 oi->keymap[i].code);
60 ret = -EINVAL;
61 goto err_bad_keymap;
62 }
63 input_set_capability(input_devs->dev[dev], oi->type,
64 oi->keymap[i].code);
65 }
66
67 for (i = 0; i < oi->keymap_size; i++) {
68 ret = gpio_request(oi->keymap[i].gpio,
69 "gpio_event_output");
70 if (ret) {
71 pr_err("gpio_event_output_func: gpio_request "
72 "failed for %d\n", oi->keymap[i].gpio);
73 goto err_gpio_request_failed;
74 }
75 ret = gpio_direction_output(oi->keymap[i].gpio,
76 output_level);
77 if (ret) {
78 pr_err("gpio_event_output_func: "
79 "gpio_direction_output failed for %d\n",
80 oi->keymap[i].gpio);
81 goto err_gpio_direction_output_failed;
82 }
83 }
84 return 0;
85 }
86
87 ret = 0;
88 for (i = oi->keymap_size - 1; i >= 0; i--) {
89err_gpio_direction_output_failed:
90 gpio_free(oi->keymap[i].gpio);
91err_gpio_request_failed:
92 ;
93 }
94err_bad_keymap:
95 return ret;
96}
97
diff --git a/drivers/input/misc/isa1200.c b/drivers/input/misc/isa1200.c
new file mode 100644
index 00000000000..deafa5ca2f7
--- /dev/null
+++ b/drivers/input/misc/isa1200.c
@@ -0,0 +1,324 @@
1/*
2 * ISA1200 linear virbrator driver
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version 2
7 * of the License, or (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
17 * MA 02110-1301, USA.
18 */
19#include <linux/delay.h>
20#include <linux/errno.h>
21#include <linux/i2c.h>
22#include <linux/init.h>
23#include <linux/hrtimer.h>
24#include <linux/platform_device.h>
25#include <linux/device.h>
26#include <linux/kernel.h>
27#include <linux/slab.h>
28#include <linux/types.h>
29#include <linux/gpio.h>
30#include <linux/earlysuspend.h>
31#include <linux/input/isa1200.h>
32#include <linux/pwm.h>
33
34#include <plat/gpio-cfg.h>
35#include "../../staging/android/timed_output.h"
36
37#define ISA1200_VERSION "1.0.0"
38#define ISA1200_NAME "isa1200"
39
40//-----------------------------------------------------------------------------
41//-----------------------------------------------------------------------------
42/*
43 * driver private data
44 */
45struct isa1200_chip {
46 struct i2c_client *i2c;
47 struct isa1200_platform_data *pdata;
48
49 struct pwm_device *pwm;
50 struct timed_output_dev timed_output;
51
52 int period;
53 int duty;
54 int pwm_id;
55};
56
57//-----------------------------------------------------------------------------
58//-----------------------------------------------------------------------------
59enum
60{
61 HCTRL_0 = 0x30,
62 HCTRL_1,
63 HCTRL_2,
64 HCTRL_3,
65 HCTRL_4,
66 HCTRL_5,
67 HCTRL_6,
68 HCTRL_7,
69 HCTRL_8,
70 HCTRL_9,
71 HCTRL_A,
72 HCTRL_B,
73 HCTRL_C,
74 HCTRL_D,
75 HCTRL_E,
76 HCTRL_F,
77 HCTRL_MAX = 0x40
78};
79
80//-----------------------------------------------------------------------------
81//-----------------------------------------------------------------------------
82static int isa1200_hw_init(struct isa1200_chip *chip)
83{
84 struct i2c_client *client = chip->i2c;
85 int ret =0;
86 unsigned val=0;
87
88 // gpio_hen enable
89 ret = gpio_is_valid(chip->pdata->gpio_hen);
90 if (ret) {
91 ret = gpio_request(chip->pdata->gpio_hen, "gpio_hen");
92 if (ret) {
93 dev_err(&client->dev, "gpio %d request failed\n",
94 chip->pdata->gpio_hen);
95 return -EIO;
96 }
97 ret = gpio_direction_output(chip->pdata->gpio_hen, 1);
98 if (ret) {
99 dev_err(&client->dev, "gpio %d set direction failed\n",
100 chip->pdata->gpio_hen);
101 return -EIO;
102 }
103 gpio_free(chip->pdata->gpio_hen);
104 }
105 else return -EIO;
106
107 mdelay(1);
108
109 // gpio_len enable
110 ret = gpio_is_valid(chip->pdata->gpio_len);
111 if (ret) {
112 ret = gpio_request(chip->pdata->gpio_len, "gpio_len");
113 if (ret) {
114 dev_err(&client->dev, "gpio %d request failed\n",
115 chip->pdata->gpio_len);
116 return -EIO;
117 }
118 ret = gpio_direction_output(chip->pdata->gpio_len, 1);
119 if (ret) {
120 dev_err(&client->dev, "gpio %d set direction failed\n",
121 chip->pdata->gpio_len);
122 return -EIO;
123 }
124 gpio_free(chip->pdata->gpio_len);
125 }
126 else return -EIO;
127
128 //pwm port pin_func init
129 if (gpio_is_valid(chip->pdata->pwm_gpio)) {
130 ret = gpio_request(chip->pdata->pwm_gpio, "pwm_gpio");
131 if (ret)
132 printk(KERN_ERR "failed to get GPIO for PWM0\n");
133 s3c_gpio_cfgpin(chip->pdata->pwm_gpio, chip->pdata->pwm_func);
134 gpio_free(chip->pdata->pwm_gpio);
135 }
136
137 mdelay (1);
138 i2c_smbus_write_byte_data(client, HCTRL_2, 0x80); //Software reset enable
139 mdelay (1);
140 i2c_smbus_write_byte_data(client, HCTRL_2, 0x00); //Software reset disable
141 mdelay (1);
142 i2c_smbus_write_byte_data(client, HCTRL_0, 0x88); // PWM_INPUT Mode
143
144 val = i2c_smbus_read_byte_data(client, 0x00);
145 printk("%s : read val = 0x%02x\n",__func__,val);
146
147 return 0;
148}
149
150//-----------------------------------------------------------------------------
151//-----------------------------------------------------------------------------
152static void isa1200_vibrator_enable (struct timed_output_dev *dev, int value)
153{
154 struct isa1200_chip *chip = container_of(dev, struct isa1200_chip, timed_output);
155
156 if(10<value) {
157
158 if(5<value) value -=5;
159 pwm_disable(chip->pwm);
160 pwm_config(chip->pwm, chip->duty * chip->period / 255, chip->period);
161 pwm_enable(chip->pwm);
162 msleep_interruptible(value);
163 pwm_disable(chip->pwm);
164 }
165 return;
166}
167
168//-----------------------------------------------------------------------------
169//-----------------------------------------------------------------------------
170static int isa1200_vibrator_get_time (struct timed_output_dev *dev)
171{
172 return 0;
173}
174
175//-----------------------------------------------------------------------------
176//-----------------------------------------------------------------------------
177static struct timed_output_dev isa1200_vibrator = {
178 .name = "vibrator",
179 .get_time = isa1200_vibrator_get_time,
180 .enable = isa1200_vibrator_enable,
181};
182
183//-----------------------------------------------------------------------------
184//-----------------------------------------------------------------------------
185static int isa1200_i2c_probe (struct i2c_client *client, const struct i2c_device_id *id)
186{
187 struct isa1200_chip *chip;
188 struct device *dev = &client->dev;
189 int err;
190
191 /* setup i2c client */
192 if (!i2c_check_functionality (client->adapter, I2C_FUNC_SMBUS_BYTE_DATA)) {
193 dev_err(&client->dev, "i2c byte data not supported\n");
194 return -EIO;
195 }
196 if (!client->dev.platform_data) {
197 dev_err(&client->dev, "pdata is not available\n");
198 return -EINVAL;
199 }
200
201 chip = kzalloc (sizeof (struct isa1200_chip), GFP_KERNEL);
202 if (!chip)
203 return -ENOMEM;
204
205 chip->pdata = client->dev.platform_data;
206 chip->i2c = client;
207 i2c_set_clientdata (client, chip);
208
209 chip->pwm = pwm_request(chip->pdata->pwm_id, id->name);
210 chip->period = chip->pdata->pwm_periode_ns;
211 chip->duty = chip->pdata->pwm_duty;
212
213 pwm_disable(chip->pwm);
214
215 isa1200_hw_init(chip);
216
217 chip->timed_output = isa1200_vibrator;
218 err = timed_output_dev_register (&chip->timed_output);
219 if (err < 0)
220 goto error;
221
222 dev_set_drvdata(dev, chip);
223
224 return 0;
225
226error:
227 kfree (chip);
228 return -1;
229}
230
231//-----------------------------------------------------------------------------
232//-----------------------------------------------------------------------------
233static int isa1200_i2c_remove (struct i2c_client *client)
234{
235 struct isa1200_chip *isa1200 = i2c_get_clientdata (client);
236
237 timed_output_dev_unregister (&isa1200->timed_output);
238 i2c_set_clientdata (client, NULL);
239 kfree (isa1200);
240
241 return 0;
242}
243
244//-----------------------------------------------------------------------------
245//-----------------------------------------------------------------------------
246#ifdef CONFIG_PM
247#ifdef CONFIG_HAS_EARLYSUSPEND
248static void isa1200_early_suspend(struct early_suspend *h)
249{
250 printk("\t%s [%d]\n",__FUNCTION__,__LINE__);
251 return;
252}
253
254//-----------------------------------------------------------------------------
255//-----------------------------------------------------------------------------
256static void isa1200_late_resume(struct early_suspend *h)
257{
258 printk("%s\n",__FUNCTION__);
259 return;
260}
261
262//-----------------------------------------------------------------------------
263//-----------------------------------------------------------------------------
264static struct early_suspend isa1200_early_suspend_desc = {
265 .level = EARLY_SUSPEND_LEVEL_BLANK_SCREEN,
266 .suspend = isa1200_early_suspend,
267 .resume = isa1200_late_resume
268};
269#endif //CONFIG_HAS_EARLYSUSPEND
270#endif //CONFIG_PM
271
272//-----------------------------------------------------------------------------
273//-----------------------------------------------------------------------------
274static const struct i2c_device_id isa1200_id[] = {
275 {ISA1200_NAME, 0},
276 {},
277};
278MODULE_DEVICE_TABLE (i2c, isa1200_id);
279
280//-----------------------------------------------------------------------------
281//-----------------------------------------------------------------------------
282struct i2c_driver isa1200_driver = {
283 .driver = {
284 .name = "isa1200",
285 .owner = THIS_MODULE,
286 },
287 .probe = isa1200_i2c_probe,
288 .remove = isa1200_i2c_remove,
289 .id_table = isa1200_id,
290};
291
292//-----------------------------------------------------------------------------
293//-----------------------------------------------------------------------------
294static int __init isa1200_init (void)
295{
296 int ret;
297
298 ret = i2c_add_driver (&isa1200_driver);
299 if (ret) {
300 printk(KERN_ERR "i2c add driver Failed %d\n", ret);
301 return -1;
302 }
303#ifdef CONFIG_HAS_EARLYSUSPEND
304 register_early_suspend(&isa1200_early_suspend_desc);
305#endif
306 return 0;
307}
308module_init (isa1200_init);
309
310//-----------------------------------------------------------------------------
311//-----------------------------------------------------------------------------
312static void __exit isa1200_exit (void)
313{
314#ifdef CONFIG_HAS_EARLYSUSPEND
315 unregister_early_suspend(&isa1200_early_suspend_desc);
316#endif
317 i2c_del_driver (&isa1200_driver);
318}
319module_exit (isa1200_exit);
320
321
322MODULE_LICENSE ("GPL");
323MODULE_DESCRIPTION ("ISA1200 linear virbrator driver");
324MODULE_VERSION (ISA1200_VERSION);
diff --git a/drivers/input/misc/keychord.c b/drivers/input/misc/keychord.c
new file mode 100644
index 00000000000..3ffab6da411
--- /dev/null
+++ b/drivers/input/misc/keychord.c
@@ -0,0 +1,387 @@
1/*
2 * drivers/input/misc/keychord.c
3 *
4 * Copyright (C) 2008 Google, Inc.
5 * Author: Mike Lockwood <lockwood@android.com>
6 *
7 * This software is licensed under the terms of the GNU General Public
8 * License version 2, as published by the Free Software Foundation, and
9 * may be copied, distributed, and modified under those terms.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16*/
17
18#include <linux/poll.h>
19#include <linux/slab.h>
20#include <linux/module.h>
21#include <linux/init.h>
22#include <linux/spinlock.h>
23#include <linux/fs.h>
24#include <linux/miscdevice.h>
25#include <linux/keychord.h>
26#include <linux/sched.h>
27
28#define KEYCHORD_NAME "keychord"
29#define BUFFER_SIZE 16
30
31MODULE_AUTHOR("Mike Lockwood <lockwood@android.com>");
32MODULE_DESCRIPTION("Key chord input driver");
33MODULE_SUPPORTED_DEVICE("keychord");
34MODULE_LICENSE("GPL");
35
36#define NEXT_KEYCHORD(kc) ((struct input_keychord *) \
37 ((char *)kc + sizeof(struct input_keychord) + \
38 kc->count * sizeof(kc->keycodes[0])))
39
40struct keychord_device {
41 struct input_handler input_handler;
42 int registered;
43
44 /* list of keychords to monitor */
45 struct input_keychord *keychords;
46 int keychord_count;
47
48 /* bitmask of keys contained in our keychords */
49 unsigned long keybit[BITS_TO_LONGS(KEY_CNT)];
50 /* current state of the keys */
51 unsigned long keystate[BITS_TO_LONGS(KEY_CNT)];
52 /* number of keys that are currently pressed */
53 int key_down;
54
55 /* second input_device_id is needed for null termination */
56 struct input_device_id device_ids[2];
57
58 spinlock_t lock;
59 wait_queue_head_t waitq;
60 unsigned char head;
61 unsigned char tail;
62 __u16 buff[BUFFER_SIZE];
63};
64
65static int check_keychord(struct keychord_device *kdev,
66 struct input_keychord *keychord)
67{
68 int i;
69
70 if (keychord->count != kdev->key_down)
71 return 0;
72
73 for (i = 0; i < keychord->count; i++) {
74 if (!test_bit(keychord->keycodes[i], kdev->keystate))
75 return 0;
76 }
77
78 /* we have a match */
79 return 1;
80}
81
82static void keychord_event(struct input_handle *handle, unsigned int type,
83 unsigned int code, int value)
84{
85 struct keychord_device *kdev = handle->private;
86 struct input_keychord *keychord;
87 unsigned long flags;
88 int i, got_chord = 0;
89
90 if (type != EV_KEY || code >= KEY_MAX)
91 return;
92
93 spin_lock_irqsave(&kdev->lock, flags);
94 /* do nothing if key state did not change */
95 if (!test_bit(code, kdev->keystate) == !value)
96 goto done;
97 __change_bit(code, kdev->keystate);
98 if (value)
99 kdev->key_down++;
100 else
101 kdev->key_down--;
102
103 /* don't notify on key up */
104 if (!value)
105 goto done;
106 /* ignore this event if it is not one of the keys we are monitoring */
107 if (!test_bit(code, kdev->keybit))
108 goto done;
109
110 keychord = kdev->keychords;
111 if (!keychord)
112 goto done;
113
114 /* check to see if the keyboard state matches any keychords */
115 for (i = 0; i < kdev->keychord_count; i++) {
116 if (check_keychord(kdev, keychord)) {
117 kdev->buff[kdev->head] = keychord->id;
118 kdev->head = (kdev->head + 1) % BUFFER_SIZE;
119 got_chord = 1;
120 break;
121 }
122 /* skip to next keychord */
123 keychord = NEXT_KEYCHORD(keychord);
124 }
125
126done:
127 spin_unlock_irqrestore(&kdev->lock, flags);
128
129 if (got_chord)
130 wake_up_interruptible(&kdev->waitq);
131}
132
133static int keychord_connect(struct input_handler *handler,
134 struct input_dev *dev,
135 const struct input_device_id *id)
136{
137 int i, ret;
138 struct input_handle *handle;
139 struct keychord_device *kdev =
140 container_of(handler, struct keychord_device, input_handler);
141
142 /*
143 * ignore this input device if it does not contain any keycodes
144 * that we are monitoring
145 */
146 for (i = 0; i < KEY_MAX; i++) {
147 if (test_bit(i, kdev->keybit) && test_bit(i, dev->keybit))
148 break;
149 }
150 if (i == KEY_MAX)
151 return -ENODEV;
152
153 handle = kzalloc(sizeof(*handle), GFP_KERNEL);
154 if (!handle)
155 return -ENOMEM;
156
157 handle->dev = dev;
158 handle->handler = handler;
159 handle->name = KEYCHORD_NAME;
160 handle->private = kdev;
161
162 ret = input_register_handle(handle);
163 if (ret)
164 goto err_input_register_handle;
165
166 ret = input_open_device(handle);
167 if (ret)
168 goto err_input_open_device;
169
170 pr_info("keychord: using input dev %s for fevent\n", dev->name);
171
172 return 0;
173
174err_input_open_device:
175 input_unregister_handle(handle);
176err_input_register_handle:
177 kfree(handle);
178 return ret;
179}
180
181static void keychord_disconnect(struct input_handle *handle)
182{
183 input_close_device(handle);
184 input_unregister_handle(handle);
185 kfree(handle);
186}
187
188/*
189 * keychord_read is used to read keychord events from the driver
190 */
191static ssize_t keychord_read(struct file *file, char __user *buffer,
192 size_t count, loff_t *ppos)
193{
194 struct keychord_device *kdev = file->private_data;
195 __u16 id;
196 int retval;
197 unsigned long flags;
198
199 if (count < sizeof(id))
200 return -EINVAL;
201 count = sizeof(id);
202
203 if (kdev->head == kdev->tail && (file->f_flags & O_NONBLOCK))
204 return -EAGAIN;
205
206 retval = wait_event_interruptible(kdev->waitq,
207 kdev->head != kdev->tail);
208 if (retval)
209 return retval;
210
211 spin_lock_irqsave(&kdev->lock, flags);
212 /* pop a keychord ID off the queue */
213 id = kdev->buff[kdev->tail];
214 kdev->tail = (kdev->tail + 1) % BUFFER_SIZE;
215 spin_unlock_irqrestore(&kdev->lock, flags);
216
217 if (copy_to_user(buffer, &id, count))
218 return -EFAULT;
219
220 return count;
221}
222
223/*
224 * keychord_write is used to configure the driver
225 */
226static ssize_t keychord_write(struct file *file, const char __user *buffer,
227 size_t count, loff_t *ppos)
228{
229 struct keychord_device *kdev = file->private_data;
230 struct input_keychord *keychords = 0;
231 struct input_keychord *keychord, *next, *end;
232 int ret, i, key;
233 unsigned long flags;
234
235 if (count < sizeof(struct input_keychord))
236 return -EINVAL;
237 keychords = kzalloc(count, GFP_KERNEL);
238 if (!keychords)
239 return -ENOMEM;
240
241 /* read list of keychords from userspace */
242 if (copy_from_user(keychords, buffer, count)) {
243 kfree(keychords);
244 return -EFAULT;
245 }
246
247 /* unregister handler before changing configuration */
248 if (kdev->registered) {
249 input_unregister_handler(&kdev->input_handler);
250 kdev->registered = 0;
251 }
252
253 spin_lock_irqsave(&kdev->lock, flags);
254 /* clear any existing configuration */
255 kfree(kdev->keychords);
256 kdev->keychords = 0;
257 kdev->keychord_count = 0;
258 kdev->key_down = 0;
259 memset(kdev->keybit, 0, sizeof(kdev->keybit));
260 memset(kdev->keystate, 0, sizeof(kdev->keystate));
261 kdev->head = kdev->tail = 0;
262
263 keychord = keychords;
264 end = (struct input_keychord *)((char *)keychord + count);
265
266 while (keychord < end) {
267 next = NEXT_KEYCHORD(keychord);
268 if (keychord->count <= 0 || next > end) {
269 pr_err("keychord: invalid keycode count %d\n",
270 keychord->count);
271 goto err_unlock_return;
272 }
273 if (keychord->version != KEYCHORD_VERSION) {
274 pr_err("keychord: unsupported version %d\n",
275 keychord->version);
276 goto err_unlock_return;
277 }
278
279 /* keep track of the keys we are monitoring in keybit */
280 for (i = 0; i < keychord->count; i++) {
281 key = keychord->keycodes[i];
282 if (key < 0 || key >= KEY_CNT) {
283 pr_err("keychord: keycode %d out of range\n",
284 key);
285 goto err_unlock_return;
286 }
287 __set_bit(key, kdev->keybit);
288 }
289
290 kdev->keychord_count++;
291 keychord = next;
292 }
293
294 kdev->keychords = keychords;
295 spin_unlock_irqrestore(&kdev->lock, flags);
296
297 ret = input_register_handler(&kdev->input_handler);
298 if (ret) {
299 kfree(keychords);
300 kdev->keychords = 0;
301 return ret;
302 }
303 kdev->registered = 1;
304
305 return count;
306
307err_unlock_return:
308 spin_unlock_irqrestore(&kdev->lock, flags);
309 kfree(keychords);
310 return -EINVAL;
311}
312
313static unsigned int keychord_poll(struct file *file, poll_table *wait)
314{
315 struct keychord_device *kdev = file->private_data;
316
317 poll_wait(file, &kdev->waitq, wait);
318
319 if (kdev->head != kdev->tail)
320 return POLLIN | POLLRDNORM;
321
322 return 0;
323}
324
325static int keychord_open(struct inode *inode, struct file *file)
326{
327 struct keychord_device *kdev;
328
329 kdev = kzalloc(sizeof(struct keychord_device), GFP_KERNEL);
330 if (!kdev)
331 return -ENOMEM;
332
333 spin_lock_init(&kdev->lock);
334 init_waitqueue_head(&kdev->waitq);
335
336 kdev->input_handler.event = keychord_event;
337 kdev->input_handler.connect = keychord_connect;
338 kdev->input_handler.disconnect = keychord_disconnect;
339 kdev->input_handler.name = KEYCHORD_NAME;
340 kdev->input_handler.id_table = kdev->device_ids;
341
342 kdev->device_ids[0].flags = INPUT_DEVICE_ID_MATCH_EVBIT;
343 __set_bit(EV_KEY, kdev->device_ids[0].evbit);
344
345 file->private_data = kdev;
346
347 return 0;
348}
349
350static int keychord_release(struct inode *inode, struct file *file)
351{
352 struct keychord_device *kdev = file->private_data;
353
354 if (kdev->registered)
355 input_unregister_handler(&kdev->input_handler);
356 kfree(kdev);
357
358 return 0;
359}
360
361static const struct file_operations keychord_fops = {
362 .owner = THIS_MODULE,
363 .open = keychord_open,
364 .release = keychord_release,
365 .read = keychord_read,
366 .write = keychord_write,
367 .poll = keychord_poll,
368};
369
370static struct miscdevice keychord_misc = {
371 .fops = &keychord_fops,
372 .name = KEYCHORD_NAME,
373 .minor = MISC_DYNAMIC_MINOR,
374};
375
376static int __init keychord_init(void)
377{
378 return misc_register(&keychord_misc);
379}
380
381static void __exit keychord_exit(void)
382{
383 misc_deregister(&keychord_misc);
384}
385
386module_init(keychord_init);
387module_exit(keychord_exit);
diff --git a/drivers/input/touchscreen/Kconfig b/drivers/input/touchscreen/Kconfig
index cabd9e54863..9548d1ac272 100644
--- a/drivers/input/touchscreen/Kconfig
+++ b/drivers/input/touchscreen/Kconfig
@@ -11,6 +11,19 @@ menuconfig INPUT_TOUCHSCREEN
11 11
12if INPUT_TOUCHSCREEN 12if INPUT_TOUCHSCREEN
13 13
14config TOUCHSCREEN_DUMMY
15 bool "ODROID Dummy touchscreen driver"
16 depends on MACH_ODROID_4210 || MACH_ODROID_4X12
17 default n
18 ---help---
19 This enables support for ODROID default Touch panel
20
21config TOUCHSCREEN_SOLOMON_MT
22 bool "Solomon 10.1\" WXGA multi touch panel(I2C Driver)"
23 default n
24 ---help---
25 This enables support for ODROID-Q 10.1\" WXGA Touch panel (Multi-Touch)
26
14config TOUCHSCREEN_88PM860X 27config TOUCHSCREEN_88PM860X
15 tristate "Marvell 88PM860x touchscreen" 28 tristate "Marvell 88PM860x touchscreen"
16 depends on MFD_88PM860X 29 depends on MFD_88PM860X
@@ -192,8 +205,7 @@ config TOUCHSCREEN_FUJITSU
192 205
193config TOUCHSCREEN_S3C2410 206config TOUCHSCREEN_S3C2410
194 tristate "Samsung S3C2410/generic touchscreen input driver" 207 tristate "Samsung S3C2410/generic touchscreen input driver"
195 depends on ARCH_S3C2410 || SAMSUNG_DEV_TS 208 depends on ARCH_S3C2410 || SAMSUNG_DEV_TS && S3C_ADC
196 select S3C_ADC
197 help 209 help
198 Say Y here if you have the s3c2410 touchscreen. 210 Say Y here if you have the s3c2410 touchscreen.
199 211
@@ -202,6 +214,24 @@ config TOUCHSCREEN_S3C2410
202 To compile this driver as a module, choose M here: the 214 To compile this driver as a module, choose M here: the
203 module will be called s3c2410_ts. 215 module will be called s3c2410_ts.
204 216
217config TOUCHSCREEN_EXYNOS4
218 tristate "Samsung EXYNOS4 10.1\" touchscreen input driver"
219 depends on ARCH_EXYNOS4
220 help
221 Say Y here if you have the EXYNOS4 touchscreen.
222
223config TOUCHSCREEN_PIXCIR
224 tristate "PIXCIR 5\" touchscreen input driver"
225 depends on ARCH_EXYNOS4
226 help
227 Say Y here if you have the Pixcir 5" touchscreen.
228
229config TOUCHSCREEN_EGALAX
230 tristate "EGALAX 10.1\" touchscreen input driver"
231 depends on ARCH_EXYNOS5
232 help
233 Say Y here if you have the Egalax 10.1\" touchscreen.
234
205config TOUCHSCREEN_GUNZE 235config TOUCHSCREEN_GUNZE
206 tristate "Gunze AHL-51S touchscreen" 236 tristate "Gunze AHL-51S touchscreen"
207 select SERIO 237 select SERIO
@@ -383,6 +413,12 @@ config TOUCHSCREEN_TNETV107X
383 To compile this driver as a module, choose M here: the 413 To compile this driver as a module, choose M here: the
384 module will be called tnetv107x-ts. 414 module will be called tnetv107x-ts.
385 415
416config TOUCHSCREEN_SYNAPTICS_I2C_RMI
417 tristate "Synaptics i2c touchscreen"
418 depends on I2C
419 help
420 This enables support for Synaptics RMI over I2C based touchscreens.
421
386config TOUCHSCREEN_TOUCHRIGHT 422config TOUCHSCREEN_TOUCHRIGHT
387 tristate "Touchright serial touchscreen" 423 tristate "Touchright serial touchscreen"
388 select SERIO 424 select SERIO
diff --git a/drivers/input/touchscreen/Makefile b/drivers/input/touchscreen/Makefile
index 282d6f76ae2..0223142024f 100644
--- a/drivers/input/touchscreen/Makefile
+++ b/drivers/input/touchscreen/Makefile
@@ -22,6 +22,7 @@ obj-$(CONFIG_TOUCHSCREEN_DYNAPRO) += dynapro.o
22obj-$(CONFIG_TOUCHSCREEN_HAMPSHIRE) += hampshire.o 22obj-$(CONFIG_TOUCHSCREEN_HAMPSHIRE) += hampshire.o
23obj-$(CONFIG_TOUCHSCREEN_GUNZE) += gunze.o 23obj-$(CONFIG_TOUCHSCREEN_GUNZE) += gunze.o
24obj-$(CONFIG_TOUCHSCREEN_EETI) += eeti_ts.o 24obj-$(CONFIG_TOUCHSCREEN_EETI) += eeti_ts.o
25obj-$(CONFIG_TOUCHSCREEN_EGALAX) += egalax_i2c.o
25obj-$(CONFIG_TOUCHSCREEN_ELO) += elo.o 26obj-$(CONFIG_TOUCHSCREEN_ELO) += elo.o
26obj-$(CONFIG_TOUCHSCREEN_FUJITSU) += fujitsu_ts.o 27obj-$(CONFIG_TOUCHSCREEN_FUJITSU) += fujitsu_ts.o
27obj-$(CONFIG_TOUCHSCREEN_INEXIO) += inexio.o 28obj-$(CONFIG_TOUCHSCREEN_INEXIO) += inexio.o
@@ -40,9 +41,12 @@ obj-$(CONFIG_TOUCHSCREEN_USB_COMPOSITE) += usbtouchscreen.o
40obj-$(CONFIG_TOUCHSCREEN_PCAP) += pcap_ts.o 41obj-$(CONFIG_TOUCHSCREEN_PCAP) += pcap_ts.o
41obj-$(CONFIG_TOUCHSCREEN_PENMOUNT) += penmount.o 42obj-$(CONFIG_TOUCHSCREEN_PENMOUNT) += penmount.o
42obj-$(CONFIG_TOUCHSCREEN_S3C2410) += s3c2410_ts.o 43obj-$(CONFIG_TOUCHSCREEN_S3C2410) += s3c2410_ts.o
44obj-$(CONFIG_TOUCHSCREEN_EXYNOS4) += s5pc210_ts.o s5pc210_ts_gpio_i2c.o s5pc210_ts_sysfs.o
45obj-$(CONFIG_TOUCHSCREEN_PIXCIR) += pixcir_i2c_ts.o
43obj-$(CONFIG_TOUCHSCREEN_ST1232) += st1232.o 46obj-$(CONFIG_TOUCHSCREEN_ST1232) += st1232.o
44obj-$(CONFIG_TOUCHSCREEN_STMPE) += stmpe-ts.o 47obj-$(CONFIG_TOUCHSCREEN_STMPE) += stmpe-ts.o
45obj-$(CONFIG_TOUCHSCREEN_TNETV107X) += tnetv107x-ts.o 48obj-$(CONFIG_TOUCHSCREEN_TNETV107X) += tnetv107x-ts.o
49obj-$(CONFIG_TOUCHSCREEN_SYNAPTICS_I2C_RMI) += synaptics_i2c_rmi.o
46obj-$(CONFIG_TOUCHSCREEN_TOUCHIT213) += touchit213.o 50obj-$(CONFIG_TOUCHSCREEN_TOUCHIT213) += touchit213.o
47obj-$(CONFIG_TOUCHSCREEN_TOUCHRIGHT) += touchright.o 51obj-$(CONFIG_TOUCHSCREEN_TOUCHRIGHT) += touchright.o
48obj-$(CONFIG_TOUCHSCREEN_TOUCHWIN) += touchwin.o 52obj-$(CONFIG_TOUCHSCREEN_TOUCHWIN) += touchwin.o
@@ -60,3 +64,6 @@ obj-$(CONFIG_TOUCHSCREEN_WM97XX_MAINSTONE) += mainstone-wm97xx.o
60obj-$(CONFIG_TOUCHSCREEN_WM97XX_ZYLONITE) += zylonite-wm97xx.o 64obj-$(CONFIG_TOUCHSCREEN_WM97XX_ZYLONITE) += zylonite-wm97xx.o
61obj-$(CONFIG_TOUCHSCREEN_W90X900) += w90p910_ts.o 65obj-$(CONFIG_TOUCHSCREEN_W90X900) += w90p910_ts.o
62obj-$(CONFIG_TOUCHSCREEN_TPS6507X) += tps6507x-ts.o 66obj-$(CONFIG_TOUCHSCREEN_TPS6507X) += tps6507x-ts.o
67# for ODROID-Q
68obj-$(CONFIG_TOUCHSCREEN_SOLOMON_MT) += touch.o touch-i2c.o touch-sysfs.o odroidq-touch.o
69obj-$(CONFIG_TOUCHSCREEN_DUMMY) += touch.o touch-i2c.o touch-sysfs.o
diff --git a/drivers/input/touchscreen/egalax_i2c.c b/drivers/input/touchscreen/egalax_i2c.c
new file mode 100644
index 00000000000..c47f98c48f7
--- /dev/null
+++ b/drivers/input/touchscreen/egalax_i2c.c
@@ -0,0 +1,962 @@
1/*
2 *
3 * Touch Screen I2C Driver for EETI Controller
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 */
16
17#include <linux/module.h>
18#include <linux/init.h>
19#include <linux/kernel.h>
20#include <linux/interrupt.h>
21#include <linux/wait.h>
22#include <linux/delay.h>
23#include <linux/platform_device.h>
24#include <linux/freezer.h>
25#include <linux/proc_fs.h>
26#include <linux/clk.h>
27#include <linux/i2c.h>
28#include <mach/regs-gpio.h>
29#include <linux/gpio.h>
30#include <linux/device.h>
31#include <linux/cdev.h>
32#include <linux/io.h>
33#include <asm/system.h>
34#include <linux/uaccess.h>
35#include <linux/poll.h>
36#include <linux/kfifo.h>
37#include <linux/version.h>
38#include <linux/input.h>
39#include <linux/irq.h>
40#include <linux/timer.h>
41#include <linux/proc_fs.h>
42#include <plat/gpio-cfg.h>
43#include <mach/regs-gpio.h>
44#include <mach/gpio.h>
45
46#ifdef CONFIG_HAS_EARLYSUSPEND
47#include <linux/earlysuspend.h>
48static struct early_suspend egalax_early_suspend;
49#endif
50
51/* Global define to enable function */
52#define _ENABLE_DBG_LEVEL
53
54static int global_major; /* dynamic major by default */
55static int global_minor;
56
57#define MAX_I2C_LEN 10
58#define FIFO_SIZE PAGE_SIZE
59#define MAX_SUPPORT_POINT 5
60#define REPORTID_MOUSE 0x01
61#define REPORTID_VENDOR 0x03
62#define REPORTID_MTOUCH 0x04
63
64/* ioctl command */
65#define EGALAX_IOC_MAGIC 0x72
66#define EGALAX_IOCWAKEUP _IO(EGALAX_IOC_MAGIC, 1)
67#define EGALAX_IOC_MAXNR 1
68
69/* running mode */
70#define MODE_STOP 0
71#define MODE_WORKING 1
72#define MODE_IDLE 2
73#define MODE_SUSPEND 3
74
75#define EGALAX_MAX 2048
76#define SCREEN_WIDTH 1280
77#define SCREEN_HIGH 800
78
79struct point_data {
80 short Status;
81 short X;
82 short Y;
83};
84
85struct egalax_i2c_platform_data {
86 unsigned int gpio_int;
87 unsigned int gpio_en;
88 unsigned int gpio_rst;
89};
90
91struct _egalax_i2c {
92 struct egalax_i2c_platform_data *pdata;
93 struct workqueue_struct *ktouch_wq;
94 struct work_struct work_irq;
95 struct work_struct work_idle;
96 struct mutex mutex_wq;
97 struct i2c_client *client;
98 unsigned char work_state;
99 unsigned char skip_packet;
100 unsigned char downCnt;
101 struct timer_list idle_timer;
102};
103
104struct egalax_char_dev {
105 int OpenCnts;
106 struct cdev cdev;
107 struct kfifo DataKFiFo;
108 unsigned char *pFiFoBuf;
109 spinlock_t FiFoLock;
110 struct semaphore sem;
111 wait_queue_head_t fifo_inq;
112};
113
114static struct _egalax_i2c *p_egalax_i2c_dev;
115static struct egalax_char_dev *p_char_dev;
116static atomic_t egalax_char_available = ATOMIC_INIT(1);
117static atomic_t wait_command_ack = ATOMIC_INIT(0);
118static struct class *egalax_class;
119static struct input_dev *input_dev;
120static struct point_data PointBuf[MAX_SUPPORT_POINT];
121
122struct mutex i2c_lock;
123
124#define DBG_MODULE 0x00000001
125#define DBG_CDEV 0x00000002
126#define DBG_PROC 0x00000004
127#define DBG_POINT 0x00000008
128#define DBG_INT 0x00000010
129#define DBG_I2C 0x00000020
130#define DBG_SUSP 0x00000040
131#define DBG_INPUT 0x00000080
132#define DBG_CONST 0x00000100
133#define DBG_IDLE 0x00000200
134#define DBG_WAKEUP 0x00000400
135#define DBG_BUTTON 0x00000800
136static unsigned int DbgLevel; /* DBG_INT|DBG_MODULE|DBG_SUSP|DBG_WAKEUP */
137
138#ifdef _ENABLE_DBG_LEVEL
139 #define PROC_FS_NAME "egalax_dbg"
140 #define PROC_FS_MAX_LEN 8
141 static struct proc_dir_entry *dbgProcFile;
142#endif
143
144#define EGALAX_DBG(level, fmt, args...) { if ((level&DbgLevel) > 0) \
145 printk(KERN_INFO "[egalax_i2c]: " fmt, ## args); }
146#define IDLE_INTERVAL HZ/20 /* 50ms */
147
148static int sendLoopback(struct i2c_client *client)
149{
150 u8 cmdbuf[MAX_I2C_LEN] = {0x03, 0x03, 0x0A, 0x01, 0x41, 0, 0, 0, 0, 0};
151 int ret;
152 ret = 0;
153 mutex_lock(&i2c_lock);
154 if (i2c_master_send(client, cmdbuf, MAX_I2C_LEN) != MAX_I2C_LEN) {
155 ret = -1;
156 printk("TS-SendLoopback (I2C Write)Error\n");
157 }
158 mutex_unlock(&i2c_lock);
159 return ret;
160}
161
162static int wakeup_controller(int irq)
163{
164 int ret = 0;
165 int gpio = p_egalax_i2c_dev->pdata->gpio_int;
166
167 if (gpio_get_value(gpio)) {
168 gpio_direction_output(gpio, 0);
169 barrier();
170 mdelay(5);
171 }
172
173 gpio_direction_output(gpio, 1);
174 gpio_direction_input(gpio);
175 EGALAX_DBG(DBG_WAKEUP, " INT wakeup touch controller done\n");
176
177 return ret;
178}
179
180static int egalax_cdev_open(struct inode *inode, struct file *filp)
181{
182 struct egalax_char_dev *cdev;
183
184 cdev = container_of(inode->i_cdev, struct egalax_char_dev, cdev);
185 if (cdev == NULL) {
186 EGALAX_DBG(DBG_CDEV, "No such char device node\n");
187 return -ENODEV;
188 }
189
190 if (!atomic_dec_and_test(&egalax_char_available)) {
191 atomic_inc(&egalax_char_available);
192 return -EBUSY; /* already open */
193 }
194
195 cdev->OpenCnts++;
196 filp->private_data = cdev;/* Used by the read and write metheds */
197
198 /* check and wakeup controller if necessary */
199 del_timer_sync(&p_egalax_i2c_dev->idle_timer);
200 cancel_work_sync(&p_egalax_i2c_dev->work_idle);
201 if (p_egalax_i2c_dev->work_state == MODE_IDLE)
202 wakeup_controller(p_egalax_i2c_dev->client->irq);
203
204 EGALAX_DBG(DBG_CDEV, " CDev open done!\n");
205 try_module_get(THIS_MODULE);
206 return 0;
207}
208
209static int egalax_cdev_release(struct inode *inode, struct file *filp)
210{
211 struct egalax_char_dev *cdev;/* device information */
212
213 cdev = container_of(inode->i_cdev, struct egalax_char_dev, cdev);
214 if (cdev == NULL) {
215 EGALAX_DBG(DBG_CDEV, "No such char device node\n");
216 return -ENODEV;
217 }
218
219 atomic_inc(&egalax_char_available); /* release the device */
220
221 filp->private_data = NULL;
222 cdev->OpenCnts--;
223
224 kfifo_reset(&cdev->DataKFiFo);
225
226 mod_timer(&p_egalax_i2c_dev->idle_timer, jiffies+IDLE_INTERVAL);
227
228 EGALAX_DBG(DBG_CDEV, "CDev release done!\n");
229 module_put(THIS_MODULE);
230 return 0;
231}
232
233#define MAX_READ_BUF_LEN 50
234static char fifo_read_buf[MAX_READ_BUF_LEN];
235static ssize_t egalax_cdev_read(struct file *file, char __user *buf,
236 size_t count, loff_t *offset)
237{
238 int read_cnt, ret, fifoLen;
239 struct egalax_char_dev *cdev = file->private_data;
240
241 if (down_interruptible(&cdev->sem))
242 return -ERESTARTSYS;
243
244 fifoLen = kfifo_len(&cdev->DataKFiFo);
245
246 while (fifoLen < 1) { /* nothing to read */
247 up(&cdev->sem); /* release the lock */
248 if (file->f_flags & O_NONBLOCK)
249 return -EAGAIN;
250
251 if (wait_event_interruptible(cdev->fifo_inq,
252 kfifo_len(&cdev->DataKFiFo) > 0)) {
253 return -ERESTARTSYS;
254 }
255
256 if (down_interruptible(&cdev->sem))
257 return -ERESTARTSYS;
258 }
259
260 if (count > MAX_READ_BUF_LEN)
261 count = MAX_READ_BUF_LEN;
262
263 EGALAX_DBG(DBG_CDEV, " \"%s\" reading fifo data\n", current->comm);
264 read_cnt = kfifo_out_locked(&cdev->DataKFiFo, fifo_read_buf,
265 count, &cdev->FiFoLock);
266
267 ret = copy_to_user(buf, fifo_read_buf, read_cnt) ? -EFAULT : read_cnt;
268
269 up(&cdev->sem);
270
271 return ret;
272}
273
274static ssize_t egalax_cdev_write(struct file *file, const char __user *buf,
275 size_t count, loff_t *offset)
276{
277 struct egalax_char_dev *cdev = file->private_data;
278 int ret = 0;
279 char *tmp;
280
281 if (down_interruptible(&cdev->sem))
282 return -ERESTARTSYS;
283
284 if (count > MAX_I2C_LEN)
285 count = MAX_I2C_LEN;
286
287 tmp = kmalloc(count, GFP_KERNEL);
288 if (tmp == NULL) {
289 up(&cdev->sem);
290 return -ENOMEM;
291 }
292
293 if (copy_from_user(tmp, buf, count)) {
294 up(&cdev->sem);
295 kfree(tmp);
296 return -EFAULT;
297 }
298
299 ret = i2c_master_send(p_egalax_i2c_dev->client, tmp, count);
300
301 up(&cdev->sem);
302 EGALAX_DBG(DBG_CDEV, " I2C writing %zu bytes.\n", count);
303 kfree(tmp);
304
305 return ret;
306}
307
308#ifdef _ENABLE_DBG_LEVEL
309static int egalax_proc_read(char *buffer, char **buffer_location, off_t offset,
310 int buffer_length, int *eof, void *data)
311{
312 int ret;
313
314 EGALAX_DBG(DBG_PROC, " \"%s\" call proc_read\n", current->comm);
315
316 if (offset > 0) /* we have finished to read, return 0 */
317 ret = 0;
318 else
319 ret = sprintf(buffer, "Debug Level: 0x%08X\n", DbgLevel);
320
321 return ret;
322}
323
324static int egalax_proc_write(struct file *file, const char *buffer,
325 unsigned long count, void *data)
326{
327 char procfs_buffer_size = 0;
328 int i;
329 unsigned char procfs_buf[PROC_FS_MAX_LEN] = {0};
330
331 EGALAX_DBG(DBG_PROC, " \"%s\" call proc_write\n", current->comm);
332
333 procfs_buffer_size = count;
334 if (procfs_buffer_size > PROC_FS_MAX_LEN)
335 procfs_buffer_size = PROC_FS_MAX_LEN+1;
336
337 if (copy_from_user(procfs_buf, buffer, procfs_buffer_size)) {
338 EGALAX_DBG(DBG_PROC, " proc_write faied at copy_from_user\n");
339 return -EFAULT;
340 }
341
342 DbgLevel = 0;
343 for (i = 0 ; i < procfs_buffer_size-1; i++) {
344 if (procfs_buf[i] >= '0' && procfs_buf[i] <= '9')
345 DbgLevel |= (procfs_buf[i] - '0');
346 else if (procfs_buf[i] >= 'A' && procfs_buf[i] <= 'F')
347 DbgLevel |= (procfs_buf[i] - 'A' + 10);
348 else if (procfs_buf[i] >= 'a' && procfs_buf[i] <= 'f')
349 DbgLevel |= (procfs_buf[i] - 'a' + 10);
350
351 if (i != procfs_buffer_size - 2)
352 DbgLevel <<= 4;
353 }
354
355 DbgLevel = DbgLevel&0xFFFFFFFF;
356
357 EGALAX_DBG(DBG_PROC, " Switch Debug Level to 0x%08X\n", DbgLevel);
358
359 return count; /* procfs_buffer_size */
360}
361#endif /* #ifdef _ENABLE_DBG_LEVEL */
362
363static long egalax_cdev_ioctl(struct file *filp, unsigned int cmd,
364 unsigned long args)
365{
366 int ret = 0;
367
368 if (_IOC_TYPE(cmd) != EGALAX_IOC_MAGIC)
369 return -ENOTTY;
370 if (_IOC_NR(cmd) > EGALAX_IOC_MAXNR)
371 return -ENOTTY;
372
373 if (_IOC_DIR(cmd) & _IOC_READ)
374 ret = !access_ok(VERIFY_WRITE, (void __user *)args,
375 _IOC_SIZE(cmd));
376 else if (_IOC_DIR(cmd) & _IOC_WRITE)
377 ret = !access_ok(VERIFY_READ, (void __user *)args,
378 _IOC_SIZE(cmd));
379
380 if (ret)
381 return -EFAULT;
382
383 EGALAX_DBG(DBG_CDEV, "Handle device ioctl command\n");
384 switch (cmd) {
385 case EGALAX_IOCWAKEUP:
386 ret = wakeup_controller(p_egalax_i2c_dev->client->irq);
387 break;
388 default:
389 ret = -ENOTTY;
390 break;
391 }
392
393 return ret;
394}
395
396static unsigned int egalax_cdev_poll(struct file *filp,
397 struct poll_table_struct *wait)
398{
399 struct egalax_char_dev *cdev = filp->private_data;
400 unsigned int mask = 0;
401 int fifoLen;
402
403 down(&cdev->sem);
404 poll_wait(filp, &cdev->fifo_inq, wait);
405
406 fifoLen = kfifo_len(&cdev->DataKFiFo);
407
408 if (fifoLen > 0)
409 mask |= POLLIN | POLLRDNORM; /* readable */
410 if ((FIFO_SIZE - fifoLen) > MAX_I2C_LEN)
411 mask |= POLLOUT | POLLWRNORM; /* writable */
412
413 up(&cdev->sem);
414 return mask;
415}
416
417static int LastUpdateID;
418static void ProcessReport(unsigned char *buf, struct _egalax_i2c *p_egalax_i2c)
419{
420 int i, cnt_down = 0, cnt_up = 0;
421 short X, Y, ContactID, Status;
422 bool bNeedReport = false;
423 int skip_point = 0;
424
425 Status = buf[1]&0x01;
426 ContactID = (buf[1]&0x7C)>>2;
427 X = ((buf[3]<<8) + buf[2])>>4;
428 X = X * SCREEN_WIDTH / EGALAX_MAX;
429 Y = ((buf[5]<<8) + buf[4])>>4;
430 Y = Y * SCREEN_HIGH / EGALAX_MAX;
431
432 if (!(ContactID >= 0 && ContactID < MAX_SUPPORT_POINT)) {
433 EGALAX_DBG(DBG_POINT, "Get I2C Point data error [%02X][%02X]\
434 [%02X][%02X][%02X][%02X]\n", buf[0], buf[1],
435 buf[2], buf[3], buf[4], buf[5]);
436 return;
437 }
438
439#ifdef CONFIG_TC4_PORTRAIT_MODE
440 PointBuf[ContactID].X = EGALAX_MAX-Y;
441 PointBuf[ContactID].Y = X;
442#else
443 PointBuf[ContactID].X = X;
444 PointBuf[ContactID].Y = Y;
445#endif
446 if (PointBuf[ContactID].Status != Status) {
447 if (Status)
448 p_egalax_i2c->downCnt++;
449 else if (PointBuf[ContactID].Status > 0)
450 p_egalax_i2c->downCnt--;
451
452 PointBuf[ContactID].Status = Status;
453 bNeedReport = true;
454 }
455
456 /* Send point report */
457 if ((bNeedReport || (ContactID <= LastUpdateID)) && (skip_point == 0)) {
458 for (i = 0; i < MAX_SUPPORT_POINT; i++) {
459 if (PointBuf[i].Status > 0) {
460 input_report_abs(input_dev,
461 ABS_MT_TRACKING_ID, i);
462 input_report_abs(input_dev,
463 ABS_MT_TOUCH_MAJOR, PointBuf[i].Status);
464 input_report_abs(input_dev,
465 ABS_MT_WIDTH_MAJOR, 0);
466 input_report_abs(input_dev,
467 ABS_MT_POSITION_X, PointBuf[ContactID].X);
468 input_report_abs(input_dev,
469 ABS_MT_POSITION_Y, PointBuf[ContactID].Y);
470 input_mt_sync(input_dev);
471 cnt_down++;
472 } else if (PointBuf[i].Status == 0) {
473 PointBuf[i].Status--;
474 cnt_up++;
475 input_mt_sync(input_dev);
476 }
477 }
478 input_sync(input_dev);
479 EGALAX_DBG(DBG_POINT, " Input sync point data done! (Down:%d Up:%d)\n",
480 cnt_down, cnt_up);
481 }
482
483 LastUpdateID = ContactID;
484}
485
486static struct input_dev *allocate_Input_Dev(void)
487{
488 int ret;
489 struct input_dev *pInputDev;
490
491 pInputDev = input_allocate_device();
492 if (pInputDev == NULL) {
493 EGALAX_DBG(DBG_MODULE, "Failed to allocate input device\n");
494 return NULL;
495 }
496
497 pInputDev->name = "egalax_i2c";
498 pInputDev->phys = "I2C";
499 pInputDev->id.bustype = BUS_I2C;
500 pInputDev->id.vendor = 0x0EEF;
501 pInputDev->id.product = 0x0020;
502 pInputDev->id.version = 0x0001;
503
504 set_bit(EV_ABS, pInputDev->evbit);
505 input_set_abs_params(pInputDev, ABS_MT_POSITION_X,
506 0, SCREEN_WIDTH, 0, 0);
507 input_set_abs_params(pInputDev, ABS_MT_POSITION_Y,
508 0, SCREEN_HIGH, 0, 0);
509 input_set_abs_params(pInputDev, ABS_MT_TOUCH_MAJOR,
510 0, 255, 0, 0);
511 input_set_abs_params(pInputDev, ABS_MT_WIDTH_MAJOR,
512 0, 255, 0, 0);
513 input_set_abs_params(pInputDev, ABS_MT_TRACKING_ID,
514 0, MAX_SUPPORT_POINT, 0, 0);
515
516 ret = input_register_device(pInputDev);
517 if (ret) {
518 EGALAX_DBG(DBG_MODULE, "Unable to register input device.\n");
519 input_free_device(pInputDev);
520 pInputDev = NULL;
521 }
522
523 return pInputDev;
524}
525
526static int egalax_i2c_measure(struct _egalax_i2c *egalax_i2c)
527{
528 struct i2c_client *client = egalax_i2c->client;
529 u8 x_buf[MAX_I2C_LEN];
530 int count, loop = 3;
531
532 EGALAX_DBG(DBG_INT, "egalax_i2c_measure\n");
533
534 do {
535 mutex_lock(&i2c_lock);
536 count = i2c_master_recv(client, x_buf, MAX_I2C_LEN);
537 mutex_unlock(&i2c_lock);
538 } while (count == EAGAIN && --loop);
539
540 if (count < 0 || (x_buf[0] != REPORTID_VENDOR && x_buf[0]
541 != REPORTID_MTOUCH)) {
542 EGALAX_DBG(DBG_I2C, "I2C read error data\
543 with Len=%d hedaer=%d\n", count, x_buf[0]);
544 return -1;
545 }
546
547 EGALAX_DBG(DBG_I2C, " I2C read data with Len=%d\n", count);
548 if (x_buf[0] == REPORTID_VENDOR) {
549 atomic_set(&wait_command_ack, 1);
550 EGALAX_DBG(DBG_I2C, " I2C get vendor command packet\n");
551 }
552
553 if (egalax_i2c->skip_packet > 0)
554 return count;
555
556 /* check buffer len & header */
557 if (count == MAX_I2C_LEN && x_buf[0] == REPORTID_MTOUCH) {
558 ProcessReport(x_buf, egalax_i2c);
559 return count;
560 }
561
562 /* If someone reading now! put the data into the buffer! */
563 if (count > 0 && p_char_dev->OpenCnts > 0) {
564 kfifo_in_locked(&p_char_dev->DataKFiFo, x_buf,
565 count, &p_char_dev->FiFoLock);
566 wake_up_interruptible(&p_char_dev->fifo_inq);
567 }
568
569 return count;
570}
571
572static void egalax_i2c_wq_irq(struct work_struct *work)
573{
574 struct _egalax_i2c *egalax_i2c =
575 container_of(work, struct _egalax_i2c, work_irq);
576 struct i2c_client *client = egalax_i2c->client;
577 int gpio = egalax_i2c->pdata->gpio_int;
578
579 EGALAX_DBG(DBG_INT, " egalax_i2c_wq run\n");
580
581 mutex_lock(&egalax_i2c->mutex_wq);
582 /*continue recv data*/
583 while (!gpio_get_value(gpio)) {
584 egalax_i2c_measure(egalax_i2c);
585 schedule();
586 }
587
588 if (egalax_i2c->skip_packet > 0)
589 egalax_i2c->skip_packet = 0;
590
591 if (p_char_dev->OpenCnts <= 0 && egalax_i2c->work_state == MODE_WORKING)
592 mod_timer(&egalax_i2c->idle_timer, jiffies+IDLE_INTERVAL);
593
594 mutex_unlock(&egalax_i2c->mutex_wq);
595
596 enable_irq(client->irq);
597
598 EGALAX_DBG(DBG_INT, " egalax_i2c_wq leave\n");
599}
600
601static irqreturn_t egalax_i2c_interrupt(int irq, void *dev_id)
602{
603 struct _egalax_i2c *egalax_i2c = (struct _egalax_i2c *)dev_id;
604
605 EGALAX_DBG(DBG_INT, " INT with irq:%d\n", irq);
606
607 del_timer(&egalax_i2c->idle_timer);
608 if (egalax_i2c->work_state == MODE_IDLE)
609 egalax_i2c->work_state = MODE_WORKING;
610
611 disable_irq_nosync(irq);
612 queue_work(egalax_i2c->ktouch_wq, &egalax_i2c->work_irq);
613
614 return IRQ_HANDLED;
615}
616
617static void egalax_i2c_wq_idle(struct work_struct *work)
618{
619 struct _egalax_i2c *egalax_i2c =
620 container_of(work, struct _egalax_i2c, work_idle);
621 unsigned char buf[] = {0x03, 0x06, 0x0A, 0x04, 0x36,
622 0x3F, 0x01, 0x00, 0, 0};
623 int ret = 0;
624
625 if (egalax_i2c->work_state == MODE_WORKING) {
626 mutex_lock(&i2c_lock);
627 ret = i2c_master_send(egalax_i2c->client, buf, MAX_I2C_LEN);
628 mutex_unlock(&i2c_lock);
629 if (ret == MAX_I2C_LEN) {
630 egalax_i2c->work_state = MODE_IDLE;
631 EGALAX_DBG(DBG_IDLE, " Set controller to idle mode\n");
632 } else
633 EGALAX_DBG(DBG_IDLE, " Try to set controller\
634 to idle failed:%d\n", ret);
635 }
636}
637
638static void egalax_idle_timer_routine(unsigned long data)
639{
640 struct _egalax_i2c *egalax_i2c = (struct _egalax_i2c *)data;
641
642 queue_work(egalax_i2c->ktouch_wq, &egalax_i2c->work_idle);
643}
644
645
646
647#ifdef CONFIG_HAS_EARLYSUSPEND
648static void egalax_i2c_early_suspend(struct early_suspend *handler)
649{
650 mod_timer(&p_egalax_i2c_dev->idle_timer, jiffies);
651
652 return;
653}
654
655#endif // #ifdef CONFIG_HAS_EARLYSUSPEND
656
657static int __devinit egalax_i2c_probe(struct i2c_client *client,
658 const struct i2c_device_id *id)
659{
660 int i, ret = 0;
661 int gpio;
662
663 EGALAX_DBG(DBG_MODULE, " Start probe\n");
664
665 p_egalax_i2c_dev = kzalloc(sizeof(struct _egalax_i2c), GFP_KERNEL);
666 if (!p_egalax_i2c_dev) {
667 EGALAX_DBG(DBG_MODULE, "Request memory failed\n");
668 ret = -ENOMEM;
669 goto fail1;
670 }
671
672 p_egalax_i2c_dev->pdata = kmalloc(sizeof(*(p_egalax_i2c_dev->pdata)),
673 GFP_KERNEL);
674 if (NULL == p_egalax_i2c_dev->pdata) {
675 dev_err(&client->dev, "fail to allocate mem for pdata\n");
676 goto fail1_1;
677 }
678
679 memcpy(p_egalax_i2c_dev->pdata, client->dev.platform_data,
680 sizeof(*(p_egalax_i2c_dev->pdata)));
681
682 gpio = p_egalax_i2c_dev->pdata->gpio_int;
683
684 input_dev = allocate_Input_Dev();
685 if (input_dev == NULL) {
686 EGALAX_DBG(DBG_MODULE, " allocate_Input_Dev failed\n");
687 ret = -EINVAL;
688 goto fail2;
689 }
690
691 EGALAX_DBG(DBG_MODULE, " Register input device done\n");
692
693 for (i = 0; i < MAX_SUPPORT_POINT; i++) {
694 PointBuf[i].Status = -1;
695 PointBuf[i].X = PointBuf[i].Y = 0;
696 }
697
698 p_egalax_i2c_dev->client = client;
699 mutex_init(&p_egalax_i2c_dev->mutex_wq);
700 mutex_init(&i2c_lock); /* cuiwenpin:i2c read write protection */
701
702 p_egalax_i2c_dev->ktouch_wq =
703 create_singlethread_workqueue("egalax_touch_wq");
704 INIT_WORK(&p_egalax_i2c_dev->work_irq, egalax_i2c_wq_irq);
705 INIT_WORK(&p_egalax_i2c_dev->work_idle, egalax_i2c_wq_idle);
706
707 i2c_set_clientdata(client, p_egalax_i2c_dev);
708
709 sendLoopback(client);
710
711 if (gpio_get_value(gpio))
712 p_egalax_i2c_dev->skip_packet = 0;
713 else
714 p_egalax_i2c_dev->skip_packet = 1;
715
716 p_egalax_i2c_dev->work_state = MODE_WORKING;
717
718 /* setup timer */
719 setup_timer(&p_egalax_i2c_dev->idle_timer, egalax_idle_timer_routine,
720 (unsigned long)p_egalax_i2c_dev);
721 mod_timer(&p_egalax_i2c_dev->idle_timer, jiffies);
722
723 ret = request_irq(client->irq, egalax_i2c_interrupt,
724 IRQF_DISABLED | IRQF_TRIGGER_FALLING,
725 client->name, p_egalax_i2c_dev);
726 if (ret) {
727 EGALAX_DBG(DBG_MODULE, "Request irq(%d) failed\n", client->irq);
728 goto fail3;
729 }
730
731#ifdef CONFIG_HAS_EARLYSUSPEND
732 egalax_early_suspend.level = EARLY_SUSPEND_LEVEL_BLANK_SCREEN;
733 egalax_early_suspend.suspend = egalax_i2c_early_suspend;
734 egalax_early_suspend.resume = NULL;
735 register_early_suspend(&egalax_early_suspend);
736 EGALAX_DBG(DBG_MODULE, " Register early_suspend done\n");
737#endif
738
739 EGALAX_DBG(DBG_MODULE, "Request irq(%d) gpio(%d) with result:%d\n",
740 client->irq, gpio, ret);
741
742
743 EGALAX_DBG(DBG_MODULE, " I2C probe done\n");
744 return 0;
745
746fail3:
747 i2c_set_clientdata(client, NULL);
748 destroy_workqueue(p_egalax_i2c_dev->ktouch_wq);
749 free_irq(client->irq, p_egalax_i2c_dev);
750 input_unregister_device(input_dev);
751 input_dev = NULL;
752fail2:
753 kfree(p_egalax_i2c_dev->pdata);
754fail1_1:
755 kfree(p_egalax_i2c_dev);
756fail1:
757 p_egalax_i2c_dev = NULL;
758
759 EGALAX_DBG(DBG_MODULE, " I2C probe failed\n");
760 return ret;
761}
762
763static int __devexit egalax_i2c_remove(struct i2c_client *client)
764{
765 struct _egalax_i2c *egalax_i2c = i2c_get_clientdata(client);
766
767 egalax_i2c->work_state = MODE_STOP;
768
769 cancel_work_sync(&egalax_i2c->work_irq);
770 del_timer_sync(&egalax_i2c->idle_timer);
771 cancel_work_sync(&egalax_i2c->work_idle);
772
773 if (client->irq) {
774 disable_irq(client->irq);
775 free_irq(client->irq, egalax_i2c);
776 }
777
778 if (egalax_i2c->ktouch_wq)
779 destroy_workqueue(egalax_i2c->ktouch_wq);
780
781#ifdef CONFIG_HAS_EARLYSUSPEND
782 unregister_early_suspend(&egalax_early_suspend);
783#endif
784
785 if (input_dev) {
786 EGALAX_DBG(DBG_MODULE, " Unregister input device\n");
787 input_unregister_device(input_dev);
788 input_dev = NULL;
789 }
790
791 i2c_set_clientdata(client, NULL);
792 kfree(egalax_i2c->pdata);
793 kfree(egalax_i2c);
794 p_egalax_i2c_dev = NULL;
795
796 return 0;
797}
798
799static const struct i2c_device_id egalax_i2c_idtable[] = {
800 { "egalax_i2c", 0 },
801 {}
802};
803
804MODULE_DEVICE_TABLE(i2c, egalax_i2c_idtable);
805
806static struct i2c_driver egalax_i2c_driver = {
807 .driver = {
808 .name = "egalax_i2c",
809 },
810 .id_table = egalax_i2c_idtable,
811 .probe = egalax_i2c_probe,
812 .remove = __devexit_p(egalax_i2c_remove),
813};
814
815static const struct file_operations egalax_cdev_fops = {
816 .owner = THIS_MODULE,
817 .read = egalax_cdev_read,
818 .write = egalax_cdev_write,
819 .unlocked_ioctl = egalax_cdev_ioctl,
820 .poll = egalax_cdev_poll,
821 .open = egalax_cdev_open,
822 .release = egalax_cdev_release,
823};
824
825static void egalax_i2c_ts_exit(void)
826{
827 dev_t devno = MKDEV(global_major, global_minor);
828
829 if (p_char_dev) {
830 EGALAX_DBG(DBG_MODULE, "Unregister character device\n");
831 kfree(p_char_dev->pFiFoBuf);
832
833 cdev_del(&p_char_dev->cdev);
834 kfree(p_char_dev);
835 p_char_dev = NULL;
836 }
837
838 unregister_chrdev_region(devno, 1);
839
840 if (!IS_ERR(egalax_class)) {
841 device_destroy(egalax_class, devno);
842 class_destroy(egalax_class);
843 }
844
845 i2c_del_driver(&egalax_i2c_driver);
846
847#ifdef _ENABLE_DBG_LEVEL
848 remove_proc_entry(PROC_FS_NAME, NULL);
849#endif
850
851 EGALAX_DBG(DBG_MODULE, " Exit driver done!\n");
852}
853
854static struct egalax_char_dev *setup_chardev(dev_t dev)
855{
856 struct egalax_char_dev *pCharDev;
857 int result;
858
859 pCharDev = kmalloc(1 * sizeof(struct egalax_char_dev), GFP_KERNEL);
860 if (!pCharDev)
861 goto fail_cdev;
862
863 memset(pCharDev, 0, sizeof(struct egalax_char_dev));
864
865 spin_lock_init(&pCharDev->FiFoLock);
866 pCharDev->pFiFoBuf = kmalloc(sizeof(unsigned char)*FIFO_SIZE,
867 GFP_KERNEL);
868 if (!pCharDev->pFiFoBuf)
869 goto fail_fifobuf;
870 memset(pCharDev->pFiFoBuf, 0, sizeof(unsigned char)*FIFO_SIZE);
871
872 kfifo_init(&pCharDev->DataKFiFo, pCharDev->pFiFoBuf, FIFO_SIZE);
873 if (!kfifo_initialized(&pCharDev->DataKFiFo))
874 goto fail_kfifo;
875
876 pCharDev->OpenCnts = 0;
877 cdev_init(&pCharDev->cdev, &egalax_cdev_fops);
878 pCharDev->cdev.owner = THIS_MODULE;
879 sema_init(&pCharDev->sem, 1);
880 init_waitqueue_head(&pCharDev->fifo_inq);
881
882 result = cdev_add(&pCharDev->cdev, dev, 1);
883 if (result) {
884 EGALAX_DBG(DBG_MODULE, " Failed at cdev added\n");
885 goto fail_kfifo;
886 }
887
888 return pCharDev;
889
890fail_kfifo:
891 kfree(pCharDev->pFiFoBuf);
892fail_fifobuf:
893 kfree(pCharDev);
894fail_cdev:
895 return NULL;
896}
897
898static int egalax_i2c_ts_init(void)
899{
900 int result;
901 dev_t devno = 0;
902
903 /* Asking for a dynamic major unless directed otherwise at load time. */
904 if (global_major) {
905 devno = MKDEV(global_major, global_minor);
906 result = register_chrdev_region(devno, 1, "egalax_i2c");
907 } else {
908 result = alloc_chrdev_region(&devno, global_minor,
909 1, "egalax_i2c");
910 global_major = MAJOR(devno);
911 }
912
913 if (result < 0) {
914 EGALAX_DBG(DBG_MODULE, " Cdev can't get major number\n");
915 return 0;
916 }
917
918 /* allocate the character device */
919 p_char_dev = setup_chardev(devno);
920 if (!p_char_dev) {
921 result = -ENOMEM;
922 goto fail;
923 }
924
925 egalax_class = class_create(THIS_MODULE, "egalax_i2c");
926 if (IS_ERR(egalax_class)) {
927 EGALAX_DBG(DBG_MODULE, " Failed in creating class.\n");
928 result = -EFAULT;
929 goto fail;
930 }
931
932 device_create(egalax_class, NULL, devno, NULL, "egalax_i2c");
933 EGALAX_DBG(DBG_MODULE, "Register egalax_i2c cdev, major: %d\n",
934 global_major);
935
936#ifdef _ENABLE_DBG_LEVEL
937 dbgProcFile = create_proc_entry(PROC_FS_NAME, 0666, NULL);
938 if (dbgProcFile == NULL) {
939 remove_proc_entry(PROC_FS_NAME, NULL);
940 EGALAX_DBG(DBG_MODULE, "Could not initialize /proc/%s\n",
941 PROC_FS_NAME);
942 } else {
943 dbgProcFile->read_proc = egalax_proc_read;
944 dbgProcFile->write_proc = egalax_proc_write;
945 EGALAX_DBG(DBG_MODULE, " /proc/%s created\n", PROC_FS_NAME);
946 }
947#endif /* #ifdef _ENABLE_DBG_LEVEL */
948
949 EGALAX_DBG(DBG_MODULE, " Driver init done!\n");
950 return i2c_add_driver(&egalax_i2c_driver);
951
952fail:
953 egalax_i2c_ts_exit();
954 return result;
955}
956
957module_init(egalax_i2c_ts_init);
958module_exit(egalax_i2c_ts_exit);
959
960MODULE_AUTHOR("EETI <touch_fae@eeti.com>");
961MODULE_DESCRIPTION("egalax touch screen i2c driver");
962MODULE_LICENSE("GPL");
diff --git a/drivers/input/touchscreen/odroidq-config.h b/drivers/input/touchscreen/odroidq-config.h
new file mode 100644
index 00000000000..8fa8fbcaccb
--- /dev/null
+++ b/drivers/input/touchscreen/odroidq-config.h
@@ -0,0 +1,151 @@
1//[*]--------------------------------------------------------------------------------------------------[*]
2//
3//
4// HardKernel(ODROID-Q) Touchscreen driver
5// 2011.12.12
6//
7//
8//[*]--------------------------------------------------------------------------------------------------[*]
9#ifndef _ODROIDQ_CONFIG_H_
10#define _ODROIDQ_CONFIG_H_
11
12//[*]--------------------------------------------------------------------------------------------------[*]
13struct ChipSetting {
14 unsigned char No;
15 unsigned char Reg;
16 unsigned char Data1;
17 unsigned char Data2;
18};
19
20//[*]--------------------------------------------------------------------------------------------------[*]
21struct ChipSetting Config[]={
22 { 0, 0x04, 0x00, 0x00}, // SSD2533 wakeup
23 {-1, 0x30, 0x00, 0x00}, // mdelay
24
25// { 1, 0xAC, 0x01, 0x00}, // SelfCap IIR filter
26// { 1, 0xAD, 0x03, 0x00}, // Scan Rate
27// { 1, 0xAE, 0x0F, 0x00}, // SelfCap Enable
28// { 1, 0xAF, 0x30, 0x00}, // SelfCap Threshold
29// { 1, 0xBC, 0x01, 0x00}, // Selfcap Enable
30
31 // 2012.06 new option
32 { 1, 0xac, 0x03, 0x00},
33 { 1, 0xad, 0x02, 0x00},
34 { 1, 0xae, 0x0f, 0x00},
35 { 1, 0xaf, 0x40, 0x00},
36 { 1, 0xb0, 0x00, 0x00},
37 { 1, 0xbb, 0x00, 0x00},
38 { 1, 0xbc, 0x01, 0x00},
39 //
40
41 { 1, 0x06, DRIVE_LINE_COUNT-1, 0x00}, //Set drive line 0=1, 1F=
42 { 1, 0x07, SENSE_LINE_COUNT-1, 0x00}, //Set sense line 0=1, 3F=
43
44 { 2, 0x08, 0x00, 0x8B}, //Set 1 drive line reg
45 { 2, 0x09, 0x00, 0x8C}, //Set 2 drive line reg
46 { 2, 0x0A, 0x00, 0x8D}, //Set 3 drive line reg
47 { 2, 0x0B, 0x00, 0x8E}, //Set 4 drive line reg
48 { 2, 0x0C, 0x00, 0x8F}, //Set 5 drive line reg
49 { 2, 0x0D, 0x00, 0x90}, //Set 6 drive line reg
50 { 2, 0x0E, 0x00, 0x91}, //Set 7 drive line reg
51 { 2, 0x0F, 0x00, 0x92}, //Set 8 drive line reg
52 { 2, 0x10, 0x00, 0x93}, //Set 9 drive line reg
53 { 2, 0x11, 0x00, 0x94}, //Set 10 drive line reg
54 { 2, 0x12, 0x00, 0x95}, //Set 11 drive line reg
55 { 2, 0x13, 0x00, 0x96}, //Set 12 drive line reg
56 { 2, 0x14, 0x01, 0x80}, //Set 13 drive line reg
57 { 2, 0x15, 0x01, 0x81}, //Set 14 drive line reg
58 { 2, 0x16, 0x01, 0x82}, //Set 15 drive line reg
59 { 2, 0x17, 0x01, 0x83}, //Set 16 drive line reg
60 { 2, 0x18, 0x01, 0x84}, //Set 17 drive line reg
61 { 2, 0x19, 0x01, 0x85}, //Set 18 drive line reg
62 { 2, 0x1A, 0x01, 0x86}, //Set 19 drive line reg
63 { 2, 0x1B, 0x01, 0x87}, //Set 20 drive line reg
64 { 2, 0x1C, 0x01, 0x88}, //Set 21 drive line reg
65 { 2, 0x1D, 0x01, 0x89}, //Set 20 drive line reg
66 { 2, 0x1E, 0x01, 0x8A}, //Set 21 drive line reg
67
68 //{ 1, 0xD5, 0x03, 0x00}, //Set Driving voltage 0(5.5V) to 7(9V)
69 //{ 1, 0xD8, 0x07, 0x00}, //Sense Bias R (2012/01/09)
70 // 2012.06 new option
71 { 1, 0xd5, 0x06, 0x00},
72 { 1, 0xd8, 0x04, 0x00},
73 //
74
75 { 1, 0x2A, 0x07, 0x00}, //Set sub-frame default=1, range 0 to F
76 { 1, 0x2C, 0x01, 0x00}, //Median Filter 0:disable to 1:enable
77 { 1, 0x2E, 0x0B, 0x00}, //Sub-frame Drive pulse number default=0x17
78
79 { 1, 0x2F, 0x01, 0x00}, //Integration Gain
80
81 // 2012.06 new option
82 //{ 1, 0x8b, 0x01, 0x00}, //added
83 //{ 1, 0x8c, 0xb0, 0x00}, //added
84 //
85
86 { 1, 0x30, 0x03, 0x00}, //start integrate 125ns/div
87
88 { 1, 0x31, 0x0B, 0x00}, //stop integrate 125n/div (2012/01/09)
89
90 //{ 1, 0xD7, 0x02, 0x00}, //ADC range default=4, 0 to 7 (2012/01/09)
91 // 2012.06 new option
92 { 1, 0xd7, 0x04, 0x00},
93 //
94
95 { 1, 0xDB, 0x02, 0x00}, //Set integration cap default=0, 0 to 7 (2012/01/09)
96
97 { 2, 0x33, 0x00, 0x00}, //Set Min. Finger area (2012/01/09)
98 { 2, 0x34, 0x00, 0x28}, //Set Min. Finger level (2012/01/09)
99 { 2, 0x35, 0x00, 0x00}, //Set Min. Finger weight
100 { 2, 0x36, 0x00, 0x1F}, //Set Max. Finger weight
101
102 { 1, 0x37, 0x00, 0x00}, //Segmentation Depth
103 { 1, 0x3D, 0x01, 0x00}, // 2D filter
104
105 // 2012.06 new option
106 { 1, 0x39, 0x02, 0x00}, //added
107 { 1, 0x40, 0xfa, 0x00}, //added
108 { 1, 0x44, 0x01, 0x00}, //added
109 //
110
111 { 1, 0x53, EVENT_MOVE_TOL, 0x00}, //Event move tolerance
112 { 2, 0x54, 0x00, X_TRACKING}, //X tracking
113 { 2, 0x55, 0x00, Y_TRACKING}, //Y tracking
114
115 { 1, 0x56, MOVE_AVR_FILTER, 0x00}, //Moving Average Filter 0:null, 1:5-3(Set), 2:6-2 3:7-1
116 { 1, 0x58, 0x00, 0x00}, //Finger weight scaling
117 { 1, 0x59, 0x01, 0x00}, //Enable Random walk
118 { 1, 0x5B, 0x01, 0x00}, //Set Random walk window ++++
119 { 1, 0x65, ORIENTATION, 0x00}, //XY Mapping
120
121{ 2, 0x66, 0x8A, 0x90},
122{ 2, 0x67, 0x95, 0x00}, //0x8F, 0x00
123//{ 2, 0x67, 0x8F, 0x00},
124
125 #if defined(IRQ_MODE_EVENT) || defined(IRQ_MODE_HYBRID) || defined(IRQ_MODE_POLLING)
126 #if defined(IRQ_MODE_EVENT)
127 // Event
128 { 2, 0x7A, 0xFF, 0xC7}, //Event Mask - Enable Leave Event
129 { 2, 0x7B, 0xFF, 0xF0}, //IRQ Mask - Mask off All Fingers interrupt except Event
130 { 1, 0x89, 0x00, 0x00}, //Enable Event IRQ mode
131 #else // IRQ_MODE_HYBRID or IRQ_MODE_POLLING
132 // Frame
133 { 2, 0x7A, 0xFF, 0xFF}, //Event Mask - Enable Leave Event
134 { 2, 0x7B, 0x00, 0x03}, //IRQ Mask - Mask off Unused Event
135 { 1, 0x89, 0x00, 0x00}, //Enable Event IRQ mode
136 #endif
137 #else // Frame IRQ Mode
138 { 2, 0x7A, 0xFF, 0xFF}, //Event Mask - Enable Leave Event
139 { 2, 0x7B, 0xFF, 0xFF}, //IRQ Mask - Mask off All Fingers & EVENT
140 { 1, 0x89, 0x01, 0x00}, //Enable Frame IRQ mode
141 #endif
142
143 { 1, 0x8A, MAX_FINGERS, 0x00}, //Max finger
144 //{ 1, 0x8B, 0x10, 0x00}, //Edge Remap
145 { 1, 0x8C, 0xB0, 0x00}, //Edge Suppress
146
147 { 1, 0x25, SCAN_MODE, 0x00}, //Set scan mode A
148};
149
150//[*]--------------------------------------------------------------------------------------------------[*]
151#endif //_ODROIDQ_CONFIG_H_
diff --git a/drivers/input/touchscreen/odroidq-touch.c b/drivers/input/touchscreen/odroidq-touch.c
new file mode 100644
index 00000000000..0fea5400c8a
--- /dev/null
+++ b/drivers/input/touchscreen/odroidq-touch.c
@@ -0,0 +1,364 @@
1//[*]--------------------------------------------------------------------------------------------------[*]
2//
3//
4//
5// I2C Touchscreen driver
6// 2012.01.17
7//
8//
9//[*]--------------------------------------------------------------------------------------------------[*]
10#include <linux/device.h>
11#include <linux/init.h>
12#include <linux/input.h>
13#include <linux/interrupt.h>
14#include <linux/irq.h>
15#include <linux/slab.h>
16#include <linux/hrtimer.h>
17#include <asm/unaligned.h>
18#include <linux/firmware.h>
19#include <linux/delay.h>
20#include <linux/gpio.h>
21#include <linux/i2c.h>
22
23//[*]--------------------------------------------------------------------------------------------------[*]
24#if defined(CONFIG_HAS_EARLYSUSPEND)
25 #include <linux/wakelock.h>
26 #include <linux/earlysuspend.h>
27 #include <linux/suspend.h>
28#endif
29
30//[*]--------------------------------------------------------------------------------------------------[*]
31#include <linux/input/touch-pdata.h>
32#include <linux/input/odroidq-touch.h>
33#include "touch.h"
34#include "odroidq-config.h"
35
36//[*]--------------------------------------------------------------------------------------------------[*]
37//#define DEBUG_TOUCH
38#define DEBUG_TOUCH_KEY
39
40//[*]--------------------------------------------------------------------------------------------------[*]
41// function prototype define
42//[*]--------------------------------------------------------------------------------------------------[*]
43// Touch data processing function
44//[*]--------------------------------------------------------------------------------------------------[*]
45static void odroidq_sw_config (struct touch *ts);
46static void odroidq_fifo_clear (struct touch *ts);
47 void odroidq_work (struct touch *ts);
48 int odroidq_calibration (struct touch *ts);
49 int odroidq_i2c_read (struct i2c_client *client, unsigned char *cmd, unsigned int cmd_len, unsigned char *data, unsigned int len);
50 void odroidq_enable (struct touch *ts);
51 void odroidq_disable (struct touch *ts);
52 int odroidq_early_probe (struct touch *ts);
53 int odroidq_probe (struct touch *ts);
54#ifdef CONFIG_HAS_EARLYSUSPEND
55 void odroidq_suspend (struct early_suspend *h);
56 void odroidq_resume (struct early_suspend *h);
57#endif
58//[*]--------------------------------------------------------------------------------------------------[*]
59//
60// i2c control function
61//
62//[*]--------------------------------------------------------------------------------------------------[*]
63int odroidq_i2c_read(struct i2c_client *client, unsigned char *cmd, unsigned int cmd_len, unsigned char *data, unsigned int len)
64{
65 struct i2c_msg msg[2];
66 int ret;
67 unsigned char temp[10];
68 unsigned char i;
69
70 if((len == 0) || (data == NULL)) {
71 dev_err(&client->dev, "I2C read error: Null pointer or length == 0\n");
72 return -1;
73 }
74
75 memset(msg, 0x00, sizeof(msg));
76
77 msg[0].addr = client->addr;
78 msg[0].flags = 0;
79 msg[0].len = cmd_len;
80 msg[0].buf = cmd;
81
82 msg[1].addr = client->addr;
83 msg[1].flags = I2C_M_RD;
84 msg[1].len = len;
85 msg[1].buf = temp;
86
87 if ((ret = i2c_transfer(client->adapter, msg, 2)) != 2) {
88 dev_err(&client->dev, "I2C read error: (%d) reg: 0x%X len: %d\n", ret, cmd[0], len);
89 return -EIO;
90 }
91
92 if(len) {
93 for(i = 0; i < len; i++) data[i] = temp[len - i -1];
94 }
95
96 return len;
97}
98
99//[*]--------------------------------------------------------------------------------------------------[*]
100int odroidq_calibration (struct touch *ts)
101{
102 if(ts->pdata->reset_gpio) gpio_set_value(ts->pdata->reset_gpio, ts->pdata->reset_level); mdelay(10);
103 if(ts->pdata->reset_gpio) gpio_set_value(ts->pdata->reset_gpio, ts->pdata->reset_level ? 0 : 1); mdelay(10);
104
105 odroidq_sw_config(ts); odroidq_fifo_clear(ts);
106
107 return 0;
108}
109
110//[*]--------------------------------------------------------------------------------------------------[*]
111//
112// Touch data processing function
113//
114//[*]--------------------------------------------------------------------------------------------------[*]
115static void odroidq_sw_config (struct touch *ts)
116{
117 unsigned char i, wdata[2], cmd;
118
119 for(i = 0; i < sizeof(Config) / sizeof(Config[0]); i++)
120 {
121 wdata[0] = Config[i].Data1; wdata[1] = Config[i].Data2;
122 cmd = Config[i].Reg;
123
124 if(Config[i].No == 0xFF) mdelay(cmd);
125 else {
126 ts->pdata->i2c_write(ts->client, (unsigned char *)&cmd, sizeof(cmd), &wdata[0], Config[i].No);
127 }
128 }
129 mdelay(10);
130}
131
132//[*]--------------------------------------------------------------------------------------------------[*]
133static void odroidq_fifo_clear (struct touch *ts)
134{
135 unsigned char wdata = 0x01, cmd = EVENT_FIFO_SCLR;
136
137 ts->pdata->i2c_write(ts->client, (unsigned char *)&cmd, sizeof(cmd), (unsigned char *)&wdata, sizeof(wdata)); // clear Event FiFo
138}
139
140//[*]--------------------------------------------------------------------------------------------------[*]
141static unsigned char odroidq_id_tracking (struct touch *ts, unsigned char find_id)
142{
143 unsigned char i, find_slot = 0xFF;
144
145 for(i = 0; i < ts->pdata->max_fingers; i++) {
146
147 if(ts->finger[i].id == find_id) find_slot = i;
148
149 if((ts->finger[i].event == TS_EVENT_UNKNOWN) && (find_slot == 0xFF)) find_slot = i;
150 }
151 return find_slot;
152}
153
154//[*]--------------------------------------------------------------------------------------------------[*]
155#if defined(SOFT_AVR_FILTER_ENABLE)
156
157typedef struct soft_filter__t {
158 unsigned int x[SOFT_AVR_COUNT];
159 unsigned int y[SOFT_AVR_COUNT];
160 unsigned int pos, cnt;
161} __attribute__ ((packed)) soft_filter_t;
162
163static soft_filter_t *pSoftFilter;
164
165static unsigned char odroidq_soft_avr_filter(struct touch *ts, event_stack_u *event_stack, unsigned char find_slot)
166{
167 unsigned int i, x, y;
168
169 if(ts->finger[find_slot].event != TS_EVENT_MOVE) {
170 pSoftFilter[find_slot].pos = 0; pSoftFilter[find_slot].cnt = 0;
171 return true;
172 }
173
174 x = (((event_stack->bits.msb_x << 8) & 0xF00) | event_stack->bits.lsb_x);
175 y = (((event_stack->bits.msb_y << 8) & 0xF00) | event_stack->bits.lsb_y);
176
177 if(y > 15) y -= 15;
178 else y = 1;
179
180 ts->finger[find_slot].id = event_stack->bits.number + 1;
181 ts->finger[find_slot].pressure =
182 (unsigned int)(event_stack->bits.pressure);
183
184 if(pSoftFilter[find_slot].cnt == 1) {
185 if((abs(pSoftFilter[find_slot].x[0] - x) < SOFT_AVR_MOVE_TOL_X) &&
186 (abs(pSoftFilter[find_slot].y[0] - y) < SOFT_AVR_MOVE_TOL_Y)) return false;
187 }
188
189 if(event_stack->bits.speed < SOFT_AVR_ENABLE_SPEED) {
190 pSoftFilter[find_slot].x[pSoftFilter[find_slot].pos] = x;
191 pSoftFilter[find_slot].y[pSoftFilter[find_slot].pos] = y;
192
193 pSoftFilter[find_slot].pos++; pSoftFilter[find_slot].pos %= SOFT_AVR_COUNT;
194
195 if(pSoftFilter[find_slot].cnt < SOFT_AVR_COUNT) pSoftFilter[find_slot].cnt++;
196
197 for(i = 0, x = 0, y = 0; i < pSoftFilter[find_slot].cnt; i++) {
198 x += pSoftFilter[find_slot].x[i]; y += pSoftFilter[find_slot].y[i];
199 }
200
201 ts->finger[find_slot].x = x / pSoftFilter[find_slot].cnt;
202 ts->finger[find_slot].y = y / pSoftFilter[find_slot].cnt;
203 }
204 else {
205 pSoftFilter[find_slot].pos = 0; pSoftFilter[find_slot].cnt = 0;
206
207 ts->finger[find_slot].x = x; ts->finger[find_slot].y = y;
208 }
209
210 return true;
211}
212
213#endif // #if defined(SOFT_AVR_FILTER_ENABLE)
214
215//[*]--------------------------------------------------------------------------------------------------[*]
216void odroidq_work (struct touch *ts)
217{
218 status_u status;
219 button_u button;
220 event_stack_u event_stack;
221 unsigned char cmd, find_slot;
222
223 cmd = TOUCH_STATUS;
224 if(ts->pdata->i2c_read(ts->client, (unsigned char *)&cmd, sizeof(cmd), (unsigned char *)&status.byte[0], sizeof(status_u)) < 0) return;
225
226 if(ts->pdata->keycode) {
227 cmd = BUTTON_STATUS;
228 if(ts->pdata->i2c_read(ts->client, (unsigned char *)&cmd, sizeof(cmd), (unsigned char *)&button.ubyte, sizeof(button_u)) < 0) return;
229 ts->pdata->key_report(ts, button.ubyte);
230 }
231
232 if(status.bits.fifo_overflow || status.bits.large_object || status.bits.abnomal_status) {
233 printk("[Error Status] fifo_overflow(%d), large_object(%d), abnomal_status(%d)\n" , status.bits.fifo_overflow
234 , status.bits.large_object
235 , status.bits.abnomal_status);
236 // Error reconfig
237 ts->pdata->disable(ts); ts->pdata->enable(ts);
238
239 return;
240 }
241
242 do {
243 cmd = EVENT_STACK;
244 ts->pdata->i2c_read(ts->client, (unsigned char *)&cmd, sizeof(cmd), (unsigned char *)&event_stack.byte[0], sizeof(event_stack_u));
245
246 if(status.bits.fifo_valid) {
247
248 if((find_slot = odroidq_id_tracking(ts, event_stack.bits.number + 1)) == 0xFF) {
249 printk("ERROR(%s) : Empty slot not found", __func__); continue;
250 }
251 if((event_stack.bits.event != EVENT_UNKNOWN) && (event_stack.bits.number < ts->pdata->max_fingers)) {
252 if((event_stack.bits.event == EVENT_PRESS) || (event_stack.bits.event == EVENT_MOVE)) {
253
254 ts->finger[find_slot].status = true;
255 ts->finger[find_slot].event = TS_EVENT_MOVE;
256
257 #if defined(SOFT_AVR_FILTER_ENABLE)
258 ts->finger[find_slot].status = odroidq_soft_avr_filter(ts, &event_stack, find_slot);
259 #else
260 ts->finger[find_slot].id = event_stack.bits.number + 1;
261 ts->finger[find_slot].x =
262 (unsigned int)(((event_stack.bits.msb_x << 8) & 0xF00) | event_stack.bits.lsb_x);
263 ts->finger[find_slot].y =
264 (unsigned int)(((event_stack.bits.msb_y << 8) & 0xF00) | event_stack.bits.lsb_y);
265
266 if(ts->finger[find_slot].y > 15) ts->finger[find_slot].y -= 15;
267 else ts->finger[find_slot].y = 1;
268
269 ts->finger[find_slot].pressure =
270 (unsigned int)(event_stack.bits.pressure);
271 #endif
272 }
273 else {
274 if(ts->finger[find_slot].event == TS_EVENT_MOVE) {
275 ts->finger[find_slot].status = true;
276 ts->finger[find_slot].event = TS_EVENT_RELEASE;
277 }
278 else {
279 ts->finger[find_slot].status = false;
280 ts->finger[find_slot].event = TS_EVENT_UNKNOWN;
281 }
282 #if defined(SOFT_AVR_FILTER_ENABLE)
283 odroidq_soft_avr_filter(ts, &event_stack, find_slot);
284 #endif
285 }
286 ts->pdata->report(ts);
287 }
288 }
289 } while(!gpio_get_value(ts->pdata->irq_gpio));
290}
291
292//[*]--------------------------------------------------------------------------------------------------[*]
293void odroidq_enable (struct touch *ts)
294{
295 if(ts->disabled) {
296 odroidq_calibration(ts);
297
298 enable_irq(ts->irq); ts->disabled = false;
299 }
300}
301
302//[*]--------------------------------------------------------------------------------------------------[*]
303void odroidq_disable (struct touch *ts)
304{
305 if(!ts->disabled) {
306 disable_irq(ts->irq); ts->disabled = true;
307
308 if(ts->pdata->event_clear) ts->pdata->event_clear(ts);
309
310 if(ts->pdata->reset_gpio) gpio_set_value(ts->pdata->reset_gpio, ts->pdata->reset_level);
311 }
312}
313
314//[*]--------------------------------------------------------------------------------------------------[*]
315int odroidq_early_probe (struct touch *ts)
316{
317#if defined(SOFT_AVR_FILTER_ENABLE)
318 if(ts->pdata->max_fingers) {
319 if(!(pSoftFilter = kzalloc(sizeof(soft_filter_t) * ts->pdata->max_fingers, GFP_KERNEL))) {
320 printk("touch soft-filter struct malloc error!\n"); return -ENOMEM;
321 }
322 }
323#endif
324
325 odroidq_calibration(ts);
326
327 return 0;
328}
329
330//[*]--------------------------------------------------------------------------------------------------[*]
331int odroidq_probe (struct touch *ts)
332{
333 int ret;
334 unsigned short rd;
335 unsigned char cmd;
336
337 // Get Touch screen information
338 cmd = DEVICE_ID; rd = 0;
339 ret = ts->pdata->i2c_read(ts->client, (unsigned char *)&cmd, sizeof(cmd), (unsigned char *)&rd, sizeof(rd));
340
341#if defined(DEBUG_TOUCH) // 0x2533
342 printk("DEVICE ID = 0x%04X\n", rd);
343#endif
344
345 cmd = VERSION_ID; rd = 0;
346 ret = ts->pdata->i2c_read(ts->client, (unsigned char *)&cmd, sizeof(cmd), (unsigned char *)&rd, sizeof(rd));
347
348#if defined(DEBUG_TOUCH)
349 printk("VERSION = 0x%04X\n", rd);
350#endif
351
352 ts->fw_version = ((rd >> 8) & 0xFF) * 100 + (rd & 0xFF);
353
354 return ret;
355}
356
357//[*]--------------------------------------------------------------------------------------------------[*]
358//[*]--------------------------------------------------------------------------------------------------[*]
359MODULE_AUTHOR("HardKernel Co., Ltd.");
360MODULE_LICENSE("GPL");
361MODULE_DESCRIPTION("Touchscreen Driver");
362
363//[*]--------------------------------------------------------------------------------------------------[*]
364//[*]--------------------------------------------------------------------------------------------------[*]
diff --git a/drivers/input/touchscreen/pixcir_i2c_ts.c b/drivers/input/touchscreen/pixcir_i2c_ts.c
new file mode 100644
index 00000000000..a1b496a8c7c
--- /dev/null
+++ b/drivers/input/touchscreen/pixcir_i2c_ts.c
@@ -0,0 +1,1008 @@
1/* drivers/input/touchscreen/pixcir_i2c_ts.c
2 *
3 * This software is licensed under the terms of the GNU General Public
4 * License version 2, as published by the Free Software Foundation, and
5 * may be copied, distributed, and modified under those terms.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 *
12 * You should have received a copy of the GNU General Public
13 * License along with this library; if not, write to the Free Software
14 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
15 *
16 * Copyright 2010 Pixcir, Inc.
17 * Copyright 2010 Bee <http://www.pixcir.com.cn>
18 * Copyright 2011 Dongsu Ha <dsfine.ha@samsung.com>
19 * Copyright 2011 Samsung Electronics <http://www.samsung.com>
20 */
21
22#include <linux/module.h>
23#include <linux/interrupt.h>
24#include <linux/input.h>
25#include <linux/i2c.h>
26#include <linux/smp.h>
27#include <linux/delay.h>
28#include <linux/slab.h>
29#include <linux/uaccess.h>
30
31#include <plat/gpio-cfg.h>
32#include <mach/gpio.h>
33#include <mach/board_rev.h>
34
35#define PIXCIR_DEBUG 0
36
37#define ATTB samsung_board_rev_is_0_0() ? EXYNOS4_GPX1(7) : EXYNOS4_GPX2(6)
38#define RESET samsung_board_rev_is_0_0() ? EXYNOS4_GPX1(6) : EXYNOS4212_GPM3(4)
39#define GPIO_NAME samsung_board_rev_is_0_0() ? "GPX1" : "GPM3"
40#define get_attb_value gpio_get_value
41#define RESETPIN_CFG s3c_gpio_cfgpin(RESET, S3C_GPIO_OUTPUT)
42#define RESETPIN_SET0 gpio_direction_output(RESET,0)
43#define RESETPIN_SET1 gpio_direction_output(RESET,1)
44
45#define SLAVE_ADDR 0x5c
46#define BOOTLOADER_ADDR 0x5d
47
48#ifndef I2C_MAJOR
49#define I2C_MAJOR 125
50#endif
51
52#define I2C_MINORS 256
53
54#define CALIBRATION_FLAG 1
55#define NORMAL_MODE 8
56#define PIXCIR_DEBUG_MODE 3
57#define VERSION_FLAG 6
58#define BOOTLOADER_MODE 7
59#define RD_EEPROM 12
60#define WR_EEPROM 13
61
62#define ENABLE_IRQ 10
63#define DISABLE_IRQ 11
64
65#define SPECOP 0x37
66
67#define reset
68
69#define MAXX 32
70#define MAXY 32
71#define TOUCHSCREEN_MINX 0
72#define TOUCHSCREEN_MAXX 480
73#define TOUCHSCREEN_MINY 0
74#define TOUCHSCREEN_MAXY 800
75
76int global_irq;
77
78static unsigned char status_reg;
79unsigned char read_XN_YN_flag;
80
81unsigned char global_touching, global_oldtouching;
82unsigned char global_posx1_low, global_posx1_high, global_posy1_low,
83 global_posy1_high, global_posx2_low, global_posx2_high,
84 global_posy2_low, global_posy2_high;
85
86unsigned char Tango_number;
87
88unsigned char interrupt_flag;
89
90unsigned char x_nb_electrodes;
91unsigned char y_nb_electrodes;
92unsigned char x2_nb_electrodes;
93unsigned char x1_x2_nb_electrodes;
94
95signed char xy_raw1[(MAXX * 2 + 3)];
96signed char xy_raw2[MAXX * 2];
97signed char xy_raw12[(MAXX * 4 + 3)];
98
99unsigned char data2eep[3], op2eep[2];
100
101struct i2c_dev {
102 struct list_head list;
103 struct i2c_adapter *adap;
104 struct device *dev;
105};
106
107static struct i2c_driver pixcir_i2c_ts_driver;
108static struct class *i2c_dev_class;
109static LIST_HEAD(i2c_dev_list);
110static DEFINE_SPINLOCK(i2c_dev_list_lock);
111
112static void return_i2c_dev(struct i2c_dev *i2c_dev)
113{
114 spin_lock(&i2c_dev_list_lock);
115 list_del(&i2c_dev->list);
116 spin_unlock(&i2c_dev_list_lock);
117 kfree(i2c_dev);
118}
119
120static struct i2c_dev *i2c_dev_get_by_minor(unsigned index)
121{
122 struct i2c_dev *i2c_dev;
123 i2c_dev = NULL;
124
125 spin_lock(&i2c_dev_list_lock);
126 list_for_each_entry(i2c_dev, &i2c_dev_list, list) {
127 if (i2c_dev->adap->nr == index)
128 goto found;
129 }
130 i2c_dev = NULL;
131found:
132 spin_unlock(&i2c_dev_list_lock);
133
134 return i2c_dev;
135}
136
137static struct i2c_dev *get_free_i2c_dev(struct i2c_adapter *adap)
138{
139 struct i2c_dev *i2c_dev;
140
141 if (adap->nr >= I2C_MINORS) {
142 printk(KERN_ERR "i2c-dev: Out of device minors (%d)\n",
143 adap->nr);
144 return ERR_PTR(-ENODEV);
145 }
146
147 i2c_dev = kzalloc(sizeof(*i2c_dev), GFP_KERNEL);
148 if (!i2c_dev)
149 return ERR_PTR(-ENOMEM);
150 i2c_dev->adap = adap;
151
152 spin_lock(&i2c_dev_list_lock);
153 list_add_tail(&i2c_dev->list, &i2c_dev_list);
154 spin_unlock(&i2c_dev_list_lock);
155
156 return i2c_dev;
157}
158
159void read_XN_YN_value(struct i2c_client *client)
160{
161 char Wrbuf[4], Rdbuf[2];
162
163 memset(Wrbuf, 0, sizeof(Wrbuf));
164 memset(Rdbuf, 0, sizeof(Rdbuf));
165
166 Wrbuf[0] = SPECOP;
167 Wrbuf[1] = 1;
168
169 Wrbuf[2] = 64;
170 Wrbuf[3] = 0;
171
172 i2c_master_send(client, Wrbuf, 4);
173 mdelay(8);
174 i2c_master_recv(client, Rdbuf, 2);
175 x_nb_electrodes = Rdbuf[0];
176
177 if (Tango_number == 1) {
178 x2_nb_electrodes = 0;
179
180 memset(Wrbuf, 0, sizeof(Wrbuf));
181 memset(Rdbuf, 0, sizeof(Rdbuf));
182
183 Wrbuf[0] = SPECOP;
184 Wrbuf[1] = 1;
185 Wrbuf[2] = 203;
186 Wrbuf[3] = 0;
187
188 i2c_master_send(client, Wrbuf, 4);
189 mdelay(4);
190
191 i2c_master_recv(client, Rdbuf, 2);
192 y_nb_electrodes = Rdbuf[0];
193 } else if (Tango_number == 2) {
194 memset(Wrbuf, 0, sizeof(Wrbuf));
195 memset(Rdbuf, 0, sizeof(Rdbuf));
196
197 Wrbuf[0] = SPECOP;
198 Wrbuf[1] = 1;
199
200 i2c_master_send(client, Wrbuf, 4);
201 mdelay(4);
202 i2c_master_recv(client, Rdbuf, 2);
203 x2_nb_electrodes = Rdbuf[0];
204
205 memset(Wrbuf, 0, sizeof(Wrbuf));
206 memset(Rdbuf, 0, sizeof(Rdbuf));
207
208 Wrbuf[0] = SPECOP;
209 Wrbuf[1] = 1;
210
211 i2c_master_send(client, Wrbuf, 4);
212 mdelay(4);
213
214 i2c_master_recv(client, Rdbuf, 2);
215 y_nb_electrodes = Rdbuf[0];
216 }
217 if (x2_nb_electrodes)
218 x1_x2_nb_electrodes = x_nb_electrodes + x2_nb_electrodes - 1;
219 else
220 x1_x2_nb_electrodes = x_nb_electrodes;
221
222 read_XN_YN_flag = 1;
223}
224
225void read_XY_tables(struct i2c_client *client, signed char *xy_raw1_buf,
226 signed char *xy_raw2_buf)
227{
228 u_int8_t Wrbuf[1];
229
230 memset(Wrbuf, 0, sizeof(Wrbuf));
231
232 i2c_master_send(client, Wrbuf, 1);
233 i2c_master_recv(client, xy_raw1_buf, (MAXX - 1) * 2);
234 i2c_master_send(client, Wrbuf, 1);
235 i2c_master_recv(client, xy_raw2_buf, (MAXX - 1) * 2);
236}
237
238static struct workqueue_struct *pixcir_wq;
239
240struct pixcir_i2c_ts_data {
241 struct i2c_client *client;
242 struct input_dev *input;
243 struct input_dev *input_key;
244 struct delayed_work work;
245 int irq;
246};
247
248static unsigned char pixcir_keycode[] = {KEY_D, KEY_A, KEY_B};
249
250static void pixcir_ts_poscheck(struct work_struct *work)
251{
252 struct pixcir_i2c_ts_data *tsdata =
253 container_of(work, struct pixcir_i2c_ts_data, work.work);
254 unsigned char touching = 0;
255 unsigned char oldtouching = 0;
256 int posx1, posy1, posx2, posy2;
257 unsigned char Rdbuf[10], Wrbuf[1];
258 int z = 50;
259 int w = 15;
260 static int pressed_keycode = -1;
261
262 interrupt_flag = 1;
263
264 memset(Wrbuf, 0, sizeof(Wrbuf));
265 memset(Rdbuf, 0, sizeof(Rdbuf));
266
267 Wrbuf[0] = 0;
268
269 i2c_master_send(tsdata->client, Wrbuf, 1);
270 i2c_master_recv(tsdata->client, Rdbuf, sizeof(Rdbuf));
271
272 posx1 = ((Rdbuf[5] << 8) | Rdbuf[4]);
273 posy1 = ((Rdbuf[3] << 8) | Rdbuf[2]);
274 posx2 = ((Rdbuf[9] << 8) | Rdbuf[8]);
275 posy2 = ((Rdbuf[7] << 8) | Rdbuf[6]);
276
277 posx1 = TOUCHSCREEN_MAXX - posx1;
278 posx2 = TOUCHSCREEN_MAXX - posx2;
279
280 touching = Rdbuf[0];
281 oldtouching = Rdbuf[1];
282
283 if (touching == 1 && posy1 > 800) {
284 if (posx1 < 100) /* MENU KEY */
285 pressed_keycode = 0;
286 else if (posx1 > (240 - 50) && posx1 < (240 + 50)) /* HOME KEY */
287 pressed_keycode = 1;
288 else if (posx1 > (480 - 100)) /* BACK KEY */
289 pressed_keycode = 2;
290 else
291 pressed_keycode = -1;
292
293 if (pressed_keycode != -1) {
294 input_event(tsdata->input_key, EV_MSC, MSC_SCAN,
295 pressed_keycode);
296 input_report_key(tsdata->input_key,
297 pixcir_keycode[pressed_keycode], 1);
298 input_sync(tsdata->input_key);
299 }
300 } else {
301 if (touching) {
302 input_report_abs(tsdata->input, ABS_X, posx1);
303 input_report_abs(tsdata->input, ABS_Y, posy1);
304 input_report_key(tsdata->input, BTN_TOUCH, 1);
305 input_report_abs(tsdata->input, ABS_PRESSURE, 1);
306 } else {
307 input_report_key(tsdata->input, BTN_TOUCH, 0);
308 input_report_abs(tsdata->input, ABS_PRESSURE, 0);
309 }
310
311 if (!(touching)) {
312 z = 0;
313 w = 0;
314 }
315 if (touching == 1) {
316 input_report_abs(tsdata->input, ABS_MT_TOUCH_MAJOR, z);
317 input_report_abs(tsdata->input, ABS_MT_WIDTH_MAJOR, w);
318 input_report_abs(tsdata->input, ABS_MT_POSITION_X, posx1);
319 input_report_abs(tsdata->input, ABS_MT_POSITION_Y, posy1);
320 input_mt_sync(tsdata->input);
321 } else if (touching == 2) {
322 input_report_abs(tsdata->input, ABS_MT_TOUCH_MAJOR, z);
323 input_report_abs(tsdata->input, ABS_MT_WIDTH_MAJOR, w);
324 input_report_abs(tsdata->input, ABS_MT_POSITION_X, posx1);
325 input_report_abs(tsdata->input, ABS_MT_POSITION_Y, posy1);
326 input_mt_sync(tsdata->input);
327
328 input_report_abs(tsdata->input, ABS_MT_TOUCH_MAJOR, z);
329 input_report_abs(tsdata->input, ABS_MT_WIDTH_MAJOR, w);
330 input_report_abs(tsdata->input, ABS_MT_POSITION_X, posx2);
331 input_report_abs(tsdata->input, ABS_MT_POSITION_Y, posy2);
332 input_mt_sync(tsdata->input);
333 }
334 input_sync(tsdata->input);
335 }
336
337 if (touching == 0) {
338 if (pressed_keycode != -1) {
339 input_event (tsdata->input_key, EV_MSC, MSC_SCAN, pressed_keycode);
340 input_report_key (tsdata->input_key, pixcir_keycode[pressed_keycode], 0);
341 input_sync(tsdata->input_key);
342 pressed_keycode = -1;
343 }
344 else {
345 input_mt_sync(tsdata->input);
346 input_sync(tsdata->input);
347 }
348 }
349
350 if (status_reg == NORMAL_MODE) {
351 global_touching = touching;
352 global_oldtouching = oldtouching;
353 global_posx1_low = Rdbuf[2];
354 global_posx1_high = Rdbuf[3];
355 global_posy1_low = Rdbuf[4];
356 global_posy1_high = Rdbuf[5];
357 global_posx2_low = Rdbuf[6];
358 global_posx2_high = Rdbuf[7];
359 global_posy2_low = Rdbuf[8];
360 global_posy2_high = Rdbuf[9];
361 }
362
363 enable_irq(tsdata->irq);
364}
365
366static irqreturn_t pixcir_ts_isr(int irq, void *dev_id)
367{
368 struct pixcir_i2c_ts_data *tsdata = dev_id;
369
370 if ((status_reg == 0) || (status_reg == NORMAL_MODE)) {
371 disable_irq_nosync(irq);
372 queue_work(pixcir_wq, &tsdata->work.work);
373 }
374
375 return IRQ_HANDLED;
376}
377
378static int pixcir_ts_open(struct input_dev *dev)
379{
380 return 0;
381}
382
383static void pixcir_ts_close(struct input_dev *dev)
384{
385}
386
387static int pixcir_i2c_ts_probe(struct i2c_client *client,
388 const struct i2c_device_id *id)
389{
390 struct pixcir_i2c_ts_data *tsdata;
391 struct input_dev *input;
392 struct input_dev *input_key;
393 struct device *dev;
394 struct i2c_dev *i2c_dev;
395 int error = 0;
396
397 tsdata = kzalloc(sizeof(*tsdata), GFP_KERNEL);
398 if (!tsdata) {
399 dev_err(&client->dev, "failed to allocate driver data!\n");
400 error = -ENOMEM;
401 dev_set_drvdata(&client->dev, NULL);
402 return error;
403 }
404
405 dev_set_drvdata(&client->dev, tsdata);
406
407 input = input_allocate_device();
408 if (!input) {
409 dev_err(&client->dev, "failed to allocate input device!\n");
410 error = -ENOMEM;
411 goto err_free_tsdata;
412 }
413
414 set_bit(EV_SYN, input->evbit);
415 set_bit(EV_KEY, input->evbit);
416 set_bit(EV_ABS, input->evbit);
417 set_bit(BTN_TOUCH, input->keybit);
418 input_set_abs_params(input, ABS_X, TOUCHSCREEN_MINX,
419 TOUCHSCREEN_MAXX, 0, 0);
420 input_set_abs_params(input, ABS_Y, TOUCHSCREEN_MINY,
421 TOUCHSCREEN_MAXY, 0, 0);
422 input_set_abs_params(input, ABS_MT_POSITION_X,
423 TOUCHSCREEN_MINX, TOUCHSCREEN_MAXX, 0, 0);
424 input_set_abs_params(input, ABS_MT_POSITION_Y,
425 TOUCHSCREEN_MINY, TOUCHSCREEN_MAXY, 0, 0);
426 input_set_abs_params(input, ABS_MT_TOUCH_MAJOR, 0, 255, 0, 0);
427 input_set_abs_params(input, ABS_MT_WIDTH_MAJOR, 0, 25, 0, 0);
428
429 input->name = "pixcir-i2c-ts";
430 input->phys = "pixcir_ts/input1";
431 input->id.bustype = BUS_I2C;
432 input->dev.parent = &client->dev;
433 input->open = pixcir_ts_open;
434 input->close = pixcir_ts_close;
435
436 input_set_drvdata(input, tsdata);
437
438 tsdata->client = client;
439 tsdata->input = input;
440
441 INIT_WORK(&tsdata->work.work, pixcir_ts_poscheck);
442
443 tsdata->irq = client->irq;
444 global_irq = client->irq;
445
446 if (input_register_device(input)) {
447 error = -EIO;
448 goto err_free_input;
449 }
450
451 /* for keypad */
452 input_key = input_allocate_device();
453 if (!input_key) {
454 dev_err(&client->dev, "failed to allocate input device!\n");
455 error = -ENOMEM;
456 goto err_unregister_input;
457 }
458
459 input_key->evbit[0] = BIT_MASK(EV_KEY);
460 input_set_capability(input_key, EV_MSC, MSC_SCAN);
461
462 input_key->keycode = pixcir_keycode;
463 input_key->keycodesize = sizeof(unsigned char);
464 input_key->keycodemax = ARRAY_SIZE(pixcir_keycode);
465
466 __set_bit(pixcir_keycode[0], input_key->keybit);
467 __set_bit(pixcir_keycode[1], input_key->keybit);
468 __set_bit(pixcir_keycode[2], input_key->keybit);
469 __clear_bit(KEY_RESERVED, input_key->keybit);
470
471 input_key->name = "pixcir-i2c-ts_key";
472 input_key->phys = "pixcir_ts/input2";
473 input_key->id.bustype = BUS_I2C;
474 input_key->dev.parent = &client->dev;
475 input_key->open = pixcir_ts_open;
476 input_key->close = pixcir_ts_close;
477
478 tsdata->input_key = input_key;
479
480 if (input_register_device(input_key)) {
481 error = -EIO;
482 goto err_free_input_key;
483 }
484
485 if (gpio_request(RESET, GPIO_NAME)) {
486 error = -EIO;
487 goto err_unregister_input_key;
488 }
489 RESETPIN_CFG;
490 RESETPIN_SET0;
491 mdelay(20);
492 RESETPIN_SET1;
493
494 mdelay(30);
495
496 error = request_irq(tsdata->irq, pixcir_ts_isr, IRQF_TRIGGER_FALLING,
497 "pixcir_ts_irq", tsdata);
498 if (error) {
499 dev_err(&client->dev, "Unable to request touchscreen IRQ.\n");
500 goto err_unregister_input_key;
501 }
502
503 s3c_gpio_setpull(ATTB, S3C_GPIO_PULL_NONE);
504
505 device_init_wakeup(&client->dev, 0);
506
507 i2c_dev = get_free_i2c_dev(client->adapter);
508 if (IS_ERR(i2c_dev)) {
509 error = PTR_ERR(i2c_dev);
510 goto err_free_irq;
511 }
512
513 dev = device_create(i2c_dev_class, &client->adapter->dev,
514 MKDEV(I2C_MAJOR, client->adapter->nr), NULL,
515 "pixcir_i2c_ts%d", 0);
516 if (IS_ERR(dev)) {
517 error = PTR_ERR(dev);
518 goto err_free_irq;
519 }
520
521 dev_err(&tsdata->client->dev, "insmod successfully!\n");
522
523 return 0;
524
525 err_free_irq:
526 free_irq(tsdata->irq, input);
527 err_unregister_input_key:
528 input_unregister_device(input_key);
529 err_free_input_key:
530 input_free_device(input_key);
531 err_unregister_input:
532 input_unregister_device(input);
533 err_free_input:
534 input_free_device(input);
535 err_free_tsdata:
536 kfree(tsdata);
537
538 return error;
539}
540
541static int pixcir_i2c_ts_remove(struct i2c_client *client)
542{
543 int error;
544 struct i2c_dev *i2c_dev;
545 struct pixcir_i2c_ts_data *tsdata = dev_get_drvdata(&client->dev);
546
547 free_irq(tsdata->irq, tsdata);
548 i2c_dev = get_free_i2c_dev(client->adapter);
549 if (IS_ERR(i2c_dev)) {
550 error = PTR_ERR(i2c_dev);
551 return error;
552 }
553 return_i2c_dev(i2c_dev);
554 device_destroy(i2c_dev_class, MKDEV(I2C_MAJOR, client->adapter->nr));
555 input_unregister_device(tsdata->input);
556 input_free_device(tsdata->input);
557 input_unregister_device(tsdata->input_key);
558 input_free_device(tsdata->input_key);
559 kfree(tsdata);
560 dev_set_drvdata(&client->dev, NULL);
561
562 return 0;
563}
564
565static int pixcir_i2c_ts_suspend(struct i2c_client *client, pm_message_t mesg)
566{
567 struct pixcir_i2c_ts_data *tsdata = dev_get_drvdata(&client->dev);
568
569 if (device_may_wakeup(&client->dev))
570 enable_irq_wake(tsdata->irq);
571
572 return 0;
573}
574
575static int pixcir_i2c_ts_resume(struct i2c_client *client)
576{
577 struct pixcir_i2c_ts_data *tsdata = dev_get_drvdata(&client->dev);
578
579 if (device_may_wakeup(&client->dev))
580 disable_irq_wake(tsdata->irq);
581
582 return 0;
583}
584
585static int pixcir_open(struct inode *inode, struct file *file)
586{
587 int subminor;
588 struct i2c_client *client;
589 struct i2c_adapter *adapter;
590 struct i2c_dev *i2c_dev;
591
592 subminor = iminor(inode);
593
594 i2c_dev = i2c_dev_get_by_minor(subminor);
595 if (!i2c_dev) {
596 printk(KERN_ERR "error i2c_dev\n");
597 return -ENODEV;
598 }
599
600 adapter = i2c_get_adapter(i2c_dev->adap->nr);
601 if (!adapter)
602 return -ENODEV;
603
604 client = kzalloc(sizeof(*client), GFP_KERNEL);
605 if (!client) {
606 i2c_put_adapter(adapter);
607 return -ENOMEM;
608 }
609 snprintf(client->name, I2C_NAME_SIZE, "pixcir_i2c_ts%d", adapter->nr);
610 client->driver = &pixcir_i2c_ts_driver;
611 client->adapter = adapter;
612 file->private_data = client;
613
614 return 0;
615}
616
617static long pixcir_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
618{
619 struct i2c_client *client =
620 (struct i2c_client *) file->private_data;
621
622 switch (cmd) {
623 case CALIBRATION_FLAG:
624 client->addr = SLAVE_ADDR;
625 status_reg = 0;
626 status_reg = CALIBRATION_FLAG;
627 break;
628
629 case NORMAL_MODE:
630 client->addr = SLAVE_ADDR;
631 status_reg = 0;
632 status_reg = NORMAL_MODE;
633 break;
634
635 case PIXCIR_DEBUG_MODE:
636 client->addr = SLAVE_ADDR;
637 status_reg = 0;
638 status_reg = PIXCIR_DEBUG_MODE;
639
640 Tango_number = arg;
641 break;
642
643 case BOOTLOADER_MODE:
644 status_reg = 0;
645 status_reg = BOOTLOADER_MODE;
646 disable_irq_nosync(global_irq);
647
648#ifdef reset
649 client->addr = BOOTLOADER_ADDR;
650
651 RESETPIN_CFG;
652 RESETPIN_SET0;
653 mdelay(20);
654 RESETPIN_SET1;
655
656 mdelay(30);
657#else
658 client->addr = SLAVE_ADDR;
659 tmp[0] = SPECOP;
660 tmp[1] = 5;
661 i2c_master_send(client, tmp, 2);
662
663 client->addr = BOOTLOADER_ADDR;
664#endif
665 break;
666
667 case ENABLE_IRQ:
668 enable_irq(global_irq);
669 status_reg = 0;
670 break;
671
672 case DISABLE_IRQ:
673 disable_irq_nosync(global_irq);
674 break;
675
676 case RD_EEPROM:
677 client->addr = SLAVE_ADDR;
678 status_reg = 0;
679 status_reg = RD_EEPROM;
680 break;
681
682 case WR_EEPROM:
683 client->addr = SLAVE_ADDR;
684 status_reg = 0;
685 status_reg = WR_EEPROM;
686break;
687
688 case VERSION_FLAG:
689 client->addr = SLAVE_ADDR;
690 status_reg = 0;
691 status_reg = VERSION_FLAG;
692
693 Tango_number = arg;
694 break;
695
696 default:
697 break;
698 }
699 return 0;
700}
701
702static ssize_t pixcir_read(struct file *file,
703 char __user *buf, size_t count, loff_t *offset)
704{
705 struct i2c_client *client =
706 (struct i2c_client *)file->private_data;
707 int ret = 0;
708 unsigned char normal_tmp[10];
709
710 switch (status_reg) {
711 case NORMAL_MODE:
712 memset(normal_tmp, 0, sizeof(normal_tmp));
713 if (interrupt_flag) {
714 normal_tmp[0] = global_touching;
715 normal_tmp[1] = global_oldtouching;
716 normal_tmp[2] = global_posx1_low;
717 normal_tmp[3] = global_posx1_high;
718 normal_tmp[4] = global_posy1_low;
719 normal_tmp[5] = global_posy1_high;
720 normal_tmp[6] = global_posx2_low;
721 normal_tmp[7] = global_posx2_high;
722 normal_tmp[8] = global_posy2_low;
723 normal_tmp[9] = global_posy2_high;
724 if (copy_to_user(buf, normal_tmp, 10)) {
725 dev_err(&client->dev, "error : copy_to_user\n");
726 return -EFAULT;
727 }
728
729 }
730 interrupt_flag = 0;
731 break;
732
733 case PIXCIR_DEBUG_MODE:
734 if (read_XN_YN_flag == 0) {
735 unsigned char buf[2];
736 memset(buf, 0, sizeof(buf));
737
738 read_XN_YN_value(client);
739
740 buf[0] = 194;
741 buf[1] = 0;
742 i2c_master_send(client, buf, 2);
743 } else {
744 memset(xy_raw1, 0, sizeof(xy_raw1));
745 memset(xy_raw2, 0, sizeof(xy_raw2));
746 read_XY_tables(client, xy_raw1, xy_raw2);
747 }
748
749 if (Tango_number == 1) {
750 xy_raw1[MAXX * 2] = x_nb_electrodes;
751 xy_raw1[MAXX * 2 + 1] = y_nb_electrodes;
752
753 if (copy_to_user(buf, xy_raw1, MAXX * 2 + 2)) {
754 dev_err(&client->dev, "error : copy_to_user\n");
755 return -EFAULT;
756 }
757
758 } else if (Tango_number == 2) {
759 xy_raw1[MAXX * 2] = x_nb_electrodes;
760 xy_raw1[MAXX * 2 + 1] = y_nb_electrodes;
761 xy_raw1[MAXX * 2 + 2] = x2_nb_electrodes;
762
763 for (ret = 0; ret < (MAXX * 2 + 3); ret++)
764 xy_raw12[ret] = xy_raw1[ret];
765
766 for (ret = 0; ret < (MAXX * 2 - 1); ret++)
767 xy_raw12[(MAXX * 2 + 3) + ret] = xy_raw2[ret];
768
769 if (copy_to_user(buf, xy_raw12, MAXX * 4 + 3)) {
770 dev_err(&client->dev, "error : copy_to_user\n");
771 return -EFAULT;
772 }
773 }
774 break;
775
776 case RD_EEPROM: {
777 unsigned char epmbytbuf[512];
778
779 memset(epmbytbuf, 0, sizeof(epmbytbuf));
780 i2c_master_recv(client, epmbytbuf, count);
781
782 if (copy_to_user(buf, epmbytbuf, count)) {
783 dev_err(&client->dev, "error : copy_to_user\n");
784 return -EFAULT;
785 }
786
787 break;
788 }
789
790 case VERSION_FLAG: {
791 unsigned char vaddbuf[1], verbuf[5];
792
793 memset(vaddbuf, 0, sizeof(vaddbuf));
794 memset(verbuf, 0, sizeof(verbuf));
795 vaddbuf[0] = 48;
796 i2c_master_send(client, vaddbuf, 1);
797 i2c_master_recv(client, verbuf, 5);
798
799 if (copy_to_user(buf, verbuf, 5)) {
800 dev_err(&client->dev, "error : copy_to_user\n");
801 return -EFAULT;
802 }
803
804 break;
805 }
806
807 default:
808 break;
809 }
810
811 return ret;
812}
813
814static ssize_t pixcir_write(struct file *file,
815 const char __user *buf, size_t count, loff_t *ppos)
816{
817 struct i2c_client *client;
818 char *tmp, bootload_data[143], Rdbuf[1];
819 int ret = 0, stu;
820 int re_value = 0;
821
822 client = file->private_data;
823
824 switch (status_reg) {
825 case CALIBRATION_FLAG:
826 tmp = kmalloc(count, GFP_KERNEL);
827 if (tmp == NULL)
828 return -ENOMEM;
829
830 if (copy_from_user(tmp, buf, count)) {
831 dev_err(&client->dev, "error : copy_from_user\n");
832 kfree(tmp);
833 return -EFAULT;
834 }
835 i2c_master_send(client, tmp, count);
836 mdelay(100);
837
838 kfree(tmp);
839
840 status_reg = 0;
841 break;
842
843 case BOOTLOADER_MODE:
844 memset(bootload_data, 0, sizeof(bootload_data));
845 memset(Rdbuf, 0, sizeof(Rdbuf));
846
847 if (copy_from_user(bootload_data, buf, count)) {
848 dev_err(&client->dev, "error : copy_from_user\n");
849 return -EFAULT;
850 }
851
852 stu = bootload_data[0];
853
854 i2c_master_send(client, bootload_data, count);
855
856 if (stu != 0x01) {
857 mdelay(1);
858 while (get_attb_value(ATTB))
859 ;
860 mdelay(1);
861
862 i2c_master_recv(client, Rdbuf, 1);
863 re_value = Rdbuf[0];
864 } else {
865 mdelay(100);
866 status_reg = 0;
867 enable_irq(global_irq);
868 }
869
870 if ((re_value & 0x80) && (stu != 0x01)) {
871 printk(KERN_ERR "Failed : (re_value & 0x80) && (stu != 0x01) = 1\n");
872 ret = 0;
873 }
874 break;
875
876 case RD_EEPROM: {
877 unsigned char epmdatabuf[2], wr2eep[4];
878
879 memset(epmdatabuf, 0, sizeof(epmdatabuf));
880 memset(wr2eep, 0, sizeof(wr2eep));
881
882 if (copy_from_user(epmdatabuf, buf, count)) {
883 dev_err(&client->dev, "error : copy_from_user\n");
884 return -EFAULT;
885 }
886
887 wr2eep[0] = SPECOP;
888 wr2eep[1] = 1;
889 wr2eep[2] = epmdatabuf[0];
890 wr2eep[3] = epmdatabuf[1];
891 i2c_master_send(client, wr2eep, 4);
892
893 break;
894 }
895
896 case WR_EEPROM: {
897 unsigned char epmdatabuf[2];
898
899 memset(epmdatabuf, 0, sizeof(epmdatabuf));
900
901 if (copy_from_user(epmdatabuf, buf, count)) {
902 dev_err(&client->dev, "error : copy_from_user\n");
903 return -EFAULT;
904 }
905
906 if (2 == count) {
907 op2eep[0] = SPECOP;
908 op2eep[1] = 2;
909 data2eep[0] = epmdatabuf[0];
910 data2eep[1] = epmdatabuf[1];
911 } else if (1 == count) {
912 data2eep[2] = epmdatabuf[0];
913 i2c_master_send(client, op2eep, 2);
914 i2c_master_send(client, data2eep, 3);
915 mdelay(4);
916 i2c_master_recv(client, data2eep, 1);
917 mdelay(100);
918 }
919 break;
920 }
921
922 default:
923 break;
924 }
925 return ret;
926}
927
928static int pixcir_release(struct inode *inode, struct file *file)
929{
930 struct i2c_client *client = file->private_data;
931
932 i2c_put_adapter(client->adapter);
933 kfree(client);
934 file->private_data = NULL;
935
936 return 0;
937}
938
939static const struct file_operations pixcir_i2c_ts_fops = {
940 .owner = THIS_MODULE,
941 .read = pixcir_read,
942 .write = pixcir_write,
943 .open = pixcir_open,
944 .unlocked_ioctl = pixcir_ioctl,
945 .release = pixcir_release,
946};
947
948static const struct i2c_device_id pixcir_i2c_ts_id[] = {
949 {"pixcir-ts", 0},
950 { }
951};
952MODULE_DEVICE_TABLE(i2c, pixcir_i2c_ts_id);
953
954static struct i2c_driver pixcir_i2c_ts_driver = {
955 .driver = {
956 .owner = THIS_MODULE,
957 .name = "pixcir-i2c-ts",
958 },
959 .probe = pixcir_i2c_ts_probe,
960 .remove = pixcir_i2c_ts_remove,
961 .suspend = pixcir_i2c_ts_suspend,
962 .resume = pixcir_i2c_ts_resume,
963 .id_table = pixcir_i2c_ts_id,
964};
965
966static int __init pixcir_i2c_ts_init(void)
967{
968 int ret;
969
970 pixcir_wq = create_singlethread_workqueue("pixcir_wq");
971
972 if (!pixcir_wq)
973 return -ENOMEM;
974
975 ret = register_chrdev(I2C_MAJOR, "pixcir_i2c_ts", &pixcir_i2c_ts_fops);
976 if (ret) {
977 printk(KERN_ERR "%s:register chrdev failed\n", __FILE__);
978 return ret;
979 }
980
981 i2c_dev_class = class_create(THIS_MODULE, "pixcir_i2c_dev");
982
983 if (IS_ERR(i2c_dev_class)) {
984 ret = PTR_ERR(i2c_dev_class);
985 class_destroy(i2c_dev_class);
986 }
987
988 return i2c_add_driver(&pixcir_i2c_ts_driver);
989}
990
991static void __exit pixcir_i2c_ts_exit(void)
992{
993 i2c_del_driver(&pixcir_i2c_ts_driver);
994 class_destroy(i2c_dev_class);
995 unregister_chrdev(I2C_MAJOR, "pixcir_i2c_ts");
996 if (pixcir_wq)
997 destroy_workqueue(pixcir_wq);
998}
999
1000module_init(pixcir_i2c_ts_init);
1001module_exit(pixcir_i2c_ts_exit);
1002
1003MODULE_AUTHOR("Dongsu Ha <dsfine.ha@samsung.com>, "
1004 "Bee<http://www.pixcir.com.cn>, "
1005 "Samsung Electronics <http://www.samsung.com>");
1006
1007MODULE_DESCRIPTION("Pixcir Touchscreen driver");
1008MODULE_LICENSE("GPL");
diff --git a/drivers/input/touchscreen/s3c2410_ts.c b/drivers/input/touchscreen/s3c2410_ts.c
index 8feb7f3c8be..c57956c3e93 100644
--- a/drivers/input/touchscreen/s3c2410_ts.c
+++ b/drivers/input/touchscreen/s3c2410_ts.c
@@ -68,10 +68,16 @@
68 * @io: Pointer to the IO base. 68 * @io: Pointer to the IO base.
69 * @xp: The accumulated X position data. 69 * @xp: The accumulated X position data.
70 * @yp: The accumulated Y position data. 70 * @yp: The accumulated Y position data.
71 * @xp_pre: The previous X position data.
72 * @yp_pre: The previous Y position data.
71 * @irq_tc: The interrupt number for pen up/down interrupt 73 * @irq_tc: The interrupt number for pen up/down interrupt
72 * @count: The number of samples collected. 74 * @count: The number of samples collected.
73 * @shift: The log2 of the maximum count to read in one go. 75 * @shift: The log2 of the maximum count to read in one go.
74 * @features: The features supported by the TSADC MOdule. 76 * @features: The features supported by the TSADC MOdule.
77 * @cal_enable: The flag of enabling calibration.
78 * @cal_x_max: The maximum value of calibrated X.
79 * @cal_y_max: The maximum value of calibrated Y.
80 * @cal_param: The parameters for calibration.
75 */ 81 */
76struct s3c2410ts { 82struct s3c2410ts {
77 struct s3c_adc_client *client; 83 struct s3c_adc_client *client;
@@ -81,14 +87,85 @@ struct s3c2410ts {
81 void __iomem *io; 87 void __iomem *io;
82 unsigned long xp; 88 unsigned long xp;
83 unsigned long yp; 89 unsigned long yp;
90 unsigned long xp_pre;
91 unsigned long yp_pre;
92
84 int irq_tc; 93 int irq_tc;
85 int count; 94 int count;
86 int shift; 95 int shift;
87 int features; 96 int features;
97 bool request_done;
98
99 int cal_enable;
100 int cal_x_max;
101 int cal_y_max;
102 int cal_param[7];
88}; 103};
89 104
90static struct s3c2410ts ts; 105static struct s3c2410ts ts;
91 106
107struct cal_data {
108 int cal_x_max;
109 int cal_y_max;
110 int cal_param[7];
111};
112
113static ssize_t set_ts_cal(struct device *dev,
114 struct device_attribute *attr,
115 const char *buf, size_t count)
116{
117 int i;
118 struct cal_data *b = (struct cal_data *) buf;
119
120 if (count < sizeof(struct cal_data))
121 return 0;
122
123 dev_dbg(ts.dev, "%s : cal_x_max : %d cal_y_max : %d "
124 "cal_param : %d %d %d %d %d %d %d\n", __func__,
125 b->cal_x_max, b->cal_y_max, b->cal_param[0],
126 b->cal_param[1], b->cal_param[2], b->cal_param[3],
127 b->cal_param[4], b->cal_param[5], b->cal_param[6]);
128
129 ts.cal_x_max = b->cal_x_max;
130 ts.cal_y_max = b->cal_y_max;
131
132 for (i = 0; i < 7; i++)
133 ts.cal_param[i] = b->cal_param[i];
134
135 input_set_abs_params(ts.input, ABS_X, 0, ts.cal_x_max, 0, 0);
136 input_set_abs_params(ts.input, ABS_Y, 0, ts.cal_y_max, 0, 0);
137
138 ts.cal_enable = 1;
139
140 return sizeof(struct cal_data);
141}
142
143static ssize_t reset_ts_cal(struct device *dev,
144 struct device_attribute *attr,
145 const char *buf, size_t count)
146{
147 input_set_abs_params(ts.input, ABS_X, 0, 0x3ff, 0, 0);
148 input_set_abs_params(ts.input, ABS_Y, 0, 0x3ff, 0, 0);
149
150 ts.cal_enable = 0;
151
152 return count;
153}
154
155static DEVICE_ATTR(set_tscal, S_IRWXUGO, NULL, set_ts_cal);
156static DEVICE_ATTR(reset_tscal, S_IRWXUGO, NULL, reset_ts_cal);
157
158static struct attribute *s5pv310_ts_sysfs_entries[] = {
159 &dev_attr_set_tscal.attr,
160 &dev_attr_reset_tscal.attr,
161 NULL
162};
163
164static struct attribute_group s5pv310_ts_attr_group = {
165 .name = NULL,
166 .attrs = s5pv310_ts_sysfs_entries,
167};
168
92/** 169/**
93 * get_down - return the down state of the pen 170 * get_down - return the down state of the pen
94 * @data0: The data read from ADCDAT0 register. 171 * @data0: The data read from ADCDAT0 register.
@@ -103,6 +180,18 @@ static inline bool get_down(unsigned long data0, unsigned long data1)
103 !(data1 & S3C2410_ADCDAT0_UPDOWN)); 180 !(data1 & S3C2410_ADCDAT0_UPDOWN));
104} 181}
105 182
183static void ts_calibrate(void)
184{
185 int x, y;
186 x = (int)ts.xp;
187 y = (int)ts.yp;
188
189 ts.xp = (long)((ts.cal_param[2] + (ts.cal_param[0] * x) +
190 (ts.cal_param[1] * y)) / ts.cal_param[6]);
191 ts.yp = (long)((ts.cal_param[5] + (ts.cal_param[3] * x) +
192 (ts.cal_param[4] * y)) / ts.cal_param[6]);
193}
194
106static void touch_timer_fire(unsigned long data) 195static void touch_timer_fire(unsigned long data)
107{ 196{
108 unsigned long data0; 197 unsigned long data0;
@@ -119,6 +208,9 @@ static void touch_timer_fire(unsigned long data)
119 ts.xp >>= ts.shift; 208 ts.xp >>= ts.shift;
120 ts.yp >>= ts.shift; 209 ts.yp >>= ts.shift;
121 210
211 if (ts.cal_enable)
212 ts_calibrate();
213
122 dev_dbg(ts.dev, "%s: X=%lu, Y=%lu, count=%d\n", 214 dev_dbg(ts.dev, "%s: X=%lu, Y=%lu, count=%d\n",
123 __func__, ts.xp, ts.yp, ts.count); 215 __func__, ts.xp, ts.yp, ts.count);
124 216
@@ -128,6 +220,9 @@ static void touch_timer_fire(unsigned long data)
128 input_report_key(ts.input, BTN_TOUCH, 1); 220 input_report_key(ts.input, BTN_TOUCH, 1);
129 input_sync(ts.input); 221 input_sync(ts.input);
130 222
223 ts.xp_pre = ts.xp;
224 ts.yp_pre = ts.yp;
225
131 ts.xp = 0; 226 ts.xp = 0;
132 ts.yp = 0; 227 ts.yp = 0;
133 ts.count = 0; 228 ts.count = 0;
@@ -139,10 +234,15 @@ static void touch_timer_fire(unsigned long data)
139 ts.yp = 0; 234 ts.yp = 0;
140 ts.count = 0; 235 ts.count = 0;
141 236
237 input_report_abs(ts.input, ABS_X, ts.xp_pre);
238 input_report_abs(ts.input, ABS_Y, ts.yp_pre);
239
142 input_report_key(ts.input, BTN_TOUCH, 0); 240 input_report_key(ts.input, BTN_TOUCH, 0);
143 input_sync(ts.input); 241 input_sync(ts.input);
144 242
145 writel(WAIT4INT | INT_DOWN, ts.io + S3C2410_ADCTSC); 243 writel(WAIT4INT | INT_DOWN, ts.io + S3C2410_ADCTSC);
244
245 ts.request_done = true;
146 } 246 }
147} 247}
148 248
@@ -170,10 +270,12 @@ static irqreturn_t stylus_irq(int irq, void *dev_id)
170 * the timer is running, but maybe we ought to verify that the 270 * the timer is running, but maybe we ought to verify that the
171 * timer isn't running anyways. */ 271 * timer isn't running anyways. */
172 272
173 if (down) 273 if (down && ts.request_done) {
274 ts.request_done = false;
174 s3c_adc_start(ts.client, 0, 1 << ts.shift); 275 s3c_adc_start(ts.client, 0, 1 << ts.shift);
175 else 276 } else {
176 dev_dbg(ts.dev, "%s: count=%d\n", __func__, ts.count); 277 dev_dbg(ts.dev, "%s: count=%d\n", __func__, ts.count);
278 }
177 279
178 if (ts.features & FEAT_PEN_IRQ) { 280 if (ts.features & FEAT_PEN_IRQ) {
179 /* Clear pen down/up interrupt */ 281 /* Clear pen down/up interrupt */
@@ -244,7 +346,13 @@ static int __devinit s3c2410ts_probe(struct platform_device *pdev)
244 struct device *dev = &pdev->dev; 346 struct device *dev = &pdev->dev;
245 struct input_dev *input_dev; 347 struct input_dev *input_dev;
246 struct resource *res; 348 struct resource *res;
247 int ret = -EINVAL; 349 int i, ret = -EINVAL;
350
351 ret = sysfs_create_group(&pdev->dev.kobj, &s5pv310_ts_attr_group);
352 if (ret < 0) {
353 dev_err(dev, "can not create sysfs\n");
354 return ret;
355 }
248 356
249 /* Initialise input stuff */ 357 /* Initialise input stuff */
250 memset(&ts, 0, sizeof(struct s3c2410ts)); 358 memset(&ts, 0, sizeof(struct s3c2410ts));
@@ -259,7 +367,7 @@ static int __devinit s3c2410ts_probe(struct platform_device *pdev)
259 367
260 dev_dbg(dev, "initialising touchscreen\n"); 368 dev_dbg(dev, "initialising touchscreen\n");
261 369
262 ts.clock = clk_get(dev, "adc"); 370 ts.clock = clk_get(NULL, "adc");
263 if (IS_ERR(ts.clock)) { 371 if (IS_ERR(ts.clock)) {
264 dev_err(dev, "cannot get adc clock source\n"); 372 dev_err(dev, "cannot get adc clock source\n");
265 return -ENOENT; 373 return -ENOENT;
@@ -316,10 +424,21 @@ static int __devinit s3c2410ts_probe(struct platform_device *pdev)
316 ts.input = input_dev; 424 ts.input = input_dev;
317 ts.input->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS); 425 ts.input->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
318 ts.input->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH); 426 ts.input->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH);
319 input_set_abs_params(ts.input, ABS_X, 0, 0x3FF, 0, 0);
320 input_set_abs_params(ts.input, ABS_Y, 0, 0x3FF, 0, 0);
321 427
322 ts.input->name = "S3C24XX TouchScreen"; 428 if (info->cal_x_max == 0 || info->cal_y_max == 0) {
429 ts.cal_enable = 0;
430 input_set_abs_params(ts.input, ABS_X, 0, 0x3FF, 32, 0);
431 input_set_abs_params(ts.input, ABS_Y, 0, 0x3FF, 32, 0);
432 } else {
433 for (i = 0; i < 7; i++)
434 ts.cal_param[i] = info->cal_param[i];
435
436 ts.cal_enable = 1;
437 input_set_abs_params(ts.input, ABS_X, 0, info->cal_x_max, 32, 0);
438 input_set_abs_params(ts.input, ABS_Y, 0, info->cal_y_max, 32, 0);
439 }
440
441 ts.input->name = "S3C24XX_TouchScreen";
323 ts.input->id.bustype = BUS_HOST; 442 ts.input->id.bustype = BUS_HOST;
324 ts.input->id.vendor = 0xDEAD; 443 ts.input->id.vendor = 0xDEAD;
325 ts.input->id.product = 0xBEEF; 444 ts.input->id.product = 0xBEEF;
@@ -327,6 +446,7 @@ static int __devinit s3c2410ts_probe(struct platform_device *pdev)
327 446
328 ts.shift = info->oversampling_shift; 447 ts.shift = info->oversampling_shift;
329 ts.features = platform_get_device_id(pdev)->driver_data; 448 ts.features = platform_get_device_id(pdev)->driver_data;
449 ts.request_done = true;
330 450
331 ret = request_irq(ts.irq_tc, stylus_irq, IRQF_DISABLED, 451 ret = request_irq(ts.irq_tc, stylus_irq, IRQF_DISABLED,
332 "s3c2410_ts_pen", ts.input); 452 "s3c2410_ts_pen", ts.input);
diff --git a/drivers/input/touchscreen/s5pc210_ts.c b/drivers/input/touchscreen/s5pc210_ts.c
new file mode 100644
index 00000000000..568b480c205
--- /dev/null
+++ b/drivers/input/touchscreen/s5pc210_ts.c
@@ -0,0 +1,488 @@
1/* drivers/input/touschcreen/s5pc210_ts.c
2 *
3 * Copyright (c) 2011 Samsung Electronics Co., Ltd.
4 * http://www.samsung.com
5 *
6 * Samsung S5PC210 10.1" touchscreen driver
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the term of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 *
22 * Copyright 2010 Hardkernel Co.,Ltd. <odroid@hardkernel.com>
23 * Copyright 2010 Samsung Electronics <samsung.com>
24 *
25 */
26#include <linux/module.h>
27#include <linux/kernel.h>
28#include <linux/init.h>
29#include <linux/irq.h>
30#include <linux/interrupt.h>
31#include <linux/platform_device.h>
32#include <linux/device.h>
33#include <linux/input.h>
34#include <linux/delay.h>
35#include <linux/fs.h>
36#include <linux/gpio.h>
37
38#include <asm/system.h>
39
40#include <plat/gpio-cfg.h>
41#include <plat/cpu.h>
42
43#include <mach/irqs.h>
44#include <mach/regs-gpio.h>
45
46#include "s5pc210_ts.h"
47#include "s5pc210_ts_gpio_i2c.h"
48#include "s5pc210_ts_sysfs.h"
49
50static int s5pv310_ts_open(struct input_dev *dev);
51static void s5pv310_ts_close(struct input_dev *dev);
52
53static void s5pv310_ts_release_device(struct device *dev);
54static void s5pv310_ts_config(unsigned char state);
55
56unsigned int irq_count;
57struct s5pv310_ts_t s5pv310_ts;
58
59#define CONFIG_DEBUG_S5PV310_TS_MSG 1
60#define CAL_DELAY 1000
61
62static int s5pv310_ts_cal(void)
63{
64 unsigned char wdata;
65
66 /* INT_mode : disable interrupt */
67 wdata = 0x00;
68 if (s5pv310_ts_write(MODULE_INTMODE, &wdata, 1)) {
69#ifdef CONFIG_DEBUG_S5PV310_TS_MSG
70 printk(KERN_ERR "failed to write disable.\n");
71#endif
72 return -1;
73 }
74
75 /* touch calibration */
76 wdata = 0x03;
77 /* set mode */
78 if (s5pv310_ts_write(MODULE_CALIBRATION, &wdata, 1)) {
79#ifdef CONFIG_DEBUG_S5PV310_TS_MSG
80 printk(KERN_ERR "failed to write cal.\n");
81#endif
82 return -1;
83 }
84
85#ifdef CONFIG_DEBUG_S5PV310_TS_MSG
86 printk(KERN_DEBUG "calibration!!!\n");
87#endif
88 mdelay(CAL_DELAY);
89
90 /* INT_mode : enable interrupt, low-active, periodically*/
91 wdata = 0x09;
92 if (s5pv310_ts_write(MODULE_INTMODE, &wdata, 1)) {
93#ifdef CONFIG_DEBUG_S5PV310_TS_MSG
94 printk(KERN_ERR "failed to write enable.\n");
95#endif
96 return -1;
97 }
98
99 return 0;
100}
101
102static void s5pv310_ts_process_data(struct touch_process_data_t *ts_data)
103{
104 /* read address setup */
105 s5pv310_ts_write(0x00, NULL, 0x00);
106
107 /* Acc data read */
108 write_seqlock(&s5pv310_ts.lock);
109 s5pv310_ts_read(&s5pv310_ts.rd[0], 10);
110
111 write_sequnlock(&s5pv310_ts.lock);
112
113 ts_data->finger_cnt = s5pv310_ts.rd[0] & 0x03;
114
115 if ((ts_data->x1 = ((s5pv310_ts.rd[3] << 8) | s5pv310_ts.rd[2]))) {
116 ts_data->x1 = (ts_data->x1 * 134) / 100;
117#ifdef CONFIG_S5PV310_TS_FLIP
118#else
119 /* flip X & resize */
120 ts_data->x1 = TS_ABS_MAX_X - ts_data->x1;
121#endif
122 }
123
124 /* resize */
125 if ((ts_data->y1 = ((s5pv310_ts.rd[5] << 8) | s5pv310_ts.rd[4]))) {
126 ts_data->y1 = (ts_data->y1 * 134) / 100;
127#ifdef CONFIG_S5PV310_TS_FLIP
128 /* flip Y & resize */
129 ts_data->y1 = TS_ABS_MAX_Y - ts_data->y1;
130#else
131#endif
132 }
133 if (ts_data->finger_cnt > 1) {
134 /* flip X & resize */
135 if ((ts_data->x2 = ((s5pv310_ts.rd[7] << 8) | s5pv310_ts.rd[6]))) {
136 ts_data->x2 = (ts_data->x2 * 133) / 100;
137#ifdef CONFIG_S5PV310_TS_FLIP
138#else
139 ts_data->x2 = TS_ABS_MAX_X - ts_data->x2;
140#endif
141 }
142 /* resize */
143 if ((ts_data->y2 = ((s5pv310_ts.rd[9] << 8) | s5pv310_ts.rd[8]))) {
144
145 ts_data->y2 = (ts_data->y2 * 128) / 100;
146#ifdef CONFIG_S5PV310_TS_FLIP
147 /* flip Y & resize */
148 ts_data->y2 = TS_ABS_MAX_Y - ts_data->y2;
149#else
150#endif
151 }
152 }
153}
154
155static void s5pv310_ts_get_data(void)
156{
157 struct touch_process_data_t ts_data;
158
159 memset(&ts_data, 0x00, sizeof(ts_data));
160
161 s5pv310_ts_process_data(&ts_data);
162#ifdef CONFIG_DEBUG_S5PV310_TS_MSG
163 printk(KERN_DEBUG "finger: %d\n", ts_data.finger_cnt);
164 printk(KERN_DEBUG "x1: %d, y1: %d\n", ts_data.x1, ts_data.y1);
165 printk(KERN_DEBUG "x2: %d, y2: %d\n", ts_data.x2, ts_data.y2);
166#endif
167
168 if (ts_data.finger_cnt == 0 && ts_data.x1 == 0 && ts_data.y1 == 0) {
169 if (irq_count > 10) {
170 s5pv310_ts_cal();
171 irq_count = 0;
172 }
173 irq_count++;
174 }
175
176 if (ts_data.finger_cnt > 0 && ts_data.finger_cnt < 3) {
177 s5pv310_ts.x = ts_data.x1;
178 s5pv310_ts.y = ts_data.y1;
179 /* press */
180 input_report_abs(s5pv310_ts.driver,
181 ABS_MT_TOUCH_MAJOR, 200);
182 input_report_abs(s5pv310_ts.driver,
183 ABS_MT_WIDTH_MAJOR, 10);
184 input_report_abs(s5pv310_ts.driver,
185 ABS_MT_POSITION_X, s5pv310_ts.x);
186 input_report_abs(s5pv310_ts.driver,
187 ABS_MT_POSITION_Y, s5pv310_ts.y);
188 input_mt_sync(s5pv310_ts.driver);
189
190 if (ts_data.finger_cnt == 2) {
191 s5pv310_ts.x = ts_data.x2;
192 s5pv310_ts.y = ts_data.y2;
193 /* press */
194 input_report_abs(s5pv310_ts.driver,
195 ABS_MT_TOUCH_MAJOR, 200);
196 input_report_abs(s5pv310_ts.driver,
197 ABS_MT_WIDTH_MAJOR, 10);
198 input_report_abs(s5pv310_ts.driver,
199 ABS_MT_POSITION_X, s5pv310_ts.x);
200 input_report_abs(s5pv310_ts.driver,
201 ABS_MT_POSITION_Y, s5pv310_ts.y);
202 input_mt_sync(s5pv310_ts.driver);
203 }
204 input_sync(s5pv310_ts.driver);
205 irq_count = 0;
206 } else {
207 /* up */
208 input_mt_sync(s5pv310_ts.driver);
209 input_sync(s5pv310_ts.driver);
210 }
211}
212
213irqreturn_t s5pv310_ts_irq(int irq, void *dev_id)
214{
215 unsigned long flags;
216
217 local_irq_save(flags);
218 local_irq_disable();
219 s5pv310_ts_get_data();
220 local_irq_restore(flags);
221 return IRQ_HANDLED;
222}
223
224static int s5pv310_ts_open(struct input_dev *dev)
225{
226#ifdef CONFIG_DEBUG_S5PV310_TS_MSG
227 printk(KERN_DEBUG "%s\n", __func__);
228#endif
229
230 return 0;
231}
232
233static void s5pv310_ts_close(struct input_dev *dev)
234{
235#ifdef CONFIG_DEBUG_S5PV310_TS_MSG
236 printk(KERN_DEBUG "%s\n", __func__);
237#endif
238}
239
240static void s5pv310_ts_release_device(struct device *dev)
241{
242#ifdef CONFIG_DEBUG_S5PV310_TS_MSG
243 printk(KERN_DEBUG "%s\n", __func__);
244#endif
245}
246
247static void s5pv310_ts_config(unsigned char state)
248{
249 unsigned char wdata;
250
251 /* s5pc210_ts_reset(); */
252 s5pv310_ts_port_init();
253 mdelay(500);
254
255 /* Touchscreen Active mode */
256 wdata = 0x00;
257 s5pv310_ts_write(MODULE_POWERMODE, &wdata, 1);
258 mdelay(100);
259
260 if (state == TOUCH_STATE_BOOT) {
261 /* INT_mode : disable interrupt */
262 wdata = 0x00;
263 s5pv310_ts_write(MODULE_INTMODE, &wdata, 1);
264
265 if ((soc_is_exynos4212() || soc_is_exynos4412()) &&
266 samsung_board_rev_is_0_1()) {
267 s5p_register_gpio_interrupt(TS_ATTB);
268 s3c_gpio_cfgpin(TS_ATTB, S3C_GPIO_SFN(0xf));
269 }
270
271 if (!request_irq(S5PV310_TS_IRQ, s5pv310_ts_irq,
272 IRQF_DISABLED, "s5pc210-Touch IRQ",
273 (void *)&s5pv310_ts))
274 printk(KERN_DEBUG "MT TOUCH request_irq = %d\r\n",
275 S5PV310_TS_IRQ);
276 else
277 printk(KERN_ERR "MT TOUCH request_irq = %d error!! \r\n",
278 S5PV310_TS_IRQ);
279
280 if (gpio_is_valid(TS_ATTB)) {
281 if (gpio_request(TS_ATTB, "TS_ATTB"))
282 printk(KERN_ERR "failed to request GPH1 for TS_ATTB..\n");
283 }
284
285 s3c_gpio_cfgpin(TS_ATTB, (0xf << 20));
286 s3c_gpio_setpull(TS_ATTB, S3C_GPIO_PULL_NONE);
287
288 irq_set_irq_type(S5PV310_TS_IRQ, IRQ_TYPE_EDGE_RISING);
289
290 /* seqlock init */
291 seqlock_init(&s5pv310_ts.lock);
292
293 s5pv310_ts.seq = 0;
294
295 } else {
296 /* INT_mode : disable interrupt, low-active, finger moving */
297 wdata = 0x01;
298 if (s5pv310_ts_write(MODULE_INTMODE, &wdata, 1)) {
299#ifdef CONFIG_DEBUG_S5PV310_TS_MSG
300 printk(KERN_ERR "failed to write disable.\n");
301#endif
302 }
303
304 mdelay(CAL_DELAY);
305 /* INT_mode : enable interrupt, low-active, finger moving */
306 wdata = 0x09;
307 if (s5pv310_ts_write(MODULE_INTMODE, &wdata, 1)) {
308#ifdef CONFIG_DEBUG_S5PV310_TS_MSG
309 printk(KERN_ERR "failed to write enable.\n");
310#endif
311 }
312 mdelay(100);
313 }
314}
315
316static int __devinit s5pv310_ts_probe(struct platform_device *pdev)
317{
318 int rc;
319
320 irq_count = 0;
321 /* struct init */
322 memset(&s5pv310_ts, 0x00, sizeof(s5pv310_ts));
323
324 /* create sys_fs */
325 rc = s5pv310_ts_sysfs_create(pdev);
326 if (rc) {
327 printk(KERN_ERR "%s : sysfs_create fail.\n", __func__);
328 return rc;
329 }
330
331 s5pv310_ts.driver = input_allocate_device();
332
333 if (!(s5pv310_ts.driver)) {
334 printk(KERN_ERR "%s : cdev_alloc() no memory.\n", __func__);
335 s5pv310_ts_sysfs_remove(pdev);
336 return -ENOMEM;
337 }
338
339 s5pv310_ts.driver->name = S5PV310_TS_DEVICE_NAME;
340 s5pv310_ts.driver->phys = "s5pv310_ts/input1";
341 s5pv310_ts.driver->open = s5pv310_ts_open;
342 s5pv310_ts.driver->close = s5pv310_ts_close;
343
344 s5pv310_ts.driver->id.bustype = BUS_HOST;
345 s5pv310_ts.driver->id.vendor = 0x16B4;
346 s5pv310_ts.driver->id.product = 0x0702;
347 s5pv310_ts.driver->id.version = 0x0001;
348
349 set_bit(EV_ABS, s5pv310_ts.driver->evbit);
350
351 /* multi touch */
352 input_set_abs_params(s5pv310_ts.driver, ABS_MT_POSITION_X,
353 TS_ABS_MIN_X, TS_ABS_MAX_X, 0, 0);
354 input_set_abs_params(s5pv310_ts.driver, ABS_MT_POSITION_Y,
355 TS_ABS_MIN_Y, TS_ABS_MAX_Y, 0, 0);
356 input_set_abs_params(s5pv310_ts.driver, ABS_MT_TOUCH_MAJOR,
357 0, 255, 2, 0);
358 input_set_abs_params(s5pv310_ts.driver, ABS_MT_WIDTH_MAJOR,
359 0, 15, 2, 0);
360
361 if (input_register_device(s5pv310_ts.driver)) {
362 printk(KERN_ERR "S5PC210 TS input register device fail.\n");
363 s5pv310_ts_sysfs_remove(pdev);
364 input_free_device(s5pv310_ts.driver);
365 return -ENODEV;
366 }
367
368 s5pv310_ts_config(TOUCH_STATE_BOOT);
369 s5pv310_ts_cal();
370
371 printk(KERN_DEBUG "SMDKC210(MT) Touch driver initialized.\n");
372
373 return 0;
374}
375
376static int __devexit s5pv310_ts_remove(struct platform_device *pdev)
377{
378#ifdef CONFIG_DEBUG_S5PV310_TS_MSG
379 printk(KERN_DEBUG "%s\n", __func__);
380#endif
381
382 free_irq(S5PV310_TS_IRQ, (void *)&s5pv310_ts);
383
384 s5pv310_ts_sysfs_remove(pdev);
385
386 input_unregister_device(s5pv310_ts.driver);
387
388 return 0;
389}
390
391#ifdef CONFIG_PM
392static int s5pv310_ts_resume(struct platform_device *dev)
393{
394 s5pv310_ts_config(TOUCH_STATE_RESUME);
395
396 /* interrupt enable */
397 enable_irq(S5PV310_TS_IRQ);
398
399 return 0;
400}
401
402static int s5pv310_ts_suspend(struct platform_device *dev, pm_message_t state)
403{
404 unsigned char wdata;
405
406 wdata = 0x00;
407 s5pv310_ts_write(MODULE_POWERMODE, &wdata, 1);
408 mdelay(CAL_DELAY);
409
410 /* INT_mode : disable interrupt */
411 wdata = 0x00;
412 s5pv310_ts_write(MODULE_INTMODE, &wdata, 1);
413 mdelay(CAL_DELAY);
414
415 /* Touchscreen enter freeze mode : */
416 wdata = 0x01;
417 s5pv310_ts_write(MODULE_POWERMODE, &wdata, 1);
418 mdelay(100);
419
420 /* interrupt disable */
421 disable_irq(S5PV310_TS_IRQ);
422
423 return 0;
424}
425#else
426static int s5pv310_ts_resume(struct platform_device *dev)
427{
428 return 0;
429}
430static int s5pv310_ts_suspend(struct platform_device *dev, pm_message_t state)
431{
432 return 0;
433}
434#endif
435
436static struct platform_driver s5pv310_ts_platform_device_driver = {
437 .probe = s5pv310_ts_probe,
438 .remove = s5pv310_ts_remove,
439 .suspend = s5pv310_ts_suspend,
440 .resume = s5pv310_ts_resume,
441 .driver = {
442 .owner = THIS_MODULE,
443 .name = S5PV310_TS_DEVICE_NAME,
444 },
445};
446
447static struct platform_device s5pv310_ts_platform_device = {
448 .name = S5PV310_TS_DEVICE_NAME,
449 .id = -1,
450 .num_resources = 0,
451 .dev = {
452 .release= s5pv310_ts_release_device,
453 },
454};
455
456static int __init s5pv310_ts_init(void)
457{
458 int ret = platform_driver_register(&s5pv310_ts_platform_device_driver);
459
460 if (!ret) {
461 ret = platform_device_register(&s5pv310_ts_platform_device);
462
463#ifdef CONFIG_DEBUG_S5PV310_TS_MSG
464 printk(KERN_DEBUG "platform_driver_register %d\n", ret);
465#endif
466
467 if (ret)
468 platform_driver_unregister(
469 &s5pv310_ts_platform_device_driver);
470 }
471 return ret;
472}
473
474static void __exit s5pv310_ts_exit(void)
475{
476#ifdef CONFIG_DEBUG_S5PV310_TS_MSG
477 printk(KERN_DEBUG "%s\n", __func__);
478#endif
479 platform_device_unregister(&s5pv310_ts_platform_device);
480 platform_driver_unregister(&s5pv310_ts_platform_device_driver);
481}
482module_init(s5pv310_ts_init);
483module_exit(s5pv310_ts_exit);
484
485MODULE_DESCRIPTION("Samsung 10.1\" Touchscreen driver");
486MODULE_AUTHOR("Dongsu Ha <dsfine.ha@samsung.com>");
487MODULE_AUTHOR("HardKernel");
488MODULE_LICENSE("GPL");
diff --git a/drivers/input/touchscreen/s5pc210_ts.h b/drivers/input/touchscreen/s5pc210_ts.h
new file mode 100644
index 00000000000..fc5cecb54ee
--- /dev/null
+++ b/drivers/input/touchscreen/s5pc210_ts.h
@@ -0,0 +1,120 @@
1/* driver/input/touchscreen/s5pc210_ts.h
2 *
3 * Copyright (c) 2011 Samsung Electronics Co., Ltd.
4 * http://www.samsung.com
5 *
6 * S5PC210 10.1" Touchscreen driver information
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11*/
12
13#ifndef _S5PV310_TS_H_
14#define _S5PV310_TS_H_
15
16#ifdef CONFIG_HAS_EARLYSUSPEND
17#include <linux/earlysuspend.h>
18#endif
19
20#include <mach/board_rev.h>
21
22#define S5PV310_TS_DEVICE_NAME "s5pc210_ts"
23
24#define TOUCH_PRESS 1
25#define TOUCH_RELEASE 0
26
27/* Touch Configuration */
28
29/* Touch Interrupt define */
30#ifdef CONFIG_MACH_SMDK4X12
31
32#define TS_ATTB samsung_board_rev_is_0_0() ? EXYNOS4_GPX1(6) : EXYNOS4212_GPM3(4)
33#define S5PV310_TS_IRQ gpio_to_irq(TS_ATTB)
34
35/* Touch should be reset before using. In order to reset it, the reset pin
36 should be set OUTPUT HIGH. The Reset pin is EXYNOS4_GPX1(5) (XEINT 13).
37 However, the SMDK4X12 uses this pin for resetting both LCD and touchscreen.
38 Therefore, it assumes that LCD driver will reset them by this pin. */
39
40#elif defined (CONFIG_MACH_SMDKV310)
41
42#define S5PV310_TS_IRQ gpio_to_irq(EXYNOS4_GPX3(5))
43#define TS_ATTB (EXYNOS4_GPX3(5))
44
45#else
46#error Unsupported board!
47#endif
48
49#define TS_ABS_MIN_X 0
50#define TS_ABS_MIN_Y 0
51#define TS_ABS_MAX_X 1366
52#define TS_ABS_MAX_Y 768
53
54#define TS_X_THRESHOLD 1
55#define TS_Y_THRESHOLD 1
56
57
58/* touch register */
59#define MODULE_CALIBRATION 0x37
60#define MODULE_POWERMODE 0x14
61#define MODULE_INTMODE 0x15
62#define MODULE_INTWIDTH 0x16
63
64#define PERIOD_10MS (HZ/100) /* 10ms */
65#define PERIOD_20MS (HZ/50) /* 20ms */
66#define PERIOD_50MS (HZ/20) /* 50ms */
67
68#define TOUCH_STATE_BOOT 0
69#define TOUCH_STATE_RESUME 1
70
71/* Touch hold event */
72#define SW_TOUCH_HOLD 0x09
73
74#if defined(CONFIG_TOUCHSCREEN_EXYNOS4)
75/* multi-touch data process struct */
76struct touch_process_data_t {
77 unsigned char finger_cnt;
78 unsigned int x1;
79 unsigned int y1;
80 unsigned int x2;
81 unsigned int y2;
82};
83#endif
84
85struct s5pv310_ts_t {
86 struct input_dev *driver;
87
88 /* seqlock_t */
89 seqlock_t lock;
90 unsigned int seq;
91
92 /* timer */
93 struct timer_list penup_timer;
94
95 /* data store */
96 unsigned int status;
97 unsigned int x;
98 unsigned int y;
99 unsigned char rd[10];
100
101 /* sysfs used */
102 unsigned char hold_status;
103 unsigned char sampling_rate;
104
105 /* x data threshold (0-10) : default 3 */
106 unsigned char threshold_x;
107 /* y data threshold (0-10) : default 3 */
108 unsigned char threshold_y;
109 /* touch sensitivity (0-255) : default 0x14 */
110 unsigned char sensitivity;
111
112#if defined CONFIG_TOUCHSCREEN_EXYNOS4
113#ifdef CONFIG_HAS_EARLYSUSPEND
114 struct early_suspend power;
115#endif
116#endif
117};
118
119extern struct s5pv310_ts_t s5pv310_ts;
120#endif
diff --git a/drivers/input/touchscreen/s5pc210_ts_gpio_i2c.c b/drivers/input/touchscreen/s5pc210_ts_gpio_i2c.c
new file mode 100644
index 00000000000..90b5fe19d14
--- /dev/null
+++ b/drivers/input/touchscreen/s5pc210_ts_gpio_i2c.c
@@ -0,0 +1,366 @@
1/* drivers/input/touschcreen/s5pc210_ts_gpio_i2c.c
2 *
3 * Copyright (c) 2011 Samsung Electronics Co., Ltd.
4 * http://www.samsung.com
5 *
6 * Samsung S5PC210 10.1" touchscreen gpio driver
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the term of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 *
22 * Copyright 2010 Hardkernel Co.,Ltd. <odroid@hardkernel.com>
23 * Copyright 2010 Samsung Electronics <samsung.com>
24 *
25 */
26#include <linux/module.h>
27#include <linux/kernel.h>
28#include <linux/init.h>
29#include <linux/irq.h>
30#include <linux/interrupt.h>
31#include <linux/platform_device.h>
32#include <linux/device.h>
33#include <linux/input.h>
34#include <linux/fs.h>
35
36#include <mach/irqs.h>
37#include <asm/system.h>
38
39#include <linux/delay.h>
40#include <mach/regs-gpio.h>
41
42#include "s5pc210_ts_gpio_i2c.h"
43#include "s5pc210_ts.h"
44
45
46/* Touch I2C Address Define */
47#define TOUCH_WR_ADDR 0xB8
48#define TOUCH_RD_ADDR 0xB9
49
50/* Touch I2C Port define */
51#ifdef CONFIG_MACH_SMDK4X12
52
53#define GPD0CON (S5P_VA_GPIO + 0xA0)
54#define GPD0DAT (S5P_VA_GPIO + 0xA4)
55
56#define SDA_CON_PORT (*(unsigned long *)GPD0CON)
57#define SDA_DAT_PORT (*(unsigned long *)GPD0DAT)
58#define SDA_PIN 2
59
60#define CLK_CON_PORT (*(unsigned long *)GPD0CON)
61#define CLK_DAT_PORT (*(unsigned long *)GPD0DAT)
62#define CLK_PIN 3
63
64#elif defined (CONFIG_MACH_SMDKV310)
65
66#define GPB1CON (S5P_VA_GPIO + 0x40)
67#define GPB1DAT (S5P_VA_GPIO + 0x44)
68
69#define SDA_CON_PORT (*(unsigned long *)GPB1CON)
70#define SDA_DAT_PORT (*(unsigned long *)GPB1DAT)
71#define SDA_PIN 6
72
73#define CLK_CON_PORT (*(unsigned long *)GPB1CON)
74#define CLK_DAT_PORT (*(unsigned long *)GPB1DAT)
75#define CLK_PIN 7
76
77#else
78#error Unsupported board!
79#endif
80
81#define DELAY_TIME 5
82#define PORT_CHANGE_DELAY_TIME 5
83#define CON_PORT_MASK 0xF
84#define CON_PORT_OFFSET 0x4
85
86#define GPIO_CON_INPUT 0x0
87#define GPIO_CON_OUTPUT 0x1
88
89#define HIGH 1
90#define LOW 0
91
92static void gpio_i2c_sda_port_control(unsigned char inout);
93static void gpio_i2c_clk_port_control(unsigned char inout);
94static unsigned char gpio_i2c_get_sda(void);
95static void gpio_i2c_set_sda(unsigned char hi_lo);
96static void gpio_i2c_set_clk(unsigned char hi_lo);
97static void gpio_i2c_start(void);
98static void gpio_i2c_stop(void);
99static void gpio_i2c_send_ack(void);
100static void gpio_i2c_send_noack(void);
101static unsigned char gpio_i2c_chk_ack(void);
102static void gpio_i2c_byte_write(unsigned char wdata);
103static void gpio_i2c_byte_read(unsigned char *rdata);
104
105static void gpio_i2c_sda_port_control(unsigned char inout)
106{
107 SDA_CON_PORT &= (unsigned long)(~(CON_PORT_MASK <<
108 (SDA_PIN * CON_PORT_OFFSET)));
109 SDA_CON_PORT |= (unsigned long)((inout <<
110 (SDA_PIN * CON_PORT_OFFSET)));
111}
112
113static void gpio_i2c_clk_port_control(unsigned char inout)
114{
115 CLK_CON_PORT &= (unsigned long)(~(CON_PORT_MASK <<
116 (CLK_PIN * CON_PORT_OFFSET)));
117 CLK_CON_PORT |= (unsigned long)((inout <<
118 (CLK_PIN * CON_PORT_OFFSET)));
119}
120
121static unsigned char gpio_i2c_get_sda(void)
122{
123 return SDA_DAT_PORT & (HIGH << SDA_PIN) ? 1 : 0;
124}
125
126static void gpio_i2c_set_sda(unsigned char hi_lo)
127{
128 if (hi_lo) {
129 gpio_i2c_sda_port_control(GPIO_CON_INPUT);
130 udelay(PORT_CHANGE_DELAY_TIME);
131 } else {
132 SDA_DAT_PORT &= ~(HIGH << SDA_PIN);
133 gpio_i2c_sda_port_control(GPIO_CON_OUTPUT);
134 udelay(PORT_CHANGE_DELAY_TIME);
135 }
136}
137
138static void gpio_i2c_set_clk(unsigned char hi_lo)
139{
140 if (hi_lo) {
141 gpio_i2c_clk_port_control(GPIO_CON_INPUT);
142 udelay(PORT_CHANGE_DELAY_TIME);
143 } else {
144 CLK_DAT_PORT &= ~(HIGH << CLK_PIN);
145 gpio_i2c_clk_port_control(GPIO_CON_OUTPUT);
146 udelay(PORT_CHANGE_DELAY_TIME);
147 }
148}
149
150static void gpio_i2c_start(void)
151{
152 /* Setup SDA, CLK output High */
153 gpio_i2c_set_sda(HIGH);
154 gpio_i2c_set_clk(HIGH);
155
156 udelay(DELAY_TIME);
157
158 /* SDA low before CLK low */
159 gpio_i2c_set_sda(LOW);
160 udelay(DELAY_TIME);
161 gpio_i2c_set_clk(LOW);
162 udelay(DELAY_TIME);
163}
164
165static void gpio_i2c_stop(void)
166{
167 /* Setup SDA, CLK output low */
168 gpio_i2c_set_sda(LOW);
169 gpio_i2c_set_clk(LOW);
170
171 udelay(DELAY_TIME);
172
173 /* SDA high after CLK high */
174 gpio_i2c_set_clk(HIGH);
175 udelay(DELAY_TIME);
176 gpio_i2c_set_sda(HIGH);
177 udelay(DELAY_TIME);
178}
179
180static void gpio_i2c_send_ack(void)
181{
182 /* SDA Low */
183 gpio_i2c_set_sda(LOW);
184 udelay(DELAY_TIME);
185 gpio_i2c_set_clk(HIGH);
186 udelay(DELAY_TIME);
187 gpio_i2c_set_clk(LOW);
188 udelay(DELAY_TIME);
189}
190
191static void gpio_i2c_send_noack(void)
192{
193 /* SDA High */
194 gpio_i2c_set_sda(HIGH);
195 udelay(DELAY_TIME);
196 gpio_i2c_set_clk(HIGH);
197 udelay(DELAY_TIME);
198 gpio_i2c_set_clk(LOW);
199 udelay(DELAY_TIME);
200}
201
202static unsigned char gpio_i2c_chk_ack(void)
203{
204 unsigned char count = 0, ret = 0;
205
206 gpio_i2c_set_sda(LOW);
207 udelay(DELAY_TIME);
208 gpio_i2c_set_clk(HIGH);
209 udelay(DELAY_TIME);
210
211 gpio_i2c_sda_port_control(GPIO_CON_INPUT);
212 udelay(PORT_CHANGE_DELAY_TIME);
213
214 while (gpio_i2c_get_sda()) {
215 if (count++ > 100) {
216 ret = 1;
217 break;
218 } else
219 udelay(DELAY_TIME);
220 }
221
222 gpio_i2c_set_clk(LOW);
223 udelay(DELAY_TIME);
224
225#if defined(DEBUG_GPIO_I2C)
226 if (ret)
227 printk(KERN_DEBUG "%s %d: no ack\n", __func__, ret);
228 else
229 printk(KERN_DEBUG "%s %d: ack\n" , __func__, ret);
230#endif
231
232 return ret;
233}
234
235static void gpio_i2c_byte_write(unsigned char wdata)
236{
237 unsigned char cnt, mask;
238
239 for (cnt = 0, mask = 0x80; cnt < 8; cnt++, mask >>= 1) {
240 if (wdata & mask)
241 gpio_i2c_set_sda(HIGH);
242 else
243 gpio_i2c_set_sda(LOW);
244
245 gpio_i2c_set_clk(HIGH);
246 udelay(DELAY_TIME);
247 gpio_i2c_set_clk(LOW);
248 udelay(DELAY_TIME);
249 }
250}
251
252static void gpio_i2c_byte_read(unsigned char *rdata)
253{
254 unsigned char cnt, mask;
255
256 gpio_i2c_sda_port_control(GPIO_CON_INPUT);
257 udelay(PORT_CHANGE_DELAY_TIME);
258
259 for (cnt = 0, mask = 0x80, *rdata = 0; cnt < 8; cnt++, mask >>= 1) {
260 gpio_i2c_set_clk(HIGH);
261 udelay(DELAY_TIME);
262
263 if (gpio_i2c_get_sda())
264 *rdata |= mask;
265
266 gpio_i2c_set_clk(LOW);
267 udelay(DELAY_TIME);
268 }
269}
270
271int s5pv310_ts_write(unsigned char addr, unsigned char *wdata,
272 unsigned char wsize)
273{
274 unsigned char cnt, ack;
275
276 /* start */
277 gpio_i2c_start();
278
279 /* i2c address */
280 gpio_i2c_byte_write(TOUCH_WR_ADDR);
281
282 ack = gpio_i2c_chk_ack();
283 if (ack) {
284#if defined(DEBUG_GPIO_I2C)
285 printk(KERN_DEBUG "%s [write addr] : no ack\n", __func__);
286#endif
287 goto write_stop;
288 }
289
290 /* register */
291 gpio_i2c_byte_write(addr);
292
293 ack = gpio_i2c_chk_ack();
294 if (ack) {
295#if defined(DEBUG_GPIO_I2C)
296 printk(KERN_DEBUG "%s [write reg] : no ack\n", __func__);
297#endif
298 }
299
300 if (wsize) {
301 for (cnt = 0; cnt < wsize; cnt++) {
302 gpio_i2c_byte_write(wdata[cnt]);
303 ack = gpio_i2c_chk_ack();
304 if (ack) {
305#if defined(DEBUG_GPIO_I2C)
306 printk(KERN_DEBUG "%s [write reg]:no ack\n", __func__);
307#endif
308 goto write_stop;
309 }
310 }
311 }
312
313write_stop:
314#if defined(CONFIG_TOUCHSCREEN_EXYNOS4)
315 if (wsize)
316 gpio_i2c_stop();
317#else
318 gpio_i2c_stop();
319#endif
320
321#if defined(DEBUG_GPIO_I2C)
322 printk(KERN_DEBUG "%s : %d\n", __func__, ack);
323#endif
324 return ack;
325}
326
327int s5pv310_ts_read(unsigned char *rdata, unsigned char rsize)
328{
329 unsigned char ack, cnt;
330
331 /* start */
332 gpio_i2c_start();
333
334 /* i2c address */
335 gpio_i2c_byte_write(TOUCH_RD_ADDR);
336
337 ack = gpio_i2c_chk_ack();
338 if (ack) {
339#if defined(DEBUG_GPIO_I2C)
340 printk(KERN_DEBUG "%s [write addr] : no ack\n", __func__);
341#endif
342 goto read_stop;
343 }
344
345 for (cnt = 0; cnt < rsize; cnt++) {
346 gpio_i2c_byte_read(&rdata[cnt]);
347
348 if (cnt == rsize - 1)
349 gpio_i2c_send_noack();
350 else
351 gpio_i2c_send_ack();
352 }
353
354read_stop:
355 gpio_i2c_stop();
356#if defined(DEBUG_GPIO_I2C)
357 printk(KERN_DEBUG "%s : %d\n", __func__, ack);
358#endif
359 return ack;
360}
361
362void s5pv310_ts_port_init(void)
363{
364 gpio_i2c_set_sda(HIGH);
365 gpio_i2c_set_clk(HIGH);
366}
diff --git a/drivers/input/touchscreen/s5pc210_ts_gpio_i2c.h b/drivers/input/touchscreen/s5pc210_ts_gpio_i2c.h
new file mode 100644
index 00000000000..c0b936481da
--- /dev/null
+++ b/drivers/input/touchscreen/s5pc210_ts_gpio_i2c.h
@@ -0,0 +1,21 @@
1/* driver/input/touchscreen/s5pc210_ts_gpio_i2c.h
2 *
3 * Copyright (c) 2011 Samsung Electronics Co., LTD.
4 * http://www.samsung.com
5 *
6 * S5PC210 10.1" Touchscreen gpio i2c information
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11*/
12
13#ifndef _S5PV310_TS_GPIO_I2C_H_
14#define _S5PV310_TS_GPIO_I2C_H_
15
16extern int s5pv310_ts_write(unsigned char addr, unsigned char *wdata,
17 unsigned char wsize);
18extern int s5pv310_ts_read(unsigned char *rdata, unsigned char rsize);
19extern void s5pv310_ts_port_init(void);
20
21#endif /*_S5PV310_TS_GPIO_I2C_H_*/
diff --git a/drivers/input/touchscreen/s5pc210_ts_sysfs.c b/drivers/input/touchscreen/s5pc210_ts_sysfs.c
new file mode 100644
index 00000000000..fbdc3deaf3e
--- /dev/null
+++ b/drivers/input/touchscreen/s5pc210_ts_sysfs.c
@@ -0,0 +1,287 @@
1/* drivers/input/touschcreen/s5pc210_ts_sysfs.c
2 *
3 * Copyright (c) 2011 Samsung Electronics Co., Ltd.
4 * http://www.samsung.com
5 *
6 * Samsung S5PC210 10.1" touchscreen sensor interface driver
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the term of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 *
22 * Copyright 2010 Hardkernel Co.,Ltd. <odroid@hardkernel.com>
23 * Copyright 2010 Samsung Electronics <samsung.com>
24 *
25 */
26#include <linux/kernel.h>
27#include <linux/types.h>
28#include <linux/module.h>
29#include <linux/device.h>
30#include <linux/platform_device.h>
31#include <linux/delay.h>
32#include <linux/irq.h>
33#include <linux/interrupt.h>
34#include <linux/sysfs.h>
35
36#include "s5pc210_ts_gpio_i2c.h"
37#include "s5pc210_ts.h"
38
39/* sysfs function prototype define */
40/* screen hold control (on -> hold, off -> normal mode) */
41static ssize_t show_hold_state(struct device *dev,
42 struct device_attribute *attr, char *buf);
43static ssize_t set_hold_state(struct device *dev, struct device_attribute *attr,
44 const char *buf, size_t count);
45static DEVICE_ATTR(hold_state, S_IRWXUGO, show_hold_state, set_hold_state);
46
47/* touch sampling rate control (5, 10, 20 : unit msec) */
48static ssize_t show_sampling_rate(struct device *dev,
49 struct device_attribute *attr, char *buf);
50static ssize_t set_sampling_rate(struct device *dev,
51 struct device_attribute *attr, const char *buf,
52 size_t count);
53static DEVICE_ATTR(sampling_rate, S_IRWXUGO, show_sampling_rate,
54 set_sampling_rate);
55
56/* touch threshold control (range 0 - 10) : default 3 */
57#define THRESHOLD_MAX 10
58
59static ssize_t show_threshold_x(struct device *dev,
60 struct device_attribute *attr, char *buf);
61static ssize_t set_threshold_x(struct device *dev,
62 struct device_attribute *attr, const char *buf,
63 size_t count);
64static DEVICE_ATTR(threshold_x, S_IRWXUGO, show_threshold_x, set_threshold_x);
65
66static ssize_t show_threshold_y(struct device *dev,
67 struct device_attribute *attr, char *buf);
68static ssize_t set_threshold_y(struct device *dev,
69 struct device_attribute *attr, const char *buf,
70 size_t count);
71static DEVICE_ATTR(threshold_y, S_IRWXUGO, show_threshold_y, set_threshold_y);
72
73/* touch calibration */
74#if defined(CONFIG_TOUCHSCREEN_EXYNOS4)
75static ssize_t set_ts_cal(struct device *dev,
76 struct device_attribute *attr, const char *buf,
77 size_t count);
78static DEVICE_ATTR(ts_cal, S_IWUGO, NULL, set_ts_cal);
79#endif
80
81static struct attribute *s5pv310_ts_sysfs_entries[] = {
82 &dev_attr_hold_state.attr,
83 &dev_attr_sampling_rate.attr,
84 &dev_attr_threshold_x.attr,
85 &dev_attr_threshold_y.attr,
86#if defined(CONFIG_TOUCHSCREEN_EXYNOS4)
87 &dev_attr_ts_cal.attr,
88#endif
89 NULL
90};
91
92static struct attribute_group s5pv310_ts_attr_group = {
93 .name = NULL,
94 .attrs = s5pv310_ts_sysfs_entries,
95};
96
97static ssize_t show_hold_state(struct device *dev,
98 struct device_attribute *attr, char *buf)
99{
100 if (s5pv310_ts.hold_status)
101 return sprintf(buf, "on\n");
102 else
103 return sprintf(buf, "off\n");
104}
105
106static ssize_t set_hold_state(struct device *dev,
107 struct device_attribute *attr, const char *buf,
108 size_t count)
109{
110 unsigned long flags;
111 unsigned char wdata;
112
113 local_irq_save(flags);
114
115 if (!strcmp(buf, "on\n"))
116 s5pv310_ts.hold_status = 1;
117 else {
118#if defined(CONFIG_TOUCHSCREEN_EXYNOS4)
119 /* INT_mode : disable interrupt, low-active, finger moving */
120 wdata = 0x01;
121 s5pv310_ts_write(MODULE_INTMODE, &wdata, 1);
122 mdelay(10);
123 /* INT_mode : enable interrupt, low-active, finger moving */
124 wdata = 0x09;
125 s5pv310_ts_write(MODULE_INTMODE, &wdata, 1);
126 mdelay(10);
127#endif
128 s5pv310_ts.hold_status = 0;
129 }
130
131 local_irq_restore(flags);
132
133 return count;
134}
135
136static ssize_t show_sampling_rate(struct device *dev,
137 struct device_attribute *attr, char *buf)
138{
139 switch (s5pv310_ts.sampling_rate) {
140 default:
141 s5pv310_ts.sampling_rate = 0;
142 case 0:
143 return sprintf(buf, "10 msec\n");
144 case 1:
145 return sprintf(buf, "20 msec\n");
146 case 2:
147 return sprintf(buf, "50 msec\n");
148 }
149}
150
151static ssize_t set_sampling_rate(struct device *dev,
152 struct device_attribute *attr, const char *buf,
153 size_t count)
154{
155 unsigned long flags;
156 unsigned int val;
157
158 if (!(sscanf(buf, "%u\n", &val)))
159 return -EINVAL;
160
161 local_irq_save(flags);
162 if (val > 20)
163 s5pv310_ts.sampling_rate = 2;
164 else if (val > 10)
165 s5pv310_ts.sampling_rate = 1;
166 else
167 s5pv310_ts.sampling_rate = 0;
168
169 local_irq_restore(flags);
170
171 return count;
172}
173
174static ssize_t show_threshold_x(struct device *dev,
175 struct device_attribute *attr, char *buf)
176{
177 if (s5pv310_ts.threshold_x > THRESHOLD_MAX)
178 s5pv310_ts.threshold_x = THRESHOLD_MAX;
179
180 return sprintf(buf, "%d\n", s5pv310_ts.threshold_x);
181}
182
183static ssize_t set_threshold_x(struct device *dev,
184 struct device_attribute *attr, const char *buf,
185 size_t count)
186{
187 unsigned long flags;
188 unsigned int val;
189
190 if (!(sscanf(buf, "%u\n", &val)))
191 return -EINVAL;
192
193 local_irq_save(flags);
194
195 if (val < 0)
196 val *= (-1);
197
198 if (val > THRESHOLD_MAX)
199 val = THRESHOLD_MAX;
200
201 s5pv310_ts.threshold_x = val;
202
203 local_irq_restore(flags);
204
205 return count;
206}
207static ssize_t show_threshold_y(struct device *dev,
208 struct device_attribute *attr, char *buf)
209{
210 if (s5pv310_ts.threshold_y > THRESHOLD_MAX)
211 s5pv310_ts.threshold_y = THRESHOLD_MAX;
212
213 return sprintf(buf, "%d\n", s5pv310_ts.threshold_y);
214}
215static ssize_t set_threshold_y(struct device *dev,
216 struct device_attribute *attr, const char *buf,
217 size_t count)
218{
219 unsigned long flags;
220 unsigned int val;
221
222 if (!(sscanf(buf, "%u\n", &val)))
223 return -EINVAL;
224
225 local_irq_save(flags);
226
227 if (val < 0)
228 val *= (-1);
229
230 if (val > THRESHOLD_MAX)
231 val = THRESHOLD_MAX;
232
233 s5pv310_ts.threshold_y = val;
234
235 local_irq_restore(flags);
236
237 return count;
238}
239
240#if defined(CONFIG_TOUCHSCREEN_EXYNOS4)
241static ssize_t set_ts_cal(struct device *dev,
242 struct device_attribute *attr, const char *buf,
243 size_t count)
244{
245 unsigned char wdata;
246 unsigned long flags;
247
248 local_irq_save(flags);
249
250 /* INT_mode : disable interrupt */
251 wdata = 0x00;
252 s5pv310_ts_write(MODULE_INTMODE, &wdata, 1);
253
254 /* touch calibration */
255 wdata = 0x03;
256 s5pv310_ts_write(MODULE_CALIBRATION, &wdata, 1);
257
258 mdelay(500);
259
260 /* INT_mode : enable interrupt, low-active, periodically*/
261 wdata = 0x09;
262 s5pv310_ts_write(MODULE_INTMODE, &wdata, 1);
263
264 local_irq_restore(flags);
265
266 return count;
267}
268#endif
269
270int s5pv310_ts_sysfs_create(struct platform_device *pdev)
271{
272 /* variable init */
273 s5pv310_ts.hold_status = 0;
274
275 /* 5 msec sampling */
276 s5pv310_ts.sampling_rate = 0;
277 /* x data threshold (0~10) */
278 s5pv310_ts.threshold_x = TS_X_THRESHOLD;
279 /* y data threshold (0~10) */
280 s5pv310_ts.threshold_y = TS_Y_THRESHOLD;
281
282 return sysfs_create_group(&pdev->dev.kobj, &s5pv310_ts_attr_group);
283}
284void s5pv310_ts_sysfs_remove(struct platform_device *pdev)
285{
286 sysfs_remove_group(&pdev->dev.kobj, &s5pv310_ts_attr_group);
287}
diff --git a/drivers/input/touchscreen/s5pc210_ts_sysfs.h b/drivers/input/touchscreen/s5pc210_ts_sysfs.h
new file mode 100644
index 00000000000..1edeee47a45
--- /dev/null
+++ b/drivers/input/touchscreen/s5pc210_ts_sysfs.h
@@ -0,0 +1,19 @@
1/* driver/input/touchscreen/s5pc210_ts_sysfs.h
2 *
3 * Copyright (c) 2011 Samsung Electronics Co., LTD.
4 * http://www.samsung.com
5 *
6 * S5PC210 10.1" Touchscreen sysfs information
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11*/
12
13#ifndef _S5PV310_TS_SYSFS_H_
14#define _S5PV310_TS_SYSFS_H_
15
16extern int s5pv310_ts_sysfs_create(struct platform_device *pdev);
17extern void s5pv310_ts_sysfs_remove(struct platform_device *pdev);
18
19#endif /* _S5PV310_TS_SYSFS_H_ */
diff --git a/drivers/input/touchscreen/synaptics_i2c_rmi.c b/drivers/input/touchscreen/synaptics_i2c_rmi.c
new file mode 100644
index 00000000000..5729602cbb6
--- /dev/null
+++ b/drivers/input/touchscreen/synaptics_i2c_rmi.c
@@ -0,0 +1,675 @@
1/* drivers/input/keyboard/synaptics_i2c_rmi.c
2 *
3 * Copyright (C) 2007 Google, Inc.
4 *
5 * This software is licensed under the terms of the GNU General Public
6 * License version 2, as published by the Free Software Foundation, and
7 * may be copied, distributed, and modified under those terms.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 */
15
16#include <linux/module.h>
17#include <linux/delay.h>
18#include <linux/earlysuspend.h>
19#include <linux/hrtimer.h>
20#include <linux/i2c.h>
21#include <linux/input.h>
22#include <linux/interrupt.h>
23#include <linux/io.h>
24#include <linux/platform_device.h>
25#include <linux/slab.h>
26#include <linux/synaptics_i2c_rmi.h>
27
28static struct workqueue_struct *synaptics_wq;
29
30struct synaptics_ts_data {
31 uint16_t addr;
32 struct i2c_client *client;
33 struct input_dev *input_dev;
34 int use_irq;
35 bool has_relative_report;
36 struct hrtimer timer;
37 struct work_struct work;
38 uint16_t max[2];
39 int snap_state[2][2];
40 int snap_down_on[2];
41 int snap_down_off[2];
42 int snap_up_on[2];
43 int snap_up_off[2];
44 int snap_down[2];
45 int snap_up[2];
46 uint32_t flags;
47 int reported_finger_count;
48 int8_t sensitivity_adjust;
49 int (*power)(int on);
50 struct early_suspend early_suspend;
51};
52
53#ifdef CONFIG_HAS_EARLYSUSPEND
54static void synaptics_ts_early_suspend(struct early_suspend *h);
55static void synaptics_ts_late_resume(struct early_suspend *h);
56#endif
57
58static int synaptics_init_panel(struct synaptics_ts_data *ts)
59{
60 int ret;
61
62 ret = i2c_smbus_write_byte_data(ts->client, 0xff, 0x10); /* page select = 0x10 */
63 if (ret < 0) {
64 printk(KERN_ERR "i2c_smbus_write_byte_data failed for page select\n");
65 goto err_page_select_failed;
66 }
67 ret = i2c_smbus_write_byte_data(ts->client, 0x41, 0x04); /* Set "No Clip Z" */
68 if (ret < 0)
69 printk(KERN_ERR "i2c_smbus_write_byte_data failed for No Clip Z\n");
70
71 ret = i2c_smbus_write_byte_data(ts->client, 0x44,
72 ts->sensitivity_adjust);
73 if (ret < 0)
74 pr_err("synaptics_ts: failed to set Sensitivity Adjust\n");
75
76err_page_select_failed:
77 ret = i2c_smbus_write_byte_data(ts->client, 0xff, 0x04); /* page select = 0x04 */
78 if (ret < 0)
79 printk(KERN_ERR "i2c_smbus_write_byte_data failed for page select\n");
80 ret = i2c_smbus_write_byte_data(ts->client, 0xf0, 0x81); /* normal operation, 80 reports per second */
81 if (ret < 0)
82 printk(KERN_ERR "synaptics_ts_resume: i2c_smbus_write_byte_data failed\n");
83 return ret;
84}
85
86static void synaptics_ts_work_func(struct work_struct *work)
87{
88 int i;
89 int ret;
90 int bad_data = 0;
91 struct i2c_msg msg[2];
92 uint8_t start_reg;
93 uint8_t buf[15];
94 struct synaptics_ts_data *ts = container_of(work, struct synaptics_ts_data, work);
95 int buf_len = ts->has_relative_report ? 15 : 13;
96
97 msg[0].addr = ts->client->addr;
98 msg[0].flags = 0;
99 msg[0].len = 1;
100 msg[0].buf = &start_reg;
101 start_reg = 0x00;
102 msg[1].addr = ts->client->addr;
103 msg[1].flags = I2C_M_RD;
104 msg[1].len = buf_len;
105 msg[1].buf = buf;
106
107 /* printk("synaptics_ts_work_func\n"); */
108 for (i = 0; i < ((ts->use_irq && !bad_data) ? 1 : 10); i++) {
109 ret = i2c_transfer(ts->client->adapter, msg, 2);
110 if (ret < 0) {
111 printk(KERN_ERR "synaptics_ts_work_func: i2c_transfer failed\n");
112 bad_data = 1;
113 } else {
114 /* printk("synaptics_ts_work_func: %x %x %x %x %x %x" */
115 /* " %x %x %x %x %x %x %x %x %x, ret %d\n", */
116 /* buf[0], buf[1], buf[2], buf[3], */
117 /* buf[4], buf[5], buf[6], buf[7], */
118 /* buf[8], buf[9], buf[10], buf[11], */
119 /* buf[12], buf[13], buf[14], ret); */
120 if ((buf[buf_len - 1] & 0xc0) != 0x40) {
121 printk(KERN_WARNING "synaptics_ts_work_func:"
122 " bad read %x %x %x %x %x %x %x %x %x"
123 " %x %x %x %x %x %x, ret %d\n",
124 buf[0], buf[1], buf[2], buf[3],
125 buf[4], buf[5], buf[6], buf[7],
126 buf[8], buf[9], buf[10], buf[11],
127 buf[12], buf[13], buf[14], ret);
128 if (bad_data)
129 synaptics_init_panel(ts);
130 bad_data = 1;
131 continue;
132 }
133 bad_data = 0;
134 if ((buf[buf_len - 1] & 1) == 0) {
135 /* printk("read %d coordinates\n", i); */
136 break;
137 } else {
138 int pos[2][2];
139 int f, a;
140 int base;
141 /* int x = buf[3] | (uint16_t)(buf[2] & 0x1f) << 8; */
142 /* int y = buf[5] | (uint16_t)(buf[4] & 0x1f) << 8; */
143 int z = buf[1];
144 int w = buf[0] >> 4;
145 int finger = buf[0] & 7;
146
147 /* int x2 = buf[3+6] | (uint16_t)(buf[2+6] & 0x1f) << 8; */
148 /* int y2 = buf[5+6] | (uint16_t)(buf[4+6] & 0x1f) << 8; */
149 /* int z2 = buf[1+6]; */
150 /* int w2 = buf[0+6] >> 4; */
151 /* int finger2 = buf[0+6] & 7; */
152
153 /* int dx = (int8_t)buf[12]; */
154 /* int dy = (int8_t)buf[13]; */
155 int finger2_pressed;
156
157 /* printk("x %4d, y %4d, z %3d, w %2d, F %d, 2nd: x %4d, y %4d, z %3d, w %2d, F %d, dx %4d, dy %4d\n", */
158 /* x, y, z, w, finger, */
159 /* x2, y2, z2, w2, finger2, */
160 /* dx, dy); */
161
162 base = 2;
163 for (f = 0; f < 2; f++) {
164 uint32_t flip_flag = SYNAPTICS_FLIP_X;
165 for (a = 0; a < 2; a++) {
166 int p = buf[base + 1];
167 p |= (uint16_t)(buf[base] & 0x1f) << 8;
168 if (ts->flags & flip_flag)
169 p = ts->max[a] - p;
170 if (ts->flags & SYNAPTICS_SNAP_TO_INACTIVE_EDGE) {
171 if (ts->snap_state[f][a]) {
172 if (p <= ts->snap_down_off[a])
173 p = ts->snap_down[a];
174 else if (p >= ts->snap_up_off[a])
175 p = ts->snap_up[a];
176 else
177 ts->snap_state[f][a] = 0;
178 } else {
179 if (p <= ts->snap_down_on[a]) {
180 p = ts->snap_down[a];
181 ts->snap_state[f][a] = 1;
182 } else if (p >= ts->snap_up_on[a]) {
183 p = ts->snap_up[a];
184 ts->snap_state[f][a] = 1;
185 }
186 }
187 }
188 pos[f][a] = p;
189 base += 2;
190 flip_flag <<= 1;
191 }
192 base += 2;
193 if (ts->flags & SYNAPTICS_SWAP_XY)
194 swap(pos[f][0], pos[f][1]);
195 }
196 if (z) {
197 input_report_abs(ts->input_dev, ABS_X, pos[0][0]);
198 input_report_abs(ts->input_dev, ABS_Y, pos[0][1]);
199 }
200 input_report_abs(ts->input_dev, ABS_PRESSURE, z);
201 input_report_abs(ts->input_dev, ABS_TOOL_WIDTH, w);
202 input_report_key(ts->input_dev, BTN_TOUCH, finger);
203 finger2_pressed = finger > 1 && finger != 7;
204 input_report_key(ts->input_dev, BTN_2, finger2_pressed);
205 if (finger2_pressed) {
206 input_report_abs(ts->input_dev, ABS_HAT0X, pos[1][0]);
207 input_report_abs(ts->input_dev, ABS_HAT0Y, pos[1][1]);
208 }
209
210 if (!finger)
211 z = 0;
212 input_report_abs(ts->input_dev, ABS_MT_TOUCH_MAJOR, z);
213 input_report_abs(ts->input_dev, ABS_MT_WIDTH_MAJOR, w);
214 input_report_abs(ts->input_dev, ABS_MT_POSITION_X, pos[0][0]);
215 input_report_abs(ts->input_dev, ABS_MT_POSITION_Y, pos[0][1]);
216 input_mt_sync(ts->input_dev);
217 if (finger2_pressed) {
218 input_report_abs(ts->input_dev, ABS_MT_TOUCH_MAJOR, z);
219 input_report_abs(ts->input_dev, ABS_MT_WIDTH_MAJOR, w);
220 input_report_abs(ts->input_dev, ABS_MT_POSITION_X, pos[1][0]);
221 input_report_abs(ts->input_dev, ABS_MT_POSITION_Y, pos[1][1]);
222 input_mt_sync(ts->input_dev);
223 } else if (ts->reported_finger_count > 1) {
224 input_report_abs(ts->input_dev, ABS_MT_TOUCH_MAJOR, 0);
225 input_report_abs(ts->input_dev, ABS_MT_WIDTH_MAJOR, 0);
226 input_mt_sync(ts->input_dev);
227 }
228 ts->reported_finger_count = finger;
229 input_sync(ts->input_dev);
230 }
231 }
232 }
233 if (ts->use_irq)
234 enable_irq(ts->client->irq);
235}
236
237static enum hrtimer_restart synaptics_ts_timer_func(struct hrtimer *timer)
238{
239 struct synaptics_ts_data *ts = container_of(timer, struct synaptics_ts_data, timer);
240 /* printk("synaptics_ts_timer_func\n"); */
241
242 queue_work(synaptics_wq, &ts->work);
243
244 hrtimer_start(&ts->timer, ktime_set(0, 12500000), HRTIMER_MODE_REL);
245 return HRTIMER_NORESTART;
246}
247
248static irqreturn_t synaptics_ts_irq_handler(int irq, void *dev_id)
249{
250 struct synaptics_ts_data *ts = dev_id;
251
252 /* printk("synaptics_ts_irq_handler\n"); */
253 disable_irq_nosync(ts->client->irq);
254 queue_work(synaptics_wq, &ts->work);
255 return IRQ_HANDLED;
256}
257
258static int synaptics_ts_probe(
259 struct i2c_client *client, const struct i2c_device_id *id)
260{
261 struct synaptics_ts_data *ts;
262 uint8_t buf0[4];
263 uint8_t buf1[8];
264 struct i2c_msg msg[2];
265 int ret = 0;
266 uint16_t max_x, max_y;
267 int fuzz_x, fuzz_y, fuzz_p, fuzz_w;
268 struct synaptics_i2c_rmi_platform_data *pdata;
269 unsigned long irqflags;
270 int inactive_area_left;
271 int inactive_area_right;
272 int inactive_area_top;
273 int inactive_area_bottom;
274 int snap_left_on;
275 int snap_left_off;
276 int snap_right_on;
277 int snap_right_off;
278 int snap_top_on;
279 int snap_top_off;
280 int snap_bottom_on;
281 int snap_bottom_off;
282 uint32_t panel_version;
283
284 if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
285 printk(KERN_ERR "synaptics_ts_probe: need I2C_FUNC_I2C\n");
286 ret = -ENODEV;
287 goto err_check_functionality_failed;
288 }
289
290 ts = kzalloc(sizeof(*ts), GFP_KERNEL);
291 if (ts == NULL) {
292 ret = -ENOMEM;
293 goto err_alloc_data_failed;
294 }
295 INIT_WORK(&ts->work, synaptics_ts_work_func);
296 ts->client = client;
297 i2c_set_clientdata(client, ts);
298 pdata = client->dev.platform_data;
299 if (pdata)
300 ts->power = pdata->power;
301 if (ts->power) {
302 ret = ts->power(1);
303 if (ret < 0) {
304 printk(KERN_ERR "synaptics_ts_probe power on failed\n");
305 goto err_power_failed;
306 }
307 }
308
309 ret = i2c_smbus_write_byte_data(ts->client, 0xf4, 0x01); /* device command = reset */
310 if (ret < 0) {
311 printk(KERN_ERR "i2c_smbus_write_byte_data failed\n");
312 /* fail? */
313 }
314 {
315 int retry = 10;
316 while (retry-- > 0) {
317 ret = i2c_smbus_read_byte_data(ts->client, 0xe4);
318 if (ret >= 0)
319 break;
320 msleep(100);
321 }
322 }
323 if (ret < 0) {
324 printk(KERN_ERR "i2c_smbus_read_byte_data failed\n");
325 goto err_detect_failed;
326 }
327 printk(KERN_INFO "synaptics_ts_probe: Product Major Version %x\n", ret);
328 panel_version = ret << 8;
329 ret = i2c_smbus_read_byte_data(ts->client, 0xe5);
330 if (ret < 0) {
331 printk(KERN_ERR "i2c_smbus_read_byte_data failed\n");
332 goto err_detect_failed;
333 }
334 printk(KERN_INFO "synaptics_ts_probe: Product Minor Version %x\n", ret);
335 panel_version |= ret;
336
337 ret = i2c_smbus_read_byte_data(ts->client, 0xe3);
338 if (ret < 0) {
339 printk(KERN_ERR "i2c_smbus_read_byte_data failed\n");
340 goto err_detect_failed;
341 }
342 printk(KERN_INFO "synaptics_ts_probe: product property %x\n", ret);
343
344 if (pdata) {
345 while (pdata->version > panel_version)
346 pdata++;
347 ts->flags = pdata->flags;
348 ts->sensitivity_adjust = pdata->sensitivity_adjust;
349 irqflags = pdata->irqflags;
350 inactive_area_left = pdata->inactive_left;
351 inactive_area_right = pdata->inactive_right;
352 inactive_area_top = pdata->inactive_top;
353 inactive_area_bottom = pdata->inactive_bottom;
354 snap_left_on = pdata->snap_left_on;
355 snap_left_off = pdata->snap_left_off;
356 snap_right_on = pdata->snap_right_on;
357 snap_right_off = pdata->snap_right_off;
358 snap_top_on = pdata->snap_top_on;
359 snap_top_off = pdata->snap_top_off;
360 snap_bottom_on = pdata->snap_bottom_on;
361 snap_bottom_off = pdata->snap_bottom_off;
362 fuzz_x = pdata->fuzz_x;
363 fuzz_y = pdata->fuzz_y;
364 fuzz_p = pdata->fuzz_p;
365 fuzz_w = pdata->fuzz_w;
366 } else {
367 irqflags = 0;
368 inactive_area_left = 0;
369 inactive_area_right = 0;
370 inactive_area_top = 0;
371 inactive_area_bottom = 0;
372 snap_left_on = 0;
373 snap_left_off = 0;
374 snap_right_on = 0;
375 snap_right_off = 0;
376 snap_top_on = 0;
377 snap_top_off = 0;
378 snap_bottom_on = 0;
379 snap_bottom_off = 0;
380 fuzz_x = 0;
381 fuzz_y = 0;
382 fuzz_p = 0;
383 fuzz_w = 0;
384 }
385
386 ret = i2c_smbus_read_byte_data(ts->client, 0xf0);
387 if (ret < 0) {
388 printk(KERN_ERR "i2c_smbus_read_byte_data failed\n");
389 goto err_detect_failed;
390 }
391 printk(KERN_INFO "synaptics_ts_probe: device control %x\n", ret);
392
393 ret = i2c_smbus_read_byte_data(ts->client, 0xf1);
394 if (ret < 0) {
395 printk(KERN_ERR "i2c_smbus_read_byte_data failed\n");
396 goto err_detect_failed;
397 }
398 printk(KERN_INFO "synaptics_ts_probe: interrupt enable %x\n", ret);
399
400 ret = i2c_smbus_write_byte_data(ts->client, 0xf1, 0); /* disable interrupt */
401 if (ret < 0) {
402 printk(KERN_ERR "i2c_smbus_write_byte_data failed\n");
403 goto err_detect_failed;
404 }
405
406 msg[0].addr = ts->client->addr;
407 msg[0].flags = 0;
408 msg[0].len = 1;
409 msg[0].buf = buf0;
410 buf0[0] = 0xe0;
411 msg[1].addr = ts->client->addr;
412 msg[1].flags = I2C_M_RD;
413 msg[1].len = 8;
414 msg[1].buf = buf1;
415 ret = i2c_transfer(ts->client->adapter, msg, 2);
416 if (ret < 0) {
417 printk(KERN_ERR "i2c_transfer failed\n");
418 goto err_detect_failed;
419 }
420 printk(KERN_INFO "synaptics_ts_probe: 0xe0: %x %x %x %x %x %x %x %x\n",
421 buf1[0], buf1[1], buf1[2], buf1[3],
422 buf1[4], buf1[5], buf1[6], buf1[7]);
423
424 ret = i2c_smbus_write_byte_data(ts->client, 0xff, 0x10); /* page select = 0x10 */
425 if (ret < 0) {
426 printk(KERN_ERR "i2c_smbus_write_byte_data failed for page select\n");
427 goto err_detect_failed;
428 }
429 ret = i2c_smbus_read_word_data(ts->client, 0x02);
430 if (ret < 0) {
431 printk(KERN_ERR "i2c_smbus_read_word_data failed\n");
432 goto err_detect_failed;
433 }
434 ts->has_relative_report = !(ret & 0x100);
435 printk(KERN_INFO "synaptics_ts_probe: Sensor properties %x\n", ret);
436 ret = i2c_smbus_read_word_data(ts->client, 0x04);
437 if (ret < 0) {
438 printk(KERN_ERR "i2c_smbus_read_word_data failed\n");
439 goto err_detect_failed;
440 }
441 ts->max[0] = max_x = (ret >> 8 & 0xff) | ((ret & 0x1f) << 8);
442 ret = i2c_smbus_read_word_data(ts->client, 0x06);
443 if (ret < 0) {
444 printk(KERN_ERR "i2c_smbus_read_word_data failed\n");
445 goto err_detect_failed;
446 }
447 ts->max[1] = max_y = (ret >> 8 & 0xff) | ((ret & 0x1f) << 8);
448 if (ts->flags & SYNAPTICS_SWAP_XY)
449 swap(max_x, max_y);
450
451 ret = synaptics_init_panel(ts); /* will also switch back to page 0x04 */
452 if (ret < 0) {
453 printk(KERN_ERR "synaptics_init_panel failed\n");
454 goto err_detect_failed;
455 }
456
457 ts->input_dev = input_allocate_device();
458 if (ts->input_dev == NULL) {
459 ret = -ENOMEM;
460 printk(KERN_ERR "synaptics_ts_probe: Failed to allocate input device\n");
461 goto err_input_dev_alloc_failed;
462 }
463 ts->input_dev->name = "synaptics-rmi-touchscreen";
464 set_bit(EV_SYN, ts->input_dev->evbit);
465 set_bit(EV_KEY, ts->input_dev->evbit);
466 set_bit(BTN_TOUCH, ts->input_dev->keybit);
467 set_bit(BTN_2, ts->input_dev->keybit);
468 set_bit(EV_ABS, ts->input_dev->evbit);
469 inactive_area_left = inactive_area_left * max_x / 0x10000;
470 inactive_area_right = inactive_area_right * max_x / 0x10000;
471 inactive_area_top = inactive_area_top * max_y / 0x10000;
472 inactive_area_bottom = inactive_area_bottom * max_y / 0x10000;
473 snap_left_on = snap_left_on * max_x / 0x10000;
474 snap_left_off = snap_left_off * max_x / 0x10000;
475 snap_right_on = snap_right_on * max_x / 0x10000;
476 snap_right_off = snap_right_off * max_x / 0x10000;
477 snap_top_on = snap_top_on * max_y / 0x10000;
478 snap_top_off = snap_top_off * max_y / 0x10000;
479 snap_bottom_on = snap_bottom_on * max_y / 0x10000;
480 snap_bottom_off = snap_bottom_off * max_y / 0x10000;
481 fuzz_x = fuzz_x * max_x / 0x10000;
482 fuzz_y = fuzz_y * max_y / 0x10000;
483 ts->snap_down[!!(ts->flags & SYNAPTICS_SWAP_XY)] = -inactive_area_left;
484 ts->snap_up[!!(ts->flags & SYNAPTICS_SWAP_XY)] = max_x + inactive_area_right;
485 ts->snap_down[!(ts->flags & SYNAPTICS_SWAP_XY)] = -inactive_area_top;
486 ts->snap_up[!(ts->flags & SYNAPTICS_SWAP_XY)] = max_y + inactive_area_bottom;
487 ts->snap_down_on[!!(ts->flags & SYNAPTICS_SWAP_XY)] = snap_left_on;
488 ts->snap_down_off[!!(ts->flags & SYNAPTICS_SWAP_XY)] = snap_left_off;
489 ts->snap_up_on[!!(ts->flags & SYNAPTICS_SWAP_XY)] = max_x - snap_right_on;
490 ts->snap_up_off[!!(ts->flags & SYNAPTICS_SWAP_XY)] = max_x - snap_right_off;
491 ts->snap_down_on[!(ts->flags & SYNAPTICS_SWAP_XY)] = snap_top_on;
492 ts->snap_down_off[!(ts->flags & SYNAPTICS_SWAP_XY)] = snap_top_off;
493 ts->snap_up_on[!(ts->flags & SYNAPTICS_SWAP_XY)] = max_y - snap_bottom_on;
494 ts->snap_up_off[!(ts->flags & SYNAPTICS_SWAP_XY)] = max_y - snap_bottom_off;
495 printk(KERN_INFO "synaptics_ts_probe: max_x %d, max_y %d\n", max_x, max_y);
496 printk(KERN_INFO "synaptics_ts_probe: inactive_x %d %d, inactive_y %d %d\n",
497 inactive_area_left, inactive_area_right,
498 inactive_area_top, inactive_area_bottom);
499 printk(KERN_INFO "synaptics_ts_probe: snap_x %d-%d %d-%d, snap_y %d-%d %d-%d\n",
500 snap_left_on, snap_left_off, snap_right_on, snap_right_off,
501 snap_top_on, snap_top_off, snap_bottom_on, snap_bottom_off);
502 input_set_abs_params(ts->input_dev, ABS_X, -inactive_area_left, max_x + inactive_area_right, fuzz_x, 0);
503 input_set_abs_params(ts->input_dev, ABS_Y, -inactive_area_top, max_y + inactive_area_bottom, fuzz_y, 0);
504 input_set_abs_params(ts->input_dev, ABS_PRESSURE, 0, 255, fuzz_p, 0);
505 input_set_abs_params(ts->input_dev, ABS_TOOL_WIDTH, 0, 15, fuzz_w, 0);
506 input_set_abs_params(ts->input_dev, ABS_HAT0X, -inactive_area_left, max_x + inactive_area_right, fuzz_x, 0);
507 input_set_abs_params(ts->input_dev, ABS_HAT0Y, -inactive_area_top, max_y + inactive_area_bottom, fuzz_y, 0);
508 input_set_abs_params(ts->input_dev, ABS_MT_POSITION_X, -inactive_area_left, max_x + inactive_area_right, fuzz_x, 0);
509 input_set_abs_params(ts->input_dev, ABS_MT_POSITION_Y, -inactive_area_top, max_y + inactive_area_bottom, fuzz_y, 0);
510 input_set_abs_params(ts->input_dev, ABS_MT_TOUCH_MAJOR, 0, 255, fuzz_p, 0);
511 input_set_abs_params(ts->input_dev, ABS_MT_WIDTH_MAJOR, 0, 15, fuzz_w, 0);
512 /* ts->input_dev->name = ts->keypad_info->name; */
513 ret = input_register_device(ts->input_dev);
514 if (ret) {
515 printk(KERN_ERR "synaptics_ts_probe: Unable to register %s input device\n", ts->input_dev->name);
516 goto err_input_register_device_failed;
517 }
518 if (client->irq) {
519 ret = request_irq(client->irq, synaptics_ts_irq_handler, irqflags, client->name, ts);
520 if (ret == 0) {
521 ret = i2c_smbus_write_byte_data(ts->client, 0xf1, 0x01); /* enable abs int */
522 if (ret)
523 free_irq(client->irq, ts);
524 }
525 if (ret == 0)
526 ts->use_irq = 1;
527 else
528 dev_err(&client->dev, "request_irq failed\n");
529 }
530 if (!ts->use_irq) {
531 hrtimer_init(&ts->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
532 ts->timer.function = synaptics_ts_timer_func;
533 hrtimer_start(&ts->timer, ktime_set(1, 0), HRTIMER_MODE_REL);
534 }
535#ifdef CONFIG_HAS_EARLYSUSPEND
536 ts->early_suspend.level = EARLY_SUSPEND_LEVEL_BLANK_SCREEN + 1;
537 ts->early_suspend.suspend = synaptics_ts_early_suspend;
538 ts->early_suspend.resume = synaptics_ts_late_resume;
539 register_early_suspend(&ts->early_suspend);
540#endif
541
542 printk(KERN_INFO "synaptics_ts_probe: Start touchscreen %s in %s mode\n", ts->input_dev->name, ts->use_irq ? "interrupt" : "polling");
543
544 return 0;
545
546err_input_register_device_failed:
547 input_free_device(ts->input_dev);
548
549err_input_dev_alloc_failed:
550err_detect_failed:
551err_power_failed:
552 kfree(ts);
553err_alloc_data_failed:
554err_check_functionality_failed:
555 return ret;
556}
557
558static int synaptics_ts_remove(struct i2c_client *client)
559{
560 struct synaptics_ts_data *ts = i2c_get_clientdata(client);
561 unregister_early_suspend(&ts->early_suspend);
562 if (ts->use_irq)
563 free_irq(client->irq, ts);
564 else
565 hrtimer_cancel(&ts->timer);
566 input_unregister_device(ts->input_dev);
567 kfree(ts);
568 return 0;
569}
570
571static int synaptics_ts_suspend(struct i2c_client *client, pm_message_t mesg)
572{
573 int ret;
574 struct synaptics_ts_data *ts = i2c_get_clientdata(client);
575
576 if (ts->use_irq)
577 disable_irq(client->irq);
578 else
579 hrtimer_cancel(&ts->timer);
580 ret = cancel_work_sync(&ts->work);
581 if (ret && ts->use_irq) /* if work was pending disable-count is now 2 */
582 enable_irq(client->irq);
583 ret = i2c_smbus_write_byte_data(ts->client, 0xf1, 0); /* disable interrupt */
584 if (ret < 0)
585 printk(KERN_ERR "synaptics_ts_suspend: i2c_smbus_write_byte_data failed\n");
586
587 ret = i2c_smbus_write_byte_data(client, 0xf0, 0x86); /* deep sleep */
588 if (ret < 0)
589 printk(KERN_ERR "synaptics_ts_suspend: i2c_smbus_write_byte_data failed\n");
590 if (ts->power) {
591 ret = ts->power(0);
592 if (ret < 0)
593 printk(KERN_ERR "synaptics_ts_resume power off failed\n");
594 }
595 return 0;
596}
597
598static int synaptics_ts_resume(struct i2c_client *client)
599{
600 int ret;
601 struct synaptics_ts_data *ts = i2c_get_clientdata(client);
602
603 if (ts->power) {
604 ret = ts->power(1);
605 if (ret < 0)
606 printk(KERN_ERR "synaptics_ts_resume power on failed\n");
607 }
608
609 synaptics_init_panel(ts);
610
611 if (ts->use_irq)
612 enable_irq(client->irq);
613
614 if (!ts->use_irq)
615 hrtimer_start(&ts->timer, ktime_set(1, 0), HRTIMER_MODE_REL);
616 else
617 i2c_smbus_write_byte_data(ts->client, 0xf1, 0x01); /* enable abs int */
618
619 return 0;
620}
621
622#ifdef CONFIG_HAS_EARLYSUSPEND
623static void synaptics_ts_early_suspend(struct early_suspend *h)
624{
625 struct synaptics_ts_data *ts;
626 ts = container_of(h, struct synaptics_ts_data, early_suspend);
627 synaptics_ts_suspend(ts->client, PMSG_SUSPEND);
628}
629
630static void synaptics_ts_late_resume(struct early_suspend *h)
631{
632 struct synaptics_ts_data *ts;
633 ts = container_of(h, struct synaptics_ts_data, early_suspend);
634 synaptics_ts_resume(ts->client);
635}
636#endif
637
638static const struct i2c_device_id synaptics_ts_id[] = {
639 { SYNAPTICS_I2C_RMI_NAME, 0 },
640 { }
641};
642
643static struct i2c_driver synaptics_ts_driver = {
644 .probe = synaptics_ts_probe,
645 .remove = synaptics_ts_remove,
646#ifndef CONFIG_HAS_EARLYSUSPEND
647 .suspend = synaptics_ts_suspend,
648 .resume = synaptics_ts_resume,
649#endif
650 .id_table = synaptics_ts_id,
651 .driver = {
652 .name = SYNAPTICS_I2C_RMI_NAME,
653 },
654};
655
656static int __devinit synaptics_ts_init(void)
657{
658 synaptics_wq = create_singlethread_workqueue("synaptics_wq");
659 if (!synaptics_wq)
660 return -ENOMEM;
661 return i2c_add_driver(&synaptics_ts_driver);
662}
663
664static void __exit synaptics_ts_exit(void)
665{
666 i2c_del_driver(&synaptics_ts_driver);
667 if (synaptics_wq)
668 destroy_workqueue(synaptics_wq);
669}
670
671module_init(synaptics_ts_init);
672module_exit(synaptics_ts_exit);
673
674MODULE_DESCRIPTION("Synaptics Touchscreen Driver");
675MODULE_LICENSE("GPL");
diff --git a/drivers/input/touchscreen/touch-i2c.c b/drivers/input/touchscreen/touch-i2c.c
new file mode 100644
index 00000000000..8526d896150
--- /dev/null
+++ b/drivers/input/touchscreen/touch-i2c.c
@@ -0,0 +1,170 @@
1//[*]--------------------------------------------------------------------------------------------------[*]
2//
3//
4//
5// I2C Touchscreen driver
6// 2012.01.17
7//
8//
9//[*]--------------------------------------------------------------------------------------------------[*]
10#include <linux/input.h> /* BUS_I2C */
11#include <linux/i2c.h>
12#include <linux/module.h>
13
14//[*]--------------------------------------------------------------------------------------------------[*]
15#include <linux/input/touch-pdata.h>
16#include "touch.h"
17
18//[*]--------------------------------------------------------------------------------------------------[*]
19//
20// function prototype
21//
22//[*]--------------------------------------------------------------------------------------------------[*]
23static void __exit touch_i2c_exit (void);
24static int __init touch_i2c_init (void);
25static int __devexit touch_i2c_remove (struct i2c_client *client);
26static int __devinit touch_i2c_probe (struct i2c_client *client, const struct i2c_device_id *id);
27 int touch_i2c_read (struct i2c_client *client, unsigned char *cmd, unsigned int cmd_len, unsigned char *data, unsigned int len);
28 int touch_i2c_write (struct i2c_client *client, unsigned char *cmd, unsigned int cmd_len, unsigned char *data, unsigned int len);
29
30//[*]--------------------------------------------------------------------------------------------------[*]
31#ifdef CONFIG_PM
32static int touch_i2c_suspend(struct i2c_client *client, pm_message_t message)
33{
34 #ifndef CONFIG_HAS_EARLYSUSPEND
35 struct touch *ts = i2c_get_clientdata(client);
36
37 ts->pdata->suspend(&client->dev);
38 #endif
39
40 return 0;
41}
42
43//[*]--------------------------------------------------------------------------------------------------[*]
44static int touch_i2c_resume(struct i2c_client *client)
45{
46 #ifndef CONFIG_HAS_EARLYSUSPEND
47 struct touch *ts = i2c_get_clientdata(client);
48
49 ts->pdata->resume(&cliet->dev);
50 #endif
51
52 return 0;
53}
54
55//[*]--------------------------------------------------------------------------------------------------[*]
56#else
57 #define touch_i2c_suspend NULL
58 #define touch_i2c_resume NULL
59#endif
60
61//[*]--------------------------------------------------------------------------------------------------[*]
62int touch_i2c_read(struct i2c_client *client, unsigned char *cmd, unsigned int cmd_len, unsigned char *data, unsigned int len)
63{
64 struct i2c_msg msg[2];
65 int ret;
66
67 if((len == 0) || (data == NULL)) {
68 dev_err(&client->dev, "I2C read error: Null pointer or length == 0\n");
69 return -1;
70 }
71
72 memset(msg, 0x00, sizeof(msg));
73
74 msg[0].addr = client->addr;
75 msg[0].flags = 0;
76 msg[0].len = cmd_len;
77 msg[0].buf = cmd;
78
79 msg[1].addr = client->addr;
80 msg[1].flags = I2C_M_RD;
81 msg[1].len = len;
82 msg[1].buf = data;
83
84 if ((ret = i2c_transfer(client->adapter, msg, 2)) != 2) {
85 dev_err(&client->dev, "I2C read error: (%d) reg: 0x%X len: %d\n", ret, cmd[0], len);
86 return -EIO;
87 }
88
89 return len;
90}
91
92//[*]--------------------------------------------------------------------------------------------------[*]
93int touch_i2c_write(struct i2c_client *client, unsigned char *cmd, unsigned int cmd_len, unsigned char *data, unsigned int len)
94{
95 int ret;
96 unsigned char block_data[10];
97
98 if((cmd_len + len) >= sizeof(block_data)) {
99 dev_err(&client->dev, "I2C write error: wdata overflow reg: 0x%X len: %d\n", cmd[0], cmd_len + len);
100 return -1;
101 }
102
103 memset(block_data, 0x00, sizeof(block_data));
104
105 if(cmd_len) memcpy(&block_data[0] , &cmd[0] , cmd_len);
106 if(len) memcpy(&block_data[cmd_len] , &data[0] , len);
107
108 if ((ret = i2c_master_send(client, block_data, (cmd_len + len)))< 0) {
109 dev_err(&client->dev, "I2C write error: (%d) reg: 0x%X len: %d\n", ret, cmd[0], len);
110 return ret;
111 }
112
113 return len;
114}
115
116//[*]--------------------------------------------------------------------------------------------------[*]
117static int __devinit touch_i2c_probe(struct i2c_client *client, const struct i2c_device_id *id)
118{
119 return touch_probe(client);
120}
121
122//[*]--------------------------------------------------------------------------------------------------[*]
123static int __devexit touch_i2c_remove(struct i2c_client *client)
124{
125 return touch_remove(&client->dev);
126}
127
128//[*]--------------------------------------------------------------------------------------------------[*]
129static const struct i2c_device_id touch_id[] = {
130 { I2C_TOUCH_NAME, 0 },
131 { }
132};
133
134MODULE_DEVICE_TABLE(i2c, touch_id);
135
136//[*]--------------------------------------------------------------------------------------------------[*]
137static struct i2c_driver touch_i2c_driver = {
138 .driver = {
139 .name = I2C_TOUCH_NAME,
140 .owner = THIS_MODULE,
141 },
142 .probe = touch_i2c_probe,
143 .remove = __devexit_p(touch_i2c_remove),
144 .suspend = touch_i2c_suspend,
145 .resume = touch_i2c_resume,
146 .id_table = touch_id,
147};
148
149//[*]--------------------------------------------------------------------------------------------------[*]
150static int __init touch_i2c_init(void)
151{
152 return i2c_add_driver(&touch_i2c_driver);
153}
154module_init(touch_i2c_init);
155
156//[*]--------------------------------------------------------------------------------------------------[*]
157static void __exit touch_i2c_exit(void)
158{
159 i2c_del_driver(&touch_i2c_driver);
160}
161module_exit(touch_i2c_exit);
162
163//[*]--------------------------------------------------------------------------------------------------[*]
164MODULE_AUTHOR("HardKernel Co., Ltd.");
165MODULE_LICENSE("GPL");
166MODULE_DESCRIPTION("Touchscreen I2C bus driver");
167MODULE_ALIAS("i2c:touch");
168
169//[*]--------------------------------------------------------------------------------------------------[*]
170//[*]--------------------------------------------------------------------------------------------------[*]
diff --git a/drivers/input/touchscreen/touch-i2c.h b/drivers/input/touchscreen/touch-i2c.h
new file mode 100644
index 00000000000..b976f46e838
--- /dev/null
+++ b/drivers/input/touchscreen/touch-i2c.h
@@ -0,0 +1,23 @@
1//[*]--------------------------------------------------------------------------------------------------[*]
2//
3//
4//
5// I2C Touchscreen driver
6// 2012.01.17
7//
8//
9//[*]--------------------------------------------------------------------------------------------------[*]
10#ifndef _TOUCH_I2C_H_
11#define _TOUCH_I2C_H_
12
13//[*]--------------------------------------------------------------------------------------------------[*]
14// extern function define
15//[*]--------------------------------------------------------------------------------------------------[*]
16extern int touch_i2c_read (struct i2c_client *client, unsigned char *cmd, unsigned int cmd_len, unsigned char *data, unsigned int len);
17extern int touch_i2c_write (struct i2c_client *client, unsigned char *cmd, unsigned int cmd_len, unsigned char *data, unsigned int len);
18
19//[*]--------------------------------------------------------------------------------------------------[*]
20#endif /* _TOUCH_I2C_H_ */
21
22//[*]--------------------------------------------------------------------------------------------------[*]
23//[*]--------------------------------------------------------------------------------------------------[*]
diff --git a/drivers/input/touchscreen/touch-sysfs.c b/drivers/input/touchscreen/touch-sysfs.c
new file mode 100644
index 00000000000..184d717fb5a
--- /dev/null
+++ b/drivers/input/touchscreen/touch-sysfs.c
@@ -0,0 +1,250 @@
1//[*]--------------------------------------------------------------------------------------------------[*]
2//
3//
4//
5// I2C Touchscreen driver
6// 2012.01.17
7//
8//
9//[*]--------------------------------------------------------------------------------------------------[*]
10#include <linux/device.h>
11#include <linux/init.h>
12#include <linux/input.h>
13#include <linux/interrupt.h>
14#include <linux/irq.h>
15#include <linux/slab.h>
16#include <linux/workqueue.h>
17#include <linux/hrtimer.h>
18#include <asm/unaligned.h>
19#include <linux/firmware.h>
20#include <linux/delay.h>
21#include <linux/fs.h>
22
23#include <linux/string.h>
24
25//[*]--------------------------------------------------------------------------------------------------[*]
26#include <linux/input/touch-pdata.h>
27#include "touch.h"
28
29//[*]--------------------------------------------------------------------------------------------------[*]
30//
31// sysfs function prototype define
32//
33//[*]--------------------------------------------------------------------------------------------------[*]
34// disablel (1 -> disable irq, cancel work, 0 -> enable irq), show irq state
35//[*]--------------------------------------------------------------------------------------------------[*]
36static ssize_t show_disable (struct device *dev, struct device_attribute *attr, char *buf);
37static ssize_t store_disable (struct device *dev, struct device_attribute *attr, const char *buf, size_t count);
38static DEVICE_ATTR(disable, S_IRWXUGO, show_disable, store_disable);
39
40//[*]--------------------------------------------------------------------------------------------------[*]
41// fw version display
42//[*]--------------------------------------------------------------------------------------------------[*]
43static ssize_t show_fw_version (struct device *dev, struct device_attribute *attr, char *buf);
44static DEVICE_ATTR(fw_version, S_IRWXUGO, show_fw_version, NULL);
45
46//[*]--------------------------------------------------------------------------------------------------[*]
47// fw data load : fw load status, fw data load
48//[*]--------------------------------------------------------------------------------------------------[*]
49static ssize_t show_fw (struct device *dev, struct device_attribute *attr, char *buf);
50static ssize_t store_fw (struct device *dev, struct device_attribute *attr, const char *buf, size_t count);
51static DEVICE_ATTR(fw, S_IRWXUGO, show_fw, store_fw);
52
53//[*]--------------------------------------------------------------------------------------------------[*]
54// fw status : fw status
55//[*]--------------------------------------------------------------------------------------------------[*]
56static ssize_t show_fw_status (struct device *dev, struct device_attribute *attr, char *buf);
57static ssize_t store_fw_status (struct device *dev, struct device_attribute *attr, const char *buf, size_t count);
58static DEVICE_ATTR(fw_status, S_IRWXUGO, show_fw_status, store_fw_status);
59
60//[*]--------------------------------------------------------------------------------------------------[*]
61// update_fw : 1 -> update fw (load fw)
62//[*]--------------------------------------------------------------------------------------------------[*]
63static ssize_t store_update_fw (struct device *dev, struct device_attribute *attr, const char *buf, size_t count);
64static DEVICE_ATTR(update_fw, S_IRWXUGO, NULL, store_update_fw);
65
66//[*]--------------------------------------------------------------------------------------------------[*]
67// calibration (1 -> update calibration, 0 -> nothing), show -> NULL
68//[*]--------------------------------------------------------------------------------------------------[*]
69static ssize_t store_calibration (struct device *dev, struct device_attribute *attr, const char *buf, size_t count);
70static DEVICE_ATTR(calibration, S_IRWXUGO, NULL, store_calibration);
71
72//[*]--------------------------------------------------------------------------------------------------[*]
73// hw reset
74//[*]--------------------------------------------------------------------------------------------------[*]
75static ssize_t store_reset (struct device *dev, struct device_attribute *attr, const char *buf, size_t count);
76static DEVICE_ATTR(reset, S_IRWXUGO, NULL, store_reset);
77
78//[*]--------------------------------------------------------------------------------------------------[*]
79//[*]--------------------------------------------------------------------------------------------------[*]
80static struct attribute *touch_sysfs_entries[] = {
81 &dev_attr_disable.attr,
82 &dev_attr_fw_version.attr,
83 &dev_attr_fw.attr,
84 &dev_attr_fw_status.attr,
85 &dev_attr_update_fw.attr,
86 &dev_attr_calibration.attr,
87 &dev_attr_reset.attr,
88 NULL
89};
90
91static struct attribute_group touch_attr_group = {
92 .name = NULL,
93 .attrs = touch_sysfs_entries,
94};
95
96//[*]--------------------------------------------------------------------------------------------------[*]
97//[*]--------------------------------------------------------------------------------------------------[*]
98static ssize_t store_reset (struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
99{
100 struct touch *ts = dev_get_drvdata(dev);
101 unsigned long val;
102 int err;
103
104 if ((err = strict_strtoul(buf, 10, &val))) return err;
105
106 if((ts->pdata->reset_gpio) && (val == 1)) touch_hw_reset(ts);
107
108 return count;
109}
110
111//[*]--------------------------------------------------------------------------------------------------[*]
112// disablel (1 -> disable irq, cancel work, 0 -> enable irq), show irq state
113//[*]--------------------------------------------------------------------------------------------------[*]
114static ssize_t show_disable (struct device *dev, struct device_attribute *attr, char *buf)
115{
116 struct touch *ts = dev_get_drvdata(dev);
117
118 return sprintf(buf, "%u\n", ts->disabled);
119}
120
121//[*]--------------------------------------------------------------------------------------------------[*]
122static ssize_t store_disable (struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
123{
124 struct touch *ts = dev_get_drvdata(dev);
125 unsigned long val;
126 int err;
127
128 if ((err = strict_strtoul(buf, 10, &val))) return err;
129
130 if (val) ts->pdata->disable(ts); // interrupt disable
131 else ts->pdata->enable(ts); // interrupt enable
132
133 return count;
134}
135
136//[*]--------------------------------------------------------------------------------------------------[*]
137// firmware version display
138//[*]--------------------------------------------------------------------------------------------------[*]
139static ssize_t show_fw_version (struct device *dev, struct device_attribute *attr, char *buf)
140{
141 struct touch *ts = dev_get_drvdata(dev);
142
143 return sprintf(buf, "%d\n", ts->fw_version);
144}
145
146//[*]--------------------------------------------------------------------------------------------------[*]
147// update_fw
148//[*]--------------------------------------------------------------------------------------------------[*]
149
150static ssize_t store_fw (struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
151{
152 struct touch *ts = dev_get_drvdata(dev);
153
154 if(ts->fw_buf != NULL) {
155
156 if(ts->fw_size < ts->pdata->fw_filesize) memcpy(&ts->fw_buf[ts->fw_size], buf, count);
157
158 ts->fw_size += count;
159 }
160
161 return count;
162}
163
164//[*]--------------------------------------------------------------------------------------------------[*]
165static ssize_t show_fw (struct device *dev, struct device_attribute *attr, char *buf)
166{
167 struct touch *ts = dev_get_drvdata(dev);
168
169 return sprintf(buf, "%d\n", ts->fw_size);
170}
171
172//[*]--------------------------------------------------------------------------------------------------[*]
173//[*]--------------------------------------------------------------------------------------------------[*]
174static ssize_t store_fw_status (struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
175{
176 struct touch *ts = dev_get_drvdata(dev);
177 int err;
178 unsigned long val;
179
180 if ((err = strict_strtoul(buf, 10, &val))) return err;
181
182 if(ts->pdata->fw_control) ts->pdata->fw_control(ts, val);
183
184 return count;
185}
186
187//[*]--------------------------------------------------------------------------------------------------[*]
188static ssize_t show_fw_status (struct device *dev, struct device_attribute *attr, char *buf)
189{
190 struct touch *ts = dev_get_drvdata(dev);
191
192 return sprintf(buf, "0x%08X\n", ts->fw_status);
193}
194
195//[*]--------------------------------------------------------------------------------------------------[*]
196static ssize_t store_update_fw (struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
197{
198 unsigned long val;
199 int err;
200 struct touch *ts = dev_get_drvdata(dev);
201
202 if ((err = strict_strtoul(buf, 10, &val))) return err;
203
204 if (val == 1) {
205 if(ts->pdata->flash_firmware) {
206 if(ts->pdata->fw_filename) ts->pdata->flash_firmware(dev, ts->pdata->fw_filename);
207 }
208 }
209
210 return count;
211}
212
213//[*]--------------------------------------------------------------------------------------------------[*]
214// calibration (1 -> update calibration, 0 -> nothing), show -> NULL
215//[*]--------------------------------------------------------------------------------------------------[*]
216static ssize_t store_calibration (struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
217{
218 struct touch *ts = dev_get_drvdata(dev);
219 unsigned long val;
220 int err;
221
222 if ((err = strict_strtoul(buf, 10, &val))) return err;
223
224 if (val == 1) {
225 ts->pdata->disable(ts); // interrupt disable
226 if(ts->pdata->calibration) ts->pdata->calibration(ts);
227 ts->pdata->enable(ts); // interrupt enable
228 }
229
230 return count;
231}
232
233//[*]--------------------------------------------------------------------------------------------------[*]
234//[*]--------------------------------------------------------------------------------------------------[*]
235int touch_sysfs_create (struct device *dev)
236{
237 return sysfs_create_group(&dev->kobj, &touch_attr_group);
238}
239
240//[*]--------------------------------------------------------------------------------------------------[*]
241void touch_sysfs_remove (struct device *dev)
242{
243 sysfs_remove_group(&dev->kobj, &touch_attr_group);
244}
245
246//[*]--------------------------------------------------------------------------------------------------[*]
247MODULE_AUTHOR("HardKernel Co., Ltd.");
248MODULE_LICENSE("GPL");
249MODULE_DESCRIPTION("Touchscreen Driver");
250//[*]--------------------------------------------------------------------------------------------------[*]
diff --git a/drivers/input/touchscreen/touch-sysfs.h b/drivers/input/touchscreen/touch-sysfs.h
new file mode 100644
index 00000000000..dd4bc94885e
--- /dev/null
+++ b/drivers/input/touchscreen/touch-sysfs.h
@@ -0,0 +1,23 @@
1//[*]--------------------------------------------------------------------------------------------------[*]
2//
3//
4//
5// I2C Touchscreen driver
6// 2012.01.17
7//
8//
9//[*]--------------------------------------------------------------------------------------------------[*]
10#ifndef _TOUCH_SYSFS_H_
11#define _TOUCH_SYSFS_H_
12
13//[*]--------------------------------------------------------------------------------------------------[*]
14// extern function define
15//[*]--------------------------------------------------------------------------------------------------[*]
16extern int touch_sysfs_create (struct device *dev);
17extern void touch_sysfs_remove (struct device *dev);
18
19//[*]--------------------------------------------------------------------------------------------------[*]
20#endif /* _TOUCH_SYSFS_H_ */
21
22//[*]--------------------------------------------------------------------------------------------------[*]
23//[*]--------------------------------------------------------------------------------------------------[*]
diff --git a/drivers/input/touchscreen/touch.c b/drivers/input/touchscreen/touch.c
new file mode 100644
index 00000000000..e6c0cc2324e
--- /dev/null
+++ b/drivers/input/touchscreen/touch.c
@@ -0,0 +1,672 @@
1//[*]--------------------------------------------------------------------------------------------------[*]
2//
3//
4//
5// I2C Touchscreen driver
6// 2012.01.17
7//
8//
9//[*]--------------------------------------------------------------------------------------------------[*]
10#include <linux/device.h>
11#include <linux/init.h>
12#include <linux/input.h>
13#include <linux/interrupt.h>
14#include <linux/irq.h>
15#include <linux/slab.h>
16#include <linux/hrtimer.h>
17#include <asm/unaligned.h>
18#include <linux/firmware.h>
19#include <linux/delay.h>
20#include <linux/gpio.h>
21#include <linux/i2c.h>
22
23//[*]--------------------------------------------------------------------------------------------------[*]
24#if defined(CONFIG_HAS_EARLYSUSPEND)
25 #include <linux/wakelock.h>
26 #include <linux/earlysuspend.h>
27 #include <linux/suspend.h>
28#endif
29
30//[*]--------------------------------------------------------------------------------------------------[*]
31#include <linux/input/mt.h>
32#include <linux/input/touch-pdata.h>
33
34//[*]--------------------------------------------------------------------------------------------------[*]
35#include "touch.h"
36#include "touch-i2c.h"
37#include "touch-sysfs.h"
38
39//[*]--------------------------------------------------------------------------------------------------[*]
40//#define DEBUG_TOUCH
41
42//[*]--------------------------------------------------------------------------------------------------[*]
43// function prototype define
44//[*]--------------------------------------------------------------------------------------------------[*]
45#ifdef CONFIG_HAS_EARLYSUSPEND
46 static void touch_suspend (struct early_suspend *h);
47 static void touch_resume (struct early_suspend *h);
48#endif
49
50irqreturn_t touch_irq (int irq, void *handle);
51static void touch_work (struct touch *ts);
52static void touch_work_q (struct work_struct *work);
53
54static void touch_key_report (struct touch *ts, unsigned char button_data);
55static void touch_report_protocol_a (struct touch *ts);
56static void touch_report_protocol_b (struct touch *ts);
57
58static void touch_event_clear (struct touch *ts);
59static void touch_enable (struct touch *ts);
60static void touch_disable (struct touch *ts);
61static void touch_input_close (struct input_dev *input);
62static int touch_input_open (struct input_dev *input);
63static int touch_check_functionality (struct touch_pdata *pdata);
64
65 void touch_hw_reset (struct touch *ts);
66 int touch_info_display (struct touch *ts);
67 int touch_probe (struct i2c_client *client);
68 int touch_remove (struct device *dev);
69
70//[*]--------------------------------------------------------------------------------------------------[*]
71irqreturn_t touch_irq (int irq, void *handle)
72{
73 struct touch *ts = handle;
74
75 if(ts->pdata->irq_mode) queue_work(ts->work_queue, &ts->work); // normal mode (work q used)
76 else ts->pdata->touch_work(ts); // thread mode
77
78 return IRQ_HANDLED;
79}
80
81//[*]--------------------------------------------------------------------------------------------------[*]
82static void touch_work (struct touch *ts)
83{
84 printk("error : undefined touch work function!!\n");
85}
86
87//[*]--------------------------------------------------------------------------------------------------[*]
88static void touch_work_q (struct work_struct *work)
89{
90 struct touch *ts = container_of(work, struct touch, work);
91
92 ts->pdata->touch_work(ts);
93}
94
95//[*]--------------------------------------------------------------------------------------------------[*]
96static void touch_key_report (struct touch *ts, unsigned char button_data)
97{
98 static button_u button_old;
99 button_u button_new;
100
101 button_new.ubyte = button_data;
102 if(button_old.ubyte != button_new.ubyte) {
103 if((button_old.bits.bt0_press != button_new.bits.bt0_press) && (ts->pdata->keycnt > 0)) {
104 if(button_new.bits.bt0_press) input_report_key(ts->input, ts->pdata->keycode[0], true);
105 else input_report_key(ts->input, ts->pdata->keycode[0], false);
106 #if defined(DEBUG_TOUCH_KEY)
107 printk("keycode[0](0x%04X) %s\n", ts->pdata->keycode[0], button_new.bits.bt0_press ? "press":"release");
108 #endif
109 }
110 if((button_old.bits.bt1_press != button_new.bits.bt1_press) && (ts->pdata->keycnt > 1)) {
111 if(button_new.bits.bt1_press) input_report_key(ts->input, ts->pdata->keycode[1], true);
112 else input_report_key(ts->input, ts->pdata->keycode[1], false);
113 #if defined(DEBUG_TOUCH_KEY)
114 printk("keycode[1](0x%04X) %s\n", ts->pdata->keycode[1], button_new.bits.bt1_press ? "press":"release");
115 #endif
116 }
117 if((button_old.bits.bt2_press != button_new.bits.bt2_press) && (ts->pdata->keycnt > 2)) {
118 if(button_new.bits.bt2_press) input_report_key(ts->input, ts->pdata->keycode[2], true);
119 else input_report_key(ts->input, ts->pdata->keycode[2], false);
120 #if defined(DEBUG_TOUCH_KEY)
121 printk("keycode[2](0x%04X) %s\n", ts->pdata->keycode[2], button_new.bits.bt2_press ? "press":"release");
122 #endif
123 }
124 if((button_old.bits.bt3_press != button_new.bits.bt3_press) && (ts->pdata->keycnt > 3)) {
125 if(button_new.bits.bt3_press) input_report_key(ts->input, ts->pdata->keycode[3], true);
126 else input_report_key(ts->input, ts->pdata->keycode[3], false);
127 #if defined(DEBUG_TOUCH_KEY)
128 printk("keycode[3](0x%04X) %s\n", ts->pdata->keycode[3], button_new.bits.bt3_press ? "press":"release");
129 #endif
130 }
131 if((button_old.bits.bt4_press != button_new.bits.bt4_press) && (ts->pdata->keycnt > 4)) {
132 if(button_new.bits.bt4_press) input_report_key(ts->input, ts->pdata->keycode[4], true);
133 else input_report_key(ts->input, ts->pdata->keycode[4], false);
134 #if defined(DEBUG_TOUCH_KEY)
135 printk("keycode[4](0x%04X) %s\n", ts->pdata->keycode[4], button_new.bits.bt4_press ? "press":"release");
136 #endif
137 }
138 if((button_old.bits.bt5_press != button_new.bits.bt5_press) && (ts->pdata->keycnt > 5)) {
139 if(button_new.bits.bt5_press) input_report_key(ts->input, ts->pdata->keycode[5], true);
140 else input_report_key(ts->input, ts->pdata->keycode[5], false);
141 #if defined(DEBUG_TOUCH_KEY)
142 printk("keycode[5](0x%04X) %s\n", ts->pdata->keycode[5], button_new.bits.bt5_press ? "press":"release");
143 #endif
144 }
145 if((button_old.bits.bt6_press != button_new.bits.bt6_press) && (ts->pdata->keycnt > 6)) {
146 if(button_new.bits.bt6_press) input_report_key(ts->input, ts->pdata->keycode[6], true);
147 else input_report_key(ts->input, ts->pdata->keycode[6], false);
148 #if defined(DEBUG_TOUCH_KEY)
149 printk("keycode[6](0x%04X) %s\n", ts->pdata->keycode[6], button_new.bits.bt6_press ? "press":"release");
150 #endif
151 }
152 if((button_old.bits.bt7_press != button_new.bits.bt7_press) && (ts->pdata->keycnt > 7)) {
153 if(button_new.bits.bt7_press) input_report_key(ts->input, ts->pdata->keycode[7], true);
154 else input_report_key(ts->input, ts->pdata->keycode[7], false);
155 #if defined(DEBUG_TOUCH_KEY)
156 printk("keycode[7](0x%04X) %s\n", ts->pdata->keycode[7], button_new.bits.bt7_press ? "press":"release");
157 #endif
158 }
159 button_old.ubyte = button_new.ubyte;
160 }
161}
162
163//[*]--------------------------------------------------------------------------------------------------[*]
164static void touch_report_single (struct touch *ts)
165{
166 if(ts->finger[0].event == TS_EVENT_UNKNOWN) return;
167
168 if(ts->finger[0].event != TS_EVENT_RELEASE) {
169 // for single touch
170 input_report_key(ts->input, BTN_TOUCH, 1);
171 input_report_abs(ts->input, ABS_X, ts->finger[0].x);
172 input_report_abs(ts->input, ABS_Y, ts->finger[0].y);
173
174#if defined(DEBUG_TOUCH)
175 printk("%s : id = %d, x = %d, y = %d\n", __func__, ts->finger[0].id, ts->finger[0].x, ts->finger[0].y);
176#endif
177 }
178 else {
179 // for single touch
180 input_report_key(ts->input, BTN_TOUCH, 0);
181
182 ts->finger[0].event = TS_EVENT_UNKNOWN;
183
184#if defined(DEBUG_TOUCH)
185 printk("%s : release id = %d\n", __func__, ts->finger[0].id);
186#endif
187 }
188 input_sync(ts->input);
189}
190
191//[*]--------------------------------------------------------------------------------------------------[*]
192static void touch_report_protocol_a (struct touch *ts)
193{
194 int id;
195
196 for(id = 0; id < ts->pdata->max_fingers; id++) {
197
198 if(ts->finger[id].event == TS_EVENT_UNKNOWN) continue;
199
200 if(ts->finger[id].event != TS_EVENT_RELEASE) {
201 if(ts->pdata->id_max) input_report_abs(ts->input, ABS_MT_TRACKING_ID, ts->finger[id].id);
202 if(ts->pdata->area_max) input_report_abs(ts->input, ABS_MT_TOUCH_MAJOR, ts->finger[id].area ? ts->finger[id].area : 10);
203 if(ts->pdata->press_max) input_report_abs(ts->input, ABS_MT_PRESSURE, ts->finger[id].pressure);
204
205 input_report_abs(ts->input, ABS_MT_POSITION_X, ts->finger[id].x);
206 input_report_abs(ts->input, ABS_MT_POSITION_Y, ts->finger[id].y);
207
208#if defined(DEBUG_TOUCH)
209 printk("%s : id = %d, x = %d, y = %d\n", __func__, ts->finger[id].id, ts->finger[id].x, ts->finger[id].y);
210#endif
211 }
212 else {
213 ts->finger[id].event = TS_EVENT_UNKNOWN;
214
215#if defined(DEBUG_TOUCH)
216 printk("%s : release id = %d\n", __func__, ts->finger[id].id);
217#endif
218 }
219
220 input_mt_sync(ts->input);
221 }
222
223 input_sync(ts->input);
224}
225
226//[*]--------------------------------------------------------------------------------------------------[*]
227static void touch_report_protocol_b (struct touch *ts)
228{
229 int id;
230
231 for(id = 0; id < ts->pdata->max_fingers; id++) {
232
233 if((ts->finger[id].event == TS_EVENT_UNKNOWN) || (ts->finger[id].status == false)) continue;
234
235 input_mt_slot(ts->input, id); ts->finger[id].status = false;
236
237 if(ts->finger[id].event != TS_EVENT_RELEASE) {
238 input_report_abs(ts->input, ABS_MT_TRACKING_ID, ts->finger[id].id);
239 input_report_abs(ts->input, ABS_MT_POSITION_X, ts->finger[id].x);
240 input_report_abs(ts->input, ABS_MT_POSITION_Y, ts->finger[id].y);
241
242 if(ts->pdata->area_max) input_report_abs(ts->input, ABS_MT_TOUCH_MAJOR, ts->finger[id].area ? ts->finger[id].area : 10);
243 if(ts->pdata->press_max) input_report_abs(ts->input, ABS_MT_PRESSURE, ts->finger[id].pressure);
244
245#if defined(DEBUG_TOUCH)
246 printk("%s : slot = %d, id = %d, x = %d, y = %d\n", __func__, id, ts->finger[id].id, ts->finger[id].x, ts->finger[id].y);
247#endif
248 }
249 else {
250 ts->finger[id].event = TS_EVENT_UNKNOWN;
251 input_report_abs(ts->input, ABS_MT_TRACKING_ID, -1);
252
253#if defined(DEBUG_TOUCH)
254 printk("%s : release slot = %d, id = %d\n", __func__, id, ts->finger[id].id);
255#endif
256 }
257 }
258 input_sync(ts->input);
259}
260
261//[*]--------------------------------------------------------------------------------------------------[*]
262static void touch_event_clear (struct touch *ts)
263{
264 unsigned char id;
265
266 for(id = 0; id < ts->pdata->max_fingers; id++) {
267 if(ts->finger[id].event == TS_EVENT_MOVE) {
268 ts->finger[id].status = true;
269 ts->finger[id].event = TS_EVENT_RELEASE;
270 }
271 }
272 ts->pdata->report(ts);
273 if(ts->pdata->keycode) ts->pdata->key_report(ts, 0x00);
274}
275
276//[*]--------------------------------------------------------------------------------------------------[*]
277static void touch_enable (struct touch *ts)
278{
279 if(ts->disabled) {
280 if(ts->irq) enable_irq(ts->irq);
281 ts->disabled = false;
282 }
283}
284
285//[*]--------------------------------------------------------------------------------------------------[*]
286static void touch_disable (struct touch *ts)
287{
288 if(!ts->disabled) {
289 if(ts->irq) disable_irq(ts->irq);
290 ts->disabled = true;
291 }
292}
293
294//[*]--------------------------------------------------------------------------------------------------[*]
295static int touch_input_open (struct input_dev *input)
296{
297 struct touch *ts = input_get_drvdata(input);
298
299 ts->pdata->enable(ts);
300
301 printk("%s\n", __func__);
302
303 return 0;
304}
305
306//[*]--------------------------------------------------------------------------------------------------[*]
307static void touch_input_close (struct input_dev *input)
308{
309 struct touch *ts = input_get_drvdata(input);
310
311 ts->pdata->disable(ts);
312
313 printk("%s\n", __func__);
314}
315
316//[*]--------------------------------------------------------------------------------------------------[*]
317static int touch_check_functionality (struct touch_pdata *pdata)
318{
319 if(!pdata) {
320 printk("Error : Platform data is NULL pointer!\n"); return -1;
321 }
322
323 if(!pdata->i2c_read) pdata->i2c_read = touch_i2c_read;
324 if(!pdata->i2c_write) pdata->i2c_write = touch_i2c_write;
325
326 if(!pdata->i2c_boot_read) pdata->i2c_boot_read = touch_i2c_read;
327 if(!pdata->i2c_boot_write) pdata->i2c_boot_write = touch_i2c_write;
328
329 if(!pdata->enable) pdata->enable = touch_enable;
330 if(!pdata->disable) pdata->disable = touch_disable;
331
332 if(!pdata->report) {
333 if(pdata->max_fingers == 1) pdata->report = touch_report_single;
334 else {
335 if(pdata->id_max) pdata->report = touch_report_protocol_b;
336 else pdata->report = touch_report_protocol_a;
337 }
338 }
339
340 if(!pdata->key_report) pdata->key_report = touch_key_report;
341
342 if(!pdata->touch_work) pdata->touch_work = touch_work;
343 if(!pdata->irq_func) pdata->irq_func = touch_irq;
344
345 if(!pdata->event_clear) pdata->event_clear = touch_event_clear;
346
347#ifdef CONFIG_HAS_EARLYSUSPEND
348 if(!pdata->resume) pdata->resume = touch_resume;
349 if(!pdata->suspend) pdata->suspend = touch_suspend;
350#endif
351
352 return 0;
353}
354
355//[*]--------------------------------------------------------------------------------------------------[*]
356void touch_hw_reset (struct touch *ts)
357{
358 if(ts->pdata->reset_gpio) {
359 if(gpio_request(ts->pdata->reset_gpio, "touch reset")) {
360 printk("--------------------------------------------------------\n");
361 printk("%s : request port error!\n", "touch reset");
362 printk("--------------------------------------------------------\n");
363 }
364 else {
365 gpio_direction_output(ts->pdata->reset_gpio, ts->pdata->reset_level ? 0 : 1);
366 mdelay(10);
367
368 gpio_direction_output(ts->pdata->reset_gpio, ts->pdata->reset_level ? 1 : 0);
369 mdelay(10);
370
371 gpio_direction_output(ts->pdata->reset_gpio, ts->pdata->reset_level ? 0 : 1);
372 mdelay(10);
373
374 gpio_free(ts->pdata->reset_gpio);
375 }
376 }
377}
378
379//[*]--------------------------------------------------------------------------------------------------[*]
380int touch_info_display (struct touch *ts)
381{
382 printk("--------------------------------------------------------\n");
383 printk(" TOUCH SCREEN INFORMATION\n");
384 printk("--------------------------------------------------------\n");
385 if(ts->pdata->irq_gpio && ts->pdata->max_fingers) {
386 printk("TOUCH INPUT Name = %s\n", ts->pdata->name);
387
388 switch(ts->pdata->irq_mode) {
389 default :
390 case IRQ_MODE_THREAD: printk("TOUCH IRQ Mode = %s\n", "IRQ_MODE_THREAD"); break;
391 case IRQ_MODE_NORMAL: printk("TOUCH IRQ Mode = %s\n", "IRQ_MODE_NORMAL"); break;
392 case IRQ_MODE_POLLING: printk("TOUCH IRQ Mode = %s\n", "IRQ_MODE_POLLING"); break;
393 }
394 printk("TOUCH F/W Version = %d.%02d\n", ts->fw_version / 100, ts->fw_version % 100);
395
396 printk("TOUCH FINGRES MAX = %d\n", ts->pdata->max_fingers);
397 printk("TOUCH ABS X MAX = %d, TOUCH ABS X MIN = %d\n", ts->pdata->abs_max_x, ts->pdata->abs_min_x);
398 printk("TOUCH ABS Y MAX = %d, TOUCH ABS Y MIN = %d\n", ts->pdata->abs_max_y, ts->pdata->abs_min_y);
399
400 if(ts->pdata->area_max)
401 printk("TOUCH MAJOR MAX = %d, TOUCH MAJOR MIN = %d\n", ts->pdata->area_max, ts->pdata->area_min);
402
403 if(ts->pdata->press_max)
404 printk("TOUCH PRESS MAX = %d, TOUCH PRESS MIN = %d\n", ts->pdata->press_max, ts->pdata->press_min);
405
406 if(ts->pdata->max_fingers == 1) {
407 printk("Single Touch Protocol Used.\n");
408 }
409 else {
410 if(ts->pdata->id_max) {
411 printk("TOUCH ID MAX = %d, TOUCH ID MIN = %d\n", ts->pdata->id_max, ts->pdata->id_min);
412 printk("Mulit-Touch Protocol-B Used.\n");
413 }
414 else
415 printk("Mulit-Touch Protocol-A Used.\n");
416 }
417
418 if(ts->pdata->gpio_init)
419 printk("GPIO early-init function implemented\n");
420
421 if(ts->pdata->reset_gpio)
422 printk("H/W Reset function implemented\n");
423
424 #ifdef CONFIG_HAS_EARLYSUSPEND
425 printk("Early-suspend function implemented\n");
426 #endif
427 if(ts->pdata->fw_control)
428 printk("Firmware update function(sysfs control) implemented\n");
429
430 if(ts->pdata->flash_firmware)
431 printk("Firmware update function(udev control) implemented\n");
432
433 if(ts->pdata->calibration)
434 printk("Calibration function implemented\n");
435 }
436 else {
437 printk("TOUCH INPUT Name = %s\n", ts->pdata->name);
438 printk("Dummy Touchscreen driver!\n");
439 }
440
441 printk("--------------------------------------------------------\n");
442
443 return 0;
444}
445
446//[*]--------------------------------------------------------------------------------------------------[*]
447int touch_probe (struct i2c_client *client)
448{
449 int rc = -1;
450 struct device *dev = &client->dev;
451 struct touch *ts;
452
453 if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA)) {
454 dev_err(&client->dev, "i2c byte data not supported\n");
455 return -EIO;
456 }
457
458 if (touch_check_functionality(client->dev.platform_data) < 0) {
459 dev_err(&client->dev, "Platform data is not available!\n");
460 return -EINVAL;
461 }
462
463 if(!(ts = kzalloc(sizeof(struct touch), GFP_KERNEL))) {
464 printk("touch struct malloc error!\n"); return -ENOMEM;
465 }
466 ts->client = client;
467 ts->pdata = client->dev.platform_data;
468
469 if(ts->pdata->irq_gpio) ts->irq = gpio_to_irq(ts->pdata->irq_gpio);
470
471 i2c_set_clientdata(client, ts);
472
473 if(ts->pdata->max_fingers) {
474 if(!(ts->finger = kzalloc(sizeof(finger_t) * ts->pdata->max_fingers, GFP_KERNEL))) {
475 kfree(ts);
476 printk("touch data struct malloc error!\n"); return -ENOMEM;
477 }
478 }
479
480 if(ts->pdata->gpio_init) ts->pdata->gpio_init();
481 if(ts->pdata->reset_gpio) touch_hw_reset(ts);
482
483 if(ts->pdata->early_probe) {
484 if((rc = ts->pdata->early_probe(ts)) < 0) goto err_free_mem;
485 }
486
487 dev_set_drvdata(dev, ts);
488
489 if(!(ts->input = input_allocate_device())) goto err_free_mem;
490
491 snprintf(ts->phys, sizeof(ts->phys), "%s/input0", ts->pdata->name);
492
493 if(!ts->pdata->input_open) ts->input->open = touch_input_open;
494 else ts->input->open = ts->pdata->input_open;
495 if(!ts->pdata->input_close) ts->input->close = touch_input_close;
496 else ts->input->close = ts->pdata->input_close;
497
498 ts->input->name = ts->pdata->name;
499 ts->input->phys = ts->phys;
500 ts->input->dev.parent = dev;
501 ts->input->id.bustype = BUS_I2C;
502
503 ts->input->id.vendor = ts->pdata->vendor;
504 ts->input->id.product = ts->pdata->product;
505 ts->input->id.version = ts->pdata->version;
506
507 set_bit(EV_SYN, ts->input->evbit);
508 set_bit(EV_ABS, ts->input->evbit);
509
510 // Touch Key Event
511 if(ts->pdata->keycode) {
512 int key;
513
514 set_bit(EV_KEY, ts->input->evbit);
515
516 for(key = 0; key < ts->pdata->keycnt; key++) {
517 if(ts->pdata->keycode[key] <= 0) continue;
518 set_bit(ts->pdata->keycode[key] & KEY_MAX, ts->input->keybit);
519 }
520 }
521
522 input_set_drvdata(ts->input, ts);
523
524 if(ts->pdata->max_fingers == 1) {
525 /* For single touch */
526 set_bit(EV_KEY, ts->input->evbit); set_bit(BTN_TOUCH, ts->input->keybit);
527 input_set_abs_params(ts->input, ABS_X, ts->pdata->abs_min_x, ts->pdata->abs_max_x, 0, 0);
528 input_set_abs_params(ts->input, ABS_Y, ts->pdata->abs_min_y, ts->pdata->abs_max_y, 0, 0);
529 }
530 else {
531 /* multi touch */
532 input_set_abs_params(ts->input, ABS_MT_POSITION_X, ts->pdata->abs_min_x, ts->pdata->abs_max_x, 0, 0);
533 input_set_abs_params(ts->input, ABS_MT_POSITION_Y, ts->pdata->abs_min_y, ts->pdata->abs_max_y, 0, 0);
534
535 if(ts->pdata->area_max)
536 input_set_abs_params(ts->input, ABS_MT_TOUCH_MAJOR, ts->pdata->area_min, ts->pdata->area_max, 0, 0);
537
538 if(ts->pdata->press_max)
539 input_set_abs_params(ts->input, ABS_MT_PRESSURE, ts->pdata->press_min, ts->pdata->press_max, 0, 0);
540 }
541
542 if(ts->pdata->id_max) {
543 input_set_abs_params(ts->input, ABS_MT_TRACKING_ID, ts->pdata->id_min, ts->pdata->id_max, 0, 0);
544 input_mt_init_slots(ts->input, ts->pdata->max_fingers);
545 }
546
547 if ((rc = input_register_device(ts->input))) {
548 dev_err(dev, "(%s) input register fail!\n", ts->input->name);
549 goto err_free_input_mem;
550 }
551
552 if(ts->irq) {
553
554 switch(ts->pdata->irq_mode) {
555 default :
556 case IRQ_MODE_THREAD:
557 if((rc = request_threaded_irq(ts->irq, NULL, ts->pdata->irq_func, ts->pdata->irq_flags, ts->pdata->name, ts))) {
558 dev_err(dev, "irq %d request fail!\n", ts->irq);
559 goto err_free_input_mem;
560 }
561 break;
562 case IRQ_MODE_NORMAL:
563 INIT_WORK(&ts->work, touch_work_q);
564 if((ts->work_queue = create_singlethread_workqueue("work_queue")) == NULL) goto err_free_input_mem;
565
566 if((rc = request_irq(ts->irq, ts->pdata->irq_func, ts->pdata->irq_flags, ts->pdata->name, ts))) {
567 printk("irq %d request fail!\n", ts->irq);
568 goto err_free_input_mem;
569 }
570 break;
571 case IRQ_MODE_POLLING:
572 printk("Error IRQ_MODE POLLING!! but defined irq_gpio\n");
573 break;
574 }
575
576 disable_irq_nosync(ts->irq);
577 }
578
579 ts->disabled = true;
580
581#if defined(CONFIG_HAS_EARLYSUSPEND)
582 if(ts->pdata->suspend) ts->power.suspend = ts->pdata->suspend;
583 if(ts->pdata->resume) ts->power.resume = ts->pdata->resume;
584
585 ts->power.level = EARLY_SUSPEND_LEVEL_DISABLE_FB-1;
586
587 //if, is in USER_SLEEP status and no active auto expiring wake lock
588 //if (has_wake_lock(WAKE_LOCK_SUSPEND) == 0 && get_suspend_state() == PM_SUSPEND_ON)
589 register_early_suspend(&ts->power);
590#endif
591
592 if((rc = touch_sysfs_create(dev)) < 0) goto err_free_irq;
593
594 if(ts->pdata->probe) {
595 if((rc = ts->pdata->probe(ts)) < 0) goto err_free_all;
596 }
597
598 touch_info_display(ts);
599
600 return 0;
601
602err_free_all:
603 touch_sysfs_remove(dev);
604err_free_irq:
605 free_irq(ts->irq, ts);
606 input_unregister_device(ts->input);
607err_free_input_mem:
608 input_free_device(ts->input);
609 ts->input = NULL;
610err_free_mem:
611 kfree(ts->finger); ts->finger = NULL;
612 kfree(ts); ts = NULL;
613 return rc;
614}
615
616//[*]--------------------------------------------------------------------------------------------------[*]
617//
618// Power Management function
619//
620//[*]--------------------------------------------------------------------------------------------------[*]
621//[*]--------------------------------------------------------------------------------------------------[*]
622#ifdef CONFIG_HAS_EARLYSUSPEND
623//[*]--------------------------------------------------------------------------------------------------[*]
624static void touch_suspend (struct early_suspend *h)
625{
626 struct touch *ts = container_of(h, struct touch, power);
627
628 printk("%s\n", __func__);
629
630 ts->pdata->disable(ts);
631}
632
633//[*]--------------------------------------------------------------------------------------------------[*]
634static void touch_resume (struct early_suspend *h)
635{
636 struct touch *ts = container_of(h, struct touch, power);
637
638 printk("%s\n", __func__);
639
640 ts->pdata->enable(ts);
641}
642
643//[*]--------------------------------------------------------------------------------------------------[*]
644#endif
645//[*]--------------------------------------------------------------------------------------------------[*]
646//[*]--------------------------------------------------------------------------------------------------[*]
647int touch_remove (struct device *dev)
648{
649 struct touch *ts = dev_get_drvdata(dev);
650
651 if(ts->irq) free_irq(ts->irq, ts);
652
653 if(ts->pdata->reset_gpio) gpio_free(ts->pdata->reset_gpio);
654
655 touch_sysfs_remove(dev);
656
657 input_unregister_device(ts->input);
658
659 dev_set_drvdata(dev, NULL);
660
661 kfree(ts);
662
663 return 0;
664}
665
666//[*]--------------------------------------------------------------------------------------------------[*]
667MODULE_AUTHOR("HardKernel Co., Ltd.");
668MODULE_LICENSE("GPL");
669MODULE_DESCRIPTION("Touchscreen Driver");
670
671//[*]--------------------------------------------------------------------------------------------------[*]
672//[*]--------------------------------------------------------------------------------------------------[*]
diff --git a/drivers/input/touchscreen/touch.h b/drivers/input/touchscreen/touch.h
new file mode 100644
index 00000000000..691d6098ab9
--- /dev/null
+++ b/drivers/input/touchscreen/touch.h
@@ -0,0 +1,25 @@
1//[*]--------------------------------------------------------------------------------------------------[*]
2//
3//
4//
5// I2C Touchscreen driver
6// 2012.01.17
7//
8//
9//[*]--------------------------------------------------------------------------------------------------[*]
10#ifndef _TOUCH_H_
11#define _TOUCH_H_
12
13//[*]--------------------------------------------------------------------------------------------------[*]
14// extern function define
15//[*]--------------------------------------------------------------------------------------------------[*]
16extern void touch_hw_reset (struct touch *ts);
17extern int touch_info_display (struct touch *ts);
18extern int touch_probe (struct i2c_client *client);
19extern int touch_remove (struct device *dev);
20
21//[*]--------------------------------------------------------------------------------------------------[*]
22#endif /* _TOUCH_H_ */
23
24//[*]--------------------------------------------------------------------------------------------------[*]
25//[*]--------------------------------------------------------------------------------------------------[*]