blob: c6b5e7dbd9420b131bc81830305fcb032c2e8f2c [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
Joonyoung Shim4cf51c32010-07-14 21:55:30 -070051
52/* Object types */
Iiro Valkonen81c88a72011-07-04 03:08:25 -070053#define MXT_DEBUG_DIAGNOSTIC_T37 37
54#define MXT_GEN_MESSAGE_T5 5
55#define MXT_GEN_COMMAND_T6 6
56#define MXT_GEN_POWER_T7 7
57#define MXT_GEN_ACQUIRE_T8 8
58#define MXT_GEN_DATASOURCE_T53 53
59#define MXT_TOUCH_MULTI_T9 9
60#define MXT_TOUCH_KEYARRAY_T15 15
61#define MXT_TOUCH_PROXIMITY_T23 23
62#define MXT_TOUCH_PROXKEY_T52 52
63#define MXT_PROCI_GRIPFACE_T20 20
64#define MXT_PROCG_NOISE_T22 22
65#define MXT_PROCI_ONETOUCH_T24 24
66#define MXT_PROCI_TWOTOUCH_T27 27
67#define MXT_PROCI_GRIP_T40 40
68#define MXT_PROCI_PALM_T41 41
69#define MXT_PROCI_TOUCHSUPPRESSION_T42 42
70#define MXT_PROCI_STYLUS_T47 47
71#define MXT_PROCG_NOISESUPPRESSION_T48 48
72#define MXT_SPT_COMMSCONFIG_T18 18
73#define MXT_SPT_GPIOPWM_T19 19
74#define MXT_SPT_SELFTEST_T25 25
75#define MXT_SPT_CTECONFIG_T28 28
76#define MXT_SPT_USERDATA_T38 38
77#define MXT_SPT_DIGITIZER_T43 43
78#define MXT_SPT_MESSAGECOUNT_T44 44
79#define MXT_SPT_CTECONFIG_T46 46
Joonyoung Shim4cf51c32010-07-14 21:55:30 -070080
Iiro Valkonen81c88a72011-07-04 03:08:25 -070081/* MXT_GEN_COMMAND_T6 field */
Iiro Valkonen7686b102011-02-02 23:21:58 -080082#define MXT_COMMAND_RESET 0
83#define MXT_COMMAND_BACKUPNV 1
84#define MXT_COMMAND_CALIBRATE 2
85#define MXT_COMMAND_REPORTALL 3
86#define MXT_COMMAND_DIAGNOSTIC 5
Joonyoung Shim4cf51c32010-07-14 21:55:30 -070087
Iiro Valkonena4a2ef42014-05-18 23:03:44 -070088/* Define for T6 status byte */
89#define MXT_T6_STATUS_RESET (1 << 7)
90
Iiro Valkonen81c88a72011-07-04 03:08:25 -070091/* MXT_GEN_POWER_T7 field */
Iiro Valkonen7686b102011-02-02 23:21:58 -080092#define MXT_POWER_IDLEACQINT 0
93#define MXT_POWER_ACTVACQINT 1
94#define MXT_POWER_ACTV2IDLETO 2
Joonyoung Shim4cf51c32010-07-14 21:55:30 -070095
Iiro Valkonen81c88a72011-07-04 03:08:25 -070096/* MXT_GEN_ACQUIRE_T8 field */
Iiro Valkonen7686b102011-02-02 23:21:58 -080097#define MXT_ACQUIRE_CHRGTIME 0
98#define MXT_ACQUIRE_TCHDRIFT 2
99#define MXT_ACQUIRE_DRIFTST 3
100#define MXT_ACQUIRE_TCHAUTOCAL 4
101#define MXT_ACQUIRE_SYNC 5
102#define MXT_ACQUIRE_ATCHCALST 6
103#define MXT_ACQUIRE_ATCHCALSTHR 7
Joonyoung Shim4cf51c32010-07-14 21:55:30 -0700104
Iiro Valkonen81c88a72011-07-04 03:08:25 -0700105/* MXT_TOUCH_MULTI_T9 field */
Iiro Valkonen7686b102011-02-02 23:21:58 -0800106#define MXT_TOUCH_CTRL 0
Nick Dyer61dc1ab2014-05-18 23:16:49 -0700107#define MXT_T9_ORIENT 9
108#define MXT_T9_RANGE 18
109
Nick Dyerf3889ed2014-05-18 23:22:04 -0700110/* MXT_TOUCH_MULTI_T9 status */
111#define MXT_T9_UNGRIP (1 << 0)
112#define MXT_T9_SUPPRESS (1 << 1)
113#define MXT_T9_AMP (1 << 2)
114#define MXT_T9_VECTOR (1 << 3)
115#define MXT_T9_MOVE (1 << 4)
116#define MXT_T9_RELEASE (1 << 5)
117#define MXT_T9_PRESS (1 << 6)
118#define MXT_T9_DETECT (1 << 7)
119
Nick Dyer61dc1ab2014-05-18 23:16:49 -0700120struct t9_range {
121 u16 x;
122 u16 y;
123} __packed;
124
Nick Dyerf3889ed2014-05-18 23:22:04 -0700125/* MXT_TOUCH_MULTI_T9 orient */
126#define MXT_T9_ORIENT_SWITCH (1 << 0)
Joonyoung Shim4cf51c32010-07-14 21:55:30 -0700127
Iiro Valkonen81c88a72011-07-04 03:08:25 -0700128/* MXT_PROCI_GRIPFACE_T20 field */
Iiro Valkonen7686b102011-02-02 23:21:58 -0800129#define MXT_GRIPFACE_CTRL 0
130#define MXT_GRIPFACE_XLOGRIP 1
131#define MXT_GRIPFACE_XHIGRIP 2
132#define MXT_GRIPFACE_YLOGRIP 3
133#define MXT_GRIPFACE_YHIGRIP 4
134#define MXT_GRIPFACE_MAXTCHS 5
135#define MXT_GRIPFACE_SZTHR1 7
136#define MXT_GRIPFACE_SZTHR2 8
137#define MXT_GRIPFACE_SHPTHR1 9
138#define MXT_GRIPFACE_SHPTHR2 10
139#define MXT_GRIPFACE_SUPEXTTO 11
Joonyoung Shim4cf51c32010-07-14 21:55:30 -0700140
Iiro Valkonen7686b102011-02-02 23:21:58 -0800141/* MXT_PROCI_NOISE field */
142#define MXT_NOISE_CTRL 0
143#define MXT_NOISE_OUTFLEN 1
144#define MXT_NOISE_GCAFUL_LSB 3
145#define MXT_NOISE_GCAFUL_MSB 4
146#define MXT_NOISE_GCAFLL_LSB 5
147#define MXT_NOISE_GCAFLL_MSB 6
148#define MXT_NOISE_ACTVGCAFVALID 7
149#define MXT_NOISE_NOISETHR 8
150#define MXT_NOISE_FREQHOPSCALE 10
151#define MXT_NOISE_FREQ0 11
152#define MXT_NOISE_FREQ1 12
153#define MXT_NOISE_FREQ2 13
154#define MXT_NOISE_FREQ3 14
155#define MXT_NOISE_FREQ4 15
156#define MXT_NOISE_IDLEGCAFVALID 16
Joonyoung Shim4cf51c32010-07-14 21:55:30 -0700157
Iiro Valkonen81c88a72011-07-04 03:08:25 -0700158/* MXT_SPT_COMMSCONFIG_T18 */
Iiro Valkonen7686b102011-02-02 23:21:58 -0800159#define MXT_COMMS_CTRL 0
160#define MXT_COMMS_CMD 1
Joonyoung Shim4cf51c32010-07-14 21:55:30 -0700161
Iiro Valkonen81c88a72011-07-04 03:08:25 -0700162/* MXT_SPT_CTECONFIG_T28 field */
Iiro Valkonen7686b102011-02-02 23:21:58 -0800163#define MXT_CTE_CTRL 0
164#define MXT_CTE_CMD 1
165#define MXT_CTE_MODE 2
166#define MXT_CTE_IDLEGCAFDEPTH 3
167#define MXT_CTE_ACTVGCAFDEPTH 4
Joonyoung Shim979a72d2011-03-14 21:41:34 -0700168#define MXT_CTE_VOLTAGE 5
Joonyoung Shim4cf51c32010-07-14 21:55:30 -0700169
Iiro Valkonen7686b102011-02-02 23:21:58 -0800170#define MXT_VOLTAGE_DEFAULT 2700000
171#define MXT_VOLTAGE_STEP 10000
Joonyoung Shim4cf51c32010-07-14 21:55:30 -0700172
Iiro Valkonen81c88a72011-07-04 03:08:25 -0700173/* Define for MXT_GEN_COMMAND_T6 */
Iiro Valkonen7686b102011-02-02 23:21:58 -0800174#define MXT_BOOT_VALUE 0xa5
Iiro Valkonena4a2ef42014-05-18 23:03:44 -0700175#define MXT_RESET_VALUE 0x01
Iiro Valkonen7686b102011-02-02 23:21:58 -0800176#define MXT_BACKUP_VALUE 0x55
Iiro Valkonena4a2ef42014-05-18 23:03:44 -0700177
178/* Delay times */
Linus Torvalds8343bce2013-03-09 10:31:01 -0800179#define MXT_BACKUP_TIME 50 /* msec */
180#define MXT_RESET_TIME 200 /* msec */
Iiro Valkonena4a2ef42014-05-18 23:03:44 -0700181#define MXT_RESET_TIMEOUT 3000 /* msec */
Nick Dyerc3f78042014-05-18 23:04:46 -0700182#define MXT_CRC_TIMEOUT 1000 /* msec */
Benson Leunga0434b72014-05-18 23:03:09 -0700183#define MXT_FW_RESET_TIME 3000 /* msec */
184#define MXT_FW_CHG_TIMEOUT 300 /* msec */
Joonyoung Shim4cf51c32010-07-14 21:55:30 -0700185
186/* Command to unlock bootloader */
Iiro Valkonen7686b102011-02-02 23:21:58 -0800187#define MXT_UNLOCK_CMD_MSB 0xaa
188#define MXT_UNLOCK_CMD_LSB 0xdc
Joonyoung Shim4cf51c32010-07-14 21:55:30 -0700189
190/* Bootloader mode status */
Iiro Valkonen7686b102011-02-02 23:21:58 -0800191#define MXT_WAITING_BOOTLOAD_CMD 0xc0 /* valid 7 6 bit only */
192#define MXT_WAITING_FRAME_DATA 0x80 /* valid 7 6 bit only */
193#define MXT_FRAME_CRC_CHECK 0x02
194#define MXT_FRAME_CRC_FAIL 0x03
195#define MXT_FRAME_CRC_PASS 0x04
196#define MXT_APP_CRC_FAIL 0x40 /* valid 7 8 bit only */
197#define MXT_BOOT_STATUS_MASK 0x3f
Nick Dyere57a66a2014-05-18 23:13:40 -0700198#define MXT_BOOT_EXTENDED_ID (1 << 5)
199#define MXT_BOOT_ID_MASK 0x1f
Joonyoung Shim4cf51c32010-07-14 21:55:30 -0700200
Joonyoung Shim4cf51c32010-07-14 21:55:30 -0700201/* Touchscreen absolute values */
Iiro Valkonen7686b102011-02-02 23:21:58 -0800202#define MXT_MAX_AREA 0xff
Joonyoung Shim4cf51c32010-07-14 21:55:30 -0700203
Daniel Kurtz22dfab72013-03-07 19:43:33 -0800204#define MXT_PIXELS_PER_MM 20
205
Iiro Valkonen7686b102011-02-02 23:21:58 -0800206struct mxt_info {
Joonyoung Shim4cf51c32010-07-14 21:55:30 -0700207 u8 family_id;
208 u8 variant_id;
209 u8 version;
210 u8 build;
211 u8 matrix_xsize;
212 u8 matrix_ysize;
213 u8 object_num;
214};
215
Iiro Valkonen7686b102011-02-02 23:21:58 -0800216struct mxt_object {
Joonyoung Shim4cf51c32010-07-14 21:55:30 -0700217 u8 type;
218 u16 start_address;
Daniel Kurtz1e0c0c52014-05-18 23:01:12 -0700219 u8 size_minus_one;
220 u8 instances_minus_one;
Joonyoung Shim4cf51c32010-07-14 21:55:30 -0700221 u8 num_report_ids;
Daniel Kurtz333e5a92012-06-28 21:08:20 +0800222} __packed;
Joonyoung Shim4cf51c32010-07-14 21:55:30 -0700223
Iiro Valkonen7686b102011-02-02 23:21:58 -0800224struct mxt_message {
Joonyoung Shim4cf51c32010-07-14 21:55:30 -0700225 u8 reportid;
226 u8 message[7];
Joonyoung Shim4cf51c32010-07-14 21:55:30 -0700227};
228
Joonyoung Shim4cf51c32010-07-14 21:55:30 -0700229/* Each client has this additional data */
Iiro Valkonen7686b102011-02-02 23:21:58 -0800230struct mxt_data {
Joonyoung Shim4cf51c32010-07-14 21:55:30 -0700231 struct i2c_client *client;
232 struct input_dev *input_dev;
Daniel Kurtzec02ac22012-06-28 21:08:02 +0800233 char phys[64]; /* device physical location */
Iiro Valkonen7686b102011-02-02 23:21:58 -0800234 const struct mxt_platform_data *pdata;
235 struct mxt_object *object_table;
236 struct mxt_info info;
Joonyoung Shim4cf51c32010-07-14 21:55:30 -0700237 unsigned int irq;
Joonyoung Shim910d8052011-04-12 23:14:38 -0700238 unsigned int max_x;
239 unsigned int max_y;
Benson Leungd79e7e42014-05-18 23:02:52 -0700240 bool in_bootloader;
Nick Dyerc3f78042014-05-18 23:04:46 -0700241 u32 config_crc;
Nick Dyerf28a8422014-05-18 23:10:49 -0700242 u8 bootloader_addr;
Daniel Kurtz333e5a92012-06-28 21:08:20 +0800243
244 /* Cached parameters from object table */
Daniel Kurtzfdf804212012-06-28 21:08:24 +0800245 u8 T6_reportid;
Iiro Valkonena4a2ef42014-05-18 23:03:44 -0700246 u16 T6_address;
Daniel Kurtz333e5a92012-06-28 21:08:20 +0800247 u8 T9_reportid_min;
248 u8 T9_reportid_max;
Daniel Kurtz22dfab72013-03-07 19:43:33 -0800249 u8 T19_reportid;
Benson Leungd79e7e42014-05-18 23:02:52 -0700250
251 /* for fw update in bootloader */
252 struct completion bl_completion;
Iiro Valkonena4a2ef42014-05-18 23:03:44 -0700253
254 /* for reset handling */
255 struct completion reset_completion;
Nick Dyerc3f78042014-05-18 23:04:46 -0700256
257 /* for config update handling */
258 struct completion crc_completion;
Joonyoung Shim4cf51c32010-07-14 21:55:30 -0700259};
260
Daniel Kurtz1e0c0c52014-05-18 23:01:12 -0700261static size_t mxt_obj_size(const struct mxt_object *obj)
262{
263 return obj->size_minus_one + 1;
264}
265
266static size_t mxt_obj_instances(const struct mxt_object *obj)
267{
268 return obj->instances_minus_one + 1;
269}
270
Iiro Valkonen7686b102011-02-02 23:21:58 -0800271static bool mxt_object_readable(unsigned int type)
Joonyoung Shim4cf51c32010-07-14 21:55:30 -0700272{
273 switch (type) {
Iiro Valkonen81c88a72011-07-04 03:08:25 -0700274 case MXT_GEN_COMMAND_T6:
275 case MXT_GEN_POWER_T7:
276 case MXT_GEN_ACQUIRE_T8:
277 case MXT_GEN_DATASOURCE_T53:
278 case MXT_TOUCH_MULTI_T9:
279 case MXT_TOUCH_KEYARRAY_T15:
280 case MXT_TOUCH_PROXIMITY_T23:
281 case MXT_TOUCH_PROXKEY_T52:
282 case MXT_PROCI_GRIPFACE_T20:
283 case MXT_PROCG_NOISE_T22:
284 case MXT_PROCI_ONETOUCH_T24:
285 case MXT_PROCI_TWOTOUCH_T27:
286 case MXT_PROCI_GRIP_T40:
287 case MXT_PROCI_PALM_T41:
288 case MXT_PROCI_TOUCHSUPPRESSION_T42:
289 case MXT_PROCI_STYLUS_T47:
290 case MXT_PROCG_NOISESUPPRESSION_T48:
291 case MXT_SPT_COMMSCONFIG_T18:
292 case MXT_SPT_GPIOPWM_T19:
293 case MXT_SPT_SELFTEST_T25:
294 case MXT_SPT_CTECONFIG_T28:
295 case MXT_SPT_USERDATA_T38:
296 case MXT_SPT_DIGITIZER_T43:
297 case MXT_SPT_CTECONFIG_T46:
Joonyoung Shim4cf51c32010-07-14 21:55:30 -0700298 return true;
299 default:
300 return false;
301 }
302}
303
Iiro Valkonen7686b102011-02-02 23:21:58 -0800304static void mxt_dump_message(struct device *dev,
Daniel Kurtz6ee3dbf2012-05-08 22:40:29 -0700305 struct mxt_message *message)
Joonyoung Shim4cf51c32010-07-14 21:55:30 -0700306{
Andy Shevchenkoeb007c82012-10-04 00:02:59 -0700307 dev_dbg(dev, "reportid: %u\tmessage: %*ph\n",
308 message->reportid, 7, message->message);
Joonyoung Shim4cf51c32010-07-14 21:55:30 -0700309}
310
Iiro Valkonena4a2ef42014-05-18 23:03:44 -0700311static int mxt_wait_for_completion(struct mxt_data *data,
312 struct completion *comp,
313 unsigned int timeout_ms)
Joonyoung Shim4cf51c32010-07-14 21:55:30 -0700314{
Benson Leungd79e7e42014-05-18 23:02:52 -0700315 struct device *dev = &data->client->dev;
Benson Leungd79e7e42014-05-18 23:02:52 -0700316 unsigned long timeout = msecs_to_jiffies(timeout_ms);
317 long ret;
318
319 ret = wait_for_completion_interruptible_timeout(comp, timeout);
320 if (ret < 0) {
321 return ret;
322 } else if (ret == 0) {
323 dev_err(dev, "Wait for completion timed out.\n");
324 return -ETIMEDOUT;
325 }
326 return 0;
327}
328
Nick Dyerf28a8422014-05-18 23:10:49 -0700329static int mxt_bootloader_read(struct mxt_data *data,
330 u8 *val, unsigned int count)
331{
332 int ret;
333 struct i2c_msg msg;
334
335 msg.addr = data->bootloader_addr;
336 msg.flags = data->client->flags & I2C_M_TEN;
337 msg.flags |= I2C_M_RD;
338 msg.len = count;
339 msg.buf = val;
340
341 ret = i2c_transfer(data->client->adapter, &msg, 1);
342
343 if (ret == 1) {
344 ret = 0;
345 } else {
346 ret = ret < 0 ? ret : -EIO;
347 dev_err(&data->client->dev, "%s: i2c recv failed (%d)\n",
348 __func__, ret);
349 }
350
351 return ret;
352}
353
354static int mxt_bootloader_write(struct mxt_data *data,
355 const u8 * const val, unsigned int count)
356{
357 int ret;
358 struct i2c_msg msg;
359
360 msg.addr = data->bootloader_addr;
361 msg.flags = data->client->flags & I2C_M_TEN;
362 msg.len = count;
363 msg.buf = (u8 *)val;
364
365 ret = i2c_transfer(data->client->adapter, &msg, 1);
366 if (ret == 1) {
367 ret = 0;
368 } else {
369 ret = ret < 0 ? ret : -EIO;
370 dev_err(&data->client->dev, "%s: i2c send failed (%d)\n",
371 __func__, ret);
372 }
373
374 return ret;
375}
376
377static int mxt_lookup_bootloader_address(struct mxt_data *data)
378{
379 u8 appmode = data->client->addr;
380 u8 bootloader;
381
382 switch (appmode) {
383 case 0x4a:
384 case 0x4b:
385 case 0x4c:
386 case 0x4d:
387 case 0x5a:
388 case 0x5b:
389 bootloader = appmode - 0x26;
390 break;
391 default:
392 dev_err(&data->client->dev,
393 "Appmode i2c address 0x%02x not found\n",
394 appmode);
395 return -EINVAL;
396 }
397
398 data->bootloader_addr = bootloader;
399 return 0;
400}
401
Nick Dyere57a66a2014-05-18 23:13:40 -0700402static u8 mxt_get_bootloader_version(struct mxt_data *data, u8 val)
403{
404 struct device *dev = &data->client->dev;
405 u8 buf[3];
406
407 if (val & MXT_BOOT_EXTENDED_ID) {
408 if (mxt_bootloader_read(data, &buf[0], 3) != 0) {
409 dev_err(dev, "%s: i2c failure\n", __func__);
Nick Dyer68807a02014-06-07 23:17:26 -0700410 return val;
Nick Dyere57a66a2014-05-18 23:13:40 -0700411 }
412
413 dev_dbg(dev, "Bootloader ID:%d Version:%d\n", buf[1], buf[2]);
414
415 return buf[0];
416 } else {
417 dev_dbg(dev, "Bootloader ID:%d\n", val & MXT_BOOT_ID_MASK);
418
419 return val;
420 }
421}
422
Benson Leungd79e7e42014-05-18 23:02:52 -0700423static int mxt_check_bootloader(struct mxt_data *data, unsigned int state)
424{
Nick Dyerf28a8422014-05-18 23:10:49 -0700425 struct device *dev = &data->client->dev;
Joonyoung Shim4cf51c32010-07-14 21:55:30 -0700426 u8 val;
Benson Leungd79e7e42014-05-18 23:02:52 -0700427 int ret;
Joonyoung Shim4cf51c32010-07-14 21:55:30 -0700428
429recheck:
Benson Leungd79e7e42014-05-18 23:02:52 -0700430 if (state != MXT_WAITING_BOOTLOAD_CMD) {
431 /*
432 * In application update mode, the interrupt
433 * line signals state transitions. We must wait for the
434 * CHG assertion before reading the status byte.
435 * Once the status byte has been read, the line is deasserted.
436 */
Iiro Valkonena4a2ef42014-05-18 23:03:44 -0700437 ret = mxt_wait_for_completion(data, &data->bl_completion,
438 MXT_FW_CHG_TIMEOUT);
Benson Leungd79e7e42014-05-18 23:02:52 -0700439 if (ret) {
440 /*
441 * TODO: handle -ERESTARTSYS better by terminating
442 * fw update process before returning to userspace
443 * by writing length 0x000 to device (iff we are in
444 * WAITING_FRAME_DATA state).
445 */
Nick Dyerf28a8422014-05-18 23:10:49 -0700446 dev_err(dev, "Update wait error %d\n", ret);
Benson Leungd79e7e42014-05-18 23:02:52 -0700447 return ret;
448 }
449 }
450
Nick Dyerf28a8422014-05-18 23:10:49 -0700451 ret = mxt_bootloader_read(data, &val, 1);
452 if (ret)
453 return ret;
Joonyoung Shim4cf51c32010-07-14 21:55:30 -0700454
Nick Dyere57a66a2014-05-18 23:13:40 -0700455 if (state == MXT_WAITING_BOOTLOAD_CMD)
456 val = mxt_get_bootloader_version(data, val);
457
Joonyoung Shim4cf51c32010-07-14 21:55:30 -0700458 switch (state) {
Iiro Valkonen7686b102011-02-02 23:21:58 -0800459 case MXT_WAITING_BOOTLOAD_CMD:
460 case MXT_WAITING_FRAME_DATA:
461 val &= ~MXT_BOOT_STATUS_MASK;
Joonyoung Shim4cf51c32010-07-14 21:55:30 -0700462 break;
Iiro Valkonen7686b102011-02-02 23:21:58 -0800463 case MXT_FRAME_CRC_PASS:
Nick Dyerf943c742014-05-18 23:14:20 -0700464 if (val == MXT_FRAME_CRC_CHECK) {
Joonyoung Shim4cf51c32010-07-14 21:55:30 -0700465 goto recheck;
Nick Dyerf943c742014-05-18 23:14:20 -0700466 } else if (val == MXT_FRAME_CRC_FAIL) {
467 dev_err(dev, "Bootloader CRC fail\n");
468 return -EINVAL;
469 }
Joonyoung Shim4cf51c32010-07-14 21:55:30 -0700470 break;
471 default:
472 return -EINVAL;
473 }
474
475 if (val != state) {
Nick Dyerf28a8422014-05-18 23:10:49 -0700476 dev_err(dev, "Invalid bootloader state %02X != %02X\n",
Nick Dyer7bed6802014-05-18 23:04:09 -0700477 val, state);
Joonyoung Shim4cf51c32010-07-14 21:55:30 -0700478 return -EINVAL;
479 }
480
481 return 0;
482}
483
Nick Dyerf28a8422014-05-18 23:10:49 -0700484static int mxt_unlock_bootloader(struct mxt_data *data)
Joonyoung Shim4cf51c32010-07-14 21:55:30 -0700485{
Nick Dyerf28a8422014-05-18 23:10:49 -0700486 int ret;
Joonyoung Shim4cf51c32010-07-14 21:55:30 -0700487 u8 buf[2];
488
Iiro Valkonen7686b102011-02-02 23:21:58 -0800489 buf[0] = MXT_UNLOCK_CMD_LSB;
490 buf[1] = MXT_UNLOCK_CMD_MSB;
Joonyoung Shim4cf51c32010-07-14 21:55:30 -0700491
Nick Dyerf28a8422014-05-18 23:10:49 -0700492 ret = mxt_bootloader_write(data, buf, 2);
493 if (ret)
494 return ret;
Joonyoung Shim4cf51c32010-07-14 21:55:30 -0700495
496 return 0;
497}
498
Iiro Valkonen7686b102011-02-02 23:21:58 -0800499static int __mxt_read_reg(struct i2c_client *client,
Joonyoung Shim4cf51c32010-07-14 21:55:30 -0700500 u16 reg, u16 len, void *val)
501{
502 struct i2c_msg xfer[2];
503 u8 buf[2];
Daniel Kurtz771733e2012-06-28 21:08:11 +0800504 int ret;
Joonyoung Shim4cf51c32010-07-14 21:55:30 -0700505
506 buf[0] = reg & 0xff;
507 buf[1] = (reg >> 8) & 0xff;
508
509 /* Write register */
510 xfer[0].addr = client->addr;
511 xfer[0].flags = 0;
512 xfer[0].len = 2;
513 xfer[0].buf = buf;
514
515 /* Read data */
516 xfer[1].addr = client->addr;
517 xfer[1].flags = I2C_M_RD;
518 xfer[1].len = len;
519 xfer[1].buf = val;
520
Daniel Kurtz771733e2012-06-28 21:08:11 +0800521 ret = i2c_transfer(client->adapter, xfer, 2);
522 if (ret == 2) {
523 ret = 0;
524 } else {
525 if (ret >= 0)
526 ret = -EIO;
527 dev_err(&client->dev, "%s: i2c transfer failed (%d)\n",
528 __func__, ret);
Joonyoung Shim4cf51c32010-07-14 21:55:30 -0700529 }
530
Daniel Kurtz771733e2012-06-28 21:08:11 +0800531 return ret;
Joonyoung Shim4cf51c32010-07-14 21:55:30 -0700532}
533
Daniel Kurtz9638ab72012-06-28 21:08:12 +0800534static int __mxt_write_reg(struct i2c_client *client, u16 reg, u16 len,
535 const void *val)
Joonyoung Shim4cf51c32010-07-14 21:55:30 -0700536{
Daniel Kurtz9638ab72012-06-28 21:08:12 +0800537 u8 *buf;
538 size_t count;
Daniel Kurtz771733e2012-06-28 21:08:11 +0800539 int ret;
Joonyoung Shim4cf51c32010-07-14 21:55:30 -0700540
Daniel Kurtz9638ab72012-06-28 21:08:12 +0800541 count = len + 2;
542 buf = kmalloc(count, GFP_KERNEL);
543 if (!buf)
544 return -ENOMEM;
Joonyoung Shim4cf51c32010-07-14 21:55:30 -0700545
546 buf[0] = reg & 0xff;
547 buf[1] = (reg >> 8) & 0xff;
Daniel Kurtz9638ab72012-06-28 21:08:12 +0800548 memcpy(&buf[2], val, len);
Joonyoung Shim4cf51c32010-07-14 21:55:30 -0700549
Daniel Kurtz9638ab72012-06-28 21:08:12 +0800550 ret = i2c_master_send(client, buf, count);
551 if (ret == count) {
Daniel Kurtz771733e2012-06-28 21:08:11 +0800552 ret = 0;
553 } else {
554 if (ret >= 0)
555 ret = -EIO;
556 dev_err(&client->dev, "%s: i2c send failed (%d)\n",
557 __func__, ret);
Joonyoung Shim4cf51c32010-07-14 21:55:30 -0700558 }
559
Daniel Kurtz9638ab72012-06-28 21:08:12 +0800560 kfree(buf);
Daniel Kurtz771733e2012-06-28 21:08:11 +0800561 return ret;
Joonyoung Shim4cf51c32010-07-14 21:55:30 -0700562}
563
Daniel Kurtz9638ab72012-06-28 21:08:12 +0800564static int mxt_write_reg(struct i2c_client *client, u16 reg, u8 val)
Joonyoung Shim4cf51c32010-07-14 21:55:30 -0700565{
Daniel Kurtz9638ab72012-06-28 21:08:12 +0800566 return __mxt_write_reg(client, reg, 1, &val);
Joonyoung Shim4cf51c32010-07-14 21:55:30 -0700567}
568
Iiro Valkonen7686b102011-02-02 23:21:58 -0800569static struct mxt_object *
570mxt_get_object(struct mxt_data *data, u8 type)
Joonyoung Shim4cf51c32010-07-14 21:55:30 -0700571{
Iiro Valkonen7686b102011-02-02 23:21:58 -0800572 struct mxt_object *object;
Joonyoung Shim4cf51c32010-07-14 21:55:30 -0700573 int i;
574
575 for (i = 0; i < data->info.object_num; i++) {
576 object = data->object_table + i;
577 if (object->type == type)
578 return object;
579 }
580
Nick Dyer50a77c62014-07-23 12:38:48 -0700581 dev_warn(&data->client->dev, "Invalid object type T%u\n", type);
Joonyoung Shim4cf51c32010-07-14 21:55:30 -0700582 return NULL;
583}
584
Iiro Valkonen7686b102011-02-02 23:21:58 -0800585static int mxt_read_message(struct mxt_data *data,
586 struct mxt_message *message)
Joonyoung Shim4cf51c32010-07-14 21:55:30 -0700587{
Iiro Valkonen7686b102011-02-02 23:21:58 -0800588 struct mxt_object *object;
Joonyoung Shim4cf51c32010-07-14 21:55:30 -0700589 u16 reg;
590
Iiro Valkonen81c88a72011-07-04 03:08:25 -0700591 object = mxt_get_object(data, MXT_GEN_MESSAGE_T5);
Joonyoung Shim4cf51c32010-07-14 21:55:30 -0700592 if (!object)
593 return -EINVAL;
594
595 reg = object->start_address;
Iiro Valkonen7686b102011-02-02 23:21:58 -0800596 return __mxt_read_reg(data->client, reg,
597 sizeof(struct mxt_message), message);
Joonyoung Shim4cf51c32010-07-14 21:55:30 -0700598}
599
Iiro Valkonen7686b102011-02-02 23:21:58 -0800600static int mxt_write_object(struct mxt_data *data,
Joonyoung Shim4cf51c32010-07-14 21:55:30 -0700601 u8 type, u8 offset, u8 val)
602{
Iiro Valkonen7686b102011-02-02 23:21:58 -0800603 struct mxt_object *object;
Joonyoung Shim4cf51c32010-07-14 21:55:30 -0700604 u16 reg;
605
Iiro Valkonen7686b102011-02-02 23:21:58 -0800606 object = mxt_get_object(data, type);
Daniel Kurtz1e0c0c52014-05-18 23:01:12 -0700607 if (!object || offset >= mxt_obj_size(object))
Joonyoung Shim4cf51c32010-07-14 21:55:30 -0700608 return -EINVAL;
609
610 reg = object->start_address;
Iiro Valkonen7686b102011-02-02 23:21:58 -0800611 return mxt_write_reg(data->client, reg + offset, val);
Joonyoung Shim4cf51c32010-07-14 21:55:30 -0700612}
613
Daniel Kurtz22dfab72013-03-07 19:43:33 -0800614static void mxt_input_button(struct mxt_data *data, struct mxt_message *message)
615{
616 struct input_dev *input = data->input_dev;
Nick Dyerfb5e4c3e2014-05-18 23:00:15 -0700617 const struct mxt_platform_data *pdata = data->pdata;
Daniel Kurtz22dfab72013-03-07 19:43:33 -0800618 bool button;
619 int i;
620
621 /* Active-low switch */
Nick Dyerfb5e4c3e2014-05-18 23:00:15 -0700622 for (i = 0; i < pdata->t19_num_keys; i++) {
623 if (pdata->t19_keymap[i] == KEY_RESERVED)
Daniel Kurtz22dfab72013-03-07 19:43:33 -0800624 continue;
Nick Dyerfb5e4c3e2014-05-18 23:00:15 -0700625 button = !(message->message[0] & (1 << i));
626 input_report_key(input, pdata->t19_keymap[i], button);
Daniel Kurtz22dfab72013-03-07 19:43:33 -0800627 }
628}
629
Benson Leungb735fbe2014-07-23 12:22:27 -0700630static void mxt_input_sync(struct mxt_data *data)
Nick Dyereef820d2014-05-18 23:22:22 -0700631{
Benson Leungb735fbe2014-07-23 12:22:27 -0700632 input_mt_report_pointer_emulation(data->input_dev,
633 data->pdata->t19_num_keys);
634 input_sync(data->input_dev);
Nick Dyereef820d2014-05-18 23:22:22 -0700635}
636
Iiro Valkonen7686b102011-02-02 23:21:58 -0800637static void mxt_input_touchevent(struct mxt_data *data,
638 struct mxt_message *message, int id)
Joonyoung Shim4cf51c32010-07-14 21:55:30 -0700639{
Joonyoung Shim4cf51c32010-07-14 21:55:30 -0700640 struct device *dev = &data->client->dev;
641 u8 status = message->message[0];
Daniel Kurtzfba5bc32012-06-28 21:08:17 +0800642 struct input_dev *input_dev = data->input_dev;
Joonyoung Shim4cf51c32010-07-14 21:55:30 -0700643 int x;
644 int y;
645 int area;
Nick Dyerfea9e462014-05-18 23:21:48 -0700646 int amplitude;
Joonyoung Shim4cf51c32010-07-14 21:55:30 -0700647
Joonyoung Shim910d8052011-04-12 23:14:38 -0700648 x = (message->message[1] << 4) | ((message->message[3] >> 4) & 0xf);
649 y = (message->message[2] << 4) | ((message->message[3] & 0xf));
Nick Dyereef820d2014-05-18 23:22:22 -0700650
651 /* Handle 10/12 bit switching */
Joonyoung Shim910d8052011-04-12 23:14:38 -0700652 if (data->max_x < 1024)
Nick Dyereef820d2014-05-18 23:22:22 -0700653 x >>= 2;
Joonyoung Shim910d8052011-04-12 23:14:38 -0700654 if (data->max_y < 1024)
Nick Dyereef820d2014-05-18 23:22:22 -0700655 y >>= 2;
Joonyoung Shim910d8052011-04-12 23:14:38 -0700656
Joonyoung Shim4cf51c32010-07-14 21:55:30 -0700657 area = message->message[4];
Nick Dyerfea9e462014-05-18 23:21:48 -0700658 amplitude = message->message[5];
Joonyoung Shim4cf51c32010-07-14 21:55:30 -0700659
Daniel Kurtzb2e459b2012-06-28 21:08:18 +0800660 dev_dbg(dev,
661 "[%u] %c%c%c%c%c%c%c%c x: %5u y: %5u area: %3u amp: %3u\n",
662 id,
Nick Dyerf3889ed2014-05-18 23:22:04 -0700663 (status & MXT_T9_DETECT) ? 'D' : '.',
664 (status & MXT_T9_PRESS) ? 'P' : '.',
665 (status & MXT_T9_RELEASE) ? 'R' : '.',
666 (status & MXT_T9_MOVE) ? 'M' : '.',
667 (status & MXT_T9_VECTOR) ? 'V' : '.',
668 (status & MXT_T9_AMP) ? 'A' : '.',
669 (status & MXT_T9_SUPPRESS) ? 'S' : '.',
670 (status & MXT_T9_UNGRIP) ? 'U' : '.',
Nick Dyerfea9e462014-05-18 23:21:48 -0700671 x, y, area, amplitude);
Joonyoung Shim4cf51c32010-07-14 21:55:30 -0700672
Daniel Kurtzfba5bc32012-06-28 21:08:17 +0800673 input_mt_slot(input_dev, id);
Joonyoung Shim4cf51c32010-07-14 21:55:30 -0700674
Nick Dyerf3889ed2014-05-18 23:22:04 -0700675 if (status & MXT_T9_DETECT) {
Nick Dyereef820d2014-05-18 23:22:22 -0700676 /*
677 * Multiple bits may be set if the host is slow to read
678 * the status messages, indicating all the events that
679 * have happened.
680 */
681 if (status & MXT_T9_RELEASE) {
682 input_mt_report_slot_state(input_dev,
683 MT_TOOL_FINGER, 0);
Benson Leungb735fbe2014-07-23 12:22:27 -0700684 mxt_input_sync(data);
Nick Dyereef820d2014-05-18 23:22:22 -0700685 }
686
687 /* Touch active */
688 input_mt_report_slot_state(input_dev, MT_TOOL_FINGER, 1);
Daniel Kurtzfba5bc32012-06-28 21:08:17 +0800689 input_report_abs(input_dev, ABS_MT_POSITION_X, x);
690 input_report_abs(input_dev, ABS_MT_POSITION_Y, y);
Nick Dyerfea9e462014-05-18 23:21:48 -0700691 input_report_abs(input_dev, ABS_MT_PRESSURE, amplitude);
Daniel Kurtzfba5bc32012-06-28 21:08:17 +0800692 input_report_abs(input_dev, ABS_MT_TOUCH_MAJOR, area);
Nick Dyereef820d2014-05-18 23:22:22 -0700693 } else {
694 /* Touch no longer active, close out slot */
695 input_mt_report_slot_state(input_dev, MT_TOOL_FINGER, 0);
Daniel Kurtzfba5bc32012-06-28 21:08:17 +0800696 }
Joonyoung Shim4cf51c32010-07-14 21:55:30 -0700697}
698
Nick Dyerc3f78042014-05-18 23:04:46 -0700699static u16 mxt_extract_T6_csum(const u8 *csum)
Daniel Kurtzfdf804212012-06-28 21:08:24 +0800700{
701 return csum[0] | (csum[1] << 8) | (csum[2] << 16);
702}
703
Daniel Kurtz04a79182012-06-28 21:08:21 +0800704static bool mxt_is_T9_message(struct mxt_data *data, struct mxt_message *msg)
705{
706 u8 id = msg->reportid;
707 return (id >= data->T9_reportid_min && id <= data->T9_reportid_max);
Joonyoung Shim4cf51c32010-07-14 21:55:30 -0700708}
709
Benson Leungd79e7e42014-05-18 23:02:52 -0700710static irqreturn_t mxt_process_messages_until_invalid(struct mxt_data *data)
Joonyoung Shim4cf51c32010-07-14 21:55:30 -0700711{
Iiro Valkonen7686b102011-02-02 23:21:58 -0800712 struct mxt_message message;
Daniel Kurtzfdf804212012-06-28 21:08:24 +0800713 const u8 *payload = &message.message[0];
Joonyoung Shim4cf51c32010-07-14 21:55:30 -0700714 struct device *dev = &data->client->dev;
Joonyoung Shim4cf51c32010-07-14 21:55:30 -0700715 u8 reportid;
Daniel Kurtz64464ae2012-06-28 21:08:23 +0800716 bool update_input = false;
Nick Dyerc3f78042014-05-18 23:04:46 -0700717 u32 crc;
Joonyoung Shim4cf51c32010-07-14 21:55:30 -0700718
719 do {
Iiro Valkonen7686b102011-02-02 23:21:58 -0800720 if (mxt_read_message(data, &message)) {
Joonyoung Shim4cf51c32010-07-14 21:55:30 -0700721 dev_err(dev, "Failed to read message\n");
Nick Dyer8d4e1632014-05-18 23:00:56 -0700722 return IRQ_NONE;
Joonyoung Shim4cf51c32010-07-14 21:55:30 -0700723 }
724
725 reportid = message.reportid;
726
Daniel Kurtzfdf804212012-06-28 21:08:24 +0800727 if (reportid == data->T6_reportid) {
728 u8 status = payload[0];
Nick Dyerc3f78042014-05-18 23:04:46 -0700729
730 crc = mxt_extract_T6_csum(&payload[1]);
731 if (crc != data->config_crc) {
732 data->config_crc = crc;
733 complete(&data->crc_completion);
734 }
735
Daniel Kurtzfdf804212012-06-28 21:08:24 +0800736 dev_dbg(dev, "Status: %02x Config Checksum: %06x\n",
Nick Dyerc3f78042014-05-18 23:04:46 -0700737 status, data->config_crc);
Iiro Valkonena4a2ef42014-05-18 23:03:44 -0700738
739 if (status & MXT_T6_STATUS_RESET)
740 complete(&data->reset_completion);
Nick Dyerdd24dcf2014-07-23 11:25:55 -0700741 } else if (!data->input_dev) {
742 /*
743 * do not report events if input device
744 * is not yet registered
745 */
746 mxt_dump_message(dev, &message);
Daniel Kurtzfdf804212012-06-28 21:08:24 +0800747 } else if (mxt_is_T9_message(data, &message)) {
748 int id = reportid - data->T9_reportid_min;
Iiro Valkonen7686b102011-02-02 23:21:58 -0800749 mxt_input_touchevent(data, &message, id);
Daniel Kurtz64464ae2012-06-28 21:08:23 +0800750 update_input = true;
Daniel Kurtz22dfab72013-03-07 19:43:33 -0800751 } else if (message.reportid == data->T19_reportid) {
752 mxt_input_button(data, &message);
753 update_input = true;
Daniel Kurtz64464ae2012-06-28 21:08:23 +0800754 } else {
Iiro Valkonen7686b102011-02-02 23:21:58 -0800755 mxt_dump_message(dev, &message);
Daniel Kurtz64464ae2012-06-28 21:08:23 +0800756 }
Joonyoung Shim4cf51c32010-07-14 21:55:30 -0700757 } while (reportid != 0xff);
758
Nick Dyereef820d2014-05-18 23:22:22 -0700759 if (update_input)
Benson Leungb735fbe2014-07-23 12:22:27 -0700760 mxt_input_sync(data);
Daniel Kurtz64464ae2012-06-28 21:08:23 +0800761
Joonyoung Shim4cf51c32010-07-14 21:55:30 -0700762 return IRQ_HANDLED;
763}
764
Benson Leungd79e7e42014-05-18 23:02:52 -0700765static irqreturn_t mxt_interrupt(int irq, void *dev_id)
766{
767 struct mxt_data *data = dev_id;
768
769 if (data->in_bootloader) {
770 /* bootloader state transition completion */
771 complete(&data->bl_completion);
772 return IRQ_HANDLED;
773 }
774
Nick Dyerdd24dcf2014-07-23 11:25:55 -0700775 if (!data->object_table)
776 return IRQ_HANDLED;
777
Benson Leungd79e7e42014-05-18 23:02:52 -0700778 return mxt_process_messages_until_invalid(data);
779}
780
Iiro Valkonena4a2ef42014-05-18 23:03:44 -0700781static int mxt_t6_command(struct mxt_data *data, u16 cmd_offset,
782 u8 value, bool wait)
783{
784 u16 reg;
785 u8 command_register;
786 int timeout_counter = 0;
787 int ret;
788
789 reg = data->T6_address + cmd_offset;
790
791 ret = mxt_write_reg(data->client, reg, value);
792 if (ret)
793 return ret;
794
795 if (!wait)
796 return 0;
797
798 do {
799 msleep(20);
800 ret = __mxt_read_reg(data->client, reg, 1, &command_register);
801 if (ret)
802 return ret;
803 } while (command_register != 0 && timeout_counter++ <= 100);
804
805 if (timeout_counter > 100) {
806 dev_err(&data->client->dev, "Command failed!\n");
807 return -EIO;
808 }
809
810 return 0;
811}
812
813static int mxt_soft_reset(struct mxt_data *data)
814{
815 struct device *dev = &data->client->dev;
816 int ret = 0;
817
818 dev_info(dev, "Resetting chip\n");
819
820 reinit_completion(&data->reset_completion);
821
822 ret = mxt_t6_command(data, MXT_COMMAND_RESET, MXT_RESET_VALUE, false);
823 if (ret)
824 return ret;
825
826 ret = mxt_wait_for_completion(data, &data->reset_completion,
827 MXT_RESET_TIMEOUT);
828 if (ret)
829 return ret;
830
831 return 0;
832}
833
Nick Dyerc3f78042014-05-18 23:04:46 -0700834static void mxt_update_crc(struct mxt_data *data, u8 cmd, u8 value)
835{
836 /*
837 * On failure, CRC is set to 0 and config will always be
838 * downloaded.
839 */
840 data->config_crc = 0;
841 reinit_completion(&data->crc_completion);
842
843 mxt_t6_command(data, cmd, value, true);
844
845 /*
846 * Wait for crc message. On failure, CRC is set to 0 and config will
847 * always be downloaded.
848 */
849 mxt_wait_for_completion(data, &data->crc_completion, MXT_CRC_TIMEOUT);
850}
851
Nick Dyer50a77c62014-07-23 12:38:48 -0700852/*
853 * mxt_update_cfg - download configuration to chip
854 *
855 * Atmel Raw Config File Format
856 *
857 * The first four lines of the raw config file contain:
858 * 1) Version
859 * 2) Chip ID Information (first 7 bytes of device memory)
860 * 3) Chip Information Block 24-bit CRC Checksum
861 * 4) Chip Configuration 24-bit CRC Checksum
862 *
863 * The rest of the file consists of one line per object instance:
864 * <TYPE> <INSTANCE> <SIZE> <CONTENTS>
865 *
866 * <TYPE> - 2-byte object type as hex
867 * <INSTANCE> - 2-byte object instance number as hex
868 * <SIZE> - 2-byte object size as hex
869 * <CONTENTS> - array of <SIZE> 1-byte hex values
870 */
871static int mxt_update_cfg(struct mxt_data *data, const struct firmware *cfg)
Joonyoung Shim4cf51c32010-07-14 21:55:30 -0700872{
Joonyoung Shim4cf51c32010-07-14 21:55:30 -0700873 struct device *dev = &data->client->dev;
Nick Dyer50a77c62014-07-23 12:38:48 -0700874 struct mxt_info cfg_info;
875 struct mxt_object *object;
Daniel Kurtzcf94bc02012-06-28 21:08:13 +0800876 int ret;
Nick Dyer50a77c62014-07-23 12:38:48 -0700877 int offset;
878 int pos;
879 int i;
880 u32 info_crc, config_crc;
881 unsigned int type, instance, size;
882 u8 val;
883 u16 reg;
Joonyoung Shim4cf51c32010-07-14 21:55:30 -0700884
Nick Dyerc3f78042014-05-18 23:04:46 -0700885 mxt_update_crc(data, MXT_COMMAND_REPORTALL, 1);
886
Nick Dyer50a77c62014-07-23 12:38:48 -0700887 if (strncmp(cfg->data, MXT_CFG_MAGIC, strlen(MXT_CFG_MAGIC))) {
888 dev_err(dev, "Unrecognised config file\n");
889 ret = -EINVAL;
890 goto release;
Nick Dyerc3f78042014-05-18 23:04:46 -0700891 }
892
Nick Dyer50a77c62014-07-23 12:38:48 -0700893 pos = strlen(MXT_CFG_MAGIC);
Nick Dyerc3f78042014-05-18 23:04:46 -0700894
Nick Dyer50a77c62014-07-23 12:38:48 -0700895 /* Load information block and check */
896 for (i = 0; i < sizeof(struct mxt_info); i++) {
897 ret = sscanf(cfg->data + pos, "%hhx%n",
898 (unsigned char *)&cfg_info + i,
899 &offset);
900 if (ret != 1) {
901 dev_err(dev, "Bad format\n");
902 ret = -EINVAL;
903 goto release;
Iiro Valkonen71749f52011-02-15 13:36:52 -0800904 }
Daniel Kurtzcf94bc02012-06-28 21:08:13 +0800905
Nick Dyer50a77c62014-07-23 12:38:48 -0700906 pos += offset;
907 }
908
909 if (cfg_info.family_id != data->info.family_id) {
910 dev_err(dev, "Family ID mismatch!\n");
911 ret = -EINVAL;
912 goto release;
913 }
914
915 if (cfg_info.variant_id != data->info.variant_id) {
916 dev_err(dev, "Variant ID mismatch!\n");
917 ret = -EINVAL;
918 goto release;
919 }
920
921 if (cfg_info.version != data->info.version)
922 dev_err(dev, "Warning: version mismatch!\n");
923
924 if (cfg_info.build != data->info.build)
925 dev_err(dev, "Warning: build num mismatch!\n");
926
927 ret = sscanf(cfg->data + pos, "%x%n", &info_crc, &offset);
928 if (ret != 1) {
929 dev_err(dev, "Bad format: failed to parse Info CRC\n");
930 ret = -EINVAL;
931 goto release;
932 }
933 pos += offset;
934
935 /* Check config CRC */
936 ret = sscanf(cfg->data + pos, "%x%n", &config_crc, &offset);
937 if (ret != 1) {
938 dev_err(dev, "Bad format: failed to parse Config CRC\n");
939 ret = -EINVAL;
940 goto release;
941 }
942 pos += offset;
943
944 if (data->config_crc == config_crc) {
945 dev_dbg(dev, "Config CRC 0x%06X: OK\n", config_crc);
946 ret = 0;
947 goto release;
948 }
949
950 dev_info(dev, "Config CRC 0x%06X: does not match file 0x%06X\n",
951 data->config_crc, config_crc);
952
953 while (pos < cfg->size) {
954 /* Read type, instance, length */
955 ret = sscanf(cfg->data + pos, "%x %x %x%n",
956 &type, &instance, &size, &offset);
957 if (ret == 0) {
958 /* EOF */
959 ret = 1;
960 goto release;
961 } else if (ret != 3) {
962 dev_err(dev, "Bad format: failed to parse object\n");
963 ret = -EINVAL;
964 goto release;
965 }
966 pos += offset;
967
968 object = mxt_get_object(data, type);
969 if (!object) {
970 /* Skip object */
971 for (i = 0; i < size; i++) {
972 ret = sscanf(cfg->data + pos, "%hhx%n",
973 &val,
974 &offset);
975 pos += offset;
976 }
977 continue;
978 }
979
980 if (size > mxt_obj_size(object)) {
981 dev_err(dev, "Discarding %zu byte(s) in T%u\n",
982 size - mxt_obj_size(object), type);
983 }
984
985 if (instance >= mxt_obj_instances(object)) {
986 dev_err(dev, "Object instances exceeded!\n");
987 ret = -EINVAL;
988 goto release;
989 }
990
991 reg = object->start_address + mxt_obj_size(object) * instance;
992
993 for (i = 0; i < size; i++) {
994 ret = sscanf(cfg->data + pos, "%hhx%n",
995 &val,
996 &offset);
997 if (ret != 1) {
998 dev_err(dev, "Bad format in T%d\n", type);
999 ret = -EINVAL;
1000 goto release;
1001 }
1002 pos += offset;
1003
1004 if (i > mxt_obj_size(object))
1005 continue;
1006
1007 ret = mxt_write_reg(data->client, reg + i, val);
1008 if (ret)
1009 goto release;
1010
1011 }
1012
1013 /*
1014 * If firmware is upgraded, new bytes may be added to end of
1015 * objects. It is generally forward compatible to zero these
1016 * bytes - previous behaviour will be retained. However
1017 * this does invalidate the CRC and will force a config
1018 * download every time until the configuration is updated.
1019 */
1020 if (size < mxt_obj_size(object)) {
1021 dev_info(dev, "Zeroing %zu byte(s) in T%d\n",
1022 mxt_obj_size(object) - size, type);
1023
1024 for (i = size + 1; i < mxt_obj_size(object); i++) {
1025 ret = mxt_write_reg(data->client, reg + i, 0);
1026 if (ret)
1027 goto release;
1028 }
1029 }
Joonyoung Shim4cf51c32010-07-14 21:55:30 -07001030 }
1031
Nick Dyerc3f78042014-05-18 23:04:46 -07001032 mxt_update_crc(data, MXT_COMMAND_BACKUPNV, MXT_BACKUP_VALUE);
1033
1034 ret = mxt_soft_reset(data);
1035 if (ret)
Nick Dyer50a77c62014-07-23 12:38:48 -07001036 goto release;
Nick Dyerc3f78042014-05-18 23:04:46 -07001037
1038 dev_info(dev, "Config successfully updated\n");
1039
Nick Dyer50a77c62014-07-23 12:38:48 -07001040release:
1041 release_firmware(cfg);
1042 return ret;
Joonyoung Shim4cf51c32010-07-14 21:55:30 -07001043}
1044
Iiro Valkonen7686b102011-02-02 23:21:58 -08001045static int mxt_make_highchg(struct mxt_data *data)
Joonyoung Shim4cf51c32010-07-14 21:55:30 -07001046{
1047 struct device *dev = &data->client->dev;
Iiro Valkonen26cdb1a2011-02-04 00:51:05 -08001048 struct mxt_message message;
Joonyoung Shim4cf51c32010-07-14 21:55:30 -07001049 int count = 10;
1050 int error;
Joonyoung Shim4cf51c32010-07-14 21:55:30 -07001051
1052 /* Read dummy message to make high CHG pin */
1053 do {
Iiro Valkonen26cdb1a2011-02-04 00:51:05 -08001054 error = mxt_read_message(data, &message);
Joonyoung Shim4cf51c32010-07-14 21:55:30 -07001055 if (error)
1056 return error;
Iiro Valkonen26cdb1a2011-02-04 00:51:05 -08001057 } while (message.reportid != 0xff && --count);
Joonyoung Shim4cf51c32010-07-14 21:55:30 -07001058
1059 if (!count) {
1060 dev_err(dev, "CHG pin isn't cleared\n");
1061 return -EBUSY;
1062 }
1063
1064 return 0;
1065}
1066
Nick Dyerdd24dcf2014-07-23 11:25:55 -07001067static int mxt_acquire_irq(struct mxt_data *data)
1068{
1069 int error;
1070
1071 enable_irq(data->irq);
1072
1073 error = mxt_make_highchg(data);
1074 if (error)
1075 return error;
1076
1077 return 0;
1078}
1079
Iiro Valkonen7686b102011-02-02 23:21:58 -08001080static int mxt_get_info(struct mxt_data *data)
Joonyoung Shim4cf51c32010-07-14 21:55:30 -07001081{
1082 struct i2c_client *client = data->client;
Iiro Valkonen7686b102011-02-02 23:21:58 -08001083 struct mxt_info *info = &data->info;
Joonyoung Shim4cf51c32010-07-14 21:55:30 -07001084 int error;
Joonyoung Shim4cf51c32010-07-14 21:55:30 -07001085
Daniel Kurtz23003a842012-06-28 21:08:14 +08001086 /* Read 7-byte info block starting at address 0 */
1087 error = __mxt_read_reg(client, MXT_INFO, sizeof(*info), info);
Joonyoung Shim4cf51c32010-07-14 21:55:30 -07001088 if (error)
1089 return error;
Joonyoung Shim4cf51c32010-07-14 21:55:30 -07001090
1091 return 0;
1092}
1093
Iiro Valkonen7686b102011-02-02 23:21:58 -08001094static int mxt_get_object_table(struct mxt_data *data)
Joonyoung Shim4cf51c32010-07-14 21:55:30 -07001095{
Daniel Kurtz333e5a92012-06-28 21:08:20 +08001096 struct i2c_client *client = data->client;
1097 size_t table_size;
Nick Dyerdd24dcf2014-07-23 11:25:55 -07001098 struct mxt_object *object_table;
Joonyoung Shim4cf51c32010-07-14 21:55:30 -07001099 int error;
1100 int i;
Daniel Kurtz333e5a92012-06-28 21:08:20 +08001101 u8 reportid;
Joonyoung Shim4cf51c32010-07-14 21:55:30 -07001102
Daniel Kurtz333e5a92012-06-28 21:08:20 +08001103 table_size = data->info.object_num * sizeof(struct mxt_object);
Nick Dyerdd24dcf2014-07-23 11:25:55 -07001104 object_table = kzalloc(table_size, GFP_KERNEL);
1105 if (!object_table) {
1106 dev_err(&data->client->dev, "Failed to allocate memory\n");
1107 return -ENOMEM;
1108 }
1109
Daniel Kurtz333e5a92012-06-28 21:08:20 +08001110 error = __mxt_read_reg(client, MXT_OBJECT_START, table_size,
Nick Dyerdd24dcf2014-07-23 11:25:55 -07001111 object_table);
1112 if (error) {
1113 kfree(object_table);
Daniel Kurtz333e5a92012-06-28 21:08:20 +08001114 return error;
Nick Dyerdd24dcf2014-07-23 11:25:55 -07001115 }
Daniel Kurtz333e5a92012-06-28 21:08:20 +08001116
1117 /* Valid Report IDs start counting from 1 */
1118 reportid = 1;
Joonyoung Shim4cf51c32010-07-14 21:55:30 -07001119 for (i = 0; i < data->info.object_num; i++) {
Nick Dyerdd24dcf2014-07-23 11:25:55 -07001120 struct mxt_object *object = object_table + i;
Daniel Kurtz333e5a92012-06-28 21:08:20 +08001121 u8 min_id, max_id;
Joonyoung Shim4cf51c32010-07-14 21:55:30 -07001122
Daniel Kurtz333e5a92012-06-28 21:08:20 +08001123 le16_to_cpus(&object->start_address);
Joonyoung Shim4cf51c32010-07-14 21:55:30 -07001124
1125 if (object->num_report_ids) {
Daniel Kurtz333e5a92012-06-28 21:08:20 +08001126 min_id = reportid;
Joonyoung Shim4cf51c32010-07-14 21:55:30 -07001127 reportid += object->num_report_ids *
Daniel Kurtz1e0c0c52014-05-18 23:01:12 -07001128 mxt_obj_instances(object);
Daniel Kurtz333e5a92012-06-28 21:08:20 +08001129 max_id = reportid - 1;
1130 } else {
1131 min_id = 0;
1132 max_id = 0;
1133 }
1134
1135 dev_dbg(&data->client->dev,
Nick Dyer7bed6802014-05-18 23:04:09 -07001136 "T%u Start:%u Size:%zu Instances:%zu Report IDs:%u-%u\n",
Daniel Kurtz1e0c0c52014-05-18 23:01:12 -07001137 object->type, object->start_address,
1138 mxt_obj_size(object), mxt_obj_instances(object),
1139 min_id, max_id);
Daniel Kurtz333e5a92012-06-28 21:08:20 +08001140
1141 switch (object->type) {
Daniel Kurtzfdf804212012-06-28 21:08:24 +08001142 case MXT_GEN_COMMAND_T6:
1143 data->T6_reportid = min_id;
Iiro Valkonena4a2ef42014-05-18 23:03:44 -07001144 data->T6_address = object->start_address;
Daniel Kurtzfdf804212012-06-28 21:08:24 +08001145 break;
Daniel Kurtz333e5a92012-06-28 21:08:20 +08001146 case MXT_TOUCH_MULTI_T9:
1147 data->T9_reportid_min = min_id;
1148 data->T9_reportid_max = max_id;
1149 break;
Daniel Kurtz22dfab72013-03-07 19:43:33 -08001150 case MXT_SPT_GPIOPWM_T19:
1151 data->T19_reportid = min_id;
1152 break;
Joonyoung Shim4cf51c32010-07-14 21:55:30 -07001153 }
1154 }
1155
Nick Dyerdd24dcf2014-07-23 11:25:55 -07001156 data->object_table = object_table;
1157
Joonyoung Shim4cf51c32010-07-14 21:55:30 -07001158 return 0;
1159}
1160
Daniel Kurtz7d4fa102012-06-28 21:08:19 +08001161static void mxt_free_object_table(struct mxt_data *data)
1162{
Nick Dyer7a53d602014-07-23 12:21:26 -07001163 input_unregister_device(data->input_dev);
1164 data->input_dev = NULL;
1165
Daniel Kurtz7d4fa102012-06-28 21:08:19 +08001166 kfree(data->object_table);
1167 data->object_table = NULL;
Daniel Kurtzfdf804212012-06-28 21:08:24 +08001168 data->T6_reportid = 0;
Daniel Kurtz333e5a92012-06-28 21:08:20 +08001169 data->T9_reportid_min = 0;
1170 data->T9_reportid_max = 0;
Daniel Kurtz22dfab72013-03-07 19:43:33 -08001171 data->T19_reportid = 0;
Daniel Kurtz7d4fa102012-06-28 21:08:19 +08001172}
1173
Nick Dyer61dc1ab2014-05-18 23:16:49 -07001174static int mxt_read_t9_resolution(struct mxt_data *data)
1175{
1176 struct i2c_client *client = data->client;
1177 int error;
1178 struct t9_range range;
1179 unsigned char orient;
1180 struct mxt_object *object;
1181
1182 object = mxt_get_object(data, MXT_TOUCH_MULTI_T9);
1183 if (!object)
1184 return -EINVAL;
1185
1186 error = __mxt_read_reg(client,
1187 object->start_address + MXT_T9_RANGE,
1188 sizeof(range), &range);
1189 if (error)
1190 return error;
1191
1192 le16_to_cpus(&range.x);
1193 le16_to_cpus(&range.y);
1194
1195 error = __mxt_read_reg(client,
1196 object->start_address + MXT_T9_ORIENT,
1197 1, &orient);
1198 if (error)
1199 return error;
1200
1201 /* Handle default values */
1202 if (range.x == 0)
1203 range.x = 1023;
1204
1205 if (range.y == 0)
1206 range.y = 1023;
1207
Nick Dyerf3889ed2014-05-18 23:22:04 -07001208 if (orient & MXT_T9_ORIENT_SWITCH) {
Nick Dyer61dc1ab2014-05-18 23:16:49 -07001209 data->max_x = range.y;
1210 data->max_y = range.x;
1211 } else {
1212 data->max_x = range.x;
1213 data->max_y = range.y;
1214 }
1215
1216 dev_dbg(&client->dev,
1217 "Touchscreen size X%uY%u\n", data->max_x, data->max_y);
1218
1219 return 0;
1220}
1221
Nick Dyer7a53d602014-07-23 12:21:26 -07001222static int mxt_input_open(struct input_dev *dev);
1223static void mxt_input_close(struct input_dev *dev);
1224
1225static int mxt_initialize_t9_input_device(struct mxt_data *data)
1226{
1227 struct device *dev = &data->client->dev;
1228 const struct mxt_platform_data *pdata = data->pdata;
1229 struct input_dev *input_dev;
1230 int error;
1231 unsigned int num_mt_slots;
1232 unsigned int mt_flags = 0;
1233 int i;
1234
1235 error = mxt_read_t9_resolution(data);
1236 if (error)
1237 dev_warn(dev, "Failed to initialize T9 resolution\n");
1238
1239 input_dev = input_allocate_device();
1240 if (!input_dev) {
1241 dev_err(dev, "Failed to allocate memory\n");
1242 return -ENOMEM;
1243 }
1244
1245 input_dev->name = "Atmel maXTouch Touchscreen";
1246 input_dev->phys = data->phys;
1247 input_dev->id.bustype = BUS_I2C;
1248 input_dev->dev.parent = dev;
1249 input_dev->open = mxt_input_open;
1250 input_dev->close = mxt_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 if (pdata->t19_num_keys) {
1257 __set_bit(INPUT_PROP_BUTTONPAD, input_dev->propbit);
1258
1259 for (i = 0; i < pdata->t19_num_keys; i++)
1260 if (pdata->t19_keymap[i] != KEY_RESERVED)
1261 input_set_capability(input_dev, EV_KEY,
1262 pdata->t19_keymap[i]);
1263
1264 mt_flags |= INPUT_MT_POINTER;
1265
1266 input_abs_set_res(input_dev, ABS_X, MXT_PIXELS_PER_MM);
1267 input_abs_set_res(input_dev, ABS_Y, MXT_PIXELS_PER_MM);
1268 input_abs_set_res(input_dev, ABS_MT_POSITION_X,
1269 MXT_PIXELS_PER_MM);
1270 input_abs_set_res(input_dev, ABS_MT_POSITION_Y,
1271 MXT_PIXELS_PER_MM);
1272
1273 input_dev->name = "Atmel maXTouch Touchpad";
1274 }
1275
1276 /* For single touch */
1277 input_set_abs_params(input_dev, ABS_X,
1278 0, data->max_x, 0, 0);
1279 input_set_abs_params(input_dev, ABS_Y,
1280 0, data->max_y, 0, 0);
1281 input_set_abs_params(input_dev, ABS_PRESSURE,
1282 0, 255, 0, 0);
1283
1284 /* For multi touch */
1285 num_mt_slots = data->T9_reportid_max - data->T9_reportid_min + 1;
1286 error = input_mt_init_slots(input_dev, num_mt_slots, mt_flags);
1287 if (error) {
1288 dev_err(dev, "Error %d initialising slots\n", error);
1289 goto err_free_mem;
1290 }
1291
1292 input_set_abs_params(input_dev, ABS_MT_TOUCH_MAJOR,
1293 0, MXT_MAX_AREA, 0, 0);
1294 input_set_abs_params(input_dev, ABS_MT_POSITION_X,
1295 0, data->max_x, 0, 0);
1296 input_set_abs_params(input_dev, ABS_MT_POSITION_Y,
1297 0, data->max_y, 0, 0);
1298 input_set_abs_params(input_dev, ABS_MT_PRESSURE,
1299 0, 255, 0, 0);
1300
1301 input_set_drvdata(input_dev, data);
1302
1303 error = input_register_device(input_dev);
1304 if (error) {
1305 dev_err(dev, "Error %d registering input device\n", error);
1306 goto err_free_mem;
1307 }
1308
1309 data->input_dev = input_dev;
1310
1311 return 0;
1312
1313err_free_mem:
1314 input_free_device(input_dev);
1315 return error;
1316}
1317
Nick Dyer50a77c62014-07-23 12:38:48 -07001318static int mxt_configure_objects(struct mxt_data *data,
1319 const struct firmware *cfg);
1320
1321static void mxt_config_cb(const struct firmware *cfg, void *ctx)
1322{
1323 mxt_configure_objects(ctx, cfg);
1324}
1325
Iiro Valkonen7686b102011-02-02 23:21:58 -08001326static int mxt_initialize(struct mxt_data *data)
Joonyoung Shim4cf51c32010-07-14 21:55:30 -07001327{
1328 struct i2c_client *client = data->client;
Joonyoung Shim4cf51c32010-07-14 21:55:30 -07001329 int error;
Joonyoung Shim4cf51c32010-07-14 21:55:30 -07001330
Iiro Valkonen7686b102011-02-02 23:21:58 -08001331 error = mxt_get_info(data);
Joonyoung Shim4cf51c32010-07-14 21:55:30 -07001332 if (error)
1333 return error;
1334
Joonyoung Shim4cf51c32010-07-14 21:55:30 -07001335 /* Get object table information */
Iiro Valkonen7686b102011-02-02 23:21:58 -08001336 error = mxt_get_object_table(data);
Nick Dyer7bed6802014-05-18 23:04:09 -07001337 if (error) {
1338 dev_err(&client->dev, "Error %d reading object table\n", error);
Nick Dyerdd24dcf2014-07-23 11:25:55 -07001339 return error;
Nick Dyer7bed6802014-05-18 23:04:09 -07001340 }
Joonyoung Shim4cf51c32010-07-14 21:55:30 -07001341
Nick Dyerdd24dcf2014-07-23 11:25:55 -07001342 mxt_acquire_irq(data);
1343 if (error)
1344 goto err_free_object_table;
1345
Nick Dyer50a77c62014-07-23 12:38:48 -07001346 request_firmware_nowait(THIS_MODULE, true, MXT_CFG_NAME,
1347 &data->client->dev, GFP_KERNEL, data,
1348 mxt_config_cb);
Joonyoung Shim4cf51c32010-07-14 21:55:30 -07001349
1350 return 0;
Daniel Kurtz7d4fa102012-06-28 21:08:19 +08001351
1352err_free_object_table:
1353 mxt_free_object_table(data);
1354 return error;
Joonyoung Shim4cf51c32010-07-14 21:55:30 -07001355}
1356
Nick Dyer50a77c62014-07-23 12:38:48 -07001357static int mxt_configure_objects(struct mxt_data *data,
1358 const struct firmware *cfg)
1359{
1360 struct device *dev = &data->client->dev;
1361 struct mxt_info *info = &data->info;
1362 int error;
1363
1364 if (cfg) {
1365 error = mxt_update_cfg(data, cfg);
1366 if (error)
1367 dev_warn(dev, "Error %d updating config\n", error);
1368 }
1369
1370 error = mxt_initialize_t9_input_device(data);
1371 if (error)
1372 return error;
1373
1374 dev_info(dev,
1375 "Family: %u Variant: %u Firmware V%u.%u.%02X Objects: %u\n",
1376 info->family_id, info->variant_id, info->version >> 4,
1377 info->version & 0xf, info->build, info->object_num);
1378
1379 return 0;
1380}
1381
Daniel Kurtzb19fc9e2012-06-28 21:08:16 +08001382/* Firmware Version is returned as Major.Minor.Build */
1383static ssize_t mxt_fw_version_show(struct device *dev,
1384 struct device_attribute *attr, char *buf)
1385{
1386 struct mxt_data *data = dev_get_drvdata(dev);
1387 struct mxt_info *info = &data->info;
1388 return scnprintf(buf, PAGE_SIZE, "%u.%u.%02X\n",
1389 info->version >> 4, info->version & 0xf, info->build);
1390}
1391
1392/* Hardware Version is returned as FamilyID.VariantID */
1393static ssize_t mxt_hw_version_show(struct device *dev,
1394 struct device_attribute *attr, char *buf)
1395{
1396 struct mxt_data *data = dev_get_drvdata(dev);
1397 struct mxt_info *info = &data->info;
1398 return scnprintf(buf, PAGE_SIZE, "%u.%u\n",
1399 info->family_id, info->variant_id);
1400}
1401
Daniel Kurtz794eb672012-06-28 21:08:10 +08001402static ssize_t mxt_show_instance(char *buf, int count,
1403 struct mxt_object *object, int instance,
1404 const u8 *val)
1405{
1406 int i;
1407
Daniel Kurtz1e0c0c52014-05-18 23:01:12 -07001408 if (mxt_obj_instances(object) > 1)
Daniel Kurtz794eb672012-06-28 21:08:10 +08001409 count += scnprintf(buf + count, PAGE_SIZE - count,
1410 "Instance %u\n", instance);
1411
Daniel Kurtz1e0c0c52014-05-18 23:01:12 -07001412 for (i = 0; i < mxt_obj_size(object); i++)
Daniel Kurtz794eb672012-06-28 21:08:10 +08001413 count += scnprintf(buf + count, PAGE_SIZE - count,
1414 "\t[%2u]: %02x (%d)\n", i, val[i], val[i]);
1415 count += scnprintf(buf + count, PAGE_SIZE - count, "\n");
1416
1417 return count;
1418}
1419
Iiro Valkonen7686b102011-02-02 23:21:58 -08001420static ssize_t mxt_object_show(struct device *dev,
Joonyoung Shim4cf51c32010-07-14 21:55:30 -07001421 struct device_attribute *attr, char *buf)
1422{
Iiro Valkonen7686b102011-02-02 23:21:58 -08001423 struct mxt_data *data = dev_get_drvdata(dev);
1424 struct mxt_object *object;
Joonyoung Shim4cf51c32010-07-14 21:55:30 -07001425 int count = 0;
1426 int i, j;
1427 int error;
Daniel Kurtz43a91d52012-06-28 21:08:08 +08001428 u8 *obuf;
Joonyoung Shim4cf51c32010-07-14 21:55:30 -07001429
Daniel Kurtz43a91d52012-06-28 21:08:08 +08001430 /* Pre-allocate buffer large enough to hold max sized object. */
1431 obuf = kmalloc(256, GFP_KERNEL);
1432 if (!obuf)
1433 return -ENOMEM;
1434
1435 error = 0;
Joonyoung Shim4cf51c32010-07-14 21:55:30 -07001436 for (i = 0; i < data->info.object_num; i++) {
1437 object = data->object_table + i;
1438
Daniel Kurtz91630952012-06-28 21:08:09 +08001439 if (!mxt_object_readable(object->type))
Joonyoung Shim4cf51c32010-07-14 21:55:30 -07001440 continue;
Joonyoung Shim4cf51c32010-07-14 21:55:30 -07001441
Daniel Kurtz91630952012-06-28 21:08:09 +08001442 count += scnprintf(buf + count, PAGE_SIZE - count,
1443 "T%u:\n", object->type);
Joonyoung Shim4cf51c32010-07-14 21:55:30 -07001444
Daniel Kurtz1e0c0c52014-05-18 23:01:12 -07001445 for (j = 0; j < mxt_obj_instances(object); j++) {
1446 u16 size = mxt_obj_size(object);
Daniel Kurtz794eb672012-06-28 21:08:10 +08001447 u16 addr = object->start_address + j * size;
Daniel Kurtz43a91d52012-06-28 21:08:08 +08001448
Daniel Kurtz794eb672012-06-28 21:08:10 +08001449 error = __mxt_read_reg(data->client, addr, size, obuf);
Joonyoung Shim4cf51c32010-07-14 21:55:30 -07001450 if (error)
Daniel Kurtz794eb672012-06-28 21:08:10 +08001451 goto done;
Joonyoung Shim4cf51c32010-07-14 21:55:30 -07001452
Daniel Kurtz794eb672012-06-28 21:08:10 +08001453 count = mxt_show_instance(buf, count, object, j, obuf);
Joonyoung Shim4cf51c32010-07-14 21:55:30 -07001454 }
Joonyoung Shim4cf51c32010-07-14 21:55:30 -07001455 }
1456
Daniel Kurtz794eb672012-06-28 21:08:10 +08001457done:
Daniel Kurtz43a91d52012-06-28 21:08:08 +08001458 kfree(obuf);
1459 return error ?: count;
Joonyoung Shim4cf51c32010-07-14 21:55:30 -07001460}
1461
Nick Dyerf2ac6cb2014-05-18 23:15:01 -07001462static int mxt_check_firmware_format(struct device *dev,
1463 const struct firmware *fw)
1464{
1465 unsigned int pos = 0;
1466 char c;
1467
1468 while (pos < fw->size) {
1469 c = *(fw->data + pos);
1470
1471 if (c < '0' || (c > '9' && c < 'A') || c > 'F')
1472 return 0;
1473
1474 pos++;
1475 }
1476
1477 /*
1478 * To convert file try:
1479 * xxd -r -p mXTXXX__APP_VX-X-XX.enc > maxtouch.fw
1480 */
1481 dev_err(dev, "Aborting: firmware file must be in binary format\n");
1482
1483 return -EINVAL;
1484}
1485
Iiro Valkonen7686b102011-02-02 23:21:58 -08001486static int mxt_load_fw(struct device *dev, const char *fn)
Joonyoung Shim4cf51c32010-07-14 21:55:30 -07001487{
Iiro Valkonen7686b102011-02-02 23:21:58 -08001488 struct mxt_data *data = dev_get_drvdata(dev);
Joonyoung Shim4cf51c32010-07-14 21:55:30 -07001489 const struct firmware *fw = NULL;
1490 unsigned int frame_size;
1491 unsigned int pos = 0;
Nick Dyerf943c742014-05-18 23:14:20 -07001492 unsigned int retry = 0;
Nick Dyerf477c752014-05-18 23:14:45 -07001493 unsigned int frame = 0;
Joonyoung Shim4cf51c32010-07-14 21:55:30 -07001494 int ret;
1495
1496 ret = request_firmware(&fw, fn, dev);
1497 if (ret) {
1498 dev_err(dev, "Unable to open firmware %s\n", fn);
1499 return ret;
1500 }
1501
Nick Dyerf2ac6cb2014-05-18 23:15:01 -07001502 /* Check for incorrect enc file */
1503 ret = mxt_check_firmware_format(dev, fw);
1504 if (ret)
1505 goto release_firmware;
1506
Nick Dyerf28a8422014-05-18 23:10:49 -07001507 ret = mxt_lookup_bootloader_address(data);
1508 if (ret)
1509 goto release_firmware;
1510
Joonyoung Shim4cf51c32010-07-14 21:55:30 -07001511 /* Change to the bootloader mode */
Benson Leungd79e7e42014-05-18 23:02:52 -07001512 data->in_bootloader = true;
1513
Iiro Valkonena4a2ef42014-05-18 23:03:44 -07001514 ret = mxt_t6_command(data, MXT_COMMAND_RESET, MXT_BOOT_VALUE, false);
1515 if (ret)
1516 goto release_firmware;
1517
Iiro Valkonen7686b102011-02-02 23:21:58 -08001518 msleep(MXT_RESET_TIME);
Joonyoung Shim4cf51c32010-07-14 21:55:30 -07001519
Benson Leungd79e7e42014-05-18 23:02:52 -07001520 reinit_completion(&data->bl_completion);
1521
1522 ret = mxt_check_bootloader(data, MXT_WAITING_BOOTLOAD_CMD);
Joonyoung Shim4cf51c32010-07-14 21:55:30 -07001523 if (ret)
Benson Leungd79e7e42014-05-18 23:02:52 -07001524 goto disable_irq;
Joonyoung Shim4cf51c32010-07-14 21:55:30 -07001525
1526 /* Unlock bootloader */
Nick Dyerf28a8422014-05-18 23:10:49 -07001527 mxt_unlock_bootloader(data);
Joonyoung Shim4cf51c32010-07-14 21:55:30 -07001528
1529 while (pos < fw->size) {
Benson Leungd79e7e42014-05-18 23:02:52 -07001530 ret = mxt_check_bootloader(data, MXT_WAITING_FRAME_DATA);
Joonyoung Shim4cf51c32010-07-14 21:55:30 -07001531 if (ret)
Benson Leungd79e7e42014-05-18 23:02:52 -07001532 goto disable_irq;
Joonyoung Shim4cf51c32010-07-14 21:55:30 -07001533
1534 frame_size = ((*(fw->data + pos) << 8) | *(fw->data + pos + 1));
1535
Nick Dyerf943c742014-05-18 23:14:20 -07001536 /* Take account of CRC bytes */
Joonyoung Shim4cf51c32010-07-14 21:55:30 -07001537 frame_size += 2;
1538
1539 /* Write one frame to device */
Nick Dyerf28a8422014-05-18 23:10:49 -07001540 ret = mxt_bootloader_write(data, fw->data + pos, frame_size);
1541 if (ret)
1542 goto disable_irq;
Joonyoung Shim4cf51c32010-07-14 21:55:30 -07001543
Benson Leungd79e7e42014-05-18 23:02:52 -07001544 ret = mxt_check_bootloader(data, MXT_FRAME_CRC_PASS);
Nick Dyerf943c742014-05-18 23:14:20 -07001545 if (ret) {
1546 retry++;
Joonyoung Shim4cf51c32010-07-14 21:55:30 -07001547
Nick Dyerf943c742014-05-18 23:14:20 -07001548 /* Back off by 20ms per retry */
1549 msleep(retry * 20);
1550
1551 if (retry > 20) {
1552 dev_err(dev, "Retry count exceeded\n");
1553 goto disable_irq;
1554 }
1555 } else {
1556 retry = 0;
1557 pos += frame_size;
Nick Dyerf477c752014-05-18 23:14:45 -07001558 frame++;
Nick Dyerf943c742014-05-18 23:14:20 -07001559 }
Joonyoung Shim4cf51c32010-07-14 21:55:30 -07001560
Nick Dyerf477c752014-05-18 23:14:45 -07001561 if (frame % 50 == 0)
1562 dev_dbg(dev, "Sent %d frames, %d/%zd bytes\n",
1563 frame, pos, fw->size);
Joonyoung Shim4cf51c32010-07-14 21:55:30 -07001564 }
1565
Benson Leunga0434b72014-05-18 23:03:09 -07001566 /* Wait for flash. */
Iiro Valkonena4a2ef42014-05-18 23:03:44 -07001567 ret = mxt_wait_for_completion(data, &data->bl_completion,
1568 MXT_FW_RESET_TIME);
Benson Leunga0434b72014-05-18 23:03:09 -07001569 if (ret)
1570 goto disable_irq;
1571
Nick Dyerf477c752014-05-18 23:14:45 -07001572 dev_dbg(dev, "Sent %d frames, %d bytes\n", frame, pos);
1573
Benson Leunga0434b72014-05-18 23:03:09 -07001574 /*
1575 * Wait for device to reset. Some bootloader versions do not assert
1576 * the CHG line after bootloading has finished, so ignore potential
1577 * errors.
1578 */
Iiro Valkonena4a2ef42014-05-18 23:03:44 -07001579 mxt_wait_for_completion(data, &data->bl_completion, MXT_FW_RESET_TIME);
Benson Leunga0434b72014-05-18 23:03:09 -07001580
Benson Leungd79e7e42014-05-18 23:02:52 -07001581 data->in_bootloader = false;
1582
1583disable_irq:
1584 disable_irq(data->irq);
Iiro Valkonena4a2ef42014-05-18 23:03:44 -07001585release_firmware:
Joonyoung Shim4cf51c32010-07-14 21:55:30 -07001586 release_firmware(fw);
Joonyoung Shim4cf51c32010-07-14 21:55:30 -07001587 return ret;
1588}
1589
Iiro Valkonen7686b102011-02-02 23:21:58 -08001590static ssize_t mxt_update_fw_store(struct device *dev,
Joonyoung Shim4cf51c32010-07-14 21:55:30 -07001591 struct device_attribute *attr,
1592 const char *buf, size_t count)
1593{
Iiro Valkonen7686b102011-02-02 23:21:58 -08001594 struct mxt_data *data = dev_get_drvdata(dev);
Joonyoung Shim4cf51c32010-07-14 21:55:30 -07001595 int error;
1596
Iiro Valkonen7686b102011-02-02 23:21:58 -08001597 error = mxt_load_fw(dev, MXT_FW_NAME);
Joonyoung Shim4cf51c32010-07-14 21:55:30 -07001598 if (error) {
1599 dev_err(dev, "The firmware update failed(%d)\n", error);
1600 count = error;
1601 } else {
Nick Dyer7bed6802014-05-18 23:04:09 -07001602 dev_info(dev, "The firmware update succeeded\n");
1603
Daniel Kurtz7d4fa102012-06-28 21:08:19 +08001604 mxt_free_object_table(data);
Joonyoung Shim4cf51c32010-07-14 21:55:30 -07001605
Nick Dyerdd24dcf2014-07-23 11:25:55 -07001606 error = mxt_initialize(data);
Benson Leungd79e7e42014-05-18 23:02:52 -07001607 if (error)
1608 return error;
Joonyoung Shim4cf51c32010-07-14 21:55:30 -07001609 }
1610
Joonyoung Shim4cf51c32010-07-14 21:55:30 -07001611 return count;
1612}
1613
Daniel Kurtzb19fc9e2012-06-28 21:08:16 +08001614static DEVICE_ATTR(fw_version, S_IRUGO, mxt_fw_version_show, NULL);
1615static DEVICE_ATTR(hw_version, S_IRUGO, mxt_hw_version_show, NULL);
Daniel Kurtz71b3e932012-05-08 22:30:14 -07001616static DEVICE_ATTR(object, S_IRUGO, mxt_object_show, NULL);
1617static DEVICE_ATTR(update_fw, S_IWUSR, NULL, mxt_update_fw_store);
Joonyoung Shim4cf51c32010-07-14 21:55:30 -07001618
Iiro Valkonen7686b102011-02-02 23:21:58 -08001619static struct attribute *mxt_attrs[] = {
Daniel Kurtzb19fc9e2012-06-28 21:08:16 +08001620 &dev_attr_fw_version.attr,
1621 &dev_attr_hw_version.attr,
Joonyoung Shim4cf51c32010-07-14 21:55:30 -07001622 &dev_attr_object.attr,
1623 &dev_attr_update_fw.attr,
1624 NULL
1625};
1626
Iiro Valkonen7686b102011-02-02 23:21:58 -08001627static const struct attribute_group mxt_attr_group = {
1628 .attrs = mxt_attrs,
Joonyoung Shim4cf51c32010-07-14 21:55:30 -07001629};
1630
Iiro Valkonen7686b102011-02-02 23:21:58 -08001631static void mxt_start(struct mxt_data *data)
Joonyoung Shim4cf51c32010-07-14 21:55:30 -07001632{
1633 /* Touch enable */
Iiro Valkonen7686b102011-02-02 23:21:58 -08001634 mxt_write_object(data,
Iiro Valkonen81c88a72011-07-04 03:08:25 -07001635 MXT_TOUCH_MULTI_T9, MXT_TOUCH_CTRL, 0x83);
Joonyoung Shim4cf51c32010-07-14 21:55:30 -07001636}
1637
Iiro Valkonen7686b102011-02-02 23:21:58 -08001638static void mxt_stop(struct mxt_data *data)
Joonyoung Shim4cf51c32010-07-14 21:55:30 -07001639{
1640 /* Touch disable */
Iiro Valkonen7686b102011-02-02 23:21:58 -08001641 mxt_write_object(data,
Iiro Valkonen81c88a72011-07-04 03:08:25 -07001642 MXT_TOUCH_MULTI_T9, MXT_TOUCH_CTRL, 0);
Joonyoung Shim4cf51c32010-07-14 21:55:30 -07001643}
1644
Iiro Valkonen7686b102011-02-02 23:21:58 -08001645static int mxt_input_open(struct input_dev *dev)
Joonyoung Shim4cf51c32010-07-14 21:55:30 -07001646{
Iiro Valkonen7686b102011-02-02 23:21:58 -08001647 struct mxt_data *data = input_get_drvdata(dev);
Joonyoung Shim4cf51c32010-07-14 21:55:30 -07001648
Iiro Valkonen7686b102011-02-02 23:21:58 -08001649 mxt_start(data);
Joonyoung Shim4cf51c32010-07-14 21:55:30 -07001650
1651 return 0;
1652}
1653
Iiro Valkonen7686b102011-02-02 23:21:58 -08001654static void mxt_input_close(struct input_dev *dev)
Joonyoung Shim4cf51c32010-07-14 21:55:30 -07001655{
Iiro Valkonen7686b102011-02-02 23:21:58 -08001656 struct mxt_data *data = input_get_drvdata(dev);
Joonyoung Shim4cf51c32010-07-14 21:55:30 -07001657
Iiro Valkonen7686b102011-02-02 23:21:58 -08001658 mxt_stop(data);
Joonyoung Shim4cf51c32010-07-14 21:55:30 -07001659}
1660
Stephen Warren78188be2014-07-23 12:23:23 -07001661#ifdef CONFIG_OF
1662static struct mxt_platform_data *mxt_parse_dt(struct i2c_client *client)
1663{
1664 struct mxt_platform_data *pdata;
1665 u32 *keymap;
1666 u32 keycode;
1667 int proplen, i, ret;
1668
1669 if (!client->dev.of_node)
1670 return ERR_PTR(-ENODEV);
1671
1672 pdata = devm_kzalloc(&client->dev, sizeof(*pdata), GFP_KERNEL);
1673 if (!pdata)
1674 return ERR_PTR(-ENOMEM);
1675
1676 if (of_find_property(client->dev.of_node, "linux,gpio-keymap",
1677 &proplen)) {
1678 pdata->t19_num_keys = proplen / sizeof(u32);
1679
1680 keymap = devm_kzalloc(&client->dev,
1681 pdata->t19_num_keys * sizeof(keymap[0]),
1682 GFP_KERNEL);
1683 if (!keymap)
1684 return ERR_PTR(-ENOMEM);
1685
1686 for (i = 0; i < pdata->t19_num_keys; i++) {
1687 ret = of_property_read_u32_index(client->dev.of_node,
1688 "linux,gpio-keymap", i, &keycode);
1689 if (ret)
1690 keycode = KEY_RESERVED;
1691
1692 keymap[i] = keycode;
1693 }
1694
1695 pdata->t19_keymap = keymap;
1696 }
1697
1698 return pdata;
1699}
1700#else
1701static struct mxt_platform_data *mxt_parse_dt(struct i2c_client *client)
1702{
1703 dev_dbg(&client->dev, "No platform data specified\n");
1704 return ERR_PTR(-EINVAL);
1705}
1706#endif
1707
1708static int mxt_probe(struct i2c_client *client, const struct i2c_device_id *id)
Joonyoung Shim4cf51c32010-07-14 21:55:30 -07001709{
Iiro Valkonen7686b102011-02-02 23:21:58 -08001710 struct mxt_data *data;
Stephen Warren78188be2014-07-23 12:23:23 -07001711 const struct mxt_platform_data *pdata;
Joonyoung Shim4cf51c32010-07-14 21:55:30 -07001712 int error;
1713
Stephen Warren78188be2014-07-23 12:23:23 -07001714 pdata = dev_get_platdata(&client->dev);
1715 if (!pdata) {
1716 pdata = mxt_parse_dt(client);
1717 if (IS_ERR(pdata))
1718 return PTR_ERR(pdata);
1719 }
Joonyoung Shim4cf51c32010-07-14 21:55:30 -07001720
Iiro Valkonen7686b102011-02-02 23:21:58 -08001721 data = kzalloc(sizeof(struct mxt_data), GFP_KERNEL);
Nick Dyer7a53d602014-07-23 12:21:26 -07001722 if (!data) {
Joonyoung Shim4cf51c32010-07-14 21:55:30 -07001723 dev_err(&client->dev, "Failed to allocate memory\n");
Nick Dyer7a53d602014-07-23 12:21:26 -07001724 return -ENOMEM;
Joonyoung Shim4cf51c32010-07-14 21:55:30 -07001725 }
1726
Daniel Kurtzec02ac22012-06-28 21:08:02 +08001727 snprintf(data->phys, sizeof(data->phys), "i2c-%u-%04x/input0",
1728 client->adapter->nr, client->addr);
Daniel Kurtz22dfab72013-03-07 19:43:33 -08001729
Joonyoung Shim910d8052011-04-12 23:14:38 -07001730 data->client = client;
Joonyoung Shim910d8052011-04-12 23:14:38 -07001731 data->pdata = pdata;
1732 data->irq = client->irq;
Nick Dyer7a53d602014-07-23 12:21:26 -07001733 i2c_set_clientdata(client, data);
Joonyoung Shim910d8052011-04-12 23:14:38 -07001734
Benson Leungd79e7e42014-05-18 23:02:52 -07001735 init_completion(&data->bl_completion);
Iiro Valkonena4a2ef42014-05-18 23:03:44 -07001736 init_completion(&data->reset_completion);
Nick Dyerc3f78042014-05-18 23:04:46 -07001737 init_completion(&data->crc_completion);
Benson Leungd79e7e42014-05-18 23:02:52 -07001738
Nick Dyerdd24dcf2014-07-23 11:25:55 -07001739 error = request_threaded_irq(client->irq, NULL, mxt_interrupt,
1740 pdata->irqflags | IRQF_ONESHOT,
1741 client->name, data);
1742 if (error) {
1743 dev_err(&client->dev, "Failed to register interrupt\n");
1744 goto err_free_mem;
1745 }
1746
1747 disable_irq(client->irq);
1748
Daniel Kurtzcb159112012-06-28 21:08:22 +08001749 error = mxt_initialize(data);
1750 if (error)
Nick Dyer7a53d602014-07-23 12:21:26 -07001751 goto err_free_irq;
Joonyoung Shim4cf51c32010-07-14 21:55:30 -07001752
Iiro Valkonen7686b102011-02-02 23:21:58 -08001753 error = sysfs_create_group(&client->dev.kobj, &mxt_attr_group);
Nick Dyer7bed6802014-05-18 23:04:09 -07001754 if (error) {
1755 dev_err(&client->dev, "Failure %d creating sysfs group\n",
1756 error);
Nick Dyer7a53d602014-07-23 12:21:26 -07001757 goto err_free_object;
Nick Dyer7bed6802014-05-18 23:04:09 -07001758 }
Joonyoung Shim4cf51c32010-07-14 21:55:30 -07001759
1760 return 0;
1761
Joonyoung Shim4cf51c32010-07-14 21:55:30 -07001762err_free_object:
1763 kfree(data->object_table);
Nick Dyerdd24dcf2014-07-23 11:25:55 -07001764err_free_irq:
1765 free_irq(client->irq, data);
Joonyoung Shim4cf51c32010-07-14 21:55:30 -07001766err_free_mem:
Joonyoung Shim4cf51c32010-07-14 21:55:30 -07001767 kfree(data);
1768 return error;
1769}
1770
Bill Pembertone2619cf2012-11-23 21:50:47 -08001771static int mxt_remove(struct i2c_client *client)
Joonyoung Shim4cf51c32010-07-14 21:55:30 -07001772{
Iiro Valkonen7686b102011-02-02 23:21:58 -08001773 struct mxt_data *data = i2c_get_clientdata(client);
Joonyoung Shim4cf51c32010-07-14 21:55:30 -07001774
Iiro Valkonen7686b102011-02-02 23:21:58 -08001775 sysfs_remove_group(&client->dev.kobj, &mxt_attr_group);
Joonyoung Shim4cf51c32010-07-14 21:55:30 -07001776 free_irq(data->irq, data);
1777 input_unregister_device(data->input_dev);
1778 kfree(data->object_table);
1779 kfree(data);
1780
1781 return 0;
1782}
1783
Daniel Kurtz3a73c812012-05-08 22:29:14 -07001784#ifdef CONFIG_PM_SLEEP
Iiro Valkonen7686b102011-02-02 23:21:58 -08001785static int mxt_suspend(struct device *dev)
Joonyoung Shim4cf51c32010-07-14 21:55:30 -07001786{
Dmitry Torokhov8b5fce02010-11-18 00:14:03 -08001787 struct i2c_client *client = to_i2c_client(dev);
Iiro Valkonen7686b102011-02-02 23:21:58 -08001788 struct mxt_data *data = i2c_get_clientdata(client);
Joonyoung Shim4cf51c32010-07-14 21:55:30 -07001789 struct input_dev *input_dev = data->input_dev;
1790
1791 mutex_lock(&input_dev->mutex);
1792
1793 if (input_dev->users)
Iiro Valkonen7686b102011-02-02 23:21:58 -08001794 mxt_stop(data);
Joonyoung Shim4cf51c32010-07-14 21:55:30 -07001795
1796 mutex_unlock(&input_dev->mutex);
1797
1798 return 0;
1799}
1800
Iiro Valkonen7686b102011-02-02 23:21:58 -08001801static int mxt_resume(struct device *dev)
Joonyoung Shim4cf51c32010-07-14 21:55:30 -07001802{
Dmitry Torokhov8b5fce02010-11-18 00:14:03 -08001803 struct i2c_client *client = to_i2c_client(dev);
Iiro Valkonen7686b102011-02-02 23:21:58 -08001804 struct mxt_data *data = i2c_get_clientdata(client);
Joonyoung Shim4cf51c32010-07-14 21:55:30 -07001805 struct input_dev *input_dev = data->input_dev;
1806
Iiro Valkonena4a2ef42014-05-18 23:03:44 -07001807 mxt_soft_reset(data);
Joonyoung Shim4cf51c32010-07-14 21:55:30 -07001808
1809 mutex_lock(&input_dev->mutex);
1810
1811 if (input_dev->users)
Iiro Valkonen7686b102011-02-02 23:21:58 -08001812 mxt_start(data);
Joonyoung Shim4cf51c32010-07-14 21:55:30 -07001813
1814 mutex_unlock(&input_dev->mutex);
1815
1816 return 0;
1817}
Joonyoung Shim4cf51c32010-07-14 21:55:30 -07001818#endif
1819
Daniel Kurtz3a73c812012-05-08 22:29:14 -07001820static SIMPLE_DEV_PM_OPS(mxt_pm_ops, mxt_suspend, mxt_resume);
1821
Stephen Warren78188be2014-07-23 12:23:23 -07001822static const struct of_device_id mxt_of_match[] = {
1823 { .compatible = "atmel,maxtouch", },
1824 {},
1825};
1826MODULE_DEVICE_TABLE(of, mxt_of_match);
1827
Iiro Valkonen7686b102011-02-02 23:21:58 -08001828static const struct i2c_device_id mxt_id[] = {
Joonyoung Shim4cf51c32010-07-14 21:55:30 -07001829 { "qt602240_ts", 0 },
Iiro Valkonen7686b102011-02-02 23:21:58 -08001830 { "atmel_mxt_ts", 0 },
Daniel Kurtz22dfab72013-03-07 19:43:33 -08001831 { "atmel_mxt_tp", 0 },
Chris Leech46ee2a02011-02-15 13:36:52 -08001832 { "mXT224", 0 },
Joonyoung Shim4cf51c32010-07-14 21:55:30 -07001833 { }
1834};
Iiro Valkonen7686b102011-02-02 23:21:58 -08001835MODULE_DEVICE_TABLE(i2c, mxt_id);
Joonyoung Shim4cf51c32010-07-14 21:55:30 -07001836
Iiro Valkonen7686b102011-02-02 23:21:58 -08001837static struct i2c_driver mxt_driver = {
Joonyoung Shim4cf51c32010-07-14 21:55:30 -07001838 .driver = {
Iiro Valkonen7686b102011-02-02 23:21:58 -08001839 .name = "atmel_mxt_ts",
Joonyoung Shim4cf51c32010-07-14 21:55:30 -07001840 .owner = THIS_MODULE,
Stephen Warren78188be2014-07-23 12:23:23 -07001841 .of_match_table = of_match_ptr(mxt_of_match),
Iiro Valkonen7686b102011-02-02 23:21:58 -08001842 .pm = &mxt_pm_ops,
Joonyoung Shim4cf51c32010-07-14 21:55:30 -07001843 },
Iiro Valkonen7686b102011-02-02 23:21:58 -08001844 .probe = mxt_probe,
Bill Pemberton1cb0aa82012-11-23 21:27:39 -08001845 .remove = mxt_remove,
Iiro Valkonen7686b102011-02-02 23:21:58 -08001846 .id_table = mxt_id,
Joonyoung Shim4cf51c32010-07-14 21:55:30 -07001847};
1848
Axel Lin1b92c1c2012-03-16 23:05:41 -07001849module_i2c_driver(mxt_driver);
Joonyoung Shim4cf51c32010-07-14 21:55:30 -07001850
1851/* Module information */
1852MODULE_AUTHOR("Joonyoung Shim <jy0922.shim@samsung.com>");
Iiro Valkonen7686b102011-02-02 23:21:58 -08001853MODULE_DESCRIPTION("Atmel maXTouch Touchscreen driver");
Joonyoung Shim4cf51c32010-07-14 21:55:30 -07001854MODULE_LICENSE("GPL");