RT-AC56 3.0.0.4.374.37 core
[tomato.git] / release / src-rt-6.x.4708 / linux / linux-2.6.36 / drivers / input / touchscreen / qt602240_ts.c
blob66b26ad3032a155fc24d823265d7c38e4d3361a3
1 /*
2 * AT42QT602240/ATMXT224 Touchscreen driver
4 * Copyright (C) 2010 Samsung Electronics Co.Ltd
5 * Author: Joonyoung Shim <jy0922.shim@samsung.com>
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation; either version 2 of the License, or (at your
10 * option) any later version.
14 #include <linux/module.h>
15 #include <linux/init.h>
16 #include <linux/delay.h>
17 #include <linux/firmware.h>
18 #include <linux/i2c.h>
19 #include <linux/i2c/qt602240_ts.h>
20 #include <linux/input.h>
21 #include <linux/interrupt.h>
22 #include <linux/slab.h>
24 /* Version */
25 #define QT602240_VER_20 20
26 #define QT602240_VER_21 21
27 #define QT602240_VER_22 22
29 /* Slave addresses */
30 #define QT602240_APP_LOW 0x4a
31 #define QT602240_APP_HIGH 0x4b
32 #define QT602240_BOOT_LOW 0x24
33 #define QT602240_BOOT_HIGH 0x25
35 /* Firmware */
36 #define QT602240_FW_NAME "qt602240.fw"
38 /* Registers */
39 #define QT602240_FAMILY_ID 0x00
40 #define QT602240_VARIANT_ID 0x01
41 #define QT602240_VERSION 0x02
42 #define QT602240_BUILD 0x03
43 #define QT602240_MATRIX_X_SIZE 0x04
44 #define QT602240_MATRIX_Y_SIZE 0x05
45 #define QT602240_OBJECT_NUM 0x06
46 #define QT602240_OBJECT_START 0x07
48 #define QT602240_OBJECT_SIZE 6
50 /* Object types */
51 #define QT602240_DEBUG_DIAGNOSTIC 37
52 #define QT602240_GEN_MESSAGE 5
53 #define QT602240_GEN_COMMAND 6
54 #define QT602240_GEN_POWER 7
55 #define QT602240_GEN_ACQUIRE 8
56 #define QT602240_TOUCH_MULTI 9
57 #define QT602240_TOUCH_KEYARRAY 15
58 #define QT602240_TOUCH_PROXIMITY 23
59 #define QT602240_PROCI_GRIPFACE 20
60 #define QT602240_PROCG_NOISE 22
61 #define QT602240_PROCI_ONETOUCH 24
62 #define QT602240_PROCI_TWOTOUCH 27
63 #define QT602240_SPT_COMMSCONFIG 18 /* firmware ver 21 over */
64 #define QT602240_SPT_GPIOPWM 19
65 #define QT602240_SPT_SELFTEST 25
66 #define QT602240_SPT_CTECONFIG 28
67 #define QT602240_SPT_USERDATA 38 /* firmware ver 21 over */
69 /* QT602240_GEN_COMMAND field */
70 #define QT602240_COMMAND_RESET 0
71 #define QT602240_COMMAND_BACKUPNV 1
72 #define QT602240_COMMAND_CALIBRATE 2
73 #define QT602240_COMMAND_REPORTALL 3
74 #define QT602240_COMMAND_DIAGNOSTIC 5
76 /* QT602240_GEN_POWER field */
77 #define QT602240_POWER_IDLEACQINT 0
78 #define QT602240_POWER_ACTVACQINT 1
79 #define QT602240_POWER_ACTV2IDLETO 2
81 /* QT602240_GEN_ACQUIRE field */
82 #define QT602240_ACQUIRE_CHRGTIME 0
83 #define QT602240_ACQUIRE_TCHDRIFT 2
84 #define QT602240_ACQUIRE_DRIFTST 3
85 #define QT602240_ACQUIRE_TCHAUTOCAL 4
86 #define QT602240_ACQUIRE_SYNC 5
87 #define QT602240_ACQUIRE_ATCHCALST 6
88 #define QT602240_ACQUIRE_ATCHCALSTHR 7
90 /* QT602240_TOUCH_MULTI field */
91 #define QT602240_TOUCH_CTRL 0
92 #define QT602240_TOUCH_XORIGIN 1
93 #define QT602240_TOUCH_YORIGIN 2
94 #define QT602240_TOUCH_XSIZE 3
95 #define QT602240_TOUCH_YSIZE 4
96 #define QT602240_TOUCH_BLEN 6
97 #define QT602240_TOUCH_TCHTHR 7
98 #define QT602240_TOUCH_TCHDI 8
99 #define QT602240_TOUCH_ORIENT 9
100 #define QT602240_TOUCH_MOVHYSTI 11
101 #define QT602240_TOUCH_MOVHYSTN 12
102 #define QT602240_TOUCH_NUMTOUCH 14
103 #define QT602240_TOUCH_MRGHYST 15
104 #define QT602240_TOUCH_MRGTHR 16
105 #define QT602240_TOUCH_AMPHYST 17
106 #define QT602240_TOUCH_XRANGE_LSB 18
107 #define QT602240_TOUCH_XRANGE_MSB 19
108 #define QT602240_TOUCH_YRANGE_LSB 20
109 #define QT602240_TOUCH_YRANGE_MSB 21
110 #define QT602240_TOUCH_XLOCLIP 22
111 #define QT602240_TOUCH_XHICLIP 23
112 #define QT602240_TOUCH_YLOCLIP 24
113 #define QT602240_TOUCH_YHICLIP 25
114 #define QT602240_TOUCH_XEDGECTRL 26
115 #define QT602240_TOUCH_XEDGEDIST 27
116 #define QT602240_TOUCH_YEDGECTRL 28
117 #define QT602240_TOUCH_YEDGEDIST 29
118 #define QT602240_TOUCH_JUMPLIMIT 30 /* firmware ver 22 over */
120 /* QT602240_PROCI_GRIPFACE field */
121 #define QT602240_GRIPFACE_CTRL 0
122 #define QT602240_GRIPFACE_XLOGRIP 1
123 #define QT602240_GRIPFACE_XHIGRIP 2
124 #define QT602240_GRIPFACE_YLOGRIP 3
125 #define QT602240_GRIPFACE_YHIGRIP 4
126 #define QT602240_GRIPFACE_MAXTCHS 5
127 #define QT602240_GRIPFACE_SZTHR1 7
128 #define QT602240_GRIPFACE_SZTHR2 8
129 #define QT602240_GRIPFACE_SHPTHR1 9
130 #define QT602240_GRIPFACE_SHPTHR2 10
131 #define QT602240_GRIPFACE_SUPEXTTO 11
133 /* QT602240_PROCI_NOISE field */
134 #define QT602240_NOISE_CTRL 0
135 #define QT602240_NOISE_OUTFLEN 1
136 #define QT602240_NOISE_GCAFUL_LSB 3
137 #define QT602240_NOISE_GCAFUL_MSB 4
138 #define QT602240_NOISE_GCAFLL_LSB 5
139 #define QT602240_NOISE_GCAFLL_MSB 6
140 #define QT602240_NOISE_ACTVGCAFVALID 7
141 #define QT602240_NOISE_NOISETHR 8
142 #define QT602240_NOISE_FREQHOPSCALE 10
143 #define QT602240_NOISE_FREQ0 11
144 #define QT602240_NOISE_FREQ1 12
145 #define QT602240_NOISE_FREQ2 13
146 #define QT602240_NOISE_FREQ3 14
147 #define QT602240_NOISE_FREQ4 15
148 #define QT602240_NOISE_IDLEGCAFVALID 16
150 /* QT602240_SPT_COMMSCONFIG */
151 #define QT602240_COMMS_CTRL 0
152 #define QT602240_COMMS_CMD 1
154 /* QT602240_SPT_CTECONFIG field */
155 #define QT602240_CTE_CTRL 0
156 #define QT602240_CTE_CMD 1
157 #define QT602240_CTE_MODE 2
158 #define QT602240_CTE_IDLEGCAFDEPTH 3
159 #define QT602240_CTE_ACTVGCAFDEPTH 4
160 #define QT602240_CTE_VOLTAGE 5 /* firmware ver 21 over */
162 #define QT602240_VOLTAGE_DEFAULT 2700000
163 #define QT602240_VOLTAGE_STEP 10000
165 /* Define for QT602240_GEN_COMMAND */
166 #define QT602240_BOOT_VALUE 0xa5
167 #define QT602240_BACKUP_VALUE 0x55
168 #define QT602240_BACKUP_TIME 25 /* msec */
169 #define QT602240_RESET_TIME 65 /* msec */
171 #define QT602240_FWRESET_TIME 175 /* msec */
173 /* Command to unlock bootloader */
174 #define QT602240_UNLOCK_CMD_MSB 0xaa
175 #define QT602240_UNLOCK_CMD_LSB 0xdc
177 /* Bootloader mode status */
178 #define QT602240_WAITING_BOOTLOAD_CMD 0xc0 /* valid 7 6 bit only */
179 #define QT602240_WAITING_FRAME_DATA 0x80 /* valid 7 6 bit only */
180 #define QT602240_FRAME_CRC_CHECK 0x02
181 #define QT602240_FRAME_CRC_FAIL 0x03
182 #define QT602240_FRAME_CRC_PASS 0x04
183 #define QT602240_APP_CRC_FAIL 0x40 /* valid 7 8 bit only */
184 #define QT602240_BOOT_STATUS_MASK 0x3f
186 /* Touch status */
187 #define QT602240_SUPPRESS (1 << 1)
188 #define QT602240_AMP (1 << 2)
189 #define QT602240_VECTOR (1 << 3)
190 #define QT602240_MOVE (1 << 4)
191 #define QT602240_RELEASE (1 << 5)
192 #define QT602240_PRESS (1 << 6)
193 #define QT602240_DETECT (1 << 7)
195 /* Touchscreen absolute values */
196 #define QT602240_MAX_XC 0x3ff
197 #define QT602240_MAX_YC 0x3ff
198 #define QT602240_MAX_AREA 0xff
200 #define QT602240_MAX_FINGER 10
202 /* Initial register values recommended from chip vendor */
203 static const u8 init_vals_ver_20[] = {
204 /* QT602240_GEN_COMMAND(6) */
205 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
206 /* QT602240_GEN_POWER(7) */
207 0x20, 0xff, 0x32,
208 /* QT602240_GEN_ACQUIRE(8) */
209 0x08, 0x05, 0x05, 0x00, 0x00, 0x00, 0x05, 0x14,
210 /* QT602240_TOUCH_MULTI(9) */
211 0x00, 0x00, 0x00, 0x11, 0x0a, 0x00, 0x00, 0x00, 0x02, 0x00,
212 0x00, 0x01, 0x01, 0x0e, 0x0a, 0x0a, 0x0a, 0x0a, 0x00, 0x00,
213 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0x64,
214 /* QT602240_TOUCH_KEYARRAY(15) */
215 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
216 0x00,
217 /* QT602240_SPT_GPIOPWM(19) */
218 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
219 0x00, 0x00,
220 /* QT602240_PROCI_GRIPFACE(20) */
221 0x00, 0x64, 0x64, 0x64, 0x64, 0x00, 0x00, 0x1e, 0x14, 0x04,
222 0x1e, 0x00,
223 /* QT602240_PROCG_NOISE(22) */
224 0x05, 0x00, 0x00, 0x19, 0x00, 0xe7, 0xff, 0x04, 0x32, 0x00,
225 0x01, 0x0a, 0x0f, 0x14, 0x00, 0x00, 0xe8,
226 /* QT602240_TOUCH_PROXIMITY(23) */
227 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
228 0x00, 0x00, 0x00,
229 /* QT602240_PROCI_ONETOUCH(24) */
230 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
231 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
232 /* QT602240_SPT_SELFTEST(25) */
233 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
234 0x00, 0x00, 0x00, 0x00,
235 /* QT602240_PROCI_TWOTOUCH(27) */
236 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
237 /* QT602240_SPT_CTECONFIG(28) */
238 0x00, 0x00, 0x00, 0x04, 0x08,
241 static const u8 init_vals_ver_21[] = {
242 /* QT602240_GEN_COMMAND(6) */
243 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
244 /* QT602240_GEN_POWER(7) */
245 0x20, 0xff, 0x32,
246 /* QT602240_GEN_ACQUIRE(8) */
247 0x0a, 0x00, 0x05, 0x00, 0x00, 0x00, 0x09, 0x23,
248 /* QT602240_TOUCH_MULTI(9) */
249 0x00, 0x00, 0x00, 0x13, 0x0b, 0x00, 0x00, 0x00, 0x02, 0x00,
250 0x00, 0x01, 0x01, 0x0e, 0x0a, 0x0a, 0x0a, 0x0a, 0x00, 0x00,
251 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
252 /* QT602240_TOUCH_KEYARRAY(15) */
253 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
254 0x00,
255 /* QT602240_SPT_GPIOPWM(19) */
256 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
257 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
258 /* QT602240_PROCI_GRIPFACE(20) */
259 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x28, 0x04,
260 0x0f, 0x0a,
261 /* QT602240_PROCG_NOISE(22) */
262 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x23, 0x00,
263 0x00, 0x05, 0x0f, 0x19, 0x23, 0x2d, 0x03,
264 /* QT602240_TOUCH_PROXIMITY(23) */
265 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
266 0x00, 0x00, 0x00,
267 /* QT602240_PROCI_ONETOUCH(24) */
268 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
269 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
270 /* QT602240_SPT_SELFTEST(25) */
271 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
272 0x00, 0x00, 0x00, 0x00,
273 /* QT602240_PROCI_TWOTOUCH(27) */
274 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
275 /* QT602240_SPT_CTECONFIG(28) */
276 0x00, 0x00, 0x00, 0x08, 0x10, 0x00,
279 static const u8 init_vals_ver_22[] = {
280 /* QT602240_GEN_COMMAND(6) */
281 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
282 /* QT602240_GEN_POWER(7) */
283 0x20, 0xff, 0x32,
284 /* QT602240_GEN_ACQUIRE(8) */
285 0x0a, 0x00, 0x05, 0x00, 0x00, 0x00, 0x09, 0x23,
286 /* QT602240_TOUCH_MULTI(9) */
287 0x00, 0x00, 0x00, 0x13, 0x0b, 0x00, 0x00, 0x00, 0x02, 0x00,
288 0x00, 0x01, 0x01, 0x0e, 0x0a, 0x0a, 0x0a, 0x0a, 0x00, 0x00,
289 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
290 0x00,
291 /* QT602240_TOUCH_KEYARRAY(15) */
292 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
293 0x00,
294 /* QT602240_SPT_GPIOPWM(19) */
295 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
296 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
297 /* QT602240_PROCI_GRIPFACE(20) */
298 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x28, 0x04,
299 0x0f, 0x0a,
300 /* QT602240_PROCG_NOISE(22) */
301 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x23, 0x00,
302 0x00, 0x05, 0x0f, 0x19, 0x23, 0x2d, 0x03,
303 /* QT602240_TOUCH_PROXIMITY(23) */
304 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
305 0x00, 0x00, 0x00, 0x00, 0x00,
306 /* QT602240_PROCI_ONETOUCH(24) */
307 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
308 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
309 /* QT602240_SPT_SELFTEST(25) */
310 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
311 0x00, 0x00, 0x00, 0x00,
312 /* QT602240_PROCI_TWOTOUCH(27) */
313 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
314 /* QT602240_SPT_CTECONFIG(28) */
315 0x00, 0x00, 0x00, 0x08, 0x10, 0x00,
318 struct qt602240_info {
319 u8 family_id;
320 u8 variant_id;
321 u8 version;
322 u8 build;
323 u8 matrix_xsize;
324 u8 matrix_ysize;
325 u8 object_num;
328 struct qt602240_object {
329 u8 type;
330 u16 start_address;
331 u8 size;
332 u8 instances;
333 u8 num_report_ids;
335 /* to map object and message */
336 u8 max_reportid;
339 struct qt602240_message {
340 u8 reportid;
341 u8 message[7];
342 u8 checksum;
345 struct qt602240_finger {
346 int status;
347 int x;
348 int y;
349 int area;
352 /* Each client has this additional data */
353 struct qt602240_data {
354 struct i2c_client *client;
355 struct input_dev *input_dev;
356 const struct qt602240_platform_data *pdata;
357 struct qt602240_object *object_table;
358 struct qt602240_info info;
359 struct qt602240_finger finger[QT602240_MAX_FINGER];
360 unsigned int irq;
363 static bool qt602240_object_readable(unsigned int type)
365 switch (type) {
366 case QT602240_GEN_MESSAGE:
367 case QT602240_GEN_COMMAND:
368 case QT602240_GEN_POWER:
369 case QT602240_GEN_ACQUIRE:
370 case QT602240_TOUCH_MULTI:
371 case QT602240_TOUCH_KEYARRAY:
372 case QT602240_TOUCH_PROXIMITY:
373 case QT602240_PROCI_GRIPFACE:
374 case QT602240_PROCG_NOISE:
375 case QT602240_PROCI_ONETOUCH:
376 case QT602240_PROCI_TWOTOUCH:
377 case QT602240_SPT_COMMSCONFIG:
378 case QT602240_SPT_GPIOPWM:
379 case QT602240_SPT_SELFTEST:
380 case QT602240_SPT_CTECONFIG:
381 case QT602240_SPT_USERDATA:
382 return true;
383 default:
384 return false;
388 static bool qt602240_object_writable(unsigned int type)
390 switch (type) {
391 case QT602240_GEN_COMMAND:
392 case QT602240_GEN_POWER:
393 case QT602240_GEN_ACQUIRE:
394 case QT602240_TOUCH_MULTI:
395 case QT602240_TOUCH_KEYARRAY:
396 case QT602240_TOUCH_PROXIMITY:
397 case QT602240_PROCI_GRIPFACE:
398 case QT602240_PROCG_NOISE:
399 case QT602240_PROCI_ONETOUCH:
400 case QT602240_PROCI_TWOTOUCH:
401 case QT602240_SPT_GPIOPWM:
402 case QT602240_SPT_SELFTEST:
403 case QT602240_SPT_CTECONFIG:
404 return true;
405 default:
406 return false;
410 static void qt602240_dump_message(struct device *dev,
411 struct qt602240_message *message)
413 dev_dbg(dev, "reportid:\t0x%x\n", message->reportid);
414 dev_dbg(dev, "message1:\t0x%x\n", message->message[0]);
415 dev_dbg(dev, "message2:\t0x%x\n", message->message[1]);
416 dev_dbg(dev, "message3:\t0x%x\n", message->message[2]);
417 dev_dbg(dev, "message4:\t0x%x\n", message->message[3]);
418 dev_dbg(dev, "message5:\t0x%x\n", message->message[4]);
419 dev_dbg(dev, "message6:\t0x%x\n", message->message[5]);
420 dev_dbg(dev, "message7:\t0x%x\n", message->message[6]);
421 dev_dbg(dev, "checksum:\t0x%x\n", message->checksum);
424 static int qt602240_check_bootloader(struct i2c_client *client,
425 unsigned int state)
427 u8 val;
429 recheck:
430 if (i2c_master_recv(client, &val, 1) != 1) {
431 dev_err(&client->dev, "%s: i2c recv failed\n", __func__);
432 return -EIO;
435 switch (state) {
436 case QT602240_WAITING_BOOTLOAD_CMD:
437 case QT602240_WAITING_FRAME_DATA:
438 val &= ~QT602240_BOOT_STATUS_MASK;
439 break;
440 case QT602240_FRAME_CRC_PASS:
441 if (val == QT602240_FRAME_CRC_CHECK)
442 goto recheck;
443 break;
444 default:
445 return -EINVAL;
448 if (val != state) {
449 dev_err(&client->dev, "Unvalid bootloader mode state\n");
450 return -EINVAL;
453 return 0;
456 static int qt602240_unlock_bootloader(struct i2c_client *client)
458 u8 buf[2];
460 buf[0] = QT602240_UNLOCK_CMD_LSB;
461 buf[1] = QT602240_UNLOCK_CMD_MSB;
463 if (i2c_master_send(client, buf, 2) != 2) {
464 dev_err(&client->dev, "%s: i2c send failed\n", __func__);
465 return -EIO;
468 return 0;
471 static int qt602240_fw_write(struct i2c_client *client,
472 const u8 *data, unsigned int frame_size)
474 if (i2c_master_send(client, data, frame_size) != frame_size) {
475 dev_err(&client->dev, "%s: i2c send failed\n", __func__);
476 return -EIO;
479 return 0;
482 static int __qt602240_read_reg(struct i2c_client *client,
483 u16 reg, u16 len, void *val)
485 struct i2c_msg xfer[2];
486 u8 buf[2];
488 buf[0] = reg & 0xff;
489 buf[1] = (reg >> 8) & 0xff;
491 /* Write register */
492 xfer[0].addr = client->addr;
493 xfer[0].flags = 0;
494 xfer[0].len = 2;
495 xfer[0].buf = buf;
497 /* Read data */
498 xfer[1].addr = client->addr;
499 xfer[1].flags = I2C_M_RD;
500 xfer[1].len = len;
501 xfer[1].buf = val;
503 if (i2c_transfer(client->adapter, xfer, 2) != 2) {
504 dev_err(&client->dev, "%s: i2c transfer failed\n", __func__);
505 return -EIO;
508 return 0;
511 static int qt602240_read_reg(struct i2c_client *client, u16 reg, u8 *val)
513 return __qt602240_read_reg(client, reg, 1, val);
516 static int qt602240_write_reg(struct i2c_client *client, u16 reg, u8 val)
518 u8 buf[3];
520 buf[0] = reg & 0xff;
521 buf[1] = (reg >> 8) & 0xff;
522 buf[2] = val;
524 if (i2c_master_send(client, buf, 3) != 3) {
525 dev_err(&client->dev, "%s: i2c send failed\n", __func__);
526 return -EIO;
529 return 0;
532 static int qt602240_read_object_table(struct i2c_client *client,
533 u16 reg, u8 *object_buf)
535 return __qt602240_read_reg(client, reg, QT602240_OBJECT_SIZE,
536 object_buf);
539 static struct qt602240_object *
540 qt602240_get_object(struct qt602240_data *data, u8 type)
542 struct qt602240_object *object;
543 int i;
545 for (i = 0; i < data->info.object_num; i++) {
546 object = data->object_table + i;
547 if (object->type == type)
548 return object;
551 dev_err(&data->client->dev, "Invalid object type\n");
552 return NULL;
555 static int qt602240_read_message(struct qt602240_data *data,
556 struct qt602240_message *message)
558 struct qt602240_object *object;
559 u16 reg;
561 object = qt602240_get_object(data, QT602240_GEN_MESSAGE);
562 if (!object)
563 return -EINVAL;
565 reg = object->start_address;
566 return __qt602240_read_reg(data->client, reg,
567 sizeof(struct qt602240_message), message);
570 static int qt602240_read_object(struct qt602240_data *data,
571 u8 type, u8 offset, u8 *val)
573 struct qt602240_object *object;
574 u16 reg;
576 object = qt602240_get_object(data, type);
577 if (!object)
578 return -EINVAL;
580 reg = object->start_address;
581 return __qt602240_read_reg(data->client, reg + offset, 1, val);
584 static int qt602240_write_object(struct qt602240_data *data,
585 u8 type, u8 offset, u8 val)
587 struct qt602240_object *object;
588 u16 reg;
590 object = qt602240_get_object(data, type);
591 if (!object)
592 return -EINVAL;
594 reg = object->start_address;
595 return qt602240_write_reg(data->client, reg + offset, val);
598 static void qt602240_input_report(struct qt602240_data *data, int single_id)
600 struct qt602240_finger *finger = data->finger;
601 struct input_dev *input_dev = data->input_dev;
602 int status = finger[single_id].status;
603 int finger_num = 0;
604 int id;
606 for (id = 0; id < QT602240_MAX_FINGER; id++) {
607 if (!finger[id].status)
608 continue;
610 input_report_abs(input_dev, ABS_MT_TOUCH_MAJOR,
611 finger[id].status != QT602240_RELEASE ?
612 finger[id].area : 0);
613 input_report_abs(input_dev, ABS_MT_POSITION_X,
614 finger[id].x);
615 input_report_abs(input_dev, ABS_MT_POSITION_Y,
616 finger[id].y);
617 input_mt_sync(input_dev);
619 if (finger[id].status == QT602240_RELEASE)
620 finger[id].status = 0;
621 else
622 finger_num++;
625 input_report_key(input_dev, BTN_TOUCH, finger_num > 0);
627 if (status != QT602240_RELEASE) {
628 input_report_abs(input_dev, ABS_X, finger[single_id].x);
629 input_report_abs(input_dev, ABS_Y, finger[single_id].y);
632 input_sync(input_dev);
635 static void qt602240_input_touchevent(struct qt602240_data *data,
636 struct qt602240_message *message, int id)
638 struct qt602240_finger *finger = data->finger;
639 struct device *dev = &data->client->dev;
640 u8 status = message->message[0];
641 int x;
642 int y;
643 int area;
645 /* Check the touch is present on the screen */
646 if (!(status & QT602240_DETECT)) {
647 if (status & QT602240_RELEASE) {
648 dev_dbg(dev, "[%d] released\n", id);
650 finger[id].status = QT602240_RELEASE;
651 qt602240_input_report(data, id);
653 return;
656 /* Check only AMP detection */
657 if (!(status & (QT602240_PRESS | QT602240_MOVE)))
658 return;
660 x = (message->message[1] << 2) | ((message->message[3] & ~0x3f) >> 6);
661 y = (message->message[2] << 2) | ((message->message[3] & ~0xf3) >> 2);
662 area = message->message[4];
664 dev_dbg(dev, "[%d] %s x: %d, y: %d, area: %d\n", id,
665 status & QT602240_MOVE ? "moved" : "pressed",
666 x, y, area);
668 finger[id].status = status & QT602240_MOVE ?
669 QT602240_MOVE : QT602240_PRESS;
670 finger[id].x = x;
671 finger[id].y = y;
672 finger[id].area = area;
674 qt602240_input_report(data, id);
677 static irqreturn_t qt602240_interrupt(int irq, void *dev_id)
679 struct qt602240_data *data = dev_id;
680 struct qt602240_message message;
681 struct qt602240_object *object;
682 struct device *dev = &data->client->dev;
683 int id;
684 u8 reportid;
685 u8 max_reportid;
686 u8 min_reportid;
688 do {
689 if (qt602240_read_message(data, &message)) {
690 dev_err(dev, "Failed to read message\n");
691 goto end;
694 reportid = message.reportid;
696 /* whether reportid is thing of QT602240_TOUCH_MULTI */
697 object = qt602240_get_object(data, QT602240_TOUCH_MULTI);
698 if (!object)
699 goto end;
701 max_reportid = object->max_reportid;
702 min_reportid = max_reportid - object->num_report_ids + 1;
703 id = reportid - min_reportid;
705 if (reportid >= min_reportid && reportid <= max_reportid)
706 qt602240_input_touchevent(data, &message, id);
707 else
708 qt602240_dump_message(dev, &message);
709 } while (reportid != 0xff);
711 end:
712 return IRQ_HANDLED;
715 static int qt602240_check_reg_init(struct qt602240_data *data)
717 struct qt602240_object *object;
718 struct device *dev = &data->client->dev;
719 int index = 0;
720 int i, j;
721 u8 version = data->info.version;
722 u8 *init_vals;
724 switch (version) {
725 case QT602240_VER_20:
726 init_vals = (u8 *)init_vals_ver_20;
727 break;
728 case QT602240_VER_21:
729 init_vals = (u8 *)init_vals_ver_21;
730 break;
731 case QT602240_VER_22:
732 init_vals = (u8 *)init_vals_ver_22;
733 break;
734 default:
735 dev_err(dev, "Firmware version %d doesn't support\n", version);
736 return -EINVAL;
739 for (i = 0; i < data->info.object_num; i++) {
740 object = data->object_table + i;
742 if (!qt602240_object_writable(object->type))
743 continue;
745 for (j = 0; j < object->size + 1; j++)
746 qt602240_write_object(data, object->type, j,
747 init_vals[index + j]);
749 index += object->size + 1;
752 return 0;
755 static int qt602240_check_matrix_size(struct qt602240_data *data)
757 const struct qt602240_platform_data *pdata = data->pdata;
758 struct device *dev = &data->client->dev;
759 int mode = -1;
760 int error;
761 u8 val;
763 dev_dbg(dev, "Number of X lines: %d\n", pdata->x_line);
764 dev_dbg(dev, "Number of Y lines: %d\n", pdata->y_line);
766 switch (pdata->x_line) {
767 case 0 ... 15:
768 if (pdata->y_line <= 14)
769 mode = 0;
770 break;
771 case 16:
772 if (pdata->y_line <= 12)
773 mode = 1;
774 if (pdata->y_line == 13 || pdata->y_line == 14)
775 mode = 0;
776 break;
777 case 17:
778 if (pdata->y_line <= 11)
779 mode = 2;
780 if (pdata->y_line == 12 || pdata->y_line == 13)
781 mode = 1;
782 break;
783 case 18:
784 if (pdata->y_line <= 10)
785 mode = 3;
786 if (pdata->y_line == 11 || pdata->y_line == 12)
787 mode = 2;
788 break;
789 case 19:
790 if (pdata->y_line <= 9)
791 mode = 4;
792 if (pdata->y_line == 10 || pdata->y_line == 11)
793 mode = 3;
794 break;
795 case 20:
796 mode = 4;
799 if (mode < 0) {
800 dev_err(dev, "Invalid X/Y lines\n");
801 return -EINVAL;
804 error = qt602240_read_object(data, QT602240_SPT_CTECONFIG,
805 QT602240_CTE_MODE, &val);
806 if (error)
807 return error;
809 if (mode == val)
810 return 0;
812 /* Change the CTE configuration */
813 qt602240_write_object(data, QT602240_SPT_CTECONFIG,
814 QT602240_CTE_CTRL, 1);
815 qt602240_write_object(data, QT602240_SPT_CTECONFIG,
816 QT602240_CTE_MODE, mode);
817 qt602240_write_object(data, QT602240_SPT_CTECONFIG,
818 QT602240_CTE_CTRL, 0);
820 return 0;
823 static int qt602240_make_highchg(struct qt602240_data *data)
825 struct device *dev = &data->client->dev;
826 int count = 10;
827 int error;
828 u8 val;
830 /* Read dummy message to make high CHG pin */
831 do {
832 error = qt602240_read_object(data, QT602240_GEN_MESSAGE, 0, &val);
833 if (error)
834 return error;
835 } while ((val != 0xff) && --count);
837 if (!count) {
838 dev_err(dev, "CHG pin isn't cleared\n");
839 return -EBUSY;
842 return 0;
845 static void qt602240_handle_pdata(struct qt602240_data *data)
847 const struct qt602240_platform_data *pdata = data->pdata;
848 u8 voltage;
850 /* Set touchscreen lines */
851 qt602240_write_object(data, QT602240_TOUCH_MULTI, QT602240_TOUCH_XSIZE,
852 pdata->x_line);
853 qt602240_write_object(data, QT602240_TOUCH_MULTI, QT602240_TOUCH_YSIZE,
854 pdata->y_line);
856 /* Set touchscreen orient */
857 qt602240_write_object(data, QT602240_TOUCH_MULTI, QT602240_TOUCH_ORIENT,
858 pdata->orient);
860 /* Set touchscreen burst length */
861 qt602240_write_object(data, QT602240_TOUCH_MULTI,
862 QT602240_TOUCH_BLEN, pdata->blen);
864 /* Set touchscreen threshold */
865 qt602240_write_object(data, QT602240_TOUCH_MULTI,
866 QT602240_TOUCH_TCHTHR, pdata->threshold);
868 /* Set touchscreen resolution */
869 qt602240_write_object(data, QT602240_TOUCH_MULTI,
870 QT602240_TOUCH_XRANGE_LSB, (pdata->x_size - 1) & 0xff);
871 qt602240_write_object(data, QT602240_TOUCH_MULTI,
872 QT602240_TOUCH_XRANGE_MSB, (pdata->x_size - 1) >> 8);
873 qt602240_write_object(data, QT602240_TOUCH_MULTI,
874 QT602240_TOUCH_YRANGE_LSB, (pdata->y_size - 1) & 0xff);
875 qt602240_write_object(data, QT602240_TOUCH_MULTI,
876 QT602240_TOUCH_YRANGE_MSB, (pdata->y_size - 1) >> 8);
878 /* Set touchscreen voltage */
879 if (data->info.version >= QT602240_VER_21 && pdata->voltage) {
880 if (pdata->voltage < QT602240_VOLTAGE_DEFAULT) {
881 voltage = (QT602240_VOLTAGE_DEFAULT - pdata->voltage) /
882 QT602240_VOLTAGE_STEP;
883 voltage = 0xff - voltage + 1;
884 } else
885 voltage = (pdata->voltage - QT602240_VOLTAGE_DEFAULT) /
886 QT602240_VOLTAGE_STEP;
888 qt602240_write_object(data, QT602240_SPT_CTECONFIG,
889 QT602240_CTE_VOLTAGE, voltage);
893 static int qt602240_get_info(struct qt602240_data *data)
895 struct i2c_client *client = data->client;
896 struct qt602240_info *info = &data->info;
897 int error;
898 u8 val;
900 error = qt602240_read_reg(client, QT602240_FAMILY_ID, &val);
901 if (error)
902 return error;
903 info->family_id = val;
905 error = qt602240_read_reg(client, QT602240_VARIANT_ID, &val);
906 if (error)
907 return error;
908 info->variant_id = val;
910 error = qt602240_read_reg(client, QT602240_VERSION, &val);
911 if (error)
912 return error;
913 info->version = val;
915 error = qt602240_read_reg(client, QT602240_BUILD, &val);
916 if (error)
917 return error;
918 info->build = val;
920 error = qt602240_read_reg(client, QT602240_OBJECT_NUM, &val);
921 if (error)
922 return error;
923 info->object_num = val;
925 return 0;
928 static int qt602240_get_object_table(struct qt602240_data *data)
930 int error;
931 int i;
932 u16 reg;
933 u8 reportid = 0;
934 u8 buf[QT602240_OBJECT_SIZE];
936 for (i = 0; i < data->info.object_num; i++) {
937 struct qt602240_object *object = data->object_table + i;
939 reg = QT602240_OBJECT_START + QT602240_OBJECT_SIZE * i;
940 error = qt602240_read_object_table(data->client, reg, buf);
941 if (error)
942 return error;
944 object->type = buf[0];
945 object->start_address = (buf[2] << 8) | buf[1];
946 object->size = buf[3];
947 object->instances = buf[4];
948 object->num_report_ids = buf[5];
950 if (object->num_report_ids) {
951 reportid += object->num_report_ids *
952 (object->instances + 1);
953 object->max_reportid = reportid;
957 return 0;
960 static int qt602240_initialize(struct qt602240_data *data)
962 struct i2c_client *client = data->client;
963 struct qt602240_info *info = &data->info;
964 int error;
965 u8 val;
967 error = qt602240_get_info(data);
968 if (error)
969 return error;
971 data->object_table = kcalloc(info->object_num,
972 sizeof(struct qt602240_data),
973 GFP_KERNEL);
974 if (!data->object_table) {
975 dev_err(&client->dev, "Failed to allocate memory\n");
976 return -ENOMEM;
979 /* Get object table information */
980 error = qt602240_get_object_table(data);
981 if (error)
982 return error;
984 /* Check register init values */
985 error = qt602240_check_reg_init(data);
986 if (error)
987 return error;
989 /* Check X/Y matrix size */
990 error = qt602240_check_matrix_size(data);
991 if (error)
992 return error;
994 error = qt602240_make_highchg(data);
995 if (error)
996 return error;
998 qt602240_handle_pdata(data);
1000 /* Backup to memory */
1001 qt602240_write_object(data, QT602240_GEN_COMMAND,
1002 QT602240_COMMAND_BACKUPNV,
1003 QT602240_BACKUP_VALUE);
1004 msleep(QT602240_BACKUP_TIME);
1006 /* Soft reset */
1007 qt602240_write_object(data, QT602240_GEN_COMMAND,
1008 QT602240_COMMAND_RESET, 1);
1009 msleep(QT602240_RESET_TIME);
1011 /* Update matrix size at info struct */
1012 error = qt602240_read_reg(client, QT602240_MATRIX_X_SIZE, &val);
1013 if (error)
1014 return error;
1015 info->matrix_xsize = val;
1017 error = qt602240_read_reg(client, QT602240_MATRIX_Y_SIZE, &val);
1018 if (error)
1019 return error;
1020 info->matrix_ysize = val;
1022 dev_info(&client->dev,
1023 "Family ID: %d Variant ID: %d Version: %d Build: %d\n",
1024 info->family_id, info->variant_id, info->version,
1025 info->build);
1027 dev_info(&client->dev,
1028 "Matrix X Size: %d Matrix Y Size: %d Object Num: %d\n",
1029 info->matrix_xsize, info->matrix_ysize,
1030 info->object_num);
1032 return 0;
1035 static ssize_t qt602240_object_show(struct device *dev,
1036 struct device_attribute *attr, char *buf)
1038 struct qt602240_data *data = dev_get_drvdata(dev);
1039 struct qt602240_object *object;
1040 int count = 0;
1041 int i, j;
1042 int error;
1043 u8 val;
1045 for (i = 0; i < data->info.object_num; i++) {
1046 object = data->object_table + i;
1048 count += sprintf(buf + count,
1049 "Object Table Element %d(Type %d)\n",
1050 i + 1, object->type);
1052 if (!qt602240_object_readable(object->type)) {
1053 count += sprintf(buf + count, "\n");
1054 continue;
1057 for (j = 0; j < object->size + 1; j++) {
1058 error = qt602240_read_object(data,
1059 object->type, j, &val);
1060 if (error)
1061 return error;
1063 count += sprintf(buf + count,
1064 " Byte %d: 0x%x (%d)\n", j, val, val);
1067 count += sprintf(buf + count, "\n");
1070 return count;
1073 static int qt602240_load_fw(struct device *dev, const char *fn)
1075 struct qt602240_data *data = dev_get_drvdata(dev);
1076 struct i2c_client *client = data->client;
1077 const struct firmware *fw = NULL;
1078 unsigned int frame_size;
1079 unsigned int pos = 0;
1080 int ret;
1082 ret = request_firmware(&fw, fn, dev);
1083 if (ret) {
1084 dev_err(dev, "Unable to open firmware %s\n", fn);
1085 return ret;
1088 /* Change to the bootloader mode */
1089 qt602240_write_object(data, QT602240_GEN_COMMAND,
1090 QT602240_COMMAND_RESET, QT602240_BOOT_VALUE);
1091 msleep(QT602240_RESET_TIME);
1093 /* Change to slave address of bootloader */
1094 if (client->addr == QT602240_APP_LOW)
1095 client->addr = QT602240_BOOT_LOW;
1096 else
1097 client->addr = QT602240_BOOT_HIGH;
1099 ret = qt602240_check_bootloader(client, QT602240_WAITING_BOOTLOAD_CMD);
1100 if (ret)
1101 goto out;
1103 /* Unlock bootloader */
1104 qt602240_unlock_bootloader(client);
1106 while (pos < fw->size) {
1107 ret = qt602240_check_bootloader(client,
1108 QT602240_WAITING_FRAME_DATA);
1109 if (ret)
1110 goto out;
1112 frame_size = ((*(fw->data + pos) << 8) | *(fw->data + pos + 1));
1114 /* We should add 2 at frame size as the the firmware data is not
1115 * included the CRC bytes.
1117 frame_size += 2;
1119 /* Write one frame to device */
1120 qt602240_fw_write(client, fw->data + pos, frame_size);
1122 ret = qt602240_check_bootloader(client,
1123 QT602240_FRAME_CRC_PASS);
1124 if (ret)
1125 goto out;
1127 pos += frame_size;
1129 dev_dbg(dev, "Updated %d bytes / %zd bytes\n", pos, fw->size);
1132 out:
1133 release_firmware(fw);
1135 /* Change to slave address of application */
1136 if (client->addr == QT602240_BOOT_LOW)
1137 client->addr = QT602240_APP_LOW;
1138 else
1139 client->addr = QT602240_APP_HIGH;
1141 return ret;
1144 static ssize_t qt602240_update_fw_store(struct device *dev,
1145 struct device_attribute *attr,
1146 const char *buf, size_t count)
1148 struct qt602240_data *data = dev_get_drvdata(dev);
1149 unsigned int version;
1150 int error;
1152 if (sscanf(buf, "%u", &version) != 1) {
1153 dev_err(dev, "Invalid values\n");
1154 return -EINVAL;
1157 if (data->info.version < QT602240_VER_21 || version < QT602240_VER_21) {
1158 dev_err(dev, "FW update supported starting with version 21\n");
1159 return -EINVAL;
1162 disable_irq(data->irq);
1164 error = qt602240_load_fw(dev, QT602240_FW_NAME);
1165 if (error) {
1166 dev_err(dev, "The firmware update failed(%d)\n", error);
1167 count = error;
1168 } else {
1169 dev_dbg(dev, "The firmware update succeeded\n");
1171 /* Wait for reset */
1172 msleep(QT602240_FWRESET_TIME);
1174 kfree(data->object_table);
1175 data->object_table = NULL;
1177 qt602240_initialize(data);
1180 enable_irq(data->irq);
1182 return count;
1185 static DEVICE_ATTR(object, 0444, qt602240_object_show, NULL);
1186 static DEVICE_ATTR(update_fw, 0664, NULL, qt602240_update_fw_store);
1188 static struct attribute *qt602240_attrs[] = {
1189 &dev_attr_object.attr,
1190 &dev_attr_update_fw.attr,
1191 NULL
1194 static const struct attribute_group qt602240_attr_group = {
1195 .attrs = qt602240_attrs,
1198 static void qt602240_start(struct qt602240_data *data)
1200 /* Touch enable */
1201 qt602240_write_object(data,
1202 QT602240_TOUCH_MULTI, QT602240_TOUCH_CTRL, 0x83);
1205 static void qt602240_stop(struct qt602240_data *data)
1207 /* Touch disable */
1208 qt602240_write_object(data,
1209 QT602240_TOUCH_MULTI, QT602240_TOUCH_CTRL, 0);
1212 static int qt602240_input_open(struct input_dev *dev)
1214 struct qt602240_data *data = input_get_drvdata(dev);
1216 qt602240_start(data);
1218 return 0;
1221 static void qt602240_input_close(struct input_dev *dev)
1223 struct qt602240_data *data = input_get_drvdata(dev);
1225 qt602240_stop(data);
1228 static int __devinit qt602240_probe(struct i2c_client *client,
1229 const struct i2c_device_id *id)
1231 struct qt602240_data *data;
1232 struct input_dev *input_dev;
1233 int error;
1235 if (!client->dev.platform_data)
1236 return -EINVAL;
1238 data = kzalloc(sizeof(struct qt602240_data), GFP_KERNEL);
1239 input_dev = input_allocate_device();
1240 if (!data || !input_dev) {
1241 dev_err(&client->dev, "Failed to allocate memory\n");
1242 error = -ENOMEM;
1243 goto err_free_mem;
1246 input_dev->name = "AT42QT602240/ATMXT224 Touchscreen";
1247 input_dev->id.bustype = BUS_I2C;
1248 input_dev->dev.parent = &client->dev;
1249 input_dev->open = qt602240_input_open;
1250 input_dev->close = qt602240_input_close;
1252 __set_bit(EV_ABS, input_dev->evbit);
1253 __set_bit(EV_KEY, input_dev->evbit);
1254 __set_bit(BTN_TOUCH, input_dev->keybit);
1256 /* For single touch */
1257 input_set_abs_params(input_dev, ABS_X,
1258 0, QT602240_MAX_XC, 0, 0);
1259 input_set_abs_params(input_dev, ABS_Y,
1260 0, QT602240_MAX_YC, 0, 0);
1262 /* For multi touch */
1263 input_set_abs_params(input_dev, ABS_MT_TOUCH_MAJOR,
1264 0, QT602240_MAX_AREA, 0, 0);
1265 input_set_abs_params(input_dev, ABS_MT_POSITION_X,
1266 0, QT602240_MAX_XC, 0, 0);
1267 input_set_abs_params(input_dev, ABS_MT_POSITION_Y,
1268 0, QT602240_MAX_YC, 0, 0);
1270 input_set_drvdata(input_dev, data);
1272 data->client = client;
1273 data->input_dev = input_dev;
1274 data->pdata = client->dev.platform_data;
1275 data->irq = client->irq;
1277 i2c_set_clientdata(client, data);
1279 error = qt602240_initialize(data);
1280 if (error)
1281 goto err_free_object;
1283 error = request_threaded_irq(client->irq, NULL, qt602240_interrupt,
1284 IRQF_TRIGGER_FALLING, client->dev.driver->name, data);
1285 if (error) {
1286 dev_err(&client->dev, "Failed to register interrupt\n");
1287 goto err_free_object;
1290 error = input_register_device(input_dev);
1291 if (error)
1292 goto err_free_irq;
1294 error = sysfs_create_group(&client->dev.kobj, &qt602240_attr_group);
1295 if (error)
1296 goto err_unregister_device;
1298 return 0;
1300 err_unregister_device:
1301 input_unregister_device(input_dev);
1302 input_dev = NULL;
1303 err_free_irq:
1304 free_irq(client->irq, data);
1305 err_free_object:
1306 kfree(data->object_table);
1307 err_free_mem:
1308 input_free_device(input_dev);
1309 kfree(data);
1310 return error;
1313 static int __devexit qt602240_remove(struct i2c_client *client)
1315 struct qt602240_data *data = i2c_get_clientdata(client);
1317 sysfs_remove_group(&client->dev.kobj, &qt602240_attr_group);
1318 free_irq(data->irq, data);
1319 input_unregister_device(data->input_dev);
1320 kfree(data->object_table);
1321 kfree(data);
1323 return 0;
1326 #ifdef CONFIG_PM
1327 static int qt602240_suspend(struct i2c_client *client, pm_message_t mesg)
1329 struct qt602240_data *data = i2c_get_clientdata(client);
1330 struct input_dev *input_dev = data->input_dev;
1332 mutex_lock(&input_dev->mutex);
1334 if (input_dev->users)
1335 qt602240_stop(data);
1337 mutex_unlock(&input_dev->mutex);
1339 return 0;
1342 static int qt602240_resume(struct i2c_client *client)
1344 struct qt602240_data *data = i2c_get_clientdata(client);
1345 struct input_dev *input_dev = data->input_dev;
1347 /* Soft reset */
1348 qt602240_write_object(data, QT602240_GEN_COMMAND,
1349 QT602240_COMMAND_RESET, 1);
1351 msleep(QT602240_RESET_TIME);
1353 mutex_lock(&input_dev->mutex);
1355 if (input_dev->users)
1356 qt602240_start(data);
1358 mutex_unlock(&input_dev->mutex);
1360 return 0;
1362 #else
1363 #define qt602240_suspend NULL
1364 #define qt602240_resume NULL
1365 #endif
1367 static const struct i2c_device_id qt602240_id[] = {
1368 { "qt602240_ts", 0 },
1371 MODULE_DEVICE_TABLE(i2c, qt602240_id);
1373 static struct i2c_driver qt602240_driver = {
1374 .driver = {
1375 .name = "qt602240_ts",
1376 .owner = THIS_MODULE,
1378 .probe = qt602240_probe,
1379 .remove = __devexit_p(qt602240_remove),
1380 .suspend = qt602240_suspend,
1381 .resume = qt602240_resume,
1382 .id_table = qt602240_id,
1385 static int __init qt602240_init(void)
1387 return i2c_add_driver(&qt602240_driver);
1390 static void __exit qt602240_exit(void)
1392 i2c_del_driver(&qt602240_driver);
1395 module_init(qt602240_init);
1396 module_exit(qt602240_exit);
1398 /* Module information */
1399 MODULE_AUTHOR("Joonyoung Shim <jy0922.shim@samsung.com>");
1400 MODULE_DESCRIPTION("AT42QT602240/ATMXT224 Touchscreen driver");
1401 MODULE_LICENSE("GPL");