~ubuntu-branches/ubuntu/precise/linux-ti-omap4/precise

« back to all changes in this revision

Viewing changes to drivers/input/touchscreen/qt602240_ts.c

  • Committer: Bazaar Package Importer
  • Author(s): Paolo Pisati
  • Date: 2011-06-29 15:23:51 UTC
  • mfrom: (26.1.1 natty-proposed)
  • Revision ID: james.westby@ubuntu.com-20110629152351-xs96tm303d95rpbk
Tags: 3.0.0-1200.2
* Rebased against 3.0.0-6.7
* BSP from TI based on 3.0.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
2
 
 * AT42QT602240/ATMXT224 Touchscreen driver
3
 
 *
4
 
 * Copyright (C) 2010 Samsung Electronics Co.Ltd
5
 
 * Author: Joonyoung Shim <jy0922.shim@samsung.com>
6
 
 *
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.
11
 
 *
12
 
 */
13
 
 
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>
23
 
 
24
 
/* Version */
25
 
#define QT602240_VER_20                 20
26
 
#define QT602240_VER_21                 21
27
 
#define QT602240_VER_22                 22
28
 
 
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
34
 
 
35
 
/* Firmware */
36
 
#define QT602240_FW_NAME                "qt602240.fw"
37
 
 
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
47
 
 
48
 
#define QT602240_OBJECT_SIZE            6
49
 
 
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 */
68
 
 
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
75
 
 
76
 
/* QT602240_GEN_POWER field */
77
 
#define QT602240_POWER_IDLEACQINT       0
78
 
#define QT602240_POWER_ACTVACQINT       1
79
 
#define QT602240_POWER_ACTV2IDLETO      2
80
 
 
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
89
 
 
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 */
119
 
 
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
132
 
 
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
149
 
 
150
 
/* QT602240_SPT_COMMSCONFIG */
151
 
#define QT602240_COMMS_CTRL             0
152
 
#define QT602240_COMMS_CMD              1
153
 
 
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 */
161
 
 
162
 
#define QT602240_VOLTAGE_DEFAULT        2700000
163
 
#define QT602240_VOLTAGE_STEP           10000
164
 
 
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 */
170
 
 
171
 
#define QT602240_FWRESET_TIME           175     /* msec */
172
 
 
173
 
/* Command to unlock bootloader */
174
 
#define QT602240_UNLOCK_CMD_MSB         0xaa
175
 
#define QT602240_UNLOCK_CMD_LSB         0xdc
176
 
 
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
185
 
 
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)
194
 
 
195
 
/* Touchscreen absolute values */
196
 
#define QT602240_MAX_XC                 0x3ff
197
 
#define QT602240_MAX_YC                 0x3ff
198
 
#define QT602240_MAX_AREA               0xff
199
 
 
200
 
#define QT602240_MAX_FINGER             10
201
 
 
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,
239
 
};
240
 
 
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,
277
 
};
278
 
 
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,
316
 
};
317
 
 
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;
326
 
};
327
 
 
328
 
struct qt602240_object {
329
 
        u8 type;
330
 
        u16 start_address;
331
 
        u8 size;
332
 
        u8 instances;
333
 
        u8 num_report_ids;
334
 
 
335
 
        /* to map object and message */
336
 
        u8 max_reportid;
337
 
};
338
 
 
339
 
struct qt602240_message {
340
 
        u8 reportid;
341
 
        u8 message[7];
342
 
        u8 checksum;
343
 
};
344
 
 
345
 
struct qt602240_finger {
346
 
        int status;
347
 
        int x;
348
 
        int y;
349
 
        int area;
350
 
};
351
 
 
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;
361
 
};
362
 
 
363
 
static bool qt602240_object_readable(unsigned int type)
364
 
{
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;
385
 
        }
386
 
}
387
 
 
388
 
static bool qt602240_object_writable(unsigned int type)
389
 
{
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;
407
 
        }
408
 
}
409
 
 
410
 
static void qt602240_dump_message(struct device *dev,
411
 
                                  struct qt602240_message *message)
412
 
{
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);
422
 
}
423
 
 
424
 
static int qt602240_check_bootloader(struct i2c_client *client,
425
 
                                     unsigned int state)
426
 
{
427
 
        u8 val;
428
 
 
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;
433
 
        }
434
 
 
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;
446
 
        }
447
 
 
448
 
        if (val != state) {
449
 
                dev_err(&client->dev, "Unvalid bootloader mode state\n");
450
 
                return -EINVAL;
451
 
        }
452
 
 
453
 
        return 0;
454
 
}
455
 
 
456
 
static int qt602240_unlock_bootloader(struct i2c_client *client)
457
 
{
458
 
        u8 buf[2];
459
 
 
460
 
        buf[0] = QT602240_UNLOCK_CMD_LSB;
461
 
        buf[1] = QT602240_UNLOCK_CMD_MSB;
462
 
 
463
 
        if (i2c_master_send(client, buf, 2) != 2) {
464
 
                dev_err(&client->dev, "%s: i2c send failed\n", __func__);
465
 
                return -EIO;
466
 
        }
467
 
 
468
 
        return 0;
469
 
}
470
 
 
471
 
static int qt602240_fw_write(struct i2c_client *client,
472
 
                             const u8 *data, unsigned int frame_size)
473
 
{
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;
477
 
        }
478
 
 
479
 
        return 0;
480
 
}
481
 
 
482
 
static int __qt602240_read_reg(struct i2c_client *client,
483
 
                               u16 reg, u16 len, void *val)
484
 
{
485
 
        struct i2c_msg xfer[2];
486
 
        u8 buf[2];
487
 
 
488
 
        buf[0] = reg & 0xff;
489
 
        buf[1] = (reg >> 8) & 0xff;
490
 
 
491
 
        /* Write register */
492
 
        xfer[0].addr = client->addr;
493
 
        xfer[0].flags = 0;
494
 
        xfer[0].len = 2;
495
 
        xfer[0].buf = buf;
496
 
 
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;
502
 
 
503
 
        if (i2c_transfer(client->adapter, xfer, 2) != 2) {
504
 
                dev_err(&client->dev, "%s: i2c transfer failed\n", __func__);
505
 
                return -EIO;
506
 
        }
507
 
 
508
 
        return 0;
509
 
}
510
 
 
511
 
static int qt602240_read_reg(struct i2c_client *client, u16 reg, u8 *val)
512
 
{
513
 
        return __qt602240_read_reg(client, reg, 1, val);
514
 
}
515
 
 
516
 
static int qt602240_write_reg(struct i2c_client *client, u16 reg, u8 val)
517
 
{
518
 
        u8 buf[3];
519
 
 
520
 
        buf[0] = reg & 0xff;
521
 
        buf[1] = (reg >> 8) & 0xff;
522
 
        buf[2] = val;
523
 
 
524
 
        if (i2c_master_send(client, buf, 3) != 3) {
525
 
                dev_err(&client->dev, "%s: i2c send failed\n", __func__);
526
 
                return -EIO;
527
 
        }
528
 
 
529
 
        return 0;
530
 
}
531
 
 
532
 
static int qt602240_read_object_table(struct i2c_client *client,
533
 
                                      u16 reg, u8 *object_buf)
534
 
{
535
 
        return __qt602240_read_reg(client, reg, QT602240_OBJECT_SIZE,
536
 
                                   object_buf);
537
 
}
538
 
 
539
 
static struct qt602240_object *
540
 
qt602240_get_object(struct qt602240_data *data, u8 type)
541
 
{
542
 
        struct qt602240_object *object;
543
 
        int i;
544
 
 
545
 
        for (i = 0; i < data->info.object_num; i++) {
546
 
                object = data->object_table + i;
547
 
                if (object->type == type)
548
 
                        return object;
549
 
        }
550
 
 
551
 
        dev_err(&data->client->dev, "Invalid object type\n");
552
 
        return NULL;
553
 
}
554
 
 
555
 
static int qt602240_read_message(struct qt602240_data *data,
556
 
                                 struct qt602240_message *message)
557
 
{
558
 
        struct qt602240_object *object;
559
 
        u16 reg;
560
 
 
561
 
        object = qt602240_get_object(data, QT602240_GEN_MESSAGE);
562
 
        if (!object)
563
 
                return -EINVAL;
564
 
 
565
 
        reg = object->start_address;
566
 
        return __qt602240_read_reg(data->client, reg,
567
 
                        sizeof(struct qt602240_message), message);
568
 
}
569
 
 
570
 
static int qt602240_read_object(struct qt602240_data *data,
571
 
                                u8 type, u8 offset, u8 *val)
572
 
{
573
 
        struct qt602240_object *object;
574
 
        u16 reg;
575
 
 
576
 
        object = qt602240_get_object(data, type);
577
 
        if (!object)
578
 
                return -EINVAL;
579
 
 
580
 
        reg = object->start_address;
581
 
        return __qt602240_read_reg(data->client, reg + offset, 1, val);
582
 
}
583
 
 
584
 
static int qt602240_write_object(struct qt602240_data *data,
585
 
                                 u8 type, u8 offset, u8 val)
586
 
{
587
 
        struct qt602240_object *object;
588
 
        u16 reg;
589
 
 
590
 
        object = qt602240_get_object(data, type);
591
 
        if (!object)
592
 
                return -EINVAL;
593
 
 
594
 
        reg = object->start_address;
595
 
        return qt602240_write_reg(data->client, reg + offset, val);
596
 
}
597
 
 
598
 
static void qt602240_input_report(struct qt602240_data *data, int single_id)
599
 
{
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;
605
 
 
606
 
        for (id = 0; id < QT602240_MAX_FINGER; id++) {
607
 
                if (!finger[id].status)
608
 
                        continue;
609
 
 
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);
618
 
 
619
 
                if (finger[id].status == QT602240_RELEASE)
620
 
                        finger[id].status = 0;
621
 
                else
622
 
                        finger_num++;
623
 
        }
624
 
 
625
 
        input_report_key(input_dev, BTN_TOUCH, finger_num > 0);
626
 
 
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);
630
 
        }
631
 
 
632
 
        input_sync(input_dev);
633
 
}
634
 
 
635
 
static void qt602240_input_touchevent(struct qt602240_data *data,
636
 
                                      struct qt602240_message *message, int id)
637
 
{
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;
644
 
 
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);
649
 
 
650
 
                        finger[id].status = QT602240_RELEASE;
651
 
                        qt602240_input_report(data, id);
652
 
                }
653
 
                return;
654
 
        }
655
 
 
656
 
        /* Check only AMP detection */
657
 
        if (!(status & (QT602240_PRESS | QT602240_MOVE)))
658
 
                return;
659
 
 
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];
663
 
 
664
 
        dev_dbg(dev, "[%d] %s x: %d, y: %d, area: %d\n", id,
665
 
                status & QT602240_MOVE ? "moved" : "pressed",
666
 
                x, y, area);
667
 
 
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;
673
 
 
674
 
        qt602240_input_report(data, id);
675
 
}
676
 
 
677
 
static irqreturn_t qt602240_interrupt(int irq, void *dev_id)
678
 
{
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;
687
 
 
688
 
        do {
689
 
                if (qt602240_read_message(data, &message)) {
690
 
                        dev_err(dev, "Failed to read message\n");
691
 
                        goto end;
692
 
                }
693
 
 
694
 
                reportid = message.reportid;
695
 
 
696
 
                /* whether reportid is thing of QT602240_TOUCH_MULTI */
697
 
                object = qt602240_get_object(data, QT602240_TOUCH_MULTI);
698
 
                if (!object)
699
 
                        goto end;
700
 
 
701
 
                max_reportid = object->max_reportid;
702
 
                min_reportid = max_reportid - object->num_report_ids + 1;
703
 
                id = reportid - min_reportid;
704
 
 
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);
710
 
 
711
 
end:
712
 
        return IRQ_HANDLED;
713
 
}
714
 
 
715
 
static int qt602240_check_reg_init(struct qt602240_data *data)
716
 
{
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;
723
 
 
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;
737
 
        }
738
 
 
739
 
        for (i = 0; i < data->info.object_num; i++) {
740
 
                object = data->object_table + i;
741
 
 
742
 
                if (!qt602240_object_writable(object->type))
743
 
                        continue;
744
 
 
745
 
                for (j = 0; j < object->size + 1; j++)
746
 
                        qt602240_write_object(data, object->type, j,
747
 
                                        init_vals[index + j]);
748
 
 
749
 
                index += object->size + 1;
750
 
        }
751
 
 
752
 
        return 0;
753
 
}
754
 
 
755
 
static int qt602240_check_matrix_size(struct qt602240_data *data)
756
 
{
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;
762
 
 
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);
765
 
 
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;
797
 
        }
798
 
 
799
 
        if (mode < 0) {
800
 
                dev_err(dev, "Invalid X/Y lines\n");
801
 
                return -EINVAL;
802
 
        }
803
 
 
804
 
        error = qt602240_read_object(data, QT602240_SPT_CTECONFIG,
805
 
                                QT602240_CTE_MODE, &val);
806
 
        if (error)
807
 
                return error;
808
 
 
809
 
        if (mode == val)
810
 
                return 0;
811
 
 
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);
819
 
 
820
 
        return 0;
821
 
}
822
 
 
823
 
static int qt602240_make_highchg(struct qt602240_data *data)
824
 
{
825
 
        struct device *dev = &data->client->dev;
826
 
        int count = 10;
827
 
        int error;
828
 
        u8 val;
829
 
 
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);
836
 
 
837
 
        if (!count) {
838
 
                dev_err(dev, "CHG pin isn't cleared\n");
839
 
                return -EBUSY;
840
 
        }
841
 
 
842
 
        return 0;
843
 
}
844
 
 
845
 
static void qt602240_handle_pdata(struct qt602240_data *data)
846
 
{
847
 
        const struct qt602240_platform_data *pdata = data->pdata;
848
 
        u8 voltage;
849
 
 
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);
855
 
 
856
 
        /* Set touchscreen orient */
857
 
        qt602240_write_object(data, QT602240_TOUCH_MULTI, QT602240_TOUCH_ORIENT,
858
 
                        pdata->orient);
859
 
 
860
 
        /* Set touchscreen burst length */
861
 
        qt602240_write_object(data, QT602240_TOUCH_MULTI,
862
 
                        QT602240_TOUCH_BLEN, pdata->blen);
863
 
 
864
 
        /* Set touchscreen threshold */
865
 
        qt602240_write_object(data, QT602240_TOUCH_MULTI,
866
 
                        QT602240_TOUCH_TCHTHR, pdata->threshold);
867
 
 
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);
877
 
 
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;
887
 
 
888
 
                qt602240_write_object(data, QT602240_SPT_CTECONFIG,
889
 
                                QT602240_CTE_VOLTAGE, voltage);
890
 
        }
891
 
}
892
 
 
893
 
static int qt602240_get_info(struct qt602240_data *data)
894
 
{
895
 
        struct i2c_client *client = data->client;
896
 
        struct qt602240_info *info = &data->info;
897
 
        int error;
898
 
        u8 val;
899
 
 
900
 
        error = qt602240_read_reg(client, QT602240_FAMILY_ID, &val);
901
 
        if (error)
902
 
                return error;
903
 
        info->family_id = val;
904
 
 
905
 
        error = qt602240_read_reg(client, QT602240_VARIANT_ID, &val);
906
 
        if (error)
907
 
                return error;
908
 
        info->variant_id = val;
909
 
 
910
 
        error = qt602240_read_reg(client, QT602240_VERSION, &val);
911
 
        if (error)
912
 
                return error;
913
 
        info->version = val;
914
 
 
915
 
        error = qt602240_read_reg(client, QT602240_BUILD, &val);
916
 
        if (error)
917
 
                return error;
918
 
        info->build = val;
919
 
 
920
 
        error = qt602240_read_reg(client, QT602240_OBJECT_NUM, &val);
921
 
        if (error)
922
 
                return error;
923
 
        info->object_num = val;
924
 
 
925
 
        return 0;
926
 
}
927
 
 
928
 
static int qt602240_get_object_table(struct qt602240_data *data)
929
 
{
930
 
        int error;
931
 
        int i;
932
 
        u16 reg;
933
 
        u8 reportid = 0;
934
 
        u8 buf[QT602240_OBJECT_SIZE];
935
 
 
936
 
        for (i = 0; i < data->info.object_num; i++) {
937
 
                struct qt602240_object *object = data->object_table + i;
938
 
 
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;
943
 
 
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];
949
 
 
950
 
                if (object->num_report_ids) {
951
 
                        reportid += object->num_report_ids *
952
 
                                        (object->instances + 1);
953
 
                        object->max_reportid = reportid;
954
 
                }
955
 
        }
956
 
 
957
 
        return 0;
958
 
}
959
 
 
960
 
static int qt602240_initialize(struct qt602240_data *data)
961
 
{
962
 
        struct i2c_client *client = data->client;
963
 
        struct qt602240_info *info = &data->info;
964
 
        int error;
965
 
        u8 val;
966
 
 
967
 
        error = qt602240_get_info(data);
968
 
        if (error)
969
 
                return error;
970
 
 
971
 
        data->object_table = kcalloc(info->object_num,
972
 
                                     sizeof(struct qt602240_object),
973
 
                                     GFP_KERNEL);
974
 
        if (!data->object_table) {
975
 
                dev_err(&client->dev, "Failed to allocate memory\n");
976
 
                return -ENOMEM;
977
 
        }
978
 
 
979
 
        /* Get object table information */
980
 
        error = qt602240_get_object_table(data);
981
 
        if (error)
982
 
                return error;
983
 
 
984
 
        /* Check register init values */
985
 
        error = qt602240_check_reg_init(data);
986
 
        if (error)
987
 
                return error;
988
 
 
989
 
        /* Check X/Y matrix size */
990
 
        error = qt602240_check_matrix_size(data);
991
 
        if (error)
992
 
                return error;
993
 
 
994
 
        error = qt602240_make_highchg(data);
995
 
        if (error)
996
 
                return error;
997
 
 
998
 
        qt602240_handle_pdata(data);
999
 
 
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);
1005
 
 
1006
 
        /* Soft reset */
1007
 
        qt602240_write_object(data, QT602240_GEN_COMMAND,
1008
 
                        QT602240_COMMAND_RESET, 1);
1009
 
        msleep(QT602240_RESET_TIME);
1010
 
 
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;
1016
 
 
1017
 
        error = qt602240_read_reg(client, QT602240_MATRIX_Y_SIZE, &val);
1018
 
        if (error)
1019
 
                return error;
1020
 
        info->matrix_ysize = val;
1021
 
 
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);
1026
 
 
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);
1031
 
 
1032
 
        return 0;
1033
 
}
1034
 
 
1035
 
static ssize_t qt602240_object_show(struct device *dev,
1036
 
                                    struct device_attribute *attr, char *buf)
1037
 
{
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;
1044
 
 
1045
 
        for (i = 0; i < data->info.object_num; i++) {
1046
 
                object = data->object_table + i;
1047
 
 
1048
 
                count += sprintf(buf + count,
1049
 
                                "Object Table Element %d(Type %d)\n",
1050
 
                                i + 1, object->type);
1051
 
 
1052
 
                if (!qt602240_object_readable(object->type)) {
1053
 
                        count += sprintf(buf + count, "\n");
1054
 
                        continue;
1055
 
                }
1056
 
 
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;
1062
 
 
1063
 
                        count += sprintf(buf + count,
1064
 
                                        "  Byte %d: 0x%x (%d)\n", j, val, val);
1065
 
                }
1066
 
 
1067
 
                count += sprintf(buf + count, "\n");
1068
 
        }
1069
 
 
1070
 
        return count;
1071
 
}
1072
 
 
1073
 
static int qt602240_load_fw(struct device *dev, const char *fn)
1074
 
{
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;
1081
 
 
1082
 
        ret = request_firmware(&fw, fn, dev);
1083
 
        if (ret) {
1084
 
                dev_err(dev, "Unable to open firmware %s\n", fn);
1085
 
                return ret;
1086
 
        }
1087
 
 
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);
1092
 
 
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;
1098
 
 
1099
 
        ret = qt602240_check_bootloader(client, QT602240_WAITING_BOOTLOAD_CMD);
1100
 
        if (ret)
1101
 
                goto out;
1102
 
 
1103
 
        /* Unlock bootloader */
1104
 
        qt602240_unlock_bootloader(client);
1105
 
 
1106
 
        while (pos < fw->size) {
1107
 
                ret = qt602240_check_bootloader(client,
1108
 
                                                QT602240_WAITING_FRAME_DATA);
1109
 
                if (ret)
1110
 
                        goto out;
1111
 
 
1112
 
                frame_size = ((*(fw->data + pos) << 8) | *(fw->data + pos + 1));
1113
 
 
1114
 
                /* We should add 2 at frame size as the the firmware data is not
1115
 
                 * included the CRC bytes.
1116
 
                 */
1117
 
                frame_size += 2;
1118
 
 
1119
 
                /* Write one frame to device */
1120
 
                qt602240_fw_write(client, fw->data + pos, frame_size);
1121
 
 
1122
 
                ret = qt602240_check_bootloader(client,
1123
 
                                                QT602240_FRAME_CRC_PASS);
1124
 
                if (ret)
1125
 
                        goto out;
1126
 
 
1127
 
                pos += frame_size;
1128
 
 
1129
 
                dev_dbg(dev, "Updated %d bytes / %zd bytes\n", pos, fw->size);
1130
 
        }
1131
 
 
1132
 
out:
1133
 
        release_firmware(fw);
1134
 
 
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;
1140
 
 
1141
 
        return ret;
1142
 
}
1143
 
 
1144
 
static ssize_t qt602240_update_fw_store(struct device *dev,
1145
 
                                        struct device_attribute *attr,
1146
 
                                        const char *buf, size_t count)
1147
 
{
1148
 
        struct qt602240_data *data = dev_get_drvdata(dev);
1149
 
        unsigned int version;
1150
 
        int error;
1151
 
 
1152
 
        if (sscanf(buf, "%u", &version) != 1) {
1153
 
                dev_err(dev, "Invalid values\n");
1154
 
                return -EINVAL;
1155
 
        }
1156
 
 
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;
1160
 
        }
1161
 
 
1162
 
        disable_irq(data->irq);
1163
 
 
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");
1170
 
 
1171
 
                /* Wait for reset */
1172
 
                msleep(QT602240_FWRESET_TIME);
1173
 
 
1174
 
                kfree(data->object_table);
1175
 
                data->object_table = NULL;
1176
 
 
1177
 
                qt602240_initialize(data);
1178
 
        }
1179
 
 
1180
 
        enable_irq(data->irq);
1181
 
 
1182
 
        return count;
1183
 
}
1184
 
 
1185
 
static DEVICE_ATTR(object, 0444, qt602240_object_show, NULL);
1186
 
static DEVICE_ATTR(update_fw, 0664, NULL, qt602240_update_fw_store);
1187
 
 
1188
 
static struct attribute *qt602240_attrs[] = {
1189
 
        &dev_attr_object.attr,
1190
 
        &dev_attr_update_fw.attr,
1191
 
        NULL
1192
 
};
1193
 
 
1194
 
static const struct attribute_group qt602240_attr_group = {
1195
 
        .attrs = qt602240_attrs,
1196
 
};
1197
 
 
1198
 
static void qt602240_start(struct qt602240_data *data)
1199
 
{
1200
 
        /* Touch enable */
1201
 
        qt602240_write_object(data,
1202
 
                        QT602240_TOUCH_MULTI, QT602240_TOUCH_CTRL, 0x83);
1203
 
}
1204
 
 
1205
 
static void qt602240_stop(struct qt602240_data *data)
1206
 
{
1207
 
        /* Touch disable */
1208
 
        qt602240_write_object(data,
1209
 
                        QT602240_TOUCH_MULTI, QT602240_TOUCH_CTRL, 0);
1210
 
}
1211
 
 
1212
 
static int qt602240_input_open(struct input_dev *dev)
1213
 
{
1214
 
        struct qt602240_data *data = input_get_drvdata(dev);
1215
 
 
1216
 
        qt602240_start(data);
1217
 
 
1218
 
        return 0;
1219
 
}
1220
 
 
1221
 
static void qt602240_input_close(struct input_dev *dev)
1222
 
{
1223
 
        struct qt602240_data *data = input_get_drvdata(dev);
1224
 
 
1225
 
        qt602240_stop(data);
1226
 
}
1227
 
 
1228
 
static int __devinit qt602240_probe(struct i2c_client *client,
1229
 
                const struct i2c_device_id *id)
1230
 
{
1231
 
        struct qt602240_data *data;
1232
 
        struct input_dev *input_dev;
1233
 
        int error;
1234
 
 
1235
 
        if (!client->dev.platform_data)
1236
 
                return -EINVAL;
1237
 
 
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;
1244
 
        }
1245
 
 
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;
1251
 
 
1252
 
        __set_bit(EV_ABS, input_dev->evbit);
1253
 
        __set_bit(EV_KEY, input_dev->evbit);
1254
 
        __set_bit(BTN_TOUCH, input_dev->keybit);
1255
 
 
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);
1261
 
 
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);
1269
 
 
1270
 
        input_set_drvdata(input_dev, data);
1271
 
 
1272
 
        data->client = client;
1273
 
        data->input_dev = input_dev;
1274
 
        data->pdata = client->dev.platform_data;
1275
 
        data->irq = client->irq;
1276
 
 
1277
 
        i2c_set_clientdata(client, data);
1278
 
 
1279
 
        error = qt602240_initialize(data);
1280
 
        if (error)
1281
 
                goto err_free_object;
1282
 
 
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;
1288
 
        }
1289
 
 
1290
 
        error = input_register_device(input_dev);
1291
 
        if (error)
1292
 
                goto err_free_irq;
1293
 
 
1294
 
        error = sysfs_create_group(&client->dev.kobj, &qt602240_attr_group);
1295
 
        if (error)
1296
 
                goto err_unregister_device;
1297
 
 
1298
 
        return 0;
1299
 
 
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;
1311
 
}
1312
 
 
1313
 
static int __devexit qt602240_remove(struct i2c_client *client)
1314
 
{
1315
 
        struct qt602240_data *data = i2c_get_clientdata(client);
1316
 
 
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);
1322
 
 
1323
 
        return 0;
1324
 
}
1325
 
 
1326
 
#ifdef CONFIG_PM
1327
 
static int qt602240_suspend(struct device *dev)
1328
 
{
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;
1332
 
 
1333
 
        mutex_lock(&input_dev->mutex);
1334
 
 
1335
 
        if (input_dev->users)
1336
 
                qt602240_stop(data);
1337
 
 
1338
 
        mutex_unlock(&input_dev->mutex);
1339
 
 
1340
 
        return 0;
1341
 
}
1342
 
 
1343
 
static int qt602240_resume(struct device *dev)
1344
 
{
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;
1348
 
 
1349
 
        /* Soft reset */
1350
 
        qt602240_write_object(data, QT602240_GEN_COMMAND,
1351
 
                        QT602240_COMMAND_RESET, 1);
1352
 
 
1353
 
        msleep(QT602240_RESET_TIME);
1354
 
 
1355
 
        mutex_lock(&input_dev->mutex);
1356
 
 
1357
 
        if (input_dev->users)
1358
 
                qt602240_start(data);
1359
 
 
1360
 
        mutex_unlock(&input_dev->mutex);
1361
 
 
1362
 
        return 0;
1363
 
}
1364
 
 
1365
 
static const struct dev_pm_ops qt602240_pm_ops = {
1366
 
        .suspend        = qt602240_suspend,
1367
 
        .resume         = qt602240_resume,
1368
 
};
1369
 
#endif
1370
 
 
1371
 
static const struct i2c_device_id qt602240_id[] = {
1372
 
        { "qt602240_ts", 0 },
1373
 
        { }
1374
 
};
1375
 
MODULE_DEVICE_TABLE(i2c, qt602240_id);
1376
 
 
1377
 
static struct i2c_driver qt602240_driver = {
1378
 
        .driver = {
1379
 
                .name   = "qt602240_ts",
1380
 
                .owner  = THIS_MODULE,
1381
 
#ifdef CONFIG_PM
1382
 
                .pm     = &qt602240_pm_ops,
1383
 
#endif
1384
 
        },
1385
 
        .probe          = qt602240_probe,
1386
 
        .remove         = __devexit_p(qt602240_remove),
1387
 
        .id_table       = qt602240_id,
1388
 
};
1389
 
 
1390
 
static int __init qt602240_init(void)
1391
 
{
1392
 
        return i2c_add_driver(&qt602240_driver);
1393
 
}
1394
 
 
1395
 
static void __exit qt602240_exit(void)
1396
 
{
1397
 
        i2c_del_driver(&qt602240_driver);
1398
 
}
1399
 
 
1400
 
module_init(qt602240_init);
1401
 
module_exit(qt602240_exit);
1402
 
 
1403
 
/* Module information */
1404
 
MODULE_AUTHOR("Joonyoung Shim <jy0922.shim@samsung.com>");
1405
 
MODULE_DESCRIPTION("AT42QT602240/ATMXT224 Touchscreen driver");
1406
 
MODULE_LICENSE("GPL");