aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/input/touchscreen/synaptics_i2c_rmi.c
diff options
context:
space:
mode:
authorJonathan Herman <hermanjl@cs.unc.edu>2013-01-22 10:38:37 -0500
committerJonathan Herman <hermanjl@cs.unc.edu>2013-01-22 10:38:37 -0500
commitfcc9d2e5a6c89d22b8b773a64fb4ad21ac318446 (patch)
treea57612d1888735a2ec7972891b68c1ac5ec8faea /drivers/input/touchscreen/synaptics_i2c_rmi.c
parent8dea78da5cee153b8af9c07a2745f6c55057fe12 (diff)
Added missing tegra files.HEADmaster
Diffstat (limited to 'drivers/input/touchscreen/synaptics_i2c_rmi.c')
-rw-r--r--drivers/input/touchscreen/synaptics_i2c_rmi.c699
1 files changed, 699 insertions, 0 deletions
diff --git a/drivers/input/touchscreen/synaptics_i2c_rmi.c b/drivers/input/touchscreen/synaptics_i2c_rmi.c
new file mode 100644
index 00000000000..6f9b83af035
--- /dev/null
+++ b/drivers/input/touchscreen/synaptics_i2c_rmi.c
@@ -0,0 +1,699 @@
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
28#define ABS_DIFF(a, b) (((a) > (b)) ? ((a) - (b)) : ((b) - (a)))
29
30static struct workqueue_struct *synaptics_wq;
31
32struct synaptics_ts_data {
33 uint16_t addr;
34 struct i2c_client *client;
35 struct input_dev *input_dev;
36 int use_irq;
37 bool has_relative_report;
38 struct hrtimer timer;
39 struct work_struct work;
40 uint16_t max[2];
41 int snap_state[2][2];
42 int snap_down_on[2];
43 int snap_down_off[2];
44 int snap_up_on[2];
45 int snap_up_off[2];
46 int snap_down[2];
47 int snap_up[2];
48 uint32_t flags;
49 int reported_finger_count;
50 int last_pos[2][2];
51 int8_t sensitivity_adjust;
52 int (*power)(int on);
53 struct early_suspend early_suspend;
54};
55
56#ifdef CONFIG_HAS_EARLYSUSPEND
57static void synaptics_ts_early_suspend(struct early_suspend *h);
58static void synaptics_ts_late_resume(struct early_suspend *h);
59#endif
60
61static int synaptics_init_panel(struct synaptics_ts_data *ts)
62{
63 int ret;
64
65 ret = i2c_smbus_write_byte_data(ts->client, 0xff, 0x10); /* page select = 0x10 */
66 if (ret < 0) {
67 printk(KERN_ERR "i2c_smbus_write_byte_data failed for page select\n");
68 goto err_page_select_failed;
69 }
70 ret = i2c_smbus_write_byte_data(ts->client, 0x41, 0x04); /* Set "No Clip Z" */
71 if (ret < 0)
72 printk(KERN_ERR "i2c_smbus_write_byte_data failed for No Clip Z\n");
73
74 ret = i2c_smbus_write_byte_data(ts->client, 0x44,
75 ts->sensitivity_adjust);
76 if (ret < 0)
77 pr_err("synaptics_ts: failed to set Sensitivity Adjust\n");
78
79err_page_select_failed:
80 ret = i2c_smbus_write_byte_data(ts->client, 0xff, 0x04); /* page select = 0x04 */
81 if (ret < 0)
82 printk(KERN_ERR "i2c_smbus_write_byte_data failed for page select\n");
83 ret = i2c_smbus_write_byte_data(ts->client, 0xf0, 0x81); /* normal operation, 80 reports per second */
84 if (ret < 0)
85 printk(KERN_ERR "synaptics_ts_resume: i2c_smbus_write_byte_data failed\n");
86 return ret;
87}
88
89static void synaptics_ts_work_func(struct work_struct *work)
90{
91 int i;
92 int ret;
93 int bad_data = 0;
94 struct i2c_msg msg[2];
95 uint8_t start_reg;
96 uint8_t buf[15];
97 struct synaptics_ts_data *ts = container_of(work, struct synaptics_ts_data, work);
98 int buf_len = ts->has_relative_report ? 15 : 13;
99
100 msg[0].addr = ts->client->addr;
101 msg[0].flags = 0;
102 msg[0].len = 1;
103 msg[0].buf = &start_reg;
104 start_reg = 0x00;
105 msg[1].addr = ts->client->addr;
106 msg[1].flags = I2C_M_RD;
107 msg[1].len = buf_len;
108 msg[1].buf = buf;
109
110 /* printk("synaptics_ts_work_func\n"); */
111 for (i = 0; i < ((ts->use_irq && !bad_data) ? 1 : 10); i++) {
112 ret = i2c_transfer(ts->client->adapter, msg, 2);
113 if (ret < 0) {
114 printk(KERN_ERR "synaptics_ts_work_func: i2c_transfer failed\n");
115 bad_data = 1;
116 } else {
117 /* printk("synaptics_ts_work_func: %x %x %x %x %x %x" */
118 /* " %x %x %x %x %x %x %x %x %x, ret %d\n", */
119 /* buf[0], buf[1], buf[2], buf[3], */
120 /* buf[4], buf[5], buf[6], buf[7], */
121 /* buf[8], buf[9], buf[10], buf[11], */
122 /* buf[12], buf[13], buf[14], ret); */
123 if ((buf[buf_len - 1] & 0xc0) != 0x40) {
124 printk(KERN_WARNING "synaptics_ts_work_func:"
125 " bad read %x %x %x %x %x %x %x %x %x"
126 " %x %x %x %x %x %x, ret %d\n",
127 buf[0], buf[1], buf[2], buf[3],
128 buf[4], buf[5], buf[6], buf[7],
129 buf[8], buf[9], buf[10], buf[11],
130 buf[12], buf[13], buf[14], ret);
131 if (bad_data)
132 synaptics_init_panel(ts);
133 bad_data = 1;
134 continue;
135 }
136 bad_data = 0;
137 if ((buf[buf_len - 1] & 1) == 0) {
138 /* printk("read %d coordinates\n", i); */
139 break;
140 } else {
141 int pos[2][2];
142 int rmpos_x, rmpos_y;
143 int f, a;
144 int base;
145 /* int x = buf[3] | (uint16_t)(buf[2] & 0x1f) << 8; */
146 /* int y = buf[5] | (uint16_t)(buf[4] & 0x1f) << 8; */
147 int z = buf[1];
148 int w = buf[0] >> 4;
149 int finger = buf[0] & 7;
150
151 /* int x2 = buf[3+6] | (uint16_t)(buf[2+6] & 0x1f) << 8; */
152 /* int y2 = buf[5+6] | (uint16_t)(buf[4+6] & 0x1f) << 8; */
153 /* int z2 = buf[1+6]; */
154 /* int w2 = buf[0+6] >> 4; */
155 /* int finger2 = buf[0+6] & 7; */
156
157 /* int dx = (int8_t)buf[12]; */
158 /* int dy = (int8_t)buf[13]; */
159 int finger2_pressed;
160
161 /* 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", */
162 /* x, y, z, w, finger, */
163 /* x2, y2, z2, w2, finger2, */
164 /* dx, dy); */
165
166 base = 2;
167 for (f = 0; f < 2; f++) {
168 uint32_t flip_flag = SYNAPTICS_FLIP_X;
169 for (a = 0; a < 2; a++) {
170 int p = buf[base + 1];
171 p |= (uint16_t)(buf[base] & 0x1f) << 8;
172 if (ts->flags & flip_flag)
173 p = ts->max[a] - p;
174 if (ts->flags & SYNAPTICS_SNAP_TO_INACTIVE_EDGE) {
175 if (ts->snap_state[f][a]) {
176 if (p <= ts->snap_down_off[a])
177 p = ts->snap_down[a];
178 else if (p >= ts->snap_up_off[a])
179 p = ts->snap_up[a];
180 else
181 ts->snap_state[f][a] = 0;
182 } else {
183 if (p <= ts->snap_down_on[a]) {
184 p = ts->snap_down[a];
185 ts->snap_state[f][a] = 1;
186 } else if (p >= ts->snap_up_on[a]) {
187 p = ts->snap_up[a];
188 ts->snap_state[f][a] = 1;
189 }
190 }
191 }
192 pos[f][a] = p;
193 base += 2;
194 flip_flag <<= 1;
195 }
196 base += 2;
197 if (ts->flags & SYNAPTICS_SWAP_XY)
198 swap(pos[f][0], pos[f][1]);
199 }
200
201 if (!finger) {
202 z = 0;
203 if (ts->reported_finger_count > 0) {
204 pos[0][0] = ts->last_pos[0][0];
205 pos[0][1] = ts->last_pos[0][1];
206 }
207 else
208 continue; /* skip touch noise */
209 }
210 finger = (finger == 7) ? 1 : finger; /* correct wrong finger count */
211 finger2_pressed = finger > 1;
212
213 input_report_abs(ts->input_dev, ABS_MT_TOUCH_MAJOR, z);
214 input_report_abs(ts->input_dev, ABS_MT_WIDTH_MAJOR, w);
215 input_report_abs(ts->input_dev, ABS_MT_POSITION_X, pos[0][0]);
216 input_report_abs(ts->input_dev, ABS_MT_POSITION_Y, pos[0][1]);
217 input_mt_sync(ts->input_dev);
218 if (finger2_pressed) {
219 input_report_abs(ts->input_dev, ABS_MT_TOUCH_MAJOR, z);
220 input_report_abs(ts->input_dev, ABS_MT_WIDTH_MAJOR, w);
221 input_report_abs(ts->input_dev, ABS_MT_POSITION_X, pos[1][0]);
222 input_report_abs(ts->input_dev, ABS_MT_POSITION_Y, pos[1][1]);
223 input_mt_sync(ts->input_dev);
224 ts->last_pos[1][0] = pos[1][0];
225 ts->last_pos[1][1] = pos[1][1];
226 } else if (ts->reported_finger_count > 1) {
227 /* check which point was removed */
228 if ((ABS_DIFF(pos[0][0],ts->last_pos[0][0]) +
229 ABS_DIFF(pos[0][1],ts->last_pos[0][1])) <
230 (ABS_DIFF(pos[0][0],ts->last_pos[1][0]) +
231 ABS_DIFF(pos[0][1],ts->last_pos[1][1]))) {
232 rmpos_x = ts->last_pos[1][0];
233 rmpos_y = ts->last_pos[1][1];
234 }
235 else {
236 rmpos_x = ts->last_pos[0][0];
237 rmpos_y = ts->last_pos[0][1];
238 }
239 input_report_abs(ts->input_dev, ABS_MT_TOUCH_MAJOR, 0);
240 input_report_abs(ts->input_dev, ABS_MT_WIDTH_MAJOR, 0);
241 input_report_abs(ts->input_dev, ABS_MT_POSITION_X, rmpos_x);
242 input_report_abs(ts->input_dev, ABS_MT_POSITION_Y, rmpos_y);
243 input_mt_sync(ts->input_dev);
244 }
245
246 if (z) {
247 input_report_abs(ts->input_dev, ABS_X, pos[0][0]);
248 input_report_abs(ts->input_dev, ABS_Y, pos[0][1]);
249 ts->last_pos[0][0] = pos[0][0];
250 ts->last_pos[0][1] = pos[0][1];
251 }
252 input_report_abs(ts->input_dev, ABS_PRESSURE, z);
253 input_report_abs(ts->input_dev, ABS_TOOL_WIDTH, w);
254 input_report_key(ts->input_dev, BTN_TOUCH, finger);
255 ts->reported_finger_count = finger;
256 input_sync(ts->input_dev);
257 }
258 }
259 }
260 if (ts->use_irq)
261 enable_irq(ts->client->irq);
262}
263
264static enum hrtimer_restart synaptics_ts_timer_func(struct hrtimer *timer)
265{
266 struct synaptics_ts_data *ts = container_of(timer, struct synaptics_ts_data, timer);
267 /* printk("synaptics_ts_timer_func\n"); */
268
269 queue_work(synaptics_wq, &ts->work);
270
271 hrtimer_start(&ts->timer, ktime_set(0, 12500000), HRTIMER_MODE_REL);
272 return HRTIMER_NORESTART;
273}
274
275static irqreturn_t synaptics_ts_irq_handler(int irq, void *dev_id)
276{
277 struct synaptics_ts_data *ts = dev_id;
278
279 /* printk("synaptics_ts_irq_handler\n"); */
280 disable_irq_nosync(ts->client->irq);
281 queue_work(synaptics_wq, &ts->work);
282 return IRQ_HANDLED;
283}
284
285static int synaptics_ts_probe(
286 struct i2c_client *client, const struct i2c_device_id *id)
287{
288 struct synaptics_ts_data *ts;
289 uint8_t buf0[4];
290 uint8_t buf1[8];
291 struct i2c_msg msg[2];
292 int ret = 0;
293 uint16_t max_x, max_y;
294 int fuzz_x, fuzz_y, fuzz_p, fuzz_w;
295 struct synaptics_i2c_rmi_platform_data *pdata;
296 unsigned long irqflags;
297 int inactive_area_left;
298 int inactive_area_right;
299 int inactive_area_top;
300 int inactive_area_bottom;
301 int snap_left_on;
302 int snap_left_off;
303 int snap_right_on;
304 int snap_right_off;
305 int snap_top_on;
306 int snap_top_off;
307 int snap_bottom_on;
308 int snap_bottom_off;
309 uint32_t panel_version;
310
311 if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
312 printk(KERN_ERR "synaptics_ts_probe: need I2C_FUNC_I2C\n");
313 ret = -ENODEV;
314 goto err_check_functionality_failed;
315 }
316
317 ts = kzalloc(sizeof(*ts), GFP_KERNEL);
318 if (ts == NULL) {
319 ret = -ENOMEM;
320 goto err_alloc_data_failed;
321 }
322 INIT_WORK(&ts->work, synaptics_ts_work_func);
323 ts->client = client;
324 i2c_set_clientdata(client, ts);
325 pdata = client->dev.platform_data;
326 if (pdata)
327 ts->power = pdata->power;
328 if (ts->power) {
329 ret = ts->power(1);
330 if (ret < 0) {
331 printk(KERN_ERR "synaptics_ts_probe power on failed\n");
332 goto err_power_failed;
333 }
334 }
335
336 ret = i2c_smbus_write_byte_data(ts->client, 0xf4, 0x01); /* device command = reset */
337 if (ret < 0) {
338 printk(KERN_ERR "i2c_smbus_write_byte_data failed\n");
339 /* fail? */
340 }
341 {
342 int retry = 10;
343 while (retry-- > 0) {
344 ret = i2c_smbus_read_byte_data(ts->client, 0xe4);
345 if (ret >= 0)
346 break;
347 msleep(100);
348 }
349 }
350 if (ret < 0) {
351 printk(KERN_ERR "i2c_smbus_read_byte_data failed\n");
352 goto err_detect_failed;
353 }
354 printk(KERN_INFO "synaptics_ts_probe: Product Major Version %x\n", ret);
355 panel_version = ret << 8;
356 ret = i2c_smbus_read_byte_data(ts->client, 0xe5);
357 if (ret < 0) {
358 printk(KERN_ERR "i2c_smbus_read_byte_data failed\n");
359 goto err_detect_failed;
360 }
361 printk(KERN_INFO "synaptics_ts_probe: Product Minor Version %x\n", ret);
362 panel_version |= ret;
363
364 ret = i2c_smbus_read_byte_data(ts->client, 0xe3);
365 if (ret < 0) {
366 printk(KERN_ERR "i2c_smbus_read_byte_data failed\n");
367 goto err_detect_failed;
368 }
369 printk(KERN_INFO "synaptics_ts_probe: product property %x\n", ret);
370
371 if (pdata) {
372 while (pdata->version > panel_version)
373 pdata++;
374 ts->flags = pdata->flags;
375 ts->sensitivity_adjust = pdata->sensitivity_adjust;
376 irqflags = pdata->irqflags;
377 inactive_area_left = pdata->inactive_left;
378 inactive_area_right = pdata->inactive_right;
379 inactive_area_top = pdata->inactive_top;
380 inactive_area_bottom = pdata->inactive_bottom;
381 snap_left_on = pdata->snap_left_on;
382 snap_left_off = pdata->snap_left_off;
383 snap_right_on = pdata->snap_right_on;
384 snap_right_off = pdata->snap_right_off;
385 snap_top_on = pdata->snap_top_on;
386 snap_top_off = pdata->snap_top_off;
387 snap_bottom_on = pdata->snap_bottom_on;
388 snap_bottom_off = pdata->snap_bottom_off;
389 fuzz_x = pdata->fuzz_x;
390 fuzz_y = pdata->fuzz_y;
391 fuzz_p = pdata->fuzz_p;
392 fuzz_w = pdata->fuzz_w;
393 } else {
394 irqflags = 0;
395 inactive_area_left = 0;
396 inactive_area_right = 0;
397 inactive_area_top = 0;
398 inactive_area_bottom = 0;
399 snap_left_on = 0;
400 snap_left_off = 0;
401 snap_right_on = 0;
402 snap_right_off = 0;
403 snap_top_on = 0;
404 snap_top_off = 0;
405 snap_bottom_on = 0;
406 snap_bottom_off = 0;
407 fuzz_x = 0;
408 fuzz_y = 0;
409 fuzz_p = 0;
410 fuzz_w = 0;
411 }
412
413 ret = i2c_smbus_read_byte_data(ts->client, 0xf0);
414 if (ret < 0) {
415 printk(KERN_ERR "i2c_smbus_read_byte_data failed\n");
416 goto err_detect_failed;
417 }
418 printk(KERN_INFO "synaptics_ts_probe: device control %x\n", ret);
419
420 ret = i2c_smbus_read_byte_data(ts->client, 0xf1);
421 if (ret < 0) {
422 printk(KERN_ERR "i2c_smbus_read_byte_data failed\n");
423 goto err_detect_failed;
424 }
425 printk(KERN_INFO "synaptics_ts_probe: interrupt enable %x\n", ret);
426
427 ret = i2c_smbus_write_byte_data(ts->client, 0xf1, 0); /* disable interrupt */
428 if (ret < 0) {
429 printk(KERN_ERR "i2c_smbus_write_byte_data failed\n");
430 goto err_detect_failed;
431 }
432
433 msg[0].addr = ts->client->addr;
434 msg[0].flags = 0;
435 msg[0].len = 1;
436 msg[0].buf = buf0;
437 buf0[0] = 0xe0;
438 msg[1].addr = ts->client->addr;
439 msg[1].flags = I2C_M_RD;
440 msg[1].len = 8;
441 msg[1].buf = buf1;
442 ret = i2c_transfer(ts->client->adapter, msg, 2);
443 if (ret < 0) {
444 printk(KERN_ERR "i2c_transfer failed\n");
445 goto err_detect_failed;
446 }
447 printk(KERN_INFO "synaptics_ts_probe: 0xe0: %x %x %x %x %x %x %x %x\n",
448 buf1[0], buf1[1], buf1[2], buf1[3],
449 buf1[4], buf1[5], buf1[6], buf1[7]);
450
451 ret = i2c_smbus_write_byte_data(ts->client, 0xff, 0x10); /* page select = 0x10 */
452 if (ret < 0) {
453 printk(KERN_ERR "i2c_smbus_write_byte_data failed for page select\n");
454 goto err_detect_failed;
455 }
456 ret = i2c_smbus_read_word_data(ts->client, 0x02);
457 if (ret < 0) {
458 printk(KERN_ERR "i2c_smbus_read_word_data failed\n");
459 goto err_detect_failed;
460 }
461 ts->has_relative_report = !(ret & 0x100);
462 printk(KERN_INFO "synaptics_ts_probe: Sensor properties %x\n", ret);
463 ret = i2c_smbus_read_word_data(ts->client, 0x04);
464 if (ret < 0) {
465 printk(KERN_ERR "i2c_smbus_read_word_data failed\n");
466 goto err_detect_failed;
467 }
468 ts->max[0] = max_x = (ret >> 8 & 0xff) | ((ret & 0x1f) << 8);
469 ret = i2c_smbus_read_word_data(ts->client, 0x06);
470 if (ret < 0) {
471 printk(KERN_ERR "i2c_smbus_read_word_data failed\n");
472 goto err_detect_failed;
473 }
474 ts->max[1] = max_y = (ret >> 8 & 0xff) | ((ret & 0x1f) << 8);
475 if (ts->flags & SYNAPTICS_SWAP_XY)
476 swap(max_x, max_y);
477
478 ret = synaptics_init_panel(ts); /* will also switch back to page 0x04 */
479 if (ret < 0) {
480 printk(KERN_ERR "synaptics_init_panel failed\n");
481 goto err_detect_failed;
482 }
483
484 ts->input_dev = input_allocate_device();
485 if (ts->input_dev == NULL) {
486 ret = -ENOMEM;
487 printk(KERN_ERR "synaptics_ts_probe: Failed to allocate input device\n");
488 goto err_input_dev_alloc_failed;
489 }
490 ts->input_dev->name = "synaptics-rmi-touchscreen";
491 set_bit(EV_SYN, ts->input_dev->evbit);
492 set_bit(EV_KEY, ts->input_dev->evbit);
493 set_bit(BTN_TOUCH, ts->input_dev->keybit);
494 set_bit(EV_ABS, ts->input_dev->evbit);
495 inactive_area_left = inactive_area_left * max_x / 0x10000;
496 inactive_area_right = inactive_area_right * max_x / 0x10000;
497 inactive_area_top = inactive_area_top * max_y / 0x10000;
498 inactive_area_bottom = inactive_area_bottom * max_y / 0x10000;
499 snap_left_on = snap_left_on * max_x / 0x10000;
500 snap_left_off = snap_left_off * max_x / 0x10000;
501 snap_right_on = snap_right_on * max_x / 0x10000;
502 snap_right_off = snap_right_off * max_x / 0x10000;
503 snap_top_on = snap_top_on * max_y / 0x10000;
504 snap_top_off = snap_top_off * max_y / 0x10000;
505 snap_bottom_on = snap_bottom_on * max_y / 0x10000;
506 snap_bottom_off = snap_bottom_off * max_y / 0x10000;
507 fuzz_x = fuzz_x * max_x / 0x10000;
508 fuzz_y = fuzz_y * max_y / 0x10000;
509 ts->snap_down[!!(ts->flags & SYNAPTICS_SWAP_XY)] = -inactive_area_left;
510 ts->snap_up[!!(ts->flags & SYNAPTICS_SWAP_XY)] = max_x + inactive_area_right;
511 ts->snap_down[!(ts->flags & SYNAPTICS_SWAP_XY)] = -inactive_area_top;
512 ts->snap_up[!(ts->flags & SYNAPTICS_SWAP_XY)] = max_y + inactive_area_bottom;
513 ts->snap_down_on[!!(ts->flags & SYNAPTICS_SWAP_XY)] = snap_left_on;
514 ts->snap_down_off[!!(ts->flags & SYNAPTICS_SWAP_XY)] = snap_left_off;
515 ts->snap_up_on[!!(ts->flags & SYNAPTICS_SWAP_XY)] = max_x - snap_right_on;
516 ts->snap_up_off[!!(ts->flags & SYNAPTICS_SWAP_XY)] = max_x - snap_right_off;
517 ts->snap_down_on[!(ts->flags & SYNAPTICS_SWAP_XY)] = snap_top_on;
518 ts->snap_down_off[!(ts->flags & SYNAPTICS_SWAP_XY)] = snap_top_off;
519 ts->snap_up_on[!(ts->flags & SYNAPTICS_SWAP_XY)] = max_y - snap_bottom_on;
520 ts->snap_up_off[!(ts->flags & SYNAPTICS_SWAP_XY)] = max_y - snap_bottom_off;
521 printk(KERN_INFO "synaptics_ts_probe: max_x %d, max_y %d\n", max_x, max_y);
522 printk(KERN_INFO "synaptics_ts_probe: inactive_x %d %d, inactive_y %d %d\n",
523 inactive_area_left, inactive_area_right,
524 inactive_area_top, inactive_area_bottom);
525 printk(KERN_INFO "synaptics_ts_probe: snap_x %d-%d %d-%d, snap_y %d-%d %d-%d\n",
526 snap_left_on, snap_left_off, snap_right_on, snap_right_off,
527 snap_top_on, snap_top_off, snap_bottom_on, snap_bottom_off);
528 input_set_abs_params(ts->input_dev, ABS_X, -inactive_area_left, max_x + inactive_area_right, fuzz_x, 0);
529 input_set_abs_params(ts->input_dev, ABS_Y, -inactive_area_top, max_y + inactive_area_bottom, fuzz_y, 0);
530 input_set_abs_params(ts->input_dev, ABS_PRESSURE, 0, 255, fuzz_p, 0);
531 input_set_abs_params(ts->input_dev, ABS_TOOL_WIDTH, 0, 15, fuzz_w, 0);
532 input_set_abs_params(ts->input_dev, ABS_MT_POSITION_X, -inactive_area_left, max_x + inactive_area_right, fuzz_x, 0);
533 input_set_abs_params(ts->input_dev, ABS_MT_POSITION_Y, -inactive_area_top, max_y + inactive_area_bottom, fuzz_y, 0);
534 input_set_abs_params(ts->input_dev, ABS_MT_TOUCH_MAJOR, 0, 255, fuzz_p, 0);
535 input_set_abs_params(ts->input_dev, ABS_MT_WIDTH_MAJOR, 0, 15, fuzz_w, 0);
536 /* ts->input_dev->name = ts->keypad_info->name; */
537 ret = input_register_device(ts->input_dev);
538 if (ret) {
539 printk(KERN_ERR "synaptics_ts_probe: Unable to register %s input device\n", ts->input_dev->name);
540 goto err_input_register_device_failed;
541 }
542 if (client->irq) {
543 ret = request_irq(client->irq, synaptics_ts_irq_handler, irqflags, client->name, ts);
544 if (ret == 0) {
545 ret = i2c_smbus_write_byte_data(ts->client, 0xf1, 0x01); /* enable abs int */
546 if (ret)
547 free_irq(client->irq, ts);
548 }
549 if (ret == 0)
550 ts->use_irq = 1;
551 else
552 dev_err(&client->dev, "request_irq failed\n");
553 }
554 if (!ts->use_irq) {
555 hrtimer_init(&ts->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
556 ts->timer.function = synaptics_ts_timer_func;
557 hrtimer_start(&ts->timer, ktime_set(1, 0), HRTIMER_MODE_REL);
558 }
559#ifdef CONFIG_HAS_EARLYSUSPEND
560 ts->early_suspend.level = EARLY_SUSPEND_LEVEL_BLANK_SCREEN + 1;
561 ts->early_suspend.suspend = synaptics_ts_early_suspend;
562 ts->early_suspend.resume = synaptics_ts_late_resume;
563 register_early_suspend(&ts->early_suspend);
564#endif
565
566 printk(KERN_INFO "synaptics_ts_probe: Start touchscreen %s in %s mode\n", ts->input_dev->name, ts->use_irq ? "interrupt" : "polling");
567
568 return 0;
569
570err_input_register_device_failed:
571 input_free_device(ts->input_dev);
572
573err_input_dev_alloc_failed:
574err_detect_failed:
575err_power_failed:
576 kfree(ts);
577err_alloc_data_failed:
578err_check_functionality_failed:
579 return ret;
580}
581
582static int synaptics_ts_remove(struct i2c_client *client)
583{
584 struct synaptics_ts_data *ts = i2c_get_clientdata(client);
585 unregister_early_suspend(&ts->early_suspend);
586 if (ts->use_irq)
587 free_irq(client->irq, ts);
588 else
589 hrtimer_cancel(&ts->timer);
590 input_unregister_device(ts->input_dev);
591 kfree(ts);
592 return 0;
593}
594
595static int synaptics_ts_suspend(struct i2c_client *client, pm_message_t mesg)
596{
597 int ret;
598 struct synaptics_ts_data *ts = i2c_get_clientdata(client);
599
600 if (ts->use_irq)
601 disable_irq(client->irq);
602 else
603 hrtimer_cancel(&ts->timer);
604 ret = cancel_work_sync(&ts->work);
605 if (ret && ts->use_irq) /* if work was pending disable-count is now 2 */
606 enable_irq(client->irq);
607 ret = i2c_smbus_write_byte_data(ts->client, 0xf1, 0); /* disable interrupt */
608 if (ret < 0)
609 printk(KERN_ERR "synaptics_ts_suspend: i2c_smbus_write_byte_data failed\n");
610
611 ret = i2c_smbus_write_byte_data(client, 0xf0, 0x86); /* deep sleep */
612 if (ret < 0)
613 printk(KERN_ERR "synaptics_ts_suspend: i2c_smbus_write_byte_data failed\n");
614 if (ts->power) {
615 ret = ts->power(0);
616 if (ret < 0)
617 printk(KERN_ERR "synaptics_ts_resume power off failed\n");
618 }
619 return 0;
620}
621
622static int synaptics_ts_resume(struct i2c_client *client)
623{
624 int ret;
625 struct synaptics_ts_data *ts = i2c_get_clientdata(client);
626
627 if (ts->power) {
628 ret = ts->power(1);
629 if (ret < 0)
630 printk(KERN_ERR "synaptics_ts_resume power on failed\n");
631 }
632
633 synaptics_init_panel(ts);
634
635 if (ts->use_irq)
636 enable_irq(client->irq);
637
638 if (!ts->use_irq)
639 hrtimer_start(&ts->timer, ktime_set(1, 0), HRTIMER_MODE_REL);
640 else
641 i2c_smbus_write_byte_data(ts->client, 0xf1, 0x01); /* enable abs int */
642
643 return 0;
644}
645
646#ifdef CONFIG_HAS_EARLYSUSPEND
647static void synaptics_ts_early_suspend(struct early_suspend *h)
648{
649 struct synaptics_ts_data *ts;
650 ts = container_of(h, struct synaptics_ts_data, early_suspend);
651 synaptics_ts_suspend(ts->client, PMSG_SUSPEND);
652}
653
654static void synaptics_ts_late_resume(struct early_suspend *h)
655{
656 struct synaptics_ts_data *ts;
657 ts = container_of(h, struct synaptics_ts_data, early_suspend);
658 synaptics_ts_resume(ts->client);
659}
660#endif
661
662static const struct i2c_device_id synaptics_ts_id[] = {
663 { SYNAPTICS_I2C_RMI_NAME, 0 },
664 { }
665};
666
667static struct i2c_driver synaptics_ts_driver = {
668 .probe = synaptics_ts_probe,
669 .remove = synaptics_ts_remove,
670#ifndef CONFIG_HAS_EARLYSUSPEND
671 .suspend = synaptics_ts_suspend,
672 .resume = synaptics_ts_resume,
673#endif
674 .id_table = synaptics_ts_id,
675 .driver = {
676 .name = SYNAPTICS_I2C_RMI_NAME,
677 },
678};
679
680static int __devinit synaptics_ts_init(void)
681{
682 synaptics_wq = create_singlethread_workqueue("synaptics_wq");
683 if (!synaptics_wq)
684 return -ENOMEM;
685 return i2c_add_driver(&synaptics_ts_driver);
686}
687
688static void __exit synaptics_ts_exit(void)
689{
690 i2c_del_driver(&synaptics_ts_driver);
691 if (synaptics_wq)
692 destroy_workqueue(synaptics_wq);
693}
694
695module_init(synaptics_ts_init);
696module_exit(synaptics_ts_exit);
697
698MODULE_DESCRIPTION("Synaptics Touchscreen Driver");
699MODULE_LICENSE("GPL");