Commit | Line | Data |
---|---|---|
78fd115e RA |
1 | /* |
2 | * clearpad_tm1217.c - Touch Screen driver for Synaptics Clearpad | |
3 | * TM1217 controller | |
4 | * | |
5 | * Copyright (C) 2008 Intel Corp | |
6 | * | |
7 | * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | |
8 | * | |
9 | * This program is free software; you can redistribute it and/or modify | |
10 | * it under the terms of the GNU General Public License as published by | |
11 | * the Free Software Foundation; version 2 of the License. | |
12 | * | |
13 | * This program is distributed in the hope that it will be useful, but | |
14 | * WITHOUT ANY WARRANTY; without even the implied warranty of | |
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
16 | * General Public License for more details. | |
17 | * | |
18 | * You should have received a copy of the GNU General Public License along | |
19 | * with this program; ifnot, write to the Free Software Foundation, Inc., | |
20 | * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. | |
21 | * | |
22 | * Questions/Comments/Bug fixes to Ramesh Agarwal (ramesh.agarwal@intel.com) | |
23 | * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | |
24 | */ | |
25 | ||
26 | #include <linux/module.h> | |
27 | #include <linux/kernel.h> | |
28 | #include <linux/input.h> | |
29 | #include <linux/interrupt.h> | |
30 | #include <linux/io.h> | |
31 | #include <linux/i2c.h> | |
32 | #include <linux/timer.h> | |
33 | #include <linux/gpio.h> | |
34 | #include <linux/hrtimer.h> | |
35 | #include <linux/kthread.h> | |
36 | #include <linux/delay.h> | |
37 | #include <linux/slab.h> | |
38 | #include "cp_tm1217.h" | |
39 | ||
40 | #define CPTM1217_DEVICE_NAME "cptm1217" | |
41 | #define CPTM1217_DRIVER_NAME CPTM1217_DEVICE_NAME | |
42 | ||
43 | #define MAX_TOUCH_SUPPORTED 2 | |
44 | #define TOUCH_SUPPORTED 1 | |
45 | #define SAMPLING_FREQ 80 /* Frequency in HZ */ | |
46 | #define DELAY_BTWIN_SAMPLE (1000 / SAMPLING_FREQ) | |
47 | #define WAIT_FOR_RESPONSE 5 /* 5msec just works */ | |
48 | #define MAX_RETRIES 5 /* As above */ | |
49 | #define INCREMENTAL_DELAY 5 /* As above */ | |
50 | ||
51 | /* Regster Definitions */ | |
52 | #define TMA1217_DEV_STATUS 0x13 /* Device Status */ | |
53 | #define TMA1217_INT_STATUS 0x14 /* Interrupt Status */ | |
54 | ||
25985edc | 55 | /* Controller can detect up to 2 possible finger touches. |
78fd115e RA |
56 | * Each finger touch provides 12 bit X Y co-ordinates, the values are split |
57 | * across 2 registers, and an 8 bit Z value */ | |
58 | #define TMA1217_FINGER_STATE 0x18 /* Finger State */ | |
59 | #define TMA1217_FINGER1_X_HIGHER8 0x19 /* Higher 8 bit of X coordinate */ | |
60 | #define TMA1217_FINGER1_Y_HIGHER8 0x1A /* Higher 8 bit of Y coordinate */ | |
61 | #define TMA1217_FINGER1_XY_LOWER4 0x1B /* Lower 4 bits of X and Y */ | |
62 | #define TMA1217_FINGER1_Z_VALUE 0x1D /* 8 bit Z value for finger 1 */ | |
63 | #define TMA1217_FINGER2_X_HIGHER8 0x1E /* Higher 8 bit of X coordinate */ | |
64 | #define TMA1217_FINGER2_Y_HIGHER8 0x1F /* Higher 8 bit of Y coordinate */ | |
65 | #define TMA1217_FINGER2_XY_LOWER4 0x20 /* Lower 4 bits of X and Y */ | |
66 | #define TMA1217_FINGER2_Z_VALUE 0x22 /* 8 bit Z value for finger 2 */ | |
67 | #define TMA1217_DEVICE_CTRL 0x23 /* Device Control */ | |
68 | #define TMA1217_INTERRUPT_ENABLE 0x24 /* Interrupt Enable */ | |
69 | #define TMA1217_REPORT_MODE 0x2B /* Reporting Mode */ | |
70 | #define TMA1217_MAX_X_LOWER8 0x31 /* Bit 0-7 for Max X */ | |
71 | #define TMA1217_MAX_X_HIGHER4 0x32 /* Bit 8-11 for Max X */ | |
72 | #define TMA1217_MAX_Y_LOWER8 0x33 /* Bit 0-7 for Max Y */ | |
73 | #define TMA1217_MAX_Y_HIGHER4 0x34 /* Bit 8-11 for Max Y */ | |
74 | #define TMA1217_DEVICE_CMD_RESET 0x67 /* Device CMD reg for reset */ | |
75 | #define TMA1217_DEVICE_CMD_REZERO 0x69 /* Device CMD reg for rezero */ | |
76 | ||
77 | #define TMA1217_MANUFACTURER_ID 0x73 /* Manufacturer Id */ | |
78 | #define TMA1217_PRODUCT_FAMILY 0x75 /* Product Family */ | |
79 | #define TMA1217_FIRMWARE_REVISION 0x76 /* Firmware Revision */ | |
80 | #define TMA1217_SERIAL_NO_HIGH 0x7C /* Bit 8-15 of device serial no. */ | |
81 | #define TMA1217_SERIAL_NO_LOW 0x7D /* Bit 0-7 of device serial no. */ | |
82 | #define TMA1217_PRODUCT_ID_START 0x7E /* Start address for 10 byte ID */ | |
83 | #define TMA1217_DEVICE_CAPABILITY 0x8B /* Reporting capability */ | |
84 | ||
85 | ||
86 | /* | |
87 | * The touch position structure. | |
88 | */ | |
89 | struct touch_state { | |
90 | int x; | |
91 | int y; | |
92 | bool button; | |
93 | }; | |
94 | ||
95 | /* Device Specific info given by the controller */ | |
96 | struct cp_dev_info { | |
97 | u16 maxX; | |
98 | u16 maxY; | |
99 | }; | |
100 | ||
101 | /* Vendor related info given by the controller */ | |
102 | struct cp_vendor_info { | |
103 | u8 vendor_id; | |
104 | u8 product_family; | |
105 | u8 firmware_rev; | |
106 | u16 serial_no; | |
107 | }; | |
108 | ||
109 | /* | |
110 | * Private structure to store the device details | |
111 | */ | |
112 | struct cp_tm1217_device { | |
113 | struct i2c_client *client; | |
114 | struct device *dev; | |
115 | struct cp_vendor_info vinfo; | |
116 | struct cp_dev_info dinfo; | |
117 | struct input_dev_info { | |
118 | char phys[32]; | |
119 | char name[128]; | |
120 | struct input_dev *input; | |
121 | struct touch_state touch; | |
122 | } cp_input_info[MAX_TOUCH_SUPPORTED]; | |
123 | ||
124 | int thread_running; | |
125 | struct mutex thread_mutex; | |
126 | ||
127 | int gpio; | |
128 | }; | |
129 | ||
130 | ||
131 | /* The following functions are used to read/write registers on the device | |
132 | * as per the RMI prorocol. Technically, a page select should be written | |
133 | * before doing read/write but since the register offsets are below 0xFF | |
134 | * we can use the default value of page which is 0x00 | |
135 | */ | |
136 | static int cp_tm1217_read(struct cp_tm1217_device *ts, | |
137 | u8 *req, int size) | |
138 | { | |
139 | int i, retval; | |
140 | ||
141 | /* Send the address */ | |
142 | retval = i2c_master_send(ts->client, &req[0], 1); | |
143 | if (retval != 1) { | |
144 | dev_err(ts->dev, "cp_tm1217: I2C send failed\n"); | |
145 | return retval; | |
146 | } | |
147 | msleep(WAIT_FOR_RESPONSE); | |
148 | for (i = 0; i < MAX_RETRIES; i++) { | |
149 | retval = i2c_master_recv(ts->client, &req[1], size); | |
150 | if (retval == size) { | |
151 | break; | |
152 | } else { | |
153 | msleep(INCREMENTAL_DELAY); | |
154 | dev_dbg(ts->dev, "cp_tm1217: Retry count is %d\n", i); | |
155 | } | |
156 | } | |
157 | if (retval != size) | |
158 | dev_err(ts->dev, "cp_tm1217: Read from device failed\n"); | |
159 | ||
160 | return retval; | |
161 | } | |
162 | ||
163 | static int cp_tm1217_write(struct cp_tm1217_device *ts, | |
164 | u8 *req, int size) | |
165 | { | |
166 | int retval; | |
167 | ||
168 | /* Send the address and the data to be written */ | |
169 | retval = i2c_master_send(ts->client, &req[0], size + 1); | |
170 | if (retval != size + 1) { | |
171 | dev_err(ts->dev, "cp_tm1217: I2C write failed: %d\n", retval); | |
172 | return retval; | |
173 | } | |
174 | /* Wait for the write to complete. TBD why this is required */ | |
175 | msleep(WAIT_FOR_RESPONSE); | |
176 | ||
177 | return size; | |
178 | } | |
179 | ||
180 | static int cp_tm1217_mask_interrupt(struct cp_tm1217_device *ts) | |
181 | { | |
182 | u8 req[2]; | |
183 | int retval; | |
184 | ||
185 | req[0] = TMA1217_INTERRUPT_ENABLE; | |
186 | req[1] = 0x0; | |
187 | retval = cp_tm1217_write(ts, req, 1); | |
188 | if (retval != 1) | |
189 | return -EIO; | |
190 | ||
191 | return 0; | |
192 | } | |
193 | ||
194 | static int cp_tm1217_unmask_interrupt(struct cp_tm1217_device *ts) | |
195 | { | |
196 | u8 req[2]; | |
197 | int retval; | |
198 | ||
199 | req[0] = TMA1217_INTERRUPT_ENABLE; | |
200 | req[1] = 0xa; | |
201 | retval = cp_tm1217_write(ts, req, 1); | |
202 | if (retval != 1) | |
203 | return -EIO; | |
204 | ||
205 | return 0; | |
206 | } | |
207 | ||
208 | static void process_touch(struct cp_tm1217_device *ts, int index) | |
209 | { | |
210 | int retval; | |
211 | struct input_dev_info *input_info = | |
212 | (struct input_dev_info *)&ts->cp_input_info[index]; | |
213 | u8 xy_data[6]; | |
214 | ||
215 | if (index == 0) | |
216 | xy_data[0] = TMA1217_FINGER1_X_HIGHER8; | |
217 | else | |
218 | xy_data[0] = TMA1217_FINGER2_X_HIGHER8; | |
219 | ||
220 | retval = cp_tm1217_read(ts, xy_data, 5); | |
221 | if (retval < 5) { | |
222 | dev_err(ts->dev, "cp_tm1217: XY read from device failed\n"); | |
223 | return; | |
224 | } | |
225 | ||
226 | /* Note: Currently not using the Z values but may be requried in | |
227 | the future. */ | |
228 | input_info->touch.x = (xy_data[1] << 4) | |
229 | | (xy_data[3] & 0x0F); | |
230 | input_info->touch.y = (xy_data[2] << 4) | |
231 | | ((xy_data[3] & 0xF0) >> 4); | |
232 | input_report_abs(input_info->input, ABS_X, input_info->touch.x); | |
233 | input_report_abs(input_info->input, ABS_Y, input_info->touch.y); | |
234 | input_sync(input_info->input); | |
235 | } | |
236 | ||
237 | static void cp_tm1217_get_data(struct cp_tm1217_device *ts) | |
238 | { | |
239 | u8 req[2]; | |
240 | int retval, i, finger_touched = 0; | |
241 | ||
242 | do { | |
243 | req[0] = TMA1217_FINGER_STATE; | |
244 | retval = cp_tm1217_read(ts, req, 1); | |
245 | if (retval != 1) { | |
246 | dev_err(ts->dev, | |
247 | "cp_tm1217: Read from device failed\n"); | |
248 | continue; | |
249 | } | |
250 | finger_touched = 0; | |
251 | /* Start sampling until the pressure is below | |
252 | threshold */ | |
253 | for (i = 0; i < TOUCH_SUPPORTED; i++) { | |
254 | if (req[1] & 0x3) { | |
255 | finger_touched++; | |
256 | if (ts->cp_input_info[i].touch.button == 0) { | |
257 | /* send the button touch event */ | |
258 | input_report_key( | |
259 | ts->cp_input_info[i].input, | |
260 | BTN_TOUCH, 1); | |
261 | ts->cp_input_info[i].touch.button = 1; | |
262 | } | |
263 | process_touch(ts, i); | |
264 | } else { | |
265 | if (ts->cp_input_info[i].touch.button == 1) { | |
266 | /* send the button release event */ | |
267 | input_report_key( | |
268 | ts->cp_input_info[i].input, | |
269 | BTN_TOUCH, 0); | |
270 | input_sync(ts->cp_input_info[i].input); | |
271 | ts->cp_input_info[i].touch.button = 0; | |
272 | } | |
273 | } | |
274 | req[1] = req[1] >> 2; | |
275 | } | |
276 | msleep(DELAY_BTWIN_SAMPLE); | |
277 | } while (finger_touched > 0); | |
278 | } | |
279 | ||
280 | static irqreturn_t cp_tm1217_sample_thread(int irq, void *handle) | |
281 | { | |
282 | struct cp_tm1217_device *ts = (struct cp_tm1217_device *) handle; | |
283 | u8 req[2]; | |
284 | int retval; | |
285 | ||
286 | /* Chedk if another thread is already running */ | |
287 | mutex_lock(&ts->thread_mutex); | |
288 | if (ts->thread_running == 1) { | |
289 | mutex_unlock(&ts->thread_mutex); | |
290 | return IRQ_HANDLED; | |
291 | } else { | |
292 | ts->thread_running = 1; | |
293 | mutex_unlock(&ts->thread_mutex); | |
294 | } | |
295 | ||
296 | /* Mask the interrupts */ | |
297 | retval = cp_tm1217_mask_interrupt(ts); | |
298 | ||
299 | /* Read the Interrupt Status register to find the cause of the | |
300 | Interrupt */ | |
301 | req[0] = TMA1217_INT_STATUS; | |
302 | retval = cp_tm1217_read(ts, req, 1); | |
303 | if (retval != 1) | |
304 | goto exit_thread; | |
305 | ||
306 | if (!(req[1] & 0x8)) | |
307 | goto exit_thread; | |
308 | ||
309 | cp_tm1217_get_data(ts); | |
310 | ||
311 | exit_thread: | |
312 | /* Unmask the interrupts before going to sleep */ | |
313 | retval = cp_tm1217_unmask_interrupt(ts); | |
314 | ||
315 | mutex_lock(&ts->thread_mutex); | |
316 | ts->thread_running = 0; | |
317 | mutex_unlock(&ts->thread_mutex); | |
318 | ||
319 | return IRQ_HANDLED; | |
320 | } | |
321 | ||
322 | static int cp_tm1217_init_data(struct cp_tm1217_device *ts) | |
323 | { | |
324 | int retval; | |
325 | u8 req[2]; | |
326 | ||
327 | /* Read the vendor id/ fw revision etc. Ignoring return check as this | |
328 | is non critical info */ | |
329 | req[0] = TMA1217_MANUFACTURER_ID; | |
330 | retval = cp_tm1217_read(ts, req, 1); | |
331 | ts->vinfo.vendor_id = req[1]; | |
332 | ||
333 | req[0] = TMA1217_PRODUCT_FAMILY; | |
334 | retval = cp_tm1217_read(ts, req, 1); | |
335 | ts->vinfo.product_family = req[1]; | |
336 | ||
337 | req[0] = TMA1217_FIRMWARE_REVISION; | |
338 | retval = cp_tm1217_read(ts, req, 1); | |
339 | ts->vinfo.firmware_rev = req[1]; | |
340 | ||
341 | req[0] = TMA1217_SERIAL_NO_HIGH; | |
342 | retval = cp_tm1217_read(ts, req, 1); | |
343 | ts->vinfo.serial_no = (req[1] << 8); | |
344 | ||
345 | req[0] = TMA1217_SERIAL_NO_LOW; | |
346 | retval = cp_tm1217_read(ts, req, 1); | |
347 | ts->vinfo.serial_no = ts->vinfo.serial_no | req[1]; | |
348 | ||
349 | req[0] = TMA1217_MAX_X_HIGHER4; | |
350 | retval = cp_tm1217_read(ts, req, 1); | |
351 | ts->dinfo.maxX = (req[1] & 0xF) << 8; | |
352 | ||
353 | req[0] = TMA1217_MAX_X_LOWER8; | |
354 | retval = cp_tm1217_read(ts, req, 1); | |
355 | ts->dinfo.maxX = ts->dinfo.maxX | req[1]; | |
356 | ||
357 | req[0] = TMA1217_MAX_Y_HIGHER4; | |
358 | retval = cp_tm1217_read(ts, req, 1); | |
359 | ts->dinfo.maxY = (req[1] & 0xF) << 8; | |
360 | ||
361 | req[0] = TMA1217_MAX_Y_LOWER8; | |
362 | retval = cp_tm1217_read(ts, req, 1); | |
363 | ts->dinfo.maxY = ts->dinfo.maxY | req[1]; | |
364 | ||
365 | return 0; | |
366 | ||
367 | } | |
368 | ||
369 | /* | |
370 | * Set up a GPIO for use as the interrupt. We can't simply do this at | |
371 | * boot time because the GPIO drivers themselves may not be around at | |
372 | * boot/firmware set up time to do the work. Instead defer it to driver | |
373 | * detection. | |
374 | */ | |
375 | ||
376 | static int cp_tm1217_setup_gpio_irq(struct cp_tm1217_device *ts) | |
377 | { | |
378 | int retval; | |
379 | ||
380 | /* Hook up the irq handler */ | |
381 | retval = gpio_request(ts->gpio, "cp_tm1217_touch"); | |
382 | if (retval < 0) { | |
383 | dev_err(ts->dev, "cp_tm1217: GPIO request failed error %d\n", | |
384 | retval); | |
385 | return retval; | |
386 | } | |
387 | ||
388 | retval = gpio_direction_input(ts->gpio); | |
389 | if (retval < 0) { | |
390 | dev_err(ts->dev, | |
391 | "cp_tm1217: GPIO direction configuration failed, error %d\n", | |
392 | retval); | |
393 | gpio_free(ts->gpio); | |
394 | return retval; | |
395 | } | |
396 | ||
397 | retval = gpio_to_irq(ts->gpio); | |
398 | if (retval < 0) { | |
399 | dev_err(ts->dev, "cp_tm1217: GPIO to IRQ failedi," | |
400 | " error %d\n", retval); | |
401 | gpio_free(ts->gpio); | |
402 | } | |
403 | dev_dbg(ts->dev, | |
404 | "cp_tm1217: Got IRQ number is %d for GPIO %d\n", | |
405 | retval, ts->gpio); | |
406 | return retval; | |
407 | } | |
408 | ||
409 | static int cp_tm1217_probe(struct i2c_client *client, | |
410 | const struct i2c_device_id *id) | |
411 | { | |
412 | struct cp_tm1217_device *ts; | |
413 | struct input_dev *input_dev; | |
414 | struct input_dev_info *input_info; | |
415 | struct cp_tm1217_platform_data *pdata; | |
416 | u8 req[2]; | |
417 | int i, retval; | |
418 | ||
419 | /* No pdata is fine - we then use "normal" IRQ mode */ | |
420 | ||
421 | pdata = client->dev.platform_data; | |
422 | ||
423 | ts = kzalloc(sizeof(struct cp_tm1217_device), GFP_KERNEL); | |
424 | if (!ts) { | |
425 | dev_err(&client->dev, | |
426 | "cp_tm1217: Private Device Struct alloc failed\n"); | |
427 | return -ENOMEM; | |
428 | } | |
429 | ||
430 | ts->client = client; | |
431 | ts->dev = &client->dev; | |
432 | i2c_set_clientdata(client, ts); | |
433 | ||
434 | ts->thread_running = 0; | |
435 | mutex_init(&ts->thread_mutex); | |
436 | ||
437 | /* Reset the Controller */ | |
438 | req[0] = TMA1217_DEVICE_CMD_RESET; | |
439 | req[1] = 0x1; | |
440 | retval = cp_tm1217_write(ts, req, 1); | |
441 | if (retval != 1) { | |
442 | dev_err(ts->dev, "cp_tm1217: Controller reset failed\n"); | |
443 | kfree(ts); | |
444 | return -EIO; | |
445 | } | |
446 | ||
447 | /* Clear up the interrupt status from reset. */ | |
448 | req[0] = TMA1217_INT_STATUS; | |
449 | retval = cp_tm1217_read(ts, req, 1); | |
450 | ||
451 | /* Mask all the interrupts */ | |
452 | retval = cp_tm1217_mask_interrupt(ts); | |
453 | ||
454 | /* Read the controller information */ | |
455 | cp_tm1217_init_data(ts); | |
456 | ||
457 | /* The following code will register multiple event devices when | |
458 | multi-pointer is enabled, the code has not been tested | |
459 | with MPX */ | |
460 | for (i = 0; i < TOUCH_SUPPORTED; i++) { | |
461 | input_dev = input_allocate_device(); | |
462 | if (input_dev == NULL) { | |
78fd115e RA |
463 | dev_err(ts->dev, |
464 | "cp_tm1217:Input Device Struct alloc failed\n"); | |
a1a26e49 | 465 | kfree(ts); |
78fd115e RA |
466 | return -ENOMEM; |
467 | } | |
468 | input_info = &ts->cp_input_info[i]; | |
469 | snprintf(input_info->name, sizeof(input_info->name), | |
470 | "cp_tm1217_touchscreen_%d", i); | |
471 | input_dev->name = input_info->name; | |
472 | snprintf(input_info->phys, sizeof(input_info->phys), | |
473 | "%s/input%d", dev_name(&client->dev), i); | |
474 | ||
475 | input_dev->phys = input_info->phys; | |
476 | input_dev->id.bustype = BUS_I2C; | |
477 | ||
478 | input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS); | |
479 | input_dev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH); | |
480 | ||
481 | input_set_abs_params(input_dev, ABS_X, 0, ts->dinfo.maxX, 0, 0); | |
482 | input_set_abs_params(input_dev, ABS_Y, 0, ts->dinfo.maxY, 0, 0); | |
483 | ||
484 | retval = input_register_device(input_dev); | |
485 | if (retval) { | |
486 | dev_err(ts->dev, | |
487 | "Input dev registration failed for %s\n", | |
488 | input_dev->name); | |
489 | goto fail; | |
490 | } | |
491 | input_info->input = input_dev; | |
492 | } | |
493 | ||
494 | /* Setup the reporting mode to send an interrupt only when | |
495 | finger arrives or departs. */ | |
496 | req[0] = TMA1217_REPORT_MODE; | |
497 | req[1] = 0x02; | |
498 | retval = cp_tm1217_write(ts, req, 1); | |
499 | ||
500 | /* Setup the device to no sleep mode for now and make it configured */ | |
501 | req[0] = TMA1217_DEVICE_CTRL; | |
502 | req[1] = 0x84; | |
503 | retval = cp_tm1217_write(ts, req, 1); | |
504 | ||
505 | /* Check for the status of the device */ | |
506 | req[0] = TMA1217_DEV_STATUS; | |
507 | retval = cp_tm1217_read(ts, req, 1); | |
508 | if (req[1] != 0) { | |
509 | dev_err(ts->dev, | |
510 | "cp_tm1217: Device Status 0x%x != 0: config failed\n", | |
511 | req[1]); | |
512 | ||
513 | retval = -EIO; | |
514 | goto fail; | |
515 | } | |
516 | ||
517 | if (pdata && pdata->gpio) { | |
518 | ts->gpio = pdata->gpio; | |
519 | retval = cp_tm1217_setup_gpio_irq(ts); | |
520 | } else | |
521 | retval = client->irq; | |
522 | ||
523 | if (retval < 0) { | |
524 | dev_err(ts->dev, "cp_tm1217: GPIO request failed error %d\n", | |
525 | retval); | |
526 | goto fail; | |
527 | } | |
528 | ||
529 | client->irq = retval; | |
530 | ||
531 | ||
532 | retval = request_threaded_irq(client->irq, | |
533 | NULL, cp_tm1217_sample_thread, | |
534 | IRQF_TRIGGER_FALLING, "cp_tm1217_touch", ts); | |
535 | if (retval < 0) { | |
536 | dev_err(ts->dev, "cp_tm1217: Request IRQ error %d\n", retval); | |
537 | goto fail_gpio; | |
538 | } | |
539 | ||
540 | /* Unmask the interrupts */ | |
541 | retval = cp_tm1217_unmask_interrupt(ts); | |
542 | if (retval == 0) | |
543 | return 0; | |
544 | ||
545 | free_irq(client->irq, ts); | |
546 | fail_gpio: | |
547 | if (ts->gpio) | |
548 | gpio_free(ts->gpio); | |
549 | fail: | |
550 | /* Clean up before returning failure */ | |
551 | for (i = 0; i < TOUCH_SUPPORTED; i++) { | |
552 | if (ts->cp_input_info[i].input) { | |
553 | input_unregister_device(ts->cp_input_info[i].input); | |
554 | input_free_device(ts->cp_input_info[i].input); | |
555 | } | |
556 | } | |
557 | kfree(ts); | |
558 | return retval; | |
559 | ||
560 | } | |
561 | ||
562 | /* | |
563 | * cp_tm1217 suspend | |
564 | * | |
565 | */ | |
566 | static int cp_tm1217_suspend(struct i2c_client *client, pm_message_t mesg) | |
567 | { | |
568 | struct cp_tm1217_device *ts = i2c_get_clientdata(client); | |
569 | u8 req[2]; | |
570 | int retval; | |
571 | ||
572 | /* Put the controller to sleep */ | |
573 | req[0] = TMA1217_DEVICE_CTRL; | |
574 | retval = cp_tm1217_read(ts, req, 1); | |
575 | req[1] = (req[1] & 0xF8) | 0x1; | |
576 | retval = cp_tm1217_write(ts, req, 1); | |
577 | ||
578 | if (device_may_wakeup(&client->dev)) | |
579 | enable_irq_wake(client->irq); | |
580 | ||
581 | return 0; | |
582 | } | |
583 | ||
584 | /* | |
585 | * cp_tm1217_resume | |
586 | * | |
587 | */ | |
588 | static int cp_tm1217_resume(struct i2c_client *client) | |
589 | { | |
590 | struct cp_tm1217_device *ts = i2c_get_clientdata(client); | |
591 | u8 req[2]; | |
592 | int retval; | |
593 | ||
594 | /* Take the controller out of sleep */ | |
595 | req[0] = TMA1217_DEVICE_CTRL; | |
596 | retval = cp_tm1217_read(ts, req, 1); | |
597 | req[1] = (req[1] & 0xF8) | 0x4; | |
598 | retval = cp_tm1217_write(ts, req, 1); | |
599 | ||
600 | /* Restore the register settings sinc the power to the | |
601 | could have been cut off */ | |
602 | ||
603 | /* Setup the reporting mode to send an interrupt only when | |
604 | finger arrives or departs. */ | |
605 | req[0] = TMA1217_REPORT_MODE; | |
606 | req[1] = 0x02; | |
607 | retval = cp_tm1217_write(ts, req, 1); | |
608 | ||
609 | /* Setup the device to no sleep mode for now and make it configured */ | |
610 | req[0] = TMA1217_DEVICE_CTRL; | |
611 | req[1] = 0x84; | |
612 | retval = cp_tm1217_write(ts, req, 1); | |
613 | ||
614 | /* Setup the interrupt mask */ | |
615 | retval = cp_tm1217_unmask_interrupt(ts); | |
616 | ||
617 | if (device_may_wakeup(&client->dev)) | |
618 | disable_irq_wake(client->irq); | |
619 | ||
620 | return 0; | |
621 | } | |
622 | ||
623 | /* | |
624 | * cp_tm1217_remove | |
625 | * | |
626 | */ | |
627 | static int cp_tm1217_remove(struct i2c_client *client) | |
628 | { | |
629 | struct cp_tm1217_device *ts = i2c_get_clientdata(client); | |
630 | int i; | |
631 | ||
632 | free_irq(client->irq, ts); | |
633 | if (ts->gpio) | |
634 | gpio_free(ts->gpio); | |
635 | for (i = 0; i < TOUCH_SUPPORTED; i++) | |
636 | input_unregister_device(ts->cp_input_info[i].input); | |
637 | kfree(ts); | |
638 | return 0; | |
639 | } | |
640 | ||
641 | static struct i2c_device_id cp_tm1217_idtable[] = { | |
642 | { CPTM1217_DEVICE_NAME, 0 }, | |
643 | { } | |
644 | }; | |
645 | ||
646 | MODULE_DEVICE_TABLE(i2c, cp_tm1217_idtable); | |
647 | ||
648 | static struct i2c_driver cp_tm1217_driver = { | |
649 | .driver = { | |
650 | .owner = THIS_MODULE, | |
651 | .name = CPTM1217_DRIVER_NAME, | |
652 | }, | |
653 | .id_table = cp_tm1217_idtable, | |
654 | .probe = cp_tm1217_probe, | |
655 | .remove = cp_tm1217_remove, | |
656 | .suspend = cp_tm1217_suspend, | |
657 | .resume = cp_tm1217_resume, | |
658 | }; | |
659 | ||
660 | static int __init clearpad_tm1217_init(void) | |
661 | { | |
662 | return i2c_add_driver(&cp_tm1217_driver); | |
663 | } | |
664 | ||
665 | static void __exit clearpad_tm1217_exit(void) | |
666 | { | |
667 | i2c_del_driver(&cp_tm1217_driver); | |
668 | } | |
669 | ||
670 | module_init(clearpad_tm1217_init); | |
671 | module_exit(clearpad_tm1217_exit); | |
672 | ||
673 | MODULE_AUTHOR("Ramesh Agarwal <ramesh.agarwal@intel.com>"); | |
674 | MODULE_DESCRIPTION("Synaptics TM1217 TouchScreen Driver"); | |
675 | MODULE_LICENSE("GPL v2"); |