blob: dc8133d6b914c2b0f2cfe04b0e4beef26cfc663c [file] [log] [blame]
Joonyoung Shim4cf51c32010-07-14 21:55:30 -07001/*
Iiro Valkonen7686b102011-02-02 23:21:58 -08002 * Atmel maXTouch Touchscreen driver
Joonyoung Shim4cf51c32010-07-14 21:55:30 -07003 *
4 * Copyright (C) 2010 Samsung Electronics Co.Ltd
Nick Dyer50a77c62014-07-23 12:38:48 -07005 * Copyright (C) 2011-2014 Atmel Corporation
Daniel Kurtz1e0c0c52014-05-18 23:01:12 -07006 * Copyright (C) 2012 Google, Inc.
7 *
Joonyoung Shim4cf51c32010-07-14 21:55:30 -07008 * Author: Joonyoung Shim <jy0922.shim@samsung.com>
9 *
10 * This program is free software; you can redistribute it and/or modify it
11 * under the terms of the GNU General Public License as published by the
12 * Free Software Foundation; either version 2 of the License, or (at your
13 * option) any later version.
14 *
15 */
16
17#include <linux/module.h>
Benson Leungd79e7e42014-05-18 23:02:52 -070018#include <linux/init.h>
19#include <linux/completion.h>
Joonyoung Shim4cf51c32010-07-14 21:55:30 -070020#include <linux/delay.h>
21#include <linux/firmware.h>
22#include <linux/i2c.h>
Dmitry Torokhov964de522011-02-02 23:21:58 -080023#include <linux/i2c/atmel_mxt_ts.h>
Joonyoung Shim8b86c1c2011-04-12 23:18:59 -070024#include <linux/input/mt.h>
Joonyoung Shim4cf51c32010-07-14 21:55:30 -070025#include <linux/interrupt.h>
Stephen Warren78188be2014-07-23 12:23:23 -070026#include <linux/of.h>
Joonyoung Shim4cf51c32010-07-14 21:55:30 -070027#include <linux/slab.h>
28
29/* Version */
Iiro Valkonen7686b102011-02-02 23:21:58 -080030#define MXT_VER_20 20
31#define MXT_VER_21 21
32#define MXT_VER_22 22
Joonyoung Shim4cf51c32010-07-14 21:55:30 -070033
Nick Dyer50a77c62014-07-23 12:38:48 -070034/* Firmware files */
Iiro Valkonen7686b102011-02-02 23:21:58 -080035#define MXT_FW_NAME "maxtouch.fw"
Nick Dyer50a77c62014-07-23 12:38:48 -070036#define MXT_CFG_NAME "maxtouch.cfg"
37#define MXT_CFG_MAGIC "OBP_RAW V1"
Joonyoung Shim4cf51c32010-07-14 21:55:30 -070038
39/* Registers */
Daniel Kurtz23003a842012-06-28 21:08:14 +080040#define MXT_INFO 0x00
Iiro Valkonen7686b102011-02-02 23:21:58 -080041#define MXT_FAMILY_ID 0x00
42#define MXT_VARIANT_ID 0x01
43#define MXT_VERSION 0x02
44#define MXT_BUILD 0x03
45#define MXT_MATRIX_X_SIZE 0x04
46#define MXT_MATRIX_Y_SIZE 0x05
47#define MXT_OBJECT_NUM 0x06
48#define MXT_OBJECT_START 0x07
Joonyoung Shim4cf51c32010-07-14 21:55:30 -070049
Iiro Valkonen7686b102011-02-02 23:21:58 -080050#define MXT_OBJECT_SIZE 6
Nick Dyer4ce6fa02014-07-23 12:40:09 -070051#define MXT_INFO_CHECKSUM_SIZE 3
52#define MXT_MAX_BLOCK_WRITE 256
Joonyoung Shim4cf51c32010-07-14 21:55:30 -070053
54/* Object types */
Iiro Valkonen81c88a72011-07-04 03:08:25 -070055#define MXT_DEBUG_DIAGNOSTIC_T37 37
56#define MXT_GEN_MESSAGE_T5 5
57#define MXT_GEN_COMMAND_T6 6
58#define MXT_GEN_POWER_T7 7
59#define MXT_GEN_ACQUIRE_T8 8
60#define MXT_GEN_DATASOURCE_T53 53
61#define MXT_TOUCH_MULTI_T9 9
62#define MXT_TOUCH_KEYARRAY_T15 15
63#define MXT_TOUCH_PROXIMITY_T23 23
64#define MXT_TOUCH_PROXKEY_T52 52
65#define MXT_PROCI_GRIPFACE_T20 20
66#define MXT_PROCG_NOISE_T22 22
67#define MXT_PROCI_ONETOUCH_T24 24
68#define MXT_PROCI_TWOTOUCH_T27 27
69#define MXT_PROCI_GRIP_T40 40
70#define MXT_PROCI_PALM_T41 41
71#define MXT_PROCI_TOUCHSUPPRESSION_T42 42
72#define MXT_PROCI_STYLUS_T47 47
73#define MXT_PROCG_NOISESUPPRESSION_T48 48
74#define MXT_SPT_COMMSCONFIG_T18 18
75#define MXT_SPT_GPIOPWM_T19 19
76#define MXT_SPT_SELFTEST_T25 25
77#define MXT_SPT_CTECONFIG_T28 28
78#define MXT_SPT_USERDATA_T38 38
79#define MXT_SPT_DIGITIZER_T43 43
80#define MXT_SPT_MESSAGECOUNT_T44 44
81#define MXT_SPT_CTECONFIG_T46 46
Joonyoung Shim4cf51c32010-07-14 21:55:30 -070082
Iiro Valkonen81c88a72011-07-04 03:08:25 -070083/* MXT_GEN_COMMAND_T6 field */
Iiro Valkonen7686b102011-02-02 23:21:58 -080084#define MXT_COMMAND_RESET 0
85#define MXT_COMMAND_BACKUPNV 1
86#define MXT_COMMAND_CALIBRATE 2
87#define MXT_COMMAND_REPORTALL 3
88#define MXT_COMMAND_DIAGNOSTIC 5
Joonyoung Shim4cf51c32010-07-14 21:55:30 -070089
Iiro Valkonena4a2ef42014-05-18 23:03:44 -070090/* Define for T6 status byte */
91#define MXT_T6_STATUS_RESET (1 << 7)
92
Iiro Valkonen81c88a72011-07-04 03:08:25 -070093/* MXT_GEN_POWER_T7 field */
Iiro Valkonen7686b102011-02-02 23:21:58 -080094#define MXT_POWER_IDLEACQINT 0
95#define MXT_POWER_ACTVACQINT 1
96#define MXT_POWER_ACTV2IDLETO 2
Joonyoung Shim4cf51c32010-07-14 21:55:30 -070097
Iiro Valkonen81c88a72011-07-04 03:08:25 -070098/* MXT_GEN_ACQUIRE_T8 field */
Iiro Valkonen7686b102011-02-02 23:21:58 -080099#define MXT_ACQUIRE_CHRGTIME 0
100#define MXT_ACQUIRE_TCHDRIFT 2
101#define MXT_ACQUIRE_DRIFTST 3
102#define MXT_ACQUIRE_TCHAUTOCAL 4
103#define MXT_ACQUIRE_SYNC 5
104#define MXT_ACQUIRE_ATCHCALST 6
105#define MXT_ACQUIRE_ATCHCALSTHR 7
Joonyoung Shim4cf51c32010-07-14 21:55:30 -0700106
Iiro Valkonen81c88a72011-07-04 03:08:25 -0700107/* MXT_TOUCH_MULTI_T9 field */
Iiro Valkonen7686b102011-02-02 23:21:58 -0800108#define MXT_TOUCH_CTRL 0
Nick Dyer61dc1ab2014-05-18 23:16:49 -0700109#define MXT_T9_ORIENT 9
110#define MXT_T9_RANGE 18
111
Nick Dyerf3889ed2014-05-18 23:22:04 -0700112/* MXT_TOUCH_MULTI_T9 status */
113#define MXT_T9_UNGRIP (1 << 0)
114#define MXT_T9_SUPPRESS (1 << 1)
115#define MXT_T9_AMP (1 << 2)
116#define MXT_T9_VECTOR (1 << 3)
117#define MXT_T9_MOVE (1 << 4)
118#define MXT_T9_RELEASE (1 << 5)
119#define MXT_T9_PRESS (1 << 6)
120#define MXT_T9_DETECT (1 << 7)
121
Nick Dyer61dc1ab2014-05-18 23:16:49 -0700122struct t9_range {
123 u16 x;
124 u16 y;
125} __packed;
126
Nick Dyerf3889ed2014-05-18 23:22:04 -0700127/* MXT_TOUCH_MULTI_T9 orient */
128#define MXT_T9_ORIENT_SWITCH (1 << 0)
Joonyoung Shim4cf51c32010-07-14 21:55:30 -0700129
Iiro Valkonen81c88a72011-07-04 03:08:25 -0700130/* MXT_PROCI_GRIPFACE_T20 field */
Iiro Valkonen7686b102011-02-02 23:21:58 -0800131#define MXT_GRIPFACE_CTRL 0
132#define MXT_GRIPFACE_XLOGRIP 1
133#define MXT_GRIPFACE_XHIGRIP 2
134#define MXT_GRIPFACE_YLOGRIP 3
135#define MXT_GRIPFACE_YHIGRIP 4
136#define MXT_GRIPFACE_MAXTCHS 5
137#define MXT_GRIPFACE_SZTHR1 7
138#define MXT_GRIPFACE_SZTHR2 8
139#define MXT_GRIPFACE_SHPTHR1 9
140#define MXT_GRIPFACE_SHPTHR2 10
141#define MXT_GRIPFACE_SUPEXTTO 11
Joonyoung Shim4cf51c32010-07-14 21:55:30 -0700142
Iiro Valkonen7686b102011-02-02 23:21:58 -0800143/* MXT_PROCI_NOISE field */
144#define MXT_NOISE_CTRL 0
145#define MXT_NOISE_OUTFLEN 1
146#define MXT_NOISE_GCAFUL_LSB 3
147#define MXT_NOISE_GCAFUL_MSB 4
148#define MXT_NOISE_GCAFLL_LSB 5
149#define MXT_NOISE_GCAFLL_MSB 6
150#define MXT_NOISE_ACTVGCAFVALID 7
151#define MXT_NOISE_NOISETHR 8
152#define MXT_NOISE_FREQHOPSCALE 10
153#define MXT_NOISE_FREQ0 11
154#define MXT_NOISE_FREQ1 12
155#define MXT_NOISE_FREQ2 13
156#define MXT_NOISE_FREQ3 14
157#define MXT_NOISE_FREQ4 15
158#define MXT_NOISE_IDLEGCAFVALID 16
Joonyoung Shim4cf51c32010-07-14 21:55:30 -0700159
Iiro Valkonen81c88a72011-07-04 03:08:25 -0700160/* MXT_SPT_COMMSCONFIG_T18 */
Iiro Valkonen7686b102011-02-02 23:21:58 -0800161#define MXT_COMMS_CTRL 0
162#define MXT_COMMS_CMD 1
Joonyoung Shim4cf51c32010-07-14 21:55:30 -0700163
Iiro Valkonen81c88a72011-07-04 03:08:25 -0700164/* MXT_SPT_CTECONFIG_T28 field */
Iiro Valkonen7686b102011-02-02 23:21:58 -0800165#define MXT_CTE_CTRL 0
166#define MXT_CTE_CMD 1
167#define MXT_CTE_MODE 2
168#define MXT_CTE_IDLEGCAFDEPTH 3
169#define MXT_CTE_ACTVGCAFDEPTH 4
Joonyoung Shim979a72d2011-03-14 21:41:34 -0700170#define MXT_CTE_VOLTAGE 5
Joonyoung Shim4cf51c32010-07-14 21:55:30 -0700171
Iiro Valkonen7686b102011-02-02 23:21:58 -0800172#define MXT_VOLTAGE_DEFAULT 2700000
173#define MXT_VOLTAGE_STEP 10000
Joonyoung Shim4cf51c32010-07-14 21:55:30 -0700174
Iiro Valkonen81c88a72011-07-04 03:08:25 -0700175/* Define for MXT_GEN_COMMAND_T6 */
Iiro Valkonen7686b102011-02-02 23:21:58 -0800176#define MXT_BOOT_VALUE 0xa5
Iiro Valkonena4a2ef42014-05-18 23:03:44 -0700177#define MXT_RESET_VALUE 0x01
Iiro Valkonen7686b102011-02-02 23:21:58 -0800178#define MXT_BACKUP_VALUE 0x55
Iiro Valkonena4a2ef42014-05-18 23:03:44 -0700179
180/* Delay times */
Linus Torvalds8343bce2013-03-09 10:31:01 -0800181#define MXT_BACKUP_TIME 50 /* msec */
182#define MXT_RESET_TIME 200 /* msec */
Iiro Valkonena4a2ef42014-05-18 23:03:44 -0700183#define MXT_RESET_TIMEOUT 3000 /* msec */
Nick Dyerc3f78042014-05-18 23:04:46 -0700184#define MXT_CRC_TIMEOUT 1000 /* msec */
Benson Leunga0434b72014-05-18 23:03:09 -0700185#define MXT_FW_RESET_TIME 3000 /* msec */
186#define MXT_FW_CHG_TIMEOUT 300 /* msec */
Joonyoung Shim4cf51c32010-07-14 21:55:30 -0700187
188/* Command to unlock bootloader */
Iiro Valkonen7686b102011-02-02 23:21:58 -0800189#define MXT_UNLOCK_CMD_MSB 0xaa
190#define MXT_UNLOCK_CMD_LSB 0xdc
Joonyoung Shim4cf51c32010-07-14 21:55:30 -0700191
192/* Bootloader mode status */
Iiro Valkonen7686b102011-02-02 23:21:58 -0800193#define MXT_WAITING_BOOTLOAD_CMD 0xc0 /* valid 7 6 bit only */
194#define MXT_WAITING_FRAME_DATA 0x80 /* valid 7 6 bit only */
195#define MXT_FRAME_CRC_CHECK 0x02
196#define MXT_FRAME_CRC_FAIL 0x03
197#define MXT_FRAME_CRC_PASS 0x04
198#define MXT_APP_CRC_FAIL 0x40 /* valid 7 8 bit only */
199#define MXT_BOOT_STATUS_MASK 0x3f
Nick Dyere57a66a2014-05-18 23:13:40 -0700200#define MXT_BOOT_EXTENDED_ID (1 << 5)
201#define MXT_BOOT_ID_MASK 0x1f
Joonyoung Shim4cf51c32010-07-14 21:55:30 -0700202
Joonyoung Shim4cf51c32010-07-14 21:55:30 -0700203/* Touchscreen absolute values */
Iiro Valkonen7686b102011-02-02 23:21:58 -0800204#define MXT_MAX_AREA 0xff
Joonyoung Shim4cf51c32010-07-14 21:55:30 -0700205
Daniel Kurtz22dfab72013-03-07 19:43:33 -0800206#define MXT_PIXELS_PER_MM 20
207
Iiro Valkonen7686b102011-02-02 23:21:58 -0800208struct mxt_info {
Joonyoung Shim4cf51c32010-07-14 21:55:30 -0700209 u8 family_id;
210 u8 variant_id;
211 u8 version;
212 u8 build;
213 u8 matrix_xsize;
214 u8 matrix_ysize;
215 u8 object_num;
216};
217
Iiro Valkonen7686b102011-02-02 23:21:58 -0800218struct mxt_object {
Joonyoung Shim4cf51c32010-07-14 21:55:30 -0700219 u8 type;
220 u16 start_address;
Daniel Kurtz1e0c0c52014-05-18 23:01:12 -0700221 u8 size_minus_one;
222 u8 instances_minus_one;
Joonyoung Shim4cf51c32010-07-14 21:55:30 -0700223 u8 num_report_ids;
Daniel Kurtz333e5a92012-06-28 21:08:20 +0800224} __packed;
Joonyoung Shim4cf51c32010-07-14 21:55:30 -0700225
Iiro Valkonen7686b102011-02-02 23:21:58 -0800226struct mxt_message {
Joonyoung Shim4cf51c32010-07-14 21:55:30 -0700227 u8 reportid;
228 u8 message[7];
Joonyoung Shim4cf51c32010-07-14 21:55:30 -0700229};
230
Joonyoung Shim4cf51c32010-07-14 21:55:30 -0700231/* Each client has this additional data */
Iiro Valkonen7686b102011-02-02 23:21:58 -0800232struct mxt_data {
Joonyoung Shim4cf51c32010-07-14 21:55:30 -0700233 struct i2c_client *client;
234 struct input_dev *input_dev;
Daniel Kurtzec02ac22012-06-28 21:08:02 +0800235 char phys[64]; /* device physical location */
Iiro Valkonen7686b102011-02-02 23:21:58 -0800236 const struct mxt_platform_data *pdata;
237 struct mxt_object *object_table;
238 struct mxt_info info;
Joonyoung Shim4cf51c32010-07-14 21:55:30 -0700239 unsigned int irq;
Joonyoung Shim910d8052011-04-12 23:14:38 -0700240 unsigned int max_x;
241 unsigned int max_y;
Benson Leungd79e7e42014-05-18 23:02:52 -0700242 bool in_bootloader;
Nick Dyer4ce6fa02014-07-23 12:40:09 -0700243 u16 mem_size;
Nick Dyerc3f78042014-05-18 23:04:46 -0700244 u32 config_crc;
Nick Dyer4ce6fa02014-07-23 12:40:09 -0700245 u32 info_crc;
Nick Dyerf28a8422014-05-18 23:10:49 -0700246 u8 bootloader_addr;
Daniel Kurtz333e5a92012-06-28 21:08:20 +0800247
248 /* Cached parameters from object table */
Daniel Kurtzfdf804212012-06-28 21:08:24 +0800249 u8 T6_reportid;
Iiro Valkonena4a2ef42014-05-18 23:03:44 -0700250 u16 T6_address;
Nick Dyer4ce6fa02014-07-23 12:40:09 -0700251 u16 T7_address;
Daniel Kurtz333e5a92012-06-28 21:08:20 +0800252 u8 T9_reportid_min;
253 u8 T9_reportid_max;
Daniel Kurtz22dfab72013-03-07 19:43:33 -0800254 u8 T19_reportid;
Benson Leungd79e7e42014-05-18 23:02:52 -0700255
256 /* for fw update in bootloader */
257 struct completion bl_completion;
Iiro Valkonena4a2ef42014-05-18 23:03:44 -0700258
259 /* for reset handling */
260 struct completion reset_completion;
Nick Dyerc3f78042014-05-18 23:04:46 -0700261
262 /* for config update handling */
263 struct completion crc_completion;
Joonyoung Shim4cf51c32010-07-14 21:55:30 -0700264};
265
Daniel Kurtz1e0c0c52014-05-18 23:01:12 -0700266static size_t mxt_obj_size(const struct mxt_object *obj)
267{
268 return obj->size_minus_one + 1;
269}
270
271static size_t mxt_obj_instances(const struct mxt_object *obj)
272{
273 return obj->instances_minus_one + 1;
274}
275
Iiro Valkonen7686b102011-02-02 23:21:58 -0800276static bool mxt_object_readable(unsigned int type)
Joonyoung Shim4cf51c32010-07-14 21:55:30 -0700277{
278 switch (type) {
Iiro Valkonen81c88a72011-07-04 03:08:25 -0700279 case MXT_GEN_COMMAND_T6:
280 case MXT_GEN_POWER_T7:
281 case MXT_GEN_ACQUIRE_T8:
282 case MXT_GEN_DATASOURCE_T53:
283 case MXT_TOUCH_MULTI_T9:
284 case MXT_TOUCH_KEYARRAY_T15:
285 case MXT_TOUCH_PROXIMITY_T23:
286 case MXT_TOUCH_PROXKEY_T52:
287 case MXT_PROCI_GRIPFACE_T20:
288 case MXT_PROCG_NOISE_T22:
289 case MXT_PROCI_ONETOUCH_T24:
290 case MXT_PROCI_TWOTOUCH_T27:
291 case MXT_PROCI_GRIP_T40:
292 case MXT_PROCI_PALM_T41:
293 case MXT_PROCI_TOUCHSUPPRESSION_T42:
294 case MXT_PROCI_STYLUS_T47:
295 case MXT_PROCG_NOISESUPPRESSION_T48:
296 case MXT_SPT_COMMSCONFIG_T18:
297 case MXT_SPT_GPIOPWM_T19:
298 case MXT_SPT_SELFTEST_T25:
299 case MXT_SPT_CTECONFIG_T28:
300 case MXT_SPT_USERDATA_T38:
301 case MXT_SPT_DIGITIZER_T43:
302 case MXT_SPT_CTECONFIG_T46:
Joonyoung Shim4cf51c32010-07-14 21:55:30 -0700303 return true;
304 default:
305 return false;
306 }
307}
308
Iiro Valkonen7686b102011-02-02 23:21:58 -0800309static void mxt_dump_message(struct device *dev,
Daniel Kurtz6ee3dbf2012-05-08 22:40:29 -0700310 struct mxt_message *message)
Joonyoung Shim4cf51c32010-07-14 21:55:30 -0700311{
Andy Shevchenkoeb007c82012-10-04 00:02:59 -0700312 dev_dbg(dev, "reportid: %u\tmessage: %*ph\n",
313 message->reportid, 7, message->message);
Joonyoung Shim4cf51c32010-07-14 21:55:30 -0700314}
315
Iiro Valkonena4a2ef42014-05-18 23:03:44 -0700316static int mxt_wait_for_completion(struct mxt_data *data,
317 struct completion *comp,
318 unsigned int timeout_ms)
Joonyoung Shim4cf51c32010-07-14 21:55:30 -0700319{
Benson Leungd79e7e42014-05-18 23:02:52 -0700320 struct device *dev = &data->client->dev;
Benson Leungd79e7e42014-05-18 23:02:52 -0700321 unsigned long timeout = msecs_to_jiffies(timeout_ms);
322 long ret;
323
324 ret = wait_for_completion_interruptible_timeout(comp, timeout);
325 if (ret < 0) {
326 return ret;
327 } else if (ret == 0) {
328 dev_err(dev, "Wait for completion timed out.\n");
329 return -ETIMEDOUT;
330 }
331 return 0;
332}
333
Nick Dyerf28a8422014-05-18 23:10:49 -0700334static int mxt_bootloader_read(struct mxt_data *data,
335 u8 *val, unsigned int count)
336{
337 int ret;
338 struct i2c_msg msg;
339
340 msg.addr = data->bootloader_addr;
341 msg.flags = data->client->flags & I2C_M_TEN;
342 msg.flags |= I2C_M_RD;
343 msg.len = count;
344 msg.buf = val;
345
346 ret = i2c_transfer(data->client->adapter, &msg, 1);
347
348 if (ret == 1) {
349 ret = 0;
350 } else {
351 ret = ret < 0 ? ret : -EIO;
352 dev_err(&data->client->dev, "%s: i2c recv failed (%d)\n",
353 __func__, ret);
354 }
355
356 return ret;
357}
358
359static int mxt_bootloader_write(struct mxt_data *data,
360 const u8 * const val, unsigned int count)
361{
362 int ret;
363 struct i2c_msg msg;
364
365 msg.addr = data->bootloader_addr;
366 msg.flags = data->client->flags & I2C_M_TEN;
367 msg.len = count;
368 msg.buf = (u8 *)val;
369
370 ret = i2c_transfer(data->client->adapter, &msg, 1);
371 if (ret == 1) {
372 ret = 0;
373 } else {
374 ret = ret < 0 ? ret : -EIO;
375 dev_err(&data->client->dev, "%s: i2c send failed (%d)\n",
376 __func__, ret);
377 }
378
379 return ret;
380}
381
382static int mxt_lookup_bootloader_address(struct mxt_data *data)
383{
384 u8 appmode = data->client->addr;
385 u8 bootloader;
386
387 switch (appmode) {
388 case 0x4a:
389 case 0x4b:
Nick Dyer44a0bab2014-07-23 12:45:26 -0700390 /* Chips after 1664S use different scheme */
391 if (data->info.family_id >= 0xa2) {
392 bootloader = appmode - 0x24;
393 break;
394 }
395 /* Fall through for normal case */
Nick Dyerf28a8422014-05-18 23:10:49 -0700396 case 0x4c:
397 case 0x4d:
398 case 0x5a:
399 case 0x5b:
400 bootloader = appmode - 0x26;
401 break;
402 default:
403 dev_err(&data->client->dev,
404 "Appmode i2c address 0x%02x not found\n",
405 appmode);
406 return -EINVAL;
407 }
408
409 data->bootloader_addr = bootloader;
410 return 0;
411}
412
Nick Dyera9fdd1e2014-07-23 12:41:58 -0700413static int mxt_probe_bootloader(struct mxt_data *data)
414{
415 struct device *dev = &data->client->dev;
416 int ret;
417 u8 val;
418 bool crc_failure;
419
420 ret = mxt_lookup_bootloader_address(data);
421 if (ret)
422 return ret;
423
424 ret = mxt_bootloader_read(data, &val, 1);
425 if (ret)
426 return ret;
427
428 /* Check app crc fail mode */
429 crc_failure = (val & ~MXT_BOOT_STATUS_MASK) == MXT_APP_CRC_FAIL;
430
431 dev_err(dev, "Detected bootloader, status:%02X%s\n",
432 val, crc_failure ? ", APP_CRC_FAIL" : "");
433
434 return 0;
435}
436
Nick Dyere57a66a2014-05-18 23:13:40 -0700437static u8 mxt_get_bootloader_version(struct mxt_data *data, u8 val)
438{
439 struct device *dev = &data->client->dev;
440 u8 buf[3];
441
442 if (val & MXT_BOOT_EXTENDED_ID) {
443 if (mxt_bootloader_read(data, &buf[0], 3) != 0) {
444 dev_err(dev, "%s: i2c failure\n", __func__);
Nick Dyer68807a02014-06-07 23:17:26 -0700445 return val;
Nick Dyere57a66a2014-05-18 23:13:40 -0700446 }
447
448 dev_dbg(dev, "Bootloader ID:%d Version:%d\n", buf[1], buf[2]);
449
450 return buf[0];
451 } else {
452 dev_dbg(dev, "Bootloader ID:%d\n", val & MXT_BOOT_ID_MASK);
453
454 return val;
455 }
456}
457
Nick Dyer385deb92014-07-23 12:42:40 -0700458static int mxt_check_bootloader(struct mxt_data *data, unsigned int state,
459 bool wait)
Benson Leungd79e7e42014-05-18 23:02:52 -0700460{
Nick Dyerf28a8422014-05-18 23:10:49 -0700461 struct device *dev = &data->client->dev;
Joonyoung Shim4cf51c32010-07-14 21:55:30 -0700462 u8 val;
Benson Leungd79e7e42014-05-18 23:02:52 -0700463 int ret;
Joonyoung Shim4cf51c32010-07-14 21:55:30 -0700464
465recheck:
Nick Dyer385deb92014-07-23 12:42:40 -0700466 if (wait) {
Benson Leungd79e7e42014-05-18 23:02:52 -0700467 /*
468 * In application update mode, the interrupt
469 * line signals state transitions. We must wait for the
470 * CHG assertion before reading the status byte.
471 * Once the status byte has been read, the line is deasserted.
472 */
Iiro Valkonena4a2ef42014-05-18 23:03:44 -0700473 ret = mxt_wait_for_completion(data, &data->bl_completion,
474 MXT_FW_CHG_TIMEOUT);
Benson Leungd79e7e42014-05-18 23:02:52 -0700475 if (ret) {
476 /*
477 * TODO: handle -ERESTARTSYS better by terminating
478 * fw update process before returning to userspace
479 * by writing length 0x000 to device (iff we are in
480 * WAITING_FRAME_DATA state).
481 */
Nick Dyerf28a8422014-05-18 23:10:49 -0700482 dev_err(dev, "Update wait error %d\n", ret);
Benson Leungd79e7e42014-05-18 23:02:52 -0700483 return ret;
484 }
485 }
486
Nick Dyerf28a8422014-05-18 23:10:49 -0700487 ret = mxt_bootloader_read(data, &val, 1);
488 if (ret)
489 return ret;
Joonyoung Shim4cf51c32010-07-14 21:55:30 -0700490
Nick Dyere57a66a2014-05-18 23:13:40 -0700491 if (state == MXT_WAITING_BOOTLOAD_CMD)
492 val = mxt_get_bootloader_version(data, val);
493
Joonyoung Shim4cf51c32010-07-14 21:55:30 -0700494 switch (state) {
Iiro Valkonen7686b102011-02-02 23:21:58 -0800495 case MXT_WAITING_BOOTLOAD_CMD:
496 case MXT_WAITING_FRAME_DATA:
Nick Dyera9fdd1e2014-07-23 12:41:58 -0700497 case MXT_APP_CRC_FAIL:
Iiro Valkonen7686b102011-02-02 23:21:58 -0800498 val &= ~MXT_BOOT_STATUS_MASK;
Joonyoung Shim4cf51c32010-07-14 21:55:30 -0700499 break;
Iiro Valkonen7686b102011-02-02 23:21:58 -0800500 case MXT_FRAME_CRC_PASS:
Nick Dyerf943c742014-05-18 23:14:20 -0700501 if (val == MXT_FRAME_CRC_CHECK) {
Joonyoung Shim4cf51c32010-07-14 21:55:30 -0700502 goto recheck;
Nick Dyerf943c742014-05-18 23:14:20 -0700503 } else if (val == MXT_FRAME_CRC_FAIL) {
504 dev_err(dev, "Bootloader CRC fail\n");
505 return -EINVAL;
506 }
Joonyoung Shim4cf51c32010-07-14 21:55:30 -0700507 break;
508 default:
509 return -EINVAL;
510 }
511
512 if (val != state) {
Nick Dyerf28a8422014-05-18 23:10:49 -0700513 dev_err(dev, "Invalid bootloader state %02X != %02X\n",
Nick Dyer7bed6802014-05-18 23:04:09 -0700514 val, state);
Joonyoung Shim4cf51c32010-07-14 21:55:30 -0700515 return -EINVAL;
516 }
517
518 return 0;
519}
520
Nick Dyerf28a8422014-05-18 23:10:49 -0700521static int mxt_unlock_bootloader(struct mxt_data *data)
Joonyoung Shim4cf51c32010-07-14 21:55:30 -0700522{
Nick Dyerf28a8422014-05-18 23:10:49 -0700523 int ret;
Joonyoung Shim4cf51c32010-07-14 21:55:30 -0700524 u8 buf[2];
525
Iiro Valkonen7686b102011-02-02 23:21:58 -0800526 buf[0] = MXT_UNLOCK_CMD_LSB;
527 buf[1] = MXT_UNLOCK_CMD_MSB;
Joonyoung Shim4cf51c32010-07-14 21:55:30 -0700528
Nick Dyerf28a8422014-05-18 23:10:49 -0700529 ret = mxt_bootloader_write(data, buf, 2);
530 if (ret)
531 return ret;
Joonyoung Shim4cf51c32010-07-14 21:55:30 -0700532
533 return 0;
534}
535
Iiro Valkonen7686b102011-02-02 23:21:58 -0800536static int __mxt_read_reg(struct i2c_client *client,
Joonyoung Shim4cf51c32010-07-14 21:55:30 -0700537 u16 reg, u16 len, void *val)
538{
539 struct i2c_msg xfer[2];
540 u8 buf[2];
Daniel Kurtz771733e2012-06-28 21:08:11 +0800541 int ret;
Joonyoung Shim4cf51c32010-07-14 21:55:30 -0700542
543 buf[0] = reg & 0xff;
544 buf[1] = (reg >> 8) & 0xff;
545
546 /* Write register */
547 xfer[0].addr = client->addr;
548 xfer[0].flags = 0;
549 xfer[0].len = 2;
550 xfer[0].buf = buf;
551
552 /* Read data */
553 xfer[1].addr = client->addr;
554 xfer[1].flags = I2C_M_RD;
555 xfer[1].len = len;
556 xfer[1].buf = val;
557
Daniel Kurtz771733e2012-06-28 21:08:11 +0800558 ret = i2c_transfer(client->adapter, xfer, 2);
559 if (ret == 2) {
560 ret = 0;
561 } else {
562 if (ret >= 0)
563 ret = -EIO;
564 dev_err(&client->dev, "%s: i2c transfer failed (%d)\n",
565 __func__, ret);
Joonyoung Shim4cf51c32010-07-14 21:55:30 -0700566 }
567
Daniel Kurtz771733e2012-06-28 21:08:11 +0800568 return ret;
Joonyoung Shim4cf51c32010-07-14 21:55:30 -0700569}
570
Daniel Kurtz9638ab72012-06-28 21:08:12 +0800571static int __mxt_write_reg(struct i2c_client *client, u16 reg, u16 len,
572 const void *val)
Joonyoung Shim4cf51c32010-07-14 21:55:30 -0700573{
Daniel Kurtz9638ab72012-06-28 21:08:12 +0800574 u8 *buf;
575 size_t count;
Daniel Kurtz771733e2012-06-28 21:08:11 +0800576 int ret;
Joonyoung Shim4cf51c32010-07-14 21:55:30 -0700577
Daniel Kurtz9638ab72012-06-28 21:08:12 +0800578 count = len + 2;
579 buf = kmalloc(count, GFP_KERNEL);
580 if (!buf)
581 return -ENOMEM;
Joonyoung Shim4cf51c32010-07-14 21:55:30 -0700582
583 buf[0] = reg & 0xff;
584 buf[1] = (reg >> 8) & 0xff;
Daniel Kurtz9638ab72012-06-28 21:08:12 +0800585 memcpy(&buf[2], val, len);
Joonyoung Shim4cf51c32010-07-14 21:55:30 -0700586
Daniel Kurtz9638ab72012-06-28 21:08:12 +0800587 ret = i2c_master_send(client, buf, count);
588 if (ret == count) {
Daniel Kurtz771733e2012-06-28 21:08:11 +0800589 ret = 0;
590 } else {
591 if (ret >= 0)
592 ret = -EIO;
593 dev_err(&client->dev, "%s: i2c send failed (%d)\n",
594 __func__, ret);
Joonyoung Shim4cf51c32010-07-14 21:55:30 -0700595 }
596
Daniel Kurtz9638ab72012-06-28 21:08:12 +0800597 kfree(buf);
Daniel Kurtz771733e2012-06-28 21:08:11 +0800598 return ret;
Joonyoung Shim4cf51c32010-07-14 21:55:30 -0700599}
600
Daniel Kurtz9638ab72012-06-28 21:08:12 +0800601static int mxt_write_reg(struct i2c_client *client, u16 reg, u8 val)
Joonyoung Shim4cf51c32010-07-14 21:55:30 -0700602{
Daniel Kurtz9638ab72012-06-28 21:08:12 +0800603 return __mxt_write_reg(client, reg, 1, &val);
Joonyoung Shim4cf51c32010-07-14 21:55:30 -0700604}
605
Iiro Valkonen7686b102011-02-02 23:21:58 -0800606static struct mxt_object *
607mxt_get_object(struct mxt_data *data, u8 type)
Joonyoung Shim4cf51c32010-07-14 21:55:30 -0700608{
Iiro Valkonen7686b102011-02-02 23:21:58 -0800609 struct mxt_object *object;
Joonyoung Shim4cf51c32010-07-14 21:55:30 -0700610 int i;
611
612 for (i = 0; i < data->info.object_num; i++) {
613 object = data->object_table + i;
614 if (object->type == type)
615 return object;
616 }
617
Nick Dyer50a77c62014-07-23 12:38:48 -0700618 dev_warn(&data->client->dev, "Invalid object type T%u\n", type);
Joonyoung Shim4cf51c32010-07-14 21:55:30 -0700619 return NULL;
620}
621
Iiro Valkonen7686b102011-02-02 23:21:58 -0800622static int mxt_read_message(struct mxt_data *data,
623 struct mxt_message *message)
Joonyoung Shim4cf51c32010-07-14 21:55:30 -0700624{
Iiro Valkonen7686b102011-02-02 23:21:58 -0800625 struct mxt_object *object;
Joonyoung Shim4cf51c32010-07-14 21:55:30 -0700626 u16 reg;
627
Iiro Valkonen81c88a72011-07-04 03:08:25 -0700628 object = mxt_get_object(data, MXT_GEN_MESSAGE_T5);
Joonyoung Shim4cf51c32010-07-14 21:55:30 -0700629 if (!object)
630 return -EINVAL;
631
632 reg = object->start_address;
Iiro Valkonen7686b102011-02-02 23:21:58 -0800633 return __mxt_read_reg(data->client, reg,
634 sizeof(struct mxt_message), message);
Joonyoung Shim4cf51c32010-07-14 21:55:30 -0700635}
636
Iiro Valkonen7686b102011-02-02 23:21:58 -0800637static int mxt_write_object(struct mxt_data *data,
Joonyoung Shim4cf51c32010-07-14 21:55:30 -0700638 u8 type, u8 offset, u8 val)
639{
Iiro Valkonen7686b102011-02-02 23:21:58 -0800640 struct mxt_object *object;
Joonyoung Shim4cf51c32010-07-14 21:55:30 -0700641 u16 reg;
642
Iiro Valkonen7686b102011-02-02 23:21:58 -0800643 object = mxt_get_object(data, type);
Daniel Kurtz1e0c0c52014-05-18 23:01:12 -0700644 if (!object || offset >= mxt_obj_size(object))
Joonyoung Shim4cf51c32010-07-14 21:55:30 -0700645 return -EINVAL;
646
647 reg = object->start_address;
Iiro Valkonen7686b102011-02-02 23:21:58 -0800648 return mxt_write_reg(data->client, reg + offset, val);
Joonyoung Shim4cf51c32010-07-14 21:55:30 -0700649}
650
Daniel Kurtz22dfab72013-03-07 19:43:33 -0800651static void mxt_input_button(struct mxt_data *data, struct mxt_message *message)
652{
653 struct input_dev *input = data->input_dev;
Nick Dyerfb5e4c3e2014-05-18 23:00:15 -0700654 const struct mxt_platform_data *pdata = data->pdata;
Daniel Kurtz22dfab72013-03-07 19:43:33 -0800655 bool button;
656 int i;
657
658 /* Active-low switch */
Nick Dyerfb5e4c3e2014-05-18 23:00:15 -0700659 for (i = 0; i < pdata->t19_num_keys; i++) {
660 if (pdata->t19_keymap[i] == KEY_RESERVED)
Daniel Kurtz22dfab72013-03-07 19:43:33 -0800661 continue;
Nick Dyerfb5e4c3e2014-05-18 23:00:15 -0700662 button = !(message->message[0] & (1 << i));
663 input_report_key(input, pdata->t19_keymap[i], button);
Daniel Kurtz22dfab72013-03-07 19:43:33 -0800664 }
665}
666
Benson Leungb735fbe2014-07-23 12:22:27 -0700667static void mxt_input_sync(struct mxt_data *data)
Nick Dyereef820d2014-05-18 23:22:22 -0700668{
Benson Leungb735fbe2014-07-23 12:22:27 -0700669 input_mt_report_pointer_emulation(data->input_dev,
670 data->pdata->t19_num_keys);
671 input_sync(data->input_dev);
Nick Dyereef820d2014-05-18 23:22:22 -0700672}
673
Iiro Valkonen7686b102011-02-02 23:21:58 -0800674static void mxt_input_touchevent(struct mxt_data *data,
675 struct mxt_message *message, int id)
Joonyoung Shim4cf51c32010-07-14 21:55:30 -0700676{
Joonyoung Shim4cf51c32010-07-14 21:55:30 -0700677 struct device *dev = &data->client->dev;
678 u8 status = message->message[0];
Daniel Kurtzfba5bc32012-06-28 21:08:17 +0800679 struct input_dev *input_dev = data->input_dev;
Joonyoung Shim4cf51c32010-07-14 21:55:30 -0700680 int x;
681 int y;
682 int area;
Nick Dyerfea9e462014-05-18 23:21:48 -0700683 int amplitude;
Joonyoung Shim4cf51c32010-07-14 21:55:30 -0700684
Joonyoung Shim910d8052011-04-12 23:14:38 -0700685 x = (message->message[1] << 4) | ((message->message[3] >> 4) & 0xf);
686 y = (message->message[2] << 4) | ((message->message[3] & 0xf));
Nick Dyereef820d2014-05-18 23:22:22 -0700687
688 /* Handle 10/12 bit switching */
Joonyoung Shim910d8052011-04-12 23:14:38 -0700689 if (data->max_x < 1024)
Nick Dyereef820d2014-05-18 23:22:22 -0700690 x >>= 2;
Joonyoung Shim910d8052011-04-12 23:14:38 -0700691 if (data->max_y < 1024)
Nick Dyereef820d2014-05-18 23:22:22 -0700692 y >>= 2;
Joonyoung Shim910d8052011-04-12 23:14:38 -0700693
Joonyoung Shim4cf51c32010-07-14 21:55:30 -0700694 area = message->message[4];
Nick Dyerfea9e462014-05-18 23:21:48 -0700695 amplitude = message->message[5];
Joonyoung Shim4cf51c32010-07-14 21:55:30 -0700696
Daniel Kurtzb2e459b2012-06-28 21:08:18 +0800697 dev_dbg(dev,
698 "[%u] %c%c%c%c%c%c%c%c x: %5u y: %5u area: %3u amp: %3u\n",
699 id,
Nick Dyerf3889ed2014-05-18 23:22:04 -0700700 (status & MXT_T9_DETECT) ? 'D' : '.',
701 (status & MXT_T9_PRESS) ? 'P' : '.',
702 (status & MXT_T9_RELEASE) ? 'R' : '.',
703 (status & MXT_T9_MOVE) ? 'M' : '.',
704 (status & MXT_T9_VECTOR) ? 'V' : '.',
705 (status & MXT_T9_AMP) ? 'A' : '.',
706 (status & MXT_T9_SUPPRESS) ? 'S' : '.',
707 (status & MXT_T9_UNGRIP) ? 'U' : '.',
Nick Dyerfea9e462014-05-18 23:21:48 -0700708 x, y, area, amplitude);
Joonyoung Shim4cf51c32010-07-14 21:55:30 -0700709
Daniel Kurtzfba5bc32012-06-28 21:08:17 +0800710 input_mt_slot(input_dev, id);
Joonyoung Shim4cf51c32010-07-14 21:55:30 -0700711
Nick Dyerf3889ed2014-05-18 23:22:04 -0700712 if (status & MXT_T9_DETECT) {
Nick Dyereef820d2014-05-18 23:22:22 -0700713 /*
714 * Multiple bits may be set if the host is slow to read
715 * the status messages, indicating all the events that
716 * have happened.
717 */
718 if (status & MXT_T9_RELEASE) {
719 input_mt_report_slot_state(input_dev,
720 MT_TOOL_FINGER, 0);
Benson Leungb735fbe2014-07-23 12:22:27 -0700721 mxt_input_sync(data);
Nick Dyereef820d2014-05-18 23:22:22 -0700722 }
723
724 /* Touch active */
725 input_mt_report_slot_state(input_dev, MT_TOOL_FINGER, 1);
Daniel Kurtzfba5bc32012-06-28 21:08:17 +0800726 input_report_abs(input_dev, ABS_MT_POSITION_X, x);
727 input_report_abs(input_dev, ABS_MT_POSITION_Y, y);
Nick Dyerfea9e462014-05-18 23:21:48 -0700728 input_report_abs(input_dev, ABS_MT_PRESSURE, amplitude);
Daniel Kurtzfba5bc32012-06-28 21:08:17 +0800729 input_report_abs(input_dev, ABS_MT_TOUCH_MAJOR, area);
Nick Dyereef820d2014-05-18 23:22:22 -0700730 } else {
731 /* Touch no longer active, close out slot */
732 input_mt_report_slot_state(input_dev, MT_TOOL_FINGER, 0);
Daniel Kurtzfba5bc32012-06-28 21:08:17 +0800733 }
Joonyoung Shim4cf51c32010-07-14 21:55:30 -0700734}
735
Nick Dyerc3f78042014-05-18 23:04:46 -0700736static u16 mxt_extract_T6_csum(const u8 *csum)
Daniel Kurtzfdf804212012-06-28 21:08:24 +0800737{
738 return csum[0] | (csum[1] << 8) | (csum[2] << 16);
739}
740
Daniel Kurtz04a79182012-06-28 21:08:21 +0800741static bool mxt_is_T9_message(struct mxt_data *data, struct mxt_message *msg)
742{
743 u8 id = msg->reportid;
744 return (id >= data->T9_reportid_min && id <= data->T9_reportid_max);
Joonyoung Shim4cf51c32010-07-14 21:55:30 -0700745}
746
Benson Leungd79e7e42014-05-18 23:02:52 -0700747static irqreturn_t mxt_process_messages_until_invalid(struct mxt_data *data)
Joonyoung Shim4cf51c32010-07-14 21:55:30 -0700748{
Iiro Valkonen7686b102011-02-02 23:21:58 -0800749 struct mxt_message message;
Daniel Kurtzfdf804212012-06-28 21:08:24 +0800750 const u8 *payload = &message.message[0];
Joonyoung Shim4cf51c32010-07-14 21:55:30 -0700751 struct device *dev = &data->client->dev;
Joonyoung Shim4cf51c32010-07-14 21:55:30 -0700752 u8 reportid;
Daniel Kurtz64464ae2012-06-28 21:08:23 +0800753 bool update_input = false;
Nick Dyerc3f78042014-05-18 23:04:46 -0700754 u32 crc;
Joonyoung Shim4cf51c32010-07-14 21:55:30 -0700755
756 do {
Iiro Valkonen7686b102011-02-02 23:21:58 -0800757 if (mxt_read_message(data, &message)) {
Joonyoung Shim4cf51c32010-07-14 21:55:30 -0700758 dev_err(dev, "Failed to read message\n");
Nick Dyer8d4e1632014-05-18 23:00:56 -0700759 return IRQ_NONE;
Joonyoung Shim4cf51c32010-07-14 21:55:30 -0700760 }
761
762 reportid = message.reportid;
763
Daniel Kurtzfdf804212012-06-28 21:08:24 +0800764 if (reportid == data->T6_reportid) {
765 u8 status = payload[0];
Nick Dyerc3f78042014-05-18 23:04:46 -0700766
767 crc = mxt_extract_T6_csum(&payload[1]);
768 if (crc != data->config_crc) {
769 data->config_crc = crc;
770 complete(&data->crc_completion);
771 }
772
Daniel Kurtzfdf804212012-06-28 21:08:24 +0800773 dev_dbg(dev, "Status: %02x Config Checksum: %06x\n",
Nick Dyerc3f78042014-05-18 23:04:46 -0700774 status, data->config_crc);
Iiro Valkonena4a2ef42014-05-18 23:03:44 -0700775
776 if (status & MXT_T6_STATUS_RESET)
777 complete(&data->reset_completion);
Nick Dyerdd24dcf2014-07-23 11:25:55 -0700778 } else if (!data->input_dev) {
779 /*
780 * do not report events if input device
781 * is not yet registered
782 */
783 mxt_dump_message(dev, &message);
Daniel Kurtzfdf804212012-06-28 21:08:24 +0800784 } else if (mxt_is_T9_message(data, &message)) {
785 int id = reportid - data->T9_reportid_min;
Iiro Valkonen7686b102011-02-02 23:21:58 -0800786 mxt_input_touchevent(data, &message, id);
Daniel Kurtz64464ae2012-06-28 21:08:23 +0800787 update_input = true;
Daniel Kurtz22dfab72013-03-07 19:43:33 -0800788 } else if (message.reportid == data->T19_reportid) {
789 mxt_input_button(data, &message);
790 update_input = true;
Daniel Kurtz64464ae2012-06-28 21:08:23 +0800791 } else {
Iiro Valkonen7686b102011-02-02 23:21:58 -0800792 mxt_dump_message(dev, &message);
Daniel Kurtz64464ae2012-06-28 21:08:23 +0800793 }
Joonyoung Shim4cf51c32010-07-14 21:55:30 -0700794 } while (reportid != 0xff);
795
Nick Dyereef820d2014-05-18 23:22:22 -0700796 if (update_input)
Benson Leungb735fbe2014-07-23 12:22:27 -0700797 mxt_input_sync(data);
Daniel Kurtz64464ae2012-06-28 21:08:23 +0800798
Joonyoung Shim4cf51c32010-07-14 21:55:30 -0700799 return IRQ_HANDLED;
800}
801
Benson Leungd79e7e42014-05-18 23:02:52 -0700802static irqreturn_t mxt_interrupt(int irq, void *dev_id)
803{
804 struct mxt_data *data = dev_id;
805
806 if (data->in_bootloader) {
807 /* bootloader state transition completion */
808 complete(&data->bl_completion);
809 return IRQ_HANDLED;
810 }
811
Nick Dyerdd24dcf2014-07-23 11:25:55 -0700812 if (!data->object_table)
813 return IRQ_HANDLED;
814
Benson Leungd79e7e42014-05-18 23:02:52 -0700815 return mxt_process_messages_until_invalid(data);
816}
817
Iiro Valkonena4a2ef42014-05-18 23:03:44 -0700818static int mxt_t6_command(struct mxt_data *data, u16 cmd_offset,
819 u8 value, bool wait)
820{
821 u16 reg;
822 u8 command_register;
823 int timeout_counter = 0;
824 int ret;
825
826 reg = data->T6_address + cmd_offset;
827
828 ret = mxt_write_reg(data->client, reg, value);
829 if (ret)
830 return ret;
831
832 if (!wait)
833 return 0;
834
835 do {
836 msleep(20);
837 ret = __mxt_read_reg(data->client, reg, 1, &command_register);
838 if (ret)
839 return ret;
840 } while (command_register != 0 && timeout_counter++ <= 100);
841
842 if (timeout_counter > 100) {
843 dev_err(&data->client->dev, "Command failed!\n");
844 return -EIO;
845 }
846
847 return 0;
848}
849
850static int mxt_soft_reset(struct mxt_data *data)
851{
852 struct device *dev = &data->client->dev;
853 int ret = 0;
854
855 dev_info(dev, "Resetting chip\n");
856
857 reinit_completion(&data->reset_completion);
858
859 ret = mxt_t6_command(data, MXT_COMMAND_RESET, MXT_RESET_VALUE, false);
860 if (ret)
861 return ret;
862
863 ret = mxt_wait_for_completion(data, &data->reset_completion,
864 MXT_RESET_TIMEOUT);
865 if (ret)
866 return ret;
867
868 return 0;
869}
870
Nick Dyerc3f78042014-05-18 23:04:46 -0700871static void mxt_update_crc(struct mxt_data *data, u8 cmd, u8 value)
872{
873 /*
874 * On failure, CRC is set to 0 and config will always be
875 * downloaded.
876 */
877 data->config_crc = 0;
878 reinit_completion(&data->crc_completion);
879
880 mxt_t6_command(data, cmd, value, true);
881
882 /*
883 * Wait for crc message. On failure, CRC is set to 0 and config will
884 * always be downloaded.
885 */
886 mxt_wait_for_completion(data, &data->crc_completion, MXT_CRC_TIMEOUT);
887}
888
Nick Dyer4ce6fa02014-07-23 12:40:09 -0700889static void mxt_calc_crc24(u32 *crc, u8 firstbyte, u8 secondbyte)
890{
891 static const unsigned int crcpoly = 0x80001B;
892 u32 result;
893 u32 data_word;
894
895 data_word = (secondbyte << 8) | firstbyte;
896 result = ((*crc << 1) ^ data_word);
897
898 if (result & 0x1000000)
899 result ^= crcpoly;
900
901 *crc = result;
902}
903
904static u32 mxt_calculate_crc(u8 *base, off_t start_off, off_t end_off)
905{
906 u32 crc = 0;
907 u8 *ptr = base + start_off;
908 u8 *last_val = base + end_off - 1;
909
910 if (end_off < start_off)
911 return -EINVAL;
912
913 while (ptr < last_val) {
914 mxt_calc_crc24(&crc, *ptr, *(ptr + 1));
915 ptr += 2;
916 }
917
918 /* if len is odd, fill the last byte with 0 */
919 if (ptr == last_val)
920 mxt_calc_crc24(&crc, *ptr, 0);
921
922 /* Mask to 24-bit */
923 crc &= 0x00FFFFFF;
924
925 return crc;
926}
927
Nick Dyer50a77c62014-07-23 12:38:48 -0700928/*
929 * mxt_update_cfg - download configuration to chip
930 *
931 * Atmel Raw Config File Format
932 *
933 * The first four lines of the raw config file contain:
934 * 1) Version
935 * 2) Chip ID Information (first 7 bytes of device memory)
936 * 3) Chip Information Block 24-bit CRC Checksum
937 * 4) Chip Configuration 24-bit CRC Checksum
938 *
939 * The rest of the file consists of one line per object instance:
940 * <TYPE> <INSTANCE> <SIZE> <CONTENTS>
941 *
942 * <TYPE> - 2-byte object type as hex
943 * <INSTANCE> - 2-byte object instance number as hex
944 * <SIZE> - 2-byte object size as hex
945 * <CONTENTS> - array of <SIZE> 1-byte hex values
946 */
947static int mxt_update_cfg(struct mxt_data *data, const struct firmware *cfg)
Joonyoung Shim4cf51c32010-07-14 21:55:30 -0700948{
Joonyoung Shim4cf51c32010-07-14 21:55:30 -0700949 struct device *dev = &data->client->dev;
Nick Dyer50a77c62014-07-23 12:38:48 -0700950 struct mxt_info cfg_info;
951 struct mxt_object *object;
Daniel Kurtzcf94bc02012-06-28 21:08:13 +0800952 int ret;
Nick Dyer50a77c62014-07-23 12:38:48 -0700953 int offset;
Nick Dyer4ce6fa02014-07-23 12:40:09 -0700954 int data_pos;
955 int byte_offset;
Nick Dyer50a77c62014-07-23 12:38:48 -0700956 int i;
Nick Dyer4ce6fa02014-07-23 12:40:09 -0700957 int cfg_start_ofs;
958 u32 info_crc, config_crc, calculated_crc;
959 u8 *config_mem;
960 size_t config_mem_size;
Nick Dyer50a77c62014-07-23 12:38:48 -0700961 unsigned int type, instance, size;
962 u8 val;
963 u16 reg;
Joonyoung Shim4cf51c32010-07-14 21:55:30 -0700964
Nick Dyerc3f78042014-05-18 23:04:46 -0700965 mxt_update_crc(data, MXT_COMMAND_REPORTALL, 1);
966
Nick Dyer50a77c62014-07-23 12:38:48 -0700967 if (strncmp(cfg->data, MXT_CFG_MAGIC, strlen(MXT_CFG_MAGIC))) {
968 dev_err(dev, "Unrecognised config file\n");
969 ret = -EINVAL;
970 goto release;
Nick Dyerc3f78042014-05-18 23:04:46 -0700971 }
972
Nick Dyer4ce6fa02014-07-23 12:40:09 -0700973 data_pos = strlen(MXT_CFG_MAGIC);
Nick Dyerc3f78042014-05-18 23:04:46 -0700974
Nick Dyer50a77c62014-07-23 12:38:48 -0700975 /* Load information block and check */
976 for (i = 0; i < sizeof(struct mxt_info); i++) {
Nick Dyer4ce6fa02014-07-23 12:40:09 -0700977 ret = sscanf(cfg->data + data_pos, "%hhx%n",
Nick Dyer50a77c62014-07-23 12:38:48 -0700978 (unsigned char *)&cfg_info + i,
979 &offset);
980 if (ret != 1) {
981 dev_err(dev, "Bad format\n");
982 ret = -EINVAL;
983 goto release;
Iiro Valkonen71749f52011-02-15 13:36:52 -0800984 }
Daniel Kurtzcf94bc02012-06-28 21:08:13 +0800985
Nick Dyer4ce6fa02014-07-23 12:40:09 -0700986 data_pos += offset;
Nick Dyer50a77c62014-07-23 12:38:48 -0700987 }
988
989 if (cfg_info.family_id != data->info.family_id) {
990 dev_err(dev, "Family ID mismatch!\n");
991 ret = -EINVAL;
992 goto release;
993 }
994
995 if (cfg_info.variant_id != data->info.variant_id) {
996 dev_err(dev, "Variant ID mismatch!\n");
997 ret = -EINVAL;
998 goto release;
999 }
1000
Nick Dyer4ce6fa02014-07-23 12:40:09 -07001001 /* Read CRCs */
1002 ret = sscanf(cfg->data + data_pos, "%x%n", &info_crc, &offset);
Nick Dyer50a77c62014-07-23 12:38:48 -07001003 if (ret != 1) {
1004 dev_err(dev, "Bad format: failed to parse Info CRC\n");
1005 ret = -EINVAL;
1006 goto release;
1007 }
Nick Dyer4ce6fa02014-07-23 12:40:09 -07001008 data_pos += offset;
Nick Dyer50a77c62014-07-23 12:38:48 -07001009
Nick Dyer4ce6fa02014-07-23 12:40:09 -07001010 ret = sscanf(cfg->data + data_pos, "%x%n", &config_crc, &offset);
Nick Dyer50a77c62014-07-23 12:38:48 -07001011 if (ret != 1) {
1012 dev_err(dev, "Bad format: failed to parse Config CRC\n");
1013 ret = -EINVAL;
1014 goto release;
1015 }
Nick Dyer4ce6fa02014-07-23 12:40:09 -07001016 data_pos += offset;
Nick Dyer50a77c62014-07-23 12:38:48 -07001017
Nick Dyer4ce6fa02014-07-23 12:40:09 -07001018 /*
1019 * The Info Block CRC is calculated over mxt_info and the object
1020 * table. If it does not match then we are trying to load the
1021 * configuration from a different chip or firmware version, so
1022 * the configuration CRC is invalid anyway.
1023 */
1024 if (info_crc == data->info_crc) {
1025 if (config_crc == 0 || data->config_crc == 0) {
1026 dev_info(dev, "CRC zero, attempting to apply config\n");
1027 } else if (config_crc == data->config_crc) {
1028 dev_dbg(dev, "Config CRC 0x%06X: OK\n",
1029 data->config_crc);
1030 ret = 0;
1031 goto release;
1032 } else {
1033 dev_info(dev, "Config CRC 0x%06X: does not match file 0x%06X\n",
1034 data->config_crc, config_crc);
1035 }
1036 } else {
1037 dev_warn(dev,
1038 "Warning: Info CRC error - device=0x%06X file=0x%06X\n",
1039 data->info_crc, info_crc);
1040 }
1041
1042 /* Malloc memory to store configuration */
1043 cfg_start_ofs = MXT_OBJECT_START +
1044 data->info.object_num * sizeof(struct mxt_object) +
1045 MXT_INFO_CHECKSUM_SIZE;
1046 config_mem_size = data->mem_size - cfg_start_ofs;
1047 config_mem = kzalloc(config_mem_size, GFP_KERNEL);
1048 if (!config_mem) {
1049 dev_err(dev, "Failed to allocate memory\n");
1050 ret = -ENOMEM;
Nick Dyer50a77c62014-07-23 12:38:48 -07001051 goto release;
1052 }
1053
Nick Dyer4ce6fa02014-07-23 12:40:09 -07001054 while (data_pos < cfg->size) {
Nick Dyer50a77c62014-07-23 12:38:48 -07001055 /* Read type, instance, length */
Nick Dyer4ce6fa02014-07-23 12:40:09 -07001056 ret = sscanf(cfg->data + data_pos, "%x %x %x%n",
Nick Dyer50a77c62014-07-23 12:38:48 -07001057 &type, &instance, &size, &offset);
1058 if (ret == 0) {
1059 /* EOF */
Nick Dyer4ce6fa02014-07-23 12:40:09 -07001060 break;
Nick Dyer50a77c62014-07-23 12:38:48 -07001061 } else if (ret != 3) {
1062 dev_err(dev, "Bad format: failed to parse object\n");
1063 ret = -EINVAL;
Nick Dyer4ce6fa02014-07-23 12:40:09 -07001064 goto release_mem;
Nick Dyer50a77c62014-07-23 12:38:48 -07001065 }
Nick Dyer4ce6fa02014-07-23 12:40:09 -07001066 data_pos += offset;
Nick Dyer50a77c62014-07-23 12:38:48 -07001067
1068 object = mxt_get_object(data, type);
1069 if (!object) {
1070 /* Skip object */
1071 for (i = 0; i < size; i++) {
Nick Dyer4ce6fa02014-07-23 12:40:09 -07001072 ret = sscanf(cfg->data + data_pos, "%hhx%n",
Nick Dyer50a77c62014-07-23 12:38:48 -07001073 &val,
1074 &offset);
Nick Dyer4ce6fa02014-07-23 12:40:09 -07001075 data_pos += offset;
Nick Dyer50a77c62014-07-23 12:38:48 -07001076 }
1077 continue;
1078 }
1079
1080 if (size > mxt_obj_size(object)) {
Nick Dyer4ce6fa02014-07-23 12:40:09 -07001081 /*
1082 * Either we are in fallback mode due to wrong
1083 * config or config from a later fw version,
1084 * or the file is corrupt or hand-edited.
1085 */
1086 dev_warn(dev, "Discarding %zu byte(s) in T%u\n",
1087 size - mxt_obj_size(object), type);
1088 } else if (mxt_obj_size(object) > size) {
1089 /*
1090 * If firmware is upgraded, new bytes may be added to
1091 * end of objects. It is generally forward compatible
1092 * to zero these bytes - previous behaviour will be
1093 * retained. However this does invalidate the CRC and
1094 * will force fallback mode until the configuration is
1095 * updated. We warn here but do nothing else - the
1096 * malloc has zeroed the entire configuration.
1097 */
1098 dev_warn(dev, "Zeroing %zu byte(s) in T%d\n",
1099 mxt_obj_size(object) - size, type);
Nick Dyer50a77c62014-07-23 12:38:48 -07001100 }
1101
1102 if (instance >= mxt_obj_instances(object)) {
1103 dev_err(dev, "Object instances exceeded!\n");
1104 ret = -EINVAL;
Nick Dyer4ce6fa02014-07-23 12:40:09 -07001105 goto release_mem;
Nick Dyer50a77c62014-07-23 12:38:48 -07001106 }
1107
1108 reg = object->start_address + mxt_obj_size(object) * instance;
1109
1110 for (i = 0; i < size; i++) {
Nick Dyer4ce6fa02014-07-23 12:40:09 -07001111 ret = sscanf(cfg->data + data_pos, "%hhx%n",
Nick Dyer50a77c62014-07-23 12:38:48 -07001112 &val,
1113 &offset);
1114 if (ret != 1) {
1115 dev_err(dev, "Bad format in T%d\n", type);
1116 ret = -EINVAL;
Nick Dyer4ce6fa02014-07-23 12:40:09 -07001117 goto release_mem;
Nick Dyer50a77c62014-07-23 12:38:48 -07001118 }
Nick Dyer4ce6fa02014-07-23 12:40:09 -07001119 data_pos += offset;
Nick Dyer50a77c62014-07-23 12:38:48 -07001120
1121 if (i > mxt_obj_size(object))
1122 continue;
1123
Nick Dyer4ce6fa02014-07-23 12:40:09 -07001124 byte_offset = reg + i - cfg_start_ofs;
Nick Dyer50a77c62014-07-23 12:38:48 -07001125
Nick Dyer4ce6fa02014-07-23 12:40:09 -07001126 if ((byte_offset >= 0)
1127 && (byte_offset <= config_mem_size)) {
1128 *(config_mem + byte_offset) = val;
1129 } else {
1130 dev_err(dev, "Bad object: reg:%d, T%d, ofs=%d\n",
1131 reg, object->type, byte_offset);
1132 ret = -EINVAL;
1133 goto release_mem;
Nick Dyer50a77c62014-07-23 12:38:48 -07001134 }
1135 }
Joonyoung Shim4cf51c32010-07-14 21:55:30 -07001136 }
1137
Nick Dyer4ce6fa02014-07-23 12:40:09 -07001138 /* Calculate crc of the received configs (not the raw config file) */
1139 if (data->T7_address < cfg_start_ofs) {
1140 dev_err(dev, "Bad T7 address, T7addr = %x, config offset %x\n",
1141 data->T7_address, cfg_start_ofs);
1142 ret = 0;
1143 goto release_mem;
1144 }
1145
1146 calculated_crc = mxt_calculate_crc(config_mem,
1147 data->T7_address - cfg_start_ofs,
1148 config_mem_size);
1149
1150 if (config_crc > 0 && (config_crc != calculated_crc))
1151 dev_warn(dev, "Config CRC error, calculated=%06X, file=%06X\n",
1152 calculated_crc, config_crc);
1153
1154 /* Write configuration as blocks */
1155 byte_offset = 0;
1156 while (byte_offset < config_mem_size) {
1157 size = config_mem_size - byte_offset;
1158
1159 if (size > MXT_MAX_BLOCK_WRITE)
1160 size = MXT_MAX_BLOCK_WRITE;
1161
1162 ret = __mxt_write_reg(data->client,
1163 cfg_start_ofs + byte_offset,
1164 size, config_mem + byte_offset);
1165 if (ret != 0) {
1166 dev_err(dev, "Config write error, ret=%d\n", ret);
1167 goto release_mem;
1168 }
1169
1170 byte_offset += size;
1171 }
1172
Nick Dyerc3f78042014-05-18 23:04:46 -07001173 mxt_update_crc(data, MXT_COMMAND_BACKUPNV, MXT_BACKUP_VALUE);
1174
1175 ret = mxt_soft_reset(data);
1176 if (ret)
Nick Dyer4ce6fa02014-07-23 12:40:09 -07001177 goto release_mem;
Nick Dyerc3f78042014-05-18 23:04:46 -07001178
1179 dev_info(dev, "Config successfully updated\n");
1180
Nick Dyer4ce6fa02014-07-23 12:40:09 -07001181release_mem:
1182 kfree(config_mem);
Nick Dyer50a77c62014-07-23 12:38:48 -07001183release:
1184 release_firmware(cfg);
1185 return ret;
Joonyoung Shim4cf51c32010-07-14 21:55:30 -07001186}
1187
Iiro Valkonen7686b102011-02-02 23:21:58 -08001188static int mxt_make_highchg(struct mxt_data *data)
Joonyoung Shim4cf51c32010-07-14 21:55:30 -07001189{
1190 struct device *dev = &data->client->dev;
Iiro Valkonen26cdb1a2011-02-04 00:51:05 -08001191 struct mxt_message message;
Joonyoung Shim4cf51c32010-07-14 21:55:30 -07001192 int count = 10;
1193 int error;
Joonyoung Shim4cf51c32010-07-14 21:55:30 -07001194
1195 /* Read dummy message to make high CHG pin */
1196 do {
Iiro Valkonen26cdb1a2011-02-04 00:51:05 -08001197 error = mxt_read_message(data, &message);
Joonyoung Shim4cf51c32010-07-14 21:55:30 -07001198 if (error)
1199 return error;
Iiro Valkonen26cdb1a2011-02-04 00:51:05 -08001200 } while (message.reportid != 0xff && --count);
Joonyoung Shim4cf51c32010-07-14 21:55:30 -07001201
1202 if (!count) {
1203 dev_err(dev, "CHG pin isn't cleared\n");
1204 return -EBUSY;
1205 }
1206
1207 return 0;
1208}
1209
Nick Dyerdd24dcf2014-07-23 11:25:55 -07001210static int mxt_acquire_irq(struct mxt_data *data)
1211{
1212 int error;
1213
1214 enable_irq(data->irq);
1215
1216 error = mxt_make_highchg(data);
1217 if (error)
1218 return error;
1219
1220 return 0;
1221}
1222
Iiro Valkonen7686b102011-02-02 23:21:58 -08001223static int mxt_get_info(struct mxt_data *data)
Joonyoung Shim4cf51c32010-07-14 21:55:30 -07001224{
1225 struct i2c_client *client = data->client;
Iiro Valkonen7686b102011-02-02 23:21:58 -08001226 struct mxt_info *info = &data->info;
Joonyoung Shim4cf51c32010-07-14 21:55:30 -07001227 int error;
Joonyoung Shim4cf51c32010-07-14 21:55:30 -07001228
Daniel Kurtz23003a842012-06-28 21:08:14 +08001229 /* Read 7-byte info block starting at address 0 */
1230 error = __mxt_read_reg(client, MXT_INFO, sizeof(*info), info);
Joonyoung Shim4cf51c32010-07-14 21:55:30 -07001231 if (error)
1232 return error;
Joonyoung Shim4cf51c32010-07-14 21:55:30 -07001233
1234 return 0;
1235}
1236
Iiro Valkonen7686b102011-02-02 23:21:58 -08001237static int mxt_get_object_table(struct mxt_data *data)
Joonyoung Shim4cf51c32010-07-14 21:55:30 -07001238{
Daniel Kurtz333e5a92012-06-28 21:08:20 +08001239 struct i2c_client *client = data->client;
1240 size_t table_size;
Nick Dyerdd24dcf2014-07-23 11:25:55 -07001241 struct mxt_object *object_table;
Joonyoung Shim4cf51c32010-07-14 21:55:30 -07001242 int error;
1243 int i;
Daniel Kurtz333e5a92012-06-28 21:08:20 +08001244 u8 reportid;
Nick Dyer4ce6fa02014-07-23 12:40:09 -07001245 u16 end_address;
Joonyoung Shim4cf51c32010-07-14 21:55:30 -07001246
Daniel Kurtz333e5a92012-06-28 21:08:20 +08001247 table_size = data->info.object_num * sizeof(struct mxt_object);
Nick Dyerdd24dcf2014-07-23 11:25:55 -07001248 object_table = kzalloc(table_size, GFP_KERNEL);
1249 if (!object_table) {
1250 dev_err(&data->client->dev, "Failed to allocate memory\n");
1251 return -ENOMEM;
1252 }
1253
Daniel Kurtz333e5a92012-06-28 21:08:20 +08001254 error = __mxt_read_reg(client, MXT_OBJECT_START, table_size,
Nick Dyerdd24dcf2014-07-23 11:25:55 -07001255 object_table);
1256 if (error) {
1257 kfree(object_table);
Daniel Kurtz333e5a92012-06-28 21:08:20 +08001258 return error;
Nick Dyerdd24dcf2014-07-23 11:25:55 -07001259 }
Daniel Kurtz333e5a92012-06-28 21:08:20 +08001260
1261 /* Valid Report IDs start counting from 1 */
1262 reportid = 1;
Nick Dyer4ce6fa02014-07-23 12:40:09 -07001263 data->mem_size = 0;
Joonyoung Shim4cf51c32010-07-14 21:55:30 -07001264 for (i = 0; i < data->info.object_num; i++) {
Nick Dyerdd24dcf2014-07-23 11:25:55 -07001265 struct mxt_object *object = object_table + i;
Daniel Kurtz333e5a92012-06-28 21:08:20 +08001266 u8 min_id, max_id;
Joonyoung Shim4cf51c32010-07-14 21:55:30 -07001267
Daniel Kurtz333e5a92012-06-28 21:08:20 +08001268 le16_to_cpus(&object->start_address);
Joonyoung Shim4cf51c32010-07-14 21:55:30 -07001269
1270 if (object->num_report_ids) {
Daniel Kurtz333e5a92012-06-28 21:08:20 +08001271 min_id = reportid;
Joonyoung Shim4cf51c32010-07-14 21:55:30 -07001272 reportid += object->num_report_ids *
Daniel Kurtz1e0c0c52014-05-18 23:01:12 -07001273 mxt_obj_instances(object);
Daniel Kurtz333e5a92012-06-28 21:08:20 +08001274 max_id = reportid - 1;
1275 } else {
1276 min_id = 0;
1277 max_id = 0;
1278 }
1279
1280 dev_dbg(&data->client->dev,
Nick Dyer7bed6802014-05-18 23:04:09 -07001281 "T%u Start:%u Size:%zu Instances:%zu Report IDs:%u-%u\n",
Daniel Kurtz1e0c0c52014-05-18 23:01:12 -07001282 object->type, object->start_address,
1283 mxt_obj_size(object), mxt_obj_instances(object),
1284 min_id, max_id);
Daniel Kurtz333e5a92012-06-28 21:08:20 +08001285
1286 switch (object->type) {
Daniel Kurtzfdf804212012-06-28 21:08:24 +08001287 case MXT_GEN_COMMAND_T6:
1288 data->T6_reportid = min_id;
Iiro Valkonena4a2ef42014-05-18 23:03:44 -07001289 data->T6_address = object->start_address;
Daniel Kurtzfdf804212012-06-28 21:08:24 +08001290 break;
Nick Dyer4ce6fa02014-07-23 12:40:09 -07001291 case MXT_GEN_POWER_T7:
1292 data->T7_address = object->start_address;
1293 break;
Daniel Kurtz333e5a92012-06-28 21:08:20 +08001294 case MXT_TOUCH_MULTI_T9:
1295 data->T9_reportid_min = min_id;
1296 data->T9_reportid_max = max_id;
1297 break;
Daniel Kurtz22dfab72013-03-07 19:43:33 -08001298 case MXT_SPT_GPIOPWM_T19:
1299 data->T19_reportid = min_id;
1300 break;
Joonyoung Shim4cf51c32010-07-14 21:55:30 -07001301 }
Nick Dyer4ce6fa02014-07-23 12:40:09 -07001302
1303 end_address = object->start_address
1304 + mxt_obj_size(object) * mxt_obj_instances(object) - 1;
1305
1306 if (end_address >= data->mem_size)
1307 data->mem_size = end_address + 1;
Joonyoung Shim4cf51c32010-07-14 21:55:30 -07001308 }
1309
Nick Dyerdd24dcf2014-07-23 11:25:55 -07001310 data->object_table = object_table;
1311
Joonyoung Shim4cf51c32010-07-14 21:55:30 -07001312 return 0;
1313}
1314
Daniel Kurtz7d4fa102012-06-28 21:08:19 +08001315static void mxt_free_object_table(struct mxt_data *data)
1316{
Nick Dyer7a53d602014-07-23 12:21:26 -07001317 input_unregister_device(data->input_dev);
1318 data->input_dev = NULL;
1319
Daniel Kurtz7d4fa102012-06-28 21:08:19 +08001320 kfree(data->object_table);
1321 data->object_table = NULL;
Daniel Kurtzfdf804212012-06-28 21:08:24 +08001322 data->T6_reportid = 0;
Daniel Kurtz333e5a92012-06-28 21:08:20 +08001323 data->T9_reportid_min = 0;
1324 data->T9_reportid_max = 0;
Daniel Kurtz22dfab72013-03-07 19:43:33 -08001325 data->T19_reportid = 0;
Daniel Kurtz7d4fa102012-06-28 21:08:19 +08001326}
1327
Nick Dyer61dc1ab2014-05-18 23:16:49 -07001328static int mxt_read_t9_resolution(struct mxt_data *data)
1329{
1330 struct i2c_client *client = data->client;
1331 int error;
1332 struct t9_range range;
1333 unsigned char orient;
1334 struct mxt_object *object;
1335
1336 object = mxt_get_object(data, MXT_TOUCH_MULTI_T9);
1337 if (!object)
1338 return -EINVAL;
1339
1340 error = __mxt_read_reg(client,
1341 object->start_address + MXT_T9_RANGE,
1342 sizeof(range), &range);
1343 if (error)
1344 return error;
1345
1346 le16_to_cpus(&range.x);
1347 le16_to_cpus(&range.y);
1348
1349 error = __mxt_read_reg(client,
1350 object->start_address + MXT_T9_ORIENT,
1351 1, &orient);
1352 if (error)
1353 return error;
1354
1355 /* Handle default values */
1356 if (range.x == 0)
1357 range.x = 1023;
1358
1359 if (range.y == 0)
1360 range.y = 1023;
1361
Nick Dyerf3889ed2014-05-18 23:22:04 -07001362 if (orient & MXT_T9_ORIENT_SWITCH) {
Nick Dyer61dc1ab2014-05-18 23:16:49 -07001363 data->max_x = range.y;
1364 data->max_y = range.x;
1365 } else {
1366 data->max_x = range.x;
1367 data->max_y = range.y;
1368 }
1369
1370 dev_dbg(&client->dev,
1371 "Touchscreen size X%uY%u\n", data->max_x, data->max_y);
1372
1373 return 0;
1374}
1375
Nick Dyer7a53d602014-07-23 12:21:26 -07001376static int mxt_input_open(struct input_dev *dev);
1377static void mxt_input_close(struct input_dev *dev);
1378
1379static int mxt_initialize_t9_input_device(struct mxt_data *data)
1380{
1381 struct device *dev = &data->client->dev;
1382 const struct mxt_platform_data *pdata = data->pdata;
1383 struct input_dev *input_dev;
1384 int error;
1385 unsigned int num_mt_slots;
1386 unsigned int mt_flags = 0;
1387 int i;
1388
1389 error = mxt_read_t9_resolution(data);
1390 if (error)
1391 dev_warn(dev, "Failed to initialize T9 resolution\n");
1392
1393 input_dev = input_allocate_device();
1394 if (!input_dev) {
1395 dev_err(dev, "Failed to allocate memory\n");
1396 return -ENOMEM;
1397 }
1398
1399 input_dev->name = "Atmel maXTouch Touchscreen";
1400 input_dev->phys = data->phys;
1401 input_dev->id.bustype = BUS_I2C;
1402 input_dev->dev.parent = dev;
1403 input_dev->open = mxt_input_open;
1404 input_dev->close = mxt_input_close;
1405
1406 __set_bit(EV_ABS, input_dev->evbit);
1407 __set_bit(EV_KEY, input_dev->evbit);
1408 __set_bit(BTN_TOUCH, input_dev->keybit);
1409
1410 if (pdata->t19_num_keys) {
1411 __set_bit(INPUT_PROP_BUTTONPAD, input_dev->propbit);
1412
1413 for (i = 0; i < pdata->t19_num_keys; i++)
1414 if (pdata->t19_keymap[i] != KEY_RESERVED)
1415 input_set_capability(input_dev, EV_KEY,
1416 pdata->t19_keymap[i]);
1417
1418 mt_flags |= INPUT_MT_POINTER;
1419
1420 input_abs_set_res(input_dev, ABS_X, MXT_PIXELS_PER_MM);
1421 input_abs_set_res(input_dev, ABS_Y, MXT_PIXELS_PER_MM);
1422 input_abs_set_res(input_dev, ABS_MT_POSITION_X,
1423 MXT_PIXELS_PER_MM);
1424 input_abs_set_res(input_dev, ABS_MT_POSITION_Y,
1425 MXT_PIXELS_PER_MM);
1426
1427 input_dev->name = "Atmel maXTouch Touchpad";
1428 }
1429
1430 /* For single touch */
1431 input_set_abs_params(input_dev, ABS_X,
1432 0, data->max_x, 0, 0);
1433 input_set_abs_params(input_dev, ABS_Y,
1434 0, data->max_y, 0, 0);
1435 input_set_abs_params(input_dev, ABS_PRESSURE,
1436 0, 255, 0, 0);
1437
1438 /* For multi touch */
1439 num_mt_slots = data->T9_reportid_max - data->T9_reportid_min + 1;
1440 error = input_mt_init_slots(input_dev, num_mt_slots, mt_flags);
1441 if (error) {
1442 dev_err(dev, "Error %d initialising slots\n", error);
1443 goto err_free_mem;
1444 }
1445
1446 input_set_abs_params(input_dev, ABS_MT_TOUCH_MAJOR,
1447 0, MXT_MAX_AREA, 0, 0);
1448 input_set_abs_params(input_dev, ABS_MT_POSITION_X,
1449 0, data->max_x, 0, 0);
1450 input_set_abs_params(input_dev, ABS_MT_POSITION_Y,
1451 0, data->max_y, 0, 0);
1452 input_set_abs_params(input_dev, ABS_MT_PRESSURE,
1453 0, 255, 0, 0);
1454
1455 input_set_drvdata(input_dev, data);
1456
1457 error = input_register_device(input_dev);
1458 if (error) {
1459 dev_err(dev, "Error %d registering input device\n", error);
1460 goto err_free_mem;
1461 }
1462
1463 data->input_dev = input_dev;
1464
1465 return 0;
1466
1467err_free_mem:
1468 input_free_device(input_dev);
1469 return error;
1470}
1471
Nick Dyer50a77c62014-07-23 12:38:48 -07001472static int mxt_configure_objects(struct mxt_data *data,
1473 const struct firmware *cfg);
1474
1475static void mxt_config_cb(const struct firmware *cfg, void *ctx)
1476{
1477 mxt_configure_objects(ctx, cfg);
1478}
1479
Iiro Valkonen7686b102011-02-02 23:21:58 -08001480static int mxt_initialize(struct mxt_data *data)
Joonyoung Shim4cf51c32010-07-14 21:55:30 -07001481{
1482 struct i2c_client *client = data->client;
Joonyoung Shim4cf51c32010-07-14 21:55:30 -07001483 int error;
Joonyoung Shim4cf51c32010-07-14 21:55:30 -07001484
Iiro Valkonen7686b102011-02-02 23:21:58 -08001485 error = mxt_get_info(data);
Nick Dyera9fdd1e2014-07-23 12:41:58 -07001486 if (error) {
1487 error = mxt_probe_bootloader(data);
1488 if (error)
1489 return error;
1490
1491 data->in_bootloader = true;
1492 return 0;
1493 }
Joonyoung Shim4cf51c32010-07-14 21:55:30 -07001494
Joonyoung Shim4cf51c32010-07-14 21:55:30 -07001495 /* Get object table information */
Iiro Valkonen7686b102011-02-02 23:21:58 -08001496 error = mxt_get_object_table(data);
Nick Dyer7bed6802014-05-18 23:04:09 -07001497 if (error) {
1498 dev_err(&client->dev, "Error %d reading object table\n", error);
Nick Dyerdd24dcf2014-07-23 11:25:55 -07001499 return error;
Nick Dyer7bed6802014-05-18 23:04:09 -07001500 }
Joonyoung Shim4cf51c32010-07-14 21:55:30 -07001501
Nick Dyerdd24dcf2014-07-23 11:25:55 -07001502 mxt_acquire_irq(data);
1503 if (error)
1504 goto err_free_object_table;
1505
Nick Dyer50a77c62014-07-23 12:38:48 -07001506 request_firmware_nowait(THIS_MODULE, true, MXT_CFG_NAME,
1507 &data->client->dev, GFP_KERNEL, data,
1508 mxt_config_cb);
Joonyoung Shim4cf51c32010-07-14 21:55:30 -07001509
1510 return 0;
Daniel Kurtz7d4fa102012-06-28 21:08:19 +08001511
1512err_free_object_table:
1513 mxt_free_object_table(data);
1514 return error;
Joonyoung Shim4cf51c32010-07-14 21:55:30 -07001515}
1516
Nick Dyer50a77c62014-07-23 12:38:48 -07001517static int mxt_configure_objects(struct mxt_data *data,
1518 const struct firmware *cfg)
1519{
1520 struct device *dev = &data->client->dev;
1521 struct mxt_info *info = &data->info;
1522 int error;
1523
1524 if (cfg) {
1525 error = mxt_update_cfg(data, cfg);
1526 if (error)
1527 dev_warn(dev, "Error %d updating config\n", error);
1528 }
1529
1530 error = mxt_initialize_t9_input_device(data);
1531 if (error)
1532 return error;
1533
1534 dev_info(dev,
1535 "Family: %u Variant: %u Firmware V%u.%u.%02X Objects: %u\n",
1536 info->family_id, info->variant_id, info->version >> 4,
1537 info->version & 0xf, info->build, info->object_num);
1538
1539 return 0;
1540}
1541
Daniel Kurtzb19fc9e2012-06-28 21:08:16 +08001542/* Firmware Version is returned as Major.Minor.Build */
1543static ssize_t mxt_fw_version_show(struct device *dev,
1544 struct device_attribute *attr, char *buf)
1545{
1546 struct mxt_data *data = dev_get_drvdata(dev);
1547 struct mxt_info *info = &data->info;
1548 return scnprintf(buf, PAGE_SIZE, "%u.%u.%02X\n",
1549 info->version >> 4, info->version & 0xf, info->build);
1550}
1551
1552/* Hardware Version is returned as FamilyID.VariantID */
1553static ssize_t mxt_hw_version_show(struct device *dev,
1554 struct device_attribute *attr, char *buf)
1555{
1556 struct mxt_data *data = dev_get_drvdata(dev);
1557 struct mxt_info *info = &data->info;
1558 return scnprintf(buf, PAGE_SIZE, "%u.%u\n",
1559 info->family_id, info->variant_id);
1560}
1561
Daniel Kurtz794eb672012-06-28 21:08:10 +08001562static ssize_t mxt_show_instance(char *buf, int count,
1563 struct mxt_object *object, int instance,
1564 const u8 *val)
1565{
1566 int i;
1567
Daniel Kurtz1e0c0c52014-05-18 23:01:12 -07001568 if (mxt_obj_instances(object) > 1)
Daniel Kurtz794eb672012-06-28 21:08:10 +08001569 count += scnprintf(buf + count, PAGE_SIZE - count,
1570 "Instance %u\n", instance);
1571
Daniel Kurtz1e0c0c52014-05-18 23:01:12 -07001572 for (i = 0; i < mxt_obj_size(object); i++)
Daniel Kurtz794eb672012-06-28 21:08:10 +08001573 count += scnprintf(buf + count, PAGE_SIZE - count,
1574 "\t[%2u]: %02x (%d)\n", i, val[i], val[i]);
1575 count += scnprintf(buf + count, PAGE_SIZE - count, "\n");
1576
1577 return count;
1578}
1579
Iiro Valkonen7686b102011-02-02 23:21:58 -08001580static ssize_t mxt_object_show(struct device *dev,
Joonyoung Shim4cf51c32010-07-14 21:55:30 -07001581 struct device_attribute *attr, char *buf)
1582{
Iiro Valkonen7686b102011-02-02 23:21:58 -08001583 struct mxt_data *data = dev_get_drvdata(dev);
1584 struct mxt_object *object;
Joonyoung Shim4cf51c32010-07-14 21:55:30 -07001585 int count = 0;
1586 int i, j;
1587 int error;
Daniel Kurtz43a91d52012-06-28 21:08:08 +08001588 u8 *obuf;
Joonyoung Shim4cf51c32010-07-14 21:55:30 -07001589
Daniel Kurtz43a91d52012-06-28 21:08:08 +08001590 /* Pre-allocate buffer large enough to hold max sized object. */
1591 obuf = kmalloc(256, GFP_KERNEL);
1592 if (!obuf)
1593 return -ENOMEM;
1594
1595 error = 0;
Joonyoung Shim4cf51c32010-07-14 21:55:30 -07001596 for (i = 0; i < data->info.object_num; i++) {
1597 object = data->object_table + i;
1598
Daniel Kurtz91630952012-06-28 21:08:09 +08001599 if (!mxt_object_readable(object->type))
Joonyoung Shim4cf51c32010-07-14 21:55:30 -07001600 continue;
Joonyoung Shim4cf51c32010-07-14 21:55:30 -07001601
Daniel Kurtz91630952012-06-28 21:08:09 +08001602 count += scnprintf(buf + count, PAGE_SIZE - count,
1603 "T%u:\n", object->type);
Joonyoung Shim4cf51c32010-07-14 21:55:30 -07001604
Daniel Kurtz1e0c0c52014-05-18 23:01:12 -07001605 for (j = 0; j < mxt_obj_instances(object); j++) {
1606 u16 size = mxt_obj_size(object);
Daniel Kurtz794eb672012-06-28 21:08:10 +08001607 u16 addr = object->start_address + j * size;
Daniel Kurtz43a91d52012-06-28 21:08:08 +08001608
Daniel Kurtz794eb672012-06-28 21:08:10 +08001609 error = __mxt_read_reg(data->client, addr, size, obuf);
Joonyoung Shim4cf51c32010-07-14 21:55:30 -07001610 if (error)
Daniel Kurtz794eb672012-06-28 21:08:10 +08001611 goto done;
Joonyoung Shim4cf51c32010-07-14 21:55:30 -07001612
Daniel Kurtz794eb672012-06-28 21:08:10 +08001613 count = mxt_show_instance(buf, count, object, j, obuf);
Joonyoung Shim4cf51c32010-07-14 21:55:30 -07001614 }
Joonyoung Shim4cf51c32010-07-14 21:55:30 -07001615 }
1616
Daniel Kurtz794eb672012-06-28 21:08:10 +08001617done:
Daniel Kurtz43a91d52012-06-28 21:08:08 +08001618 kfree(obuf);
1619 return error ?: count;
Joonyoung Shim4cf51c32010-07-14 21:55:30 -07001620}
1621
Nick Dyerf2ac6cb2014-05-18 23:15:01 -07001622static int mxt_check_firmware_format(struct device *dev,
1623 const struct firmware *fw)
1624{
1625 unsigned int pos = 0;
1626 char c;
1627
1628 while (pos < fw->size) {
1629 c = *(fw->data + pos);
1630
1631 if (c < '0' || (c > '9' && c < 'A') || c > 'F')
1632 return 0;
1633
1634 pos++;
1635 }
1636
1637 /*
1638 * To convert file try:
1639 * xxd -r -p mXTXXX__APP_VX-X-XX.enc > maxtouch.fw
1640 */
1641 dev_err(dev, "Aborting: firmware file must be in binary format\n");
1642
1643 return -EINVAL;
1644}
1645
Iiro Valkonen7686b102011-02-02 23:21:58 -08001646static int mxt_load_fw(struct device *dev, const char *fn)
Joonyoung Shim4cf51c32010-07-14 21:55:30 -07001647{
Iiro Valkonen7686b102011-02-02 23:21:58 -08001648 struct mxt_data *data = dev_get_drvdata(dev);
Joonyoung Shim4cf51c32010-07-14 21:55:30 -07001649 const struct firmware *fw = NULL;
1650 unsigned int frame_size;
1651 unsigned int pos = 0;
Nick Dyerf943c742014-05-18 23:14:20 -07001652 unsigned int retry = 0;
Nick Dyerf477c752014-05-18 23:14:45 -07001653 unsigned int frame = 0;
Joonyoung Shim4cf51c32010-07-14 21:55:30 -07001654 int ret;
1655
1656 ret = request_firmware(&fw, fn, dev);
1657 if (ret) {
1658 dev_err(dev, "Unable to open firmware %s\n", fn);
1659 return ret;
1660 }
1661
Nick Dyerf2ac6cb2014-05-18 23:15:01 -07001662 /* Check for incorrect enc file */
1663 ret = mxt_check_firmware_format(dev, fw);
1664 if (ret)
1665 goto release_firmware;
1666
Nick Dyerf28a8422014-05-18 23:10:49 -07001667 ret = mxt_lookup_bootloader_address(data);
1668 if (ret)
1669 goto release_firmware;
1670
Nick Dyera9fdd1e2014-07-23 12:41:58 -07001671 if (!data->in_bootloader) {
1672 /* Change to the bootloader mode */
1673 data->in_bootloader = true;
Benson Leungd79e7e42014-05-18 23:02:52 -07001674
Nick Dyera9fdd1e2014-07-23 12:41:58 -07001675 ret = mxt_t6_command(data, MXT_COMMAND_RESET,
1676 MXT_BOOT_VALUE, false);
1677 if (ret)
1678 goto release_firmware;
Iiro Valkonena4a2ef42014-05-18 23:03:44 -07001679
Nick Dyera9fdd1e2014-07-23 12:41:58 -07001680 msleep(MXT_RESET_TIME);
1681 }
Joonyoung Shim4cf51c32010-07-14 21:55:30 -07001682
Nick Dyera9fdd1e2014-07-23 12:41:58 -07001683 mxt_free_object_table(data);
Benson Leungd79e7e42014-05-18 23:02:52 -07001684 reinit_completion(&data->bl_completion);
1685
Nick Dyer385deb92014-07-23 12:42:40 -07001686 ret = mxt_check_bootloader(data, MXT_WAITING_BOOTLOAD_CMD, false);
1687 if (ret) {
1688 /* Bootloader may still be unlocked from previous attempt */
1689 ret = mxt_check_bootloader(data, MXT_WAITING_FRAME_DATA, false);
1690 if (ret)
1691 goto disable_irq;
1692 } else {
1693 dev_info(dev, "Unlocking bootloader\n");
Joonyoung Shim4cf51c32010-07-14 21:55:30 -07001694
Nick Dyer385deb92014-07-23 12:42:40 -07001695 /* Unlock bootloader */
1696 ret = mxt_unlock_bootloader(data);
1697 if (ret)
1698 goto disable_irq;
1699 }
Joonyoung Shim4cf51c32010-07-14 21:55:30 -07001700
1701 while (pos < fw->size) {
Nick Dyer385deb92014-07-23 12:42:40 -07001702 ret = mxt_check_bootloader(data, MXT_WAITING_FRAME_DATA, true);
Joonyoung Shim4cf51c32010-07-14 21:55:30 -07001703 if (ret)
Benson Leungd79e7e42014-05-18 23:02:52 -07001704 goto disable_irq;
Joonyoung Shim4cf51c32010-07-14 21:55:30 -07001705
1706 frame_size = ((*(fw->data + pos) << 8) | *(fw->data + pos + 1));
1707
Nick Dyerf943c742014-05-18 23:14:20 -07001708 /* Take account of CRC bytes */
Joonyoung Shim4cf51c32010-07-14 21:55:30 -07001709 frame_size += 2;
1710
1711 /* Write one frame to device */
Nick Dyerf28a8422014-05-18 23:10:49 -07001712 ret = mxt_bootloader_write(data, fw->data + pos, frame_size);
1713 if (ret)
1714 goto disable_irq;
Joonyoung Shim4cf51c32010-07-14 21:55:30 -07001715
Nick Dyer385deb92014-07-23 12:42:40 -07001716 ret = mxt_check_bootloader(data, MXT_FRAME_CRC_PASS, true);
Nick Dyerf943c742014-05-18 23:14:20 -07001717 if (ret) {
1718 retry++;
Joonyoung Shim4cf51c32010-07-14 21:55:30 -07001719
Nick Dyerf943c742014-05-18 23:14:20 -07001720 /* Back off by 20ms per retry */
1721 msleep(retry * 20);
1722
1723 if (retry > 20) {
1724 dev_err(dev, "Retry count exceeded\n");
1725 goto disable_irq;
1726 }
1727 } else {
1728 retry = 0;
1729 pos += frame_size;
Nick Dyerf477c752014-05-18 23:14:45 -07001730 frame++;
Nick Dyerf943c742014-05-18 23:14:20 -07001731 }
Joonyoung Shim4cf51c32010-07-14 21:55:30 -07001732
Nick Dyerf477c752014-05-18 23:14:45 -07001733 if (frame % 50 == 0)
1734 dev_dbg(dev, "Sent %d frames, %d/%zd bytes\n",
1735 frame, pos, fw->size);
Joonyoung Shim4cf51c32010-07-14 21:55:30 -07001736 }
1737
Benson Leunga0434b72014-05-18 23:03:09 -07001738 /* Wait for flash. */
Iiro Valkonena4a2ef42014-05-18 23:03:44 -07001739 ret = mxt_wait_for_completion(data, &data->bl_completion,
1740 MXT_FW_RESET_TIME);
Benson Leunga0434b72014-05-18 23:03:09 -07001741 if (ret)
1742 goto disable_irq;
1743
Nick Dyerf477c752014-05-18 23:14:45 -07001744 dev_dbg(dev, "Sent %d frames, %d bytes\n", frame, pos);
1745
Benson Leunga0434b72014-05-18 23:03:09 -07001746 /*
1747 * Wait for device to reset. Some bootloader versions do not assert
1748 * the CHG line after bootloading has finished, so ignore potential
1749 * errors.
1750 */
Iiro Valkonena4a2ef42014-05-18 23:03:44 -07001751 mxt_wait_for_completion(data, &data->bl_completion, MXT_FW_RESET_TIME);
Benson Leunga0434b72014-05-18 23:03:09 -07001752
Benson Leungd79e7e42014-05-18 23:02:52 -07001753 data->in_bootloader = false;
1754
1755disable_irq:
1756 disable_irq(data->irq);
Iiro Valkonena4a2ef42014-05-18 23:03:44 -07001757release_firmware:
Joonyoung Shim4cf51c32010-07-14 21:55:30 -07001758 release_firmware(fw);
Joonyoung Shim4cf51c32010-07-14 21:55:30 -07001759 return ret;
1760}
1761
Iiro Valkonen7686b102011-02-02 23:21:58 -08001762static ssize_t mxt_update_fw_store(struct device *dev,
Joonyoung Shim4cf51c32010-07-14 21:55:30 -07001763 struct device_attribute *attr,
1764 const char *buf, size_t count)
1765{
Iiro Valkonen7686b102011-02-02 23:21:58 -08001766 struct mxt_data *data = dev_get_drvdata(dev);
Joonyoung Shim4cf51c32010-07-14 21:55:30 -07001767 int error;
1768
Iiro Valkonen7686b102011-02-02 23:21:58 -08001769 error = mxt_load_fw(dev, MXT_FW_NAME);
Joonyoung Shim4cf51c32010-07-14 21:55:30 -07001770 if (error) {
1771 dev_err(dev, "The firmware update failed(%d)\n", error);
1772 count = error;
1773 } else {
Nick Dyer7bed6802014-05-18 23:04:09 -07001774 dev_info(dev, "The firmware update succeeded\n");
1775
Nick Dyerdd24dcf2014-07-23 11:25:55 -07001776 error = mxt_initialize(data);
Benson Leungd79e7e42014-05-18 23:02:52 -07001777 if (error)
1778 return error;
Joonyoung Shim4cf51c32010-07-14 21:55:30 -07001779 }
1780
Joonyoung Shim4cf51c32010-07-14 21:55:30 -07001781 return count;
1782}
1783
Daniel Kurtzb19fc9e2012-06-28 21:08:16 +08001784static DEVICE_ATTR(fw_version, S_IRUGO, mxt_fw_version_show, NULL);
1785static DEVICE_ATTR(hw_version, S_IRUGO, mxt_hw_version_show, NULL);
Daniel Kurtz71b3e932012-05-08 22:30:14 -07001786static DEVICE_ATTR(object, S_IRUGO, mxt_object_show, NULL);
1787static DEVICE_ATTR(update_fw, S_IWUSR, NULL, mxt_update_fw_store);
Joonyoung Shim4cf51c32010-07-14 21:55:30 -07001788
Iiro Valkonen7686b102011-02-02 23:21:58 -08001789static struct attribute *mxt_attrs[] = {
Daniel Kurtzb19fc9e2012-06-28 21:08:16 +08001790 &dev_attr_fw_version.attr,
1791 &dev_attr_hw_version.attr,
Joonyoung Shim4cf51c32010-07-14 21:55:30 -07001792 &dev_attr_object.attr,
1793 &dev_attr_update_fw.attr,
1794 NULL
1795};
1796
Iiro Valkonen7686b102011-02-02 23:21:58 -08001797static const struct attribute_group mxt_attr_group = {
1798 .attrs = mxt_attrs,
Joonyoung Shim4cf51c32010-07-14 21:55:30 -07001799};
1800
Iiro Valkonen7686b102011-02-02 23:21:58 -08001801static void mxt_start(struct mxt_data *data)
Joonyoung Shim4cf51c32010-07-14 21:55:30 -07001802{
1803 /* Touch enable */
Iiro Valkonen7686b102011-02-02 23:21:58 -08001804 mxt_write_object(data,
Iiro Valkonen81c88a72011-07-04 03:08:25 -07001805 MXT_TOUCH_MULTI_T9, MXT_TOUCH_CTRL, 0x83);
Joonyoung Shim4cf51c32010-07-14 21:55:30 -07001806}
1807
Iiro Valkonen7686b102011-02-02 23:21:58 -08001808static void mxt_stop(struct mxt_data *data)
Joonyoung Shim4cf51c32010-07-14 21:55:30 -07001809{
1810 /* Touch disable */
Iiro Valkonen7686b102011-02-02 23:21:58 -08001811 mxt_write_object(data,
Iiro Valkonen81c88a72011-07-04 03:08:25 -07001812 MXT_TOUCH_MULTI_T9, MXT_TOUCH_CTRL, 0);
Joonyoung Shim4cf51c32010-07-14 21:55:30 -07001813}
1814
Iiro Valkonen7686b102011-02-02 23:21:58 -08001815static int mxt_input_open(struct input_dev *dev)
Joonyoung Shim4cf51c32010-07-14 21:55:30 -07001816{
Iiro Valkonen7686b102011-02-02 23:21:58 -08001817 struct mxt_data *data = input_get_drvdata(dev);
Joonyoung Shim4cf51c32010-07-14 21:55:30 -07001818
Iiro Valkonen7686b102011-02-02 23:21:58 -08001819 mxt_start(data);
Joonyoung Shim4cf51c32010-07-14 21:55:30 -07001820
1821 return 0;
1822}
1823
Iiro Valkonen7686b102011-02-02 23:21:58 -08001824static void mxt_input_close(struct input_dev *dev)
Joonyoung Shim4cf51c32010-07-14 21:55:30 -07001825{
Iiro Valkonen7686b102011-02-02 23:21:58 -08001826 struct mxt_data *data = input_get_drvdata(dev);
Joonyoung Shim4cf51c32010-07-14 21:55:30 -07001827
Iiro Valkonen7686b102011-02-02 23:21:58 -08001828 mxt_stop(data);
Joonyoung Shim4cf51c32010-07-14 21:55:30 -07001829}
1830
Stephen Warren78188be2014-07-23 12:23:23 -07001831#ifdef CONFIG_OF
1832static struct mxt_platform_data *mxt_parse_dt(struct i2c_client *client)
1833{
1834 struct mxt_platform_data *pdata;
1835 u32 *keymap;
1836 u32 keycode;
1837 int proplen, i, ret;
1838
1839 if (!client->dev.of_node)
1840 return ERR_PTR(-ENODEV);
1841
1842 pdata = devm_kzalloc(&client->dev, sizeof(*pdata), GFP_KERNEL);
1843 if (!pdata)
1844 return ERR_PTR(-ENOMEM);
1845
1846 if (of_find_property(client->dev.of_node, "linux,gpio-keymap",
1847 &proplen)) {
1848 pdata->t19_num_keys = proplen / sizeof(u32);
1849
1850 keymap = devm_kzalloc(&client->dev,
1851 pdata->t19_num_keys * sizeof(keymap[0]),
1852 GFP_KERNEL);
1853 if (!keymap)
1854 return ERR_PTR(-ENOMEM);
1855
1856 for (i = 0; i < pdata->t19_num_keys; i++) {
1857 ret = of_property_read_u32_index(client->dev.of_node,
1858 "linux,gpio-keymap", i, &keycode);
1859 if (ret)
1860 keycode = KEY_RESERVED;
1861
1862 keymap[i] = keycode;
1863 }
1864
1865 pdata->t19_keymap = keymap;
1866 }
1867
1868 return pdata;
1869}
1870#else
1871static struct mxt_platform_data *mxt_parse_dt(struct i2c_client *client)
1872{
1873 dev_dbg(&client->dev, "No platform data specified\n");
1874 return ERR_PTR(-EINVAL);
1875}
1876#endif
1877
1878static int mxt_probe(struct i2c_client *client, const struct i2c_device_id *id)
Joonyoung Shim4cf51c32010-07-14 21:55:30 -07001879{
Iiro Valkonen7686b102011-02-02 23:21:58 -08001880 struct mxt_data *data;
Stephen Warren78188be2014-07-23 12:23:23 -07001881 const struct mxt_platform_data *pdata;
Joonyoung Shim4cf51c32010-07-14 21:55:30 -07001882 int error;
1883
Stephen Warren78188be2014-07-23 12:23:23 -07001884 pdata = dev_get_platdata(&client->dev);
1885 if (!pdata) {
1886 pdata = mxt_parse_dt(client);
1887 if (IS_ERR(pdata))
1888 return PTR_ERR(pdata);
1889 }
Joonyoung Shim4cf51c32010-07-14 21:55:30 -07001890
Iiro Valkonen7686b102011-02-02 23:21:58 -08001891 data = kzalloc(sizeof(struct mxt_data), GFP_KERNEL);
Nick Dyer7a53d602014-07-23 12:21:26 -07001892 if (!data) {
Joonyoung Shim4cf51c32010-07-14 21:55:30 -07001893 dev_err(&client->dev, "Failed to allocate memory\n");
Nick Dyer7a53d602014-07-23 12:21:26 -07001894 return -ENOMEM;
Joonyoung Shim4cf51c32010-07-14 21:55:30 -07001895 }
1896
Daniel Kurtzec02ac22012-06-28 21:08:02 +08001897 snprintf(data->phys, sizeof(data->phys), "i2c-%u-%04x/input0",
1898 client->adapter->nr, client->addr);
Daniel Kurtz22dfab72013-03-07 19:43:33 -08001899
Joonyoung Shim910d8052011-04-12 23:14:38 -07001900 data->client = client;
Joonyoung Shim910d8052011-04-12 23:14:38 -07001901 data->pdata = pdata;
1902 data->irq = client->irq;
Nick Dyer7a53d602014-07-23 12:21:26 -07001903 i2c_set_clientdata(client, data);
Joonyoung Shim910d8052011-04-12 23:14:38 -07001904
Benson Leungd79e7e42014-05-18 23:02:52 -07001905 init_completion(&data->bl_completion);
Iiro Valkonena4a2ef42014-05-18 23:03:44 -07001906 init_completion(&data->reset_completion);
Nick Dyerc3f78042014-05-18 23:04:46 -07001907 init_completion(&data->crc_completion);
Benson Leungd79e7e42014-05-18 23:02:52 -07001908
Nick Dyerdd24dcf2014-07-23 11:25:55 -07001909 error = request_threaded_irq(client->irq, NULL, mxt_interrupt,
1910 pdata->irqflags | IRQF_ONESHOT,
1911 client->name, data);
1912 if (error) {
1913 dev_err(&client->dev, "Failed to register interrupt\n");
1914 goto err_free_mem;
1915 }
1916
1917 disable_irq(client->irq);
1918
Daniel Kurtzcb159112012-06-28 21:08:22 +08001919 error = mxt_initialize(data);
1920 if (error)
Nick Dyer7a53d602014-07-23 12:21:26 -07001921 goto err_free_irq;
Joonyoung Shim4cf51c32010-07-14 21:55:30 -07001922
Iiro Valkonen7686b102011-02-02 23:21:58 -08001923 error = sysfs_create_group(&client->dev.kobj, &mxt_attr_group);
Nick Dyer7bed6802014-05-18 23:04:09 -07001924 if (error) {
1925 dev_err(&client->dev, "Failure %d creating sysfs group\n",
1926 error);
Nick Dyer7a53d602014-07-23 12:21:26 -07001927 goto err_free_object;
Nick Dyer7bed6802014-05-18 23:04:09 -07001928 }
Joonyoung Shim4cf51c32010-07-14 21:55:30 -07001929
1930 return 0;
1931
Joonyoung Shim4cf51c32010-07-14 21:55:30 -07001932err_free_object:
1933 kfree(data->object_table);
Nick Dyerdd24dcf2014-07-23 11:25:55 -07001934err_free_irq:
1935 free_irq(client->irq, data);
Joonyoung Shim4cf51c32010-07-14 21:55:30 -07001936err_free_mem:
Joonyoung Shim4cf51c32010-07-14 21:55:30 -07001937 kfree(data);
1938 return error;
1939}
1940
Bill Pembertone2619cf2012-11-23 21:50:47 -08001941static int mxt_remove(struct i2c_client *client)
Joonyoung Shim4cf51c32010-07-14 21:55:30 -07001942{
Iiro Valkonen7686b102011-02-02 23:21:58 -08001943 struct mxt_data *data = i2c_get_clientdata(client);
Joonyoung Shim4cf51c32010-07-14 21:55:30 -07001944
Iiro Valkonen7686b102011-02-02 23:21:58 -08001945 sysfs_remove_group(&client->dev.kobj, &mxt_attr_group);
Joonyoung Shim4cf51c32010-07-14 21:55:30 -07001946 free_irq(data->irq, data);
1947 input_unregister_device(data->input_dev);
1948 kfree(data->object_table);
1949 kfree(data);
1950
1951 return 0;
1952}
1953
Daniel Kurtz3a73c812012-05-08 22:29:14 -07001954#ifdef CONFIG_PM_SLEEP
Iiro Valkonen7686b102011-02-02 23:21:58 -08001955static int mxt_suspend(struct device *dev)
Joonyoung Shim4cf51c32010-07-14 21:55:30 -07001956{
Dmitry Torokhov8b5fce02010-11-18 00:14:03 -08001957 struct i2c_client *client = to_i2c_client(dev);
Iiro Valkonen7686b102011-02-02 23:21:58 -08001958 struct mxt_data *data = i2c_get_clientdata(client);
Joonyoung Shim4cf51c32010-07-14 21:55:30 -07001959 struct input_dev *input_dev = data->input_dev;
1960
1961 mutex_lock(&input_dev->mutex);
1962
1963 if (input_dev->users)
Iiro Valkonen7686b102011-02-02 23:21:58 -08001964 mxt_stop(data);
Joonyoung Shim4cf51c32010-07-14 21:55:30 -07001965
1966 mutex_unlock(&input_dev->mutex);
1967
1968 return 0;
1969}
1970
Iiro Valkonen7686b102011-02-02 23:21:58 -08001971static int mxt_resume(struct device *dev)
Joonyoung Shim4cf51c32010-07-14 21:55:30 -07001972{
Dmitry Torokhov8b5fce02010-11-18 00:14:03 -08001973 struct i2c_client *client = to_i2c_client(dev);
Iiro Valkonen7686b102011-02-02 23:21:58 -08001974 struct mxt_data *data = i2c_get_clientdata(client);
Joonyoung Shim4cf51c32010-07-14 21:55:30 -07001975 struct input_dev *input_dev = data->input_dev;
1976
Iiro Valkonena4a2ef42014-05-18 23:03:44 -07001977 mxt_soft_reset(data);
Joonyoung Shim4cf51c32010-07-14 21:55:30 -07001978
1979 mutex_lock(&input_dev->mutex);
1980
1981 if (input_dev->users)
Iiro Valkonen7686b102011-02-02 23:21:58 -08001982 mxt_start(data);
Joonyoung Shim4cf51c32010-07-14 21:55:30 -07001983
1984 mutex_unlock(&input_dev->mutex);
1985
1986 return 0;
1987}
Joonyoung Shim4cf51c32010-07-14 21:55:30 -07001988#endif
1989
Daniel Kurtz3a73c812012-05-08 22:29:14 -07001990static SIMPLE_DEV_PM_OPS(mxt_pm_ops, mxt_suspend, mxt_resume);
1991
Stephen Warren78188be2014-07-23 12:23:23 -07001992static const struct of_device_id mxt_of_match[] = {
1993 { .compatible = "atmel,maxtouch", },
1994 {},
1995};
1996MODULE_DEVICE_TABLE(of, mxt_of_match);
1997
Iiro Valkonen7686b102011-02-02 23:21:58 -08001998static const struct i2c_device_id mxt_id[] = {
Joonyoung Shim4cf51c32010-07-14 21:55:30 -07001999 { "qt602240_ts", 0 },
Iiro Valkonen7686b102011-02-02 23:21:58 -08002000 { "atmel_mxt_ts", 0 },
Daniel Kurtz22dfab72013-03-07 19:43:33 -08002001 { "atmel_mxt_tp", 0 },
Chris Leech46ee2a02011-02-15 13:36:52 -08002002 { "mXT224", 0 },
Joonyoung Shim4cf51c32010-07-14 21:55:30 -07002003 { }
2004};
Iiro Valkonen7686b102011-02-02 23:21:58 -08002005MODULE_DEVICE_TABLE(i2c, mxt_id);
Joonyoung Shim4cf51c32010-07-14 21:55:30 -07002006
Iiro Valkonen7686b102011-02-02 23:21:58 -08002007static struct i2c_driver mxt_driver = {
Joonyoung Shim4cf51c32010-07-14 21:55:30 -07002008 .driver = {
Iiro Valkonen7686b102011-02-02 23:21:58 -08002009 .name = "atmel_mxt_ts",
Joonyoung Shim4cf51c32010-07-14 21:55:30 -07002010 .owner = THIS_MODULE,
Stephen Warren78188be2014-07-23 12:23:23 -07002011 .of_match_table = of_match_ptr(mxt_of_match),
Iiro Valkonen7686b102011-02-02 23:21:58 -08002012 .pm = &mxt_pm_ops,
Joonyoung Shim4cf51c32010-07-14 21:55:30 -07002013 },
Iiro Valkonen7686b102011-02-02 23:21:58 -08002014 .probe = mxt_probe,
Bill Pemberton1cb0aa82012-11-23 21:27:39 -08002015 .remove = mxt_remove,
Iiro Valkonen7686b102011-02-02 23:21:58 -08002016 .id_table = mxt_id,
Joonyoung Shim4cf51c32010-07-14 21:55:30 -07002017};
2018
Axel Lin1b92c1c2012-03-16 23:05:41 -07002019module_i2c_driver(mxt_driver);
Joonyoung Shim4cf51c32010-07-14 21:55:30 -07002020
2021/* Module information */
2022MODULE_AUTHOR("Joonyoung Shim <jy0922.shim@samsung.com>");
Iiro Valkonen7686b102011-02-02 23:21:58 -08002023MODULE_DESCRIPTION("Atmel maXTouch Touchscreen driver");
Joonyoung Shim4cf51c32010-07-14 21:55:30 -07002024MODULE_LICENSE("GPL");