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>
25
#define QT602240_VER_20 20
26
#define QT602240_VER_21 21
27
#define QT602240_VER_22 22
30
#define QT602240_APP_LOW 0x4a
31
#define QT602240_APP_HIGH 0x4b
32
#define QT602240_BOOT_LOW 0x24
33
#define QT602240_BOOT_HIGH 0x25
36
#define QT602240_FW_NAME "qt602240.fw"
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
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
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) */
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,
217
/* QT602240_SPT_GPIOPWM(19) */
218
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
220
/* QT602240_PROCI_GRIPFACE(20) */
221
0x00, 0x64, 0x64, 0x64, 0x64, 0x00, 0x00, 0x1e, 0x14, 0x04,
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,
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) */
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,
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,
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,
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) */
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,
291
/* QT602240_TOUCH_KEYARRAY(15) */
292
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 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,
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 {
328
struct qt602240_object {
335
/* to map object and message */
339
struct qt602240_message {
345
struct qt602240_finger {
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];
363
static bool qt602240_object_readable(unsigned int 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:
388
static bool qt602240_object_writable(unsigned int 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:
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,
430
if (i2c_master_recv(client, &val, 1) != 1) {
431
dev_err(&client->dev, "%s: i2c recv failed\n", __func__);
436
case QT602240_WAITING_BOOTLOAD_CMD:
437
case QT602240_WAITING_FRAME_DATA:
438
val &= ~QT602240_BOOT_STATUS_MASK;
440
case QT602240_FRAME_CRC_PASS:
441
if (val == QT602240_FRAME_CRC_CHECK)
449
dev_err(&client->dev, "Unvalid bootloader mode state\n");
456
static int qt602240_unlock_bootloader(struct i2c_client *client)
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__);
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__);
482
static int __qt602240_read_reg(struct i2c_client *client,
483
u16 reg, u16 len, void *val)
485
struct i2c_msg xfer[2];
489
buf[1] = (reg >> 8) & 0xff;
492
xfer[0].addr = client->addr;
498
xfer[1].addr = client->addr;
499
xfer[1].flags = I2C_M_RD;
503
if (i2c_transfer(client->adapter, xfer, 2) != 2) {
504
dev_err(&client->dev, "%s: i2c transfer failed\n", __func__);
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)
521
buf[1] = (reg >> 8) & 0xff;
524
if (i2c_master_send(client, buf, 3) != 3) {
525
dev_err(&client->dev, "%s: i2c send failed\n", __func__);
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,
539
static struct qt602240_object *
540
qt602240_get_object(struct qt602240_data *data, u8 type)
542
struct qt602240_object *object;
545
for (i = 0; i < data->info.object_num; i++) {
546
object = data->object_table + i;
547
if (object->type == type)
551
dev_err(&data->client->dev, "Invalid object type\n");
555
static int qt602240_read_message(struct qt602240_data *data,
556
struct qt602240_message *message)
558
struct qt602240_object *object;
561
object = qt602240_get_object(data, QT602240_GEN_MESSAGE);
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;
576
object = qt602240_get_object(data, type);
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;
590
object = qt602240_get_object(data, type);
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;
606
for (id = 0; id < QT602240_MAX_FINGER; id++) {
607
if (!finger[id].status)
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,
615
input_report_abs(input_dev, ABS_MT_POSITION_Y,
617
input_mt_sync(input_dev);
619
if (finger[id].status == QT602240_RELEASE)
620
finger[id].status = 0;
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];
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);
656
/* Check only AMP detection */
657
if (!(status & (QT602240_PRESS | QT602240_MOVE)))
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",
668
finger[id].status = status & QT602240_MOVE ?
669
QT602240_MOVE : QT602240_PRESS;
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;
689
if (qt602240_read_message(data, &message)) {
690
dev_err(dev, "Failed to read message\n");
694
reportid = message.reportid;
696
/* whether reportid is thing of QT602240_TOUCH_MULTI */
697
object = qt602240_get_object(data, QT602240_TOUCH_MULTI);
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);
708
qt602240_dump_message(dev, &message);
709
} while (reportid != 0xff);
715
static int qt602240_check_reg_init(struct qt602240_data *data)
717
struct qt602240_object *object;
718
struct device *dev = &data->client->dev;
721
u8 version = data->info.version;
725
case QT602240_VER_20:
726
init_vals = (u8 *)init_vals_ver_20;
728
case QT602240_VER_21:
729
init_vals = (u8 *)init_vals_ver_21;
731
case QT602240_VER_22:
732
init_vals = (u8 *)init_vals_ver_22;
735
dev_err(dev, "Firmware version %d doesn't support\n", version);
739
for (i = 0; i < data->info.object_num; i++) {
740
object = data->object_table + i;
742
if (!qt602240_object_writable(object->type))
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;
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;
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) {
768
if (pdata->y_line <= 14)
772
if (pdata->y_line <= 12)
774
if (pdata->y_line == 13 || pdata->y_line == 14)
778
if (pdata->y_line <= 11)
780
if (pdata->y_line == 12 || pdata->y_line == 13)
784
if (pdata->y_line <= 10)
786
if (pdata->y_line == 11 || pdata->y_line == 12)
790
if (pdata->y_line <= 9)
792
if (pdata->y_line == 10 || pdata->y_line == 11)
800
dev_err(dev, "Invalid X/Y lines\n");
804
error = qt602240_read_object(data, QT602240_SPT_CTECONFIG,
805
QT602240_CTE_MODE, &val);
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);
823
static int qt602240_make_highchg(struct qt602240_data *data)
825
struct device *dev = &data->client->dev;
830
/* Read dummy message to make high CHG pin */
832
error = qt602240_read_object(data, QT602240_GEN_MESSAGE, 0, &val);
835
} while ((val != 0xff) && --count);
838
dev_err(dev, "CHG pin isn't cleared\n");
845
static void qt602240_handle_pdata(struct qt602240_data *data)
847
const struct qt602240_platform_data *pdata = data->pdata;
850
/* Set touchscreen lines */
851
qt602240_write_object(data, QT602240_TOUCH_MULTI, QT602240_TOUCH_XSIZE,
853
qt602240_write_object(data, QT602240_TOUCH_MULTI, QT602240_TOUCH_YSIZE,
856
/* Set touchscreen orient */
857
qt602240_write_object(data, QT602240_TOUCH_MULTI, QT602240_TOUCH_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;
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;
900
error = qt602240_read_reg(client, QT602240_FAMILY_ID, &val);
903
info->family_id = val;
905
error = qt602240_read_reg(client, QT602240_VARIANT_ID, &val);
908
info->variant_id = val;
910
error = qt602240_read_reg(client, QT602240_VERSION, &val);
915
error = qt602240_read_reg(client, QT602240_BUILD, &val);
920
error = qt602240_read_reg(client, QT602240_OBJECT_NUM, &val);
923
info->object_num = val;
928
static int qt602240_get_object_table(struct qt602240_data *data)
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);
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;
960
static int qt602240_initialize(struct qt602240_data *data)
962
struct i2c_client *client = data->client;
963
struct qt602240_info *info = &data->info;
967
error = qt602240_get_info(data);
971
data->object_table = kcalloc(info->object_num,
972
sizeof(struct qt602240_object),
974
if (!data->object_table) {
975
dev_err(&client->dev, "Failed to allocate memory\n");
979
/* Get object table information */
980
error = qt602240_get_object_table(data);
984
/* Check register init values */
985
error = qt602240_check_reg_init(data);
989
/* Check X/Y matrix size */
990
error = qt602240_check_matrix_size(data);
994
error = qt602240_make_highchg(data);
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);
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);
1015
info->matrix_xsize = val;
1017
error = qt602240_read_reg(client, QT602240_MATRIX_Y_SIZE, &val);
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,
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,
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;
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");
1057
for (j = 0; j < object->size + 1; j++) {
1058
error = qt602240_read_object(data,
1059
object->type, j, &val);
1063
count += sprintf(buf + count,
1064
" Byte %d: 0x%x (%d)\n", j, val, val);
1067
count += sprintf(buf + count, "\n");
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;
1082
ret = request_firmware(&fw, fn, dev);
1084
dev_err(dev, "Unable to open firmware %s\n", fn);
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;
1097
client->addr = QT602240_BOOT_HIGH;
1099
ret = qt602240_check_bootloader(client, QT602240_WAITING_BOOTLOAD_CMD);
1103
/* Unlock bootloader */
1104
qt602240_unlock_bootloader(client);
1106
while (pos < fw->size) {
1107
ret = qt602240_check_bootloader(client,
1108
QT602240_WAITING_FRAME_DATA);
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.
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);
1129
dev_dbg(dev, "Updated %d bytes / %zd bytes\n", pos, fw->size);
1133
release_firmware(fw);
1135
/* Change to slave address of application */
1136
if (client->addr == QT602240_BOOT_LOW)
1137
client->addr = QT602240_APP_LOW;
1139
client->addr = QT602240_APP_HIGH;
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;
1152
if (sscanf(buf, "%u", &version) != 1) {
1153
dev_err(dev, "Invalid values\n");
1157
if (data->info.version < QT602240_VER_21 || version < QT602240_VER_21) {
1158
dev_err(dev, "FW update supported starting with version 21\n");
1162
disable_irq(data->irq);
1164
error = qt602240_load_fw(dev, QT602240_FW_NAME);
1166
dev_err(dev, "The firmware update failed(%d)\n", error);
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);
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,
1194
static const struct attribute_group qt602240_attr_group = {
1195
.attrs = qt602240_attrs,
1198
static void qt602240_start(struct qt602240_data *data)
1201
qt602240_write_object(data,
1202
QT602240_TOUCH_MULTI, QT602240_TOUCH_CTRL, 0x83);
1205
static void qt602240_stop(struct qt602240_data *data)
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);
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;
1235
if (!client->dev.platform_data)
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");
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);
1281
goto err_free_object;
1283
error = request_threaded_irq(client->irq, NULL, qt602240_interrupt,
1284
IRQF_TRIGGER_FALLING, client->dev.driver->name, data);
1286
dev_err(&client->dev, "Failed to register interrupt\n");
1287
goto err_free_object;
1290
error = input_register_device(input_dev);
1294
error = sysfs_create_group(&client->dev.kobj, &qt602240_attr_group);
1296
goto err_unregister_device;
1300
err_unregister_device:
1301
input_unregister_device(input_dev);
1304
free_irq(client->irq, data);
1306
kfree(data->object_table);
1308
input_free_device(input_dev);
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);
1327
static int qt602240_suspend(struct device *dev)
1329
struct i2c_client *client = to_i2c_client(dev);
1330
struct qt602240_data *data = i2c_get_clientdata(client);
1331
struct input_dev *input_dev = data->input_dev;
1333
mutex_lock(&input_dev->mutex);
1335
if (input_dev->users)
1336
qt602240_stop(data);
1338
mutex_unlock(&input_dev->mutex);
1343
static int qt602240_resume(struct device *dev)
1345
struct i2c_client *client = to_i2c_client(dev);
1346
struct qt602240_data *data = i2c_get_clientdata(client);
1347
struct input_dev *input_dev = data->input_dev;
1350
qt602240_write_object(data, QT602240_GEN_COMMAND,
1351
QT602240_COMMAND_RESET, 1);
1353
msleep(QT602240_RESET_TIME);
1355
mutex_lock(&input_dev->mutex);
1357
if (input_dev->users)
1358
qt602240_start(data);
1360
mutex_unlock(&input_dev->mutex);
1365
static const struct dev_pm_ops qt602240_pm_ops = {
1366
.suspend = qt602240_suspend,
1367
.resume = qt602240_resume,
1371
static const struct i2c_device_id qt602240_id[] = {
1372
{ "qt602240_ts", 0 },
1375
MODULE_DEVICE_TABLE(i2c, qt602240_id);
1377
static struct i2c_driver qt602240_driver = {
1379
.name = "qt602240_ts",
1380
.owner = THIS_MODULE,
1382
.pm = &qt602240_pm_ops,
1385
.probe = qt602240_probe,
1386
.remove = __devexit_p(qt602240_remove),
1387
.id_table = qt602240_id,
1390
static int __init qt602240_init(void)
1392
return i2c_add_driver(&qt602240_driver);
1395
static void __exit qt602240_exit(void)
1397
i2c_del_driver(&qt602240_driver);
1400
module_init(qt602240_init);
1401
module_exit(qt602240_exit);
1403
/* Module information */
1404
MODULE_AUTHOR("Joonyoung Shim <jy0922.shim@samsung.com>");
1405
MODULE_DESCRIPTION("AT42QT602240/ATMXT224 Touchscreen driver");
1406
MODULE_LICENSE("GPL");