atmel_mxt_ts: revert changes to the upstream atmel_mxt_ts driver
authorHong Liu <hong.liu@intel.com>
Tue, 7 Feb 2012 10:02:34 +0000 (18:02 +0800)
committerbuildbot <buildbot@intel.com>
Thu, 16 Feb 2012 21:08:50 +0000 (13:08 -0800)
BZ: 20808

Revert the changes to prepare for applying the OTC patches to
this driver.

Change-Id: Ia3b8db53861069e12d7e3237ae62d11fd12341d0
Signed-off-by: Hong Liu <hong.liu@intel.com>
Reviewed-on: http://android.intel.com:8080/34434
Reviewed-by: Continente, Christophe <christophe.continente@intel.com>
Reviewed-by: Chotard, Celine <celine.chotard@intel.com>
Tested-by: Chotard, Celine <celine.chotard@intel.com>
Reviewed-by: buildbot <buildbot@intel.com>
Tested-by: buildbot <buildbot@intel.com>
arch/x86/platform/intel-mid/board-redridge.c
drivers/input/touchscreen/atmel_mxt_ts.c
include/linux/atmel_mxt_ts.h [deleted file]

index d93b663..61319bb 100644 (file)
@@ -47,7 +47,6 @@
 #include <linux/ms5607.h>
 #include <linux/i2c-gpio.h>
 #include <linux/rmi_i2c.h>
-#include <linux/atmel_mxt_ts.h>
 #include <linux/i2c/tc35876x.h>
 
 #include <linux/atomisp_platform.h>
@@ -1098,20 +1097,6 @@ void *wl12xx_platform_data_init(void *info)
 }
 #endif
 
-void *mxt_platform_data_init(void *info)
-{
-       static struct mxt_platform_data mxt_pdata;
-
-       mxt_pdata.numtouch       = 10;
-       mxt_pdata.max_x          = 1023;
-       mxt_pdata.max_y          = 975;
-       mxt_pdata.orientation    = MXT_MSGB_T9_ORIENT_HORZ_FLIP;
-       mxt_pdata.reset          = 129;
-       mxt_pdata.irq            = 62;
-
-       return &mxt_pdata;
-}
-
 #define AUDIENCE_WAKEUP_GPIO               "audience-wakeup"
 #define AUDIENCE_RESET_GPIO                 "audience-reset"
 static int audience_request_resources(struct i2c_client *client)
@@ -1592,7 +1577,6 @@ struct devs_id __initconst device_ids[] = {
                                        &intel_ignore_i2c_device_register},
        {"mt9m114", SFI_DEV_TYPE_I2C, 0, &mt9m114_platform_data_init,
                                        &intel_ignore_i2c_device_register},
-       {"mxt1386", SFI_DEV_TYPE_I2C, 0, &mxt_platform_data_init, NULL},
        {"audience_es305", SFI_DEV_TYPE_I2C, 0, &audience_platform_data_init,
                                                NULL},
        {"accel", SFI_DEV_TYPE_I2C, 0, &lis3dh_pdata_init, NULL},
@@ -1994,29 +1978,3 @@ static int __init blackbay_i2c_init(void)
        return 0;
 }
 device_initcall(blackbay_i2c_init);
-/*
- * mxt1386 initialization routines for Redridge board
- * (Should be removed once SFI tables are updated)
- */
-static struct mxt_platform_data mxt1386_pdata = {
-       .numtouch       = 10,
-       .max_x          = 1023,
-       .max_y          = 975,
-       .orientation    = MXT_MSGB_T9_ORIENT_HORZ_FLIP,
-       .reset          = 129,
-       .irq            = 62,
-};
-static struct i2c_board_info dv10_i2c_bus0_devs[] = {
-       {
-               .type       = "mxt1386",
-               .addr       = 0x4C,
-               .platform_data = &mxt1386_pdata,
-       },
-};
-static int __init redridge_i2c_init(void)
-{
-       i2c_register_board_info(0, dv10_i2c_bus0_devs,
-                               ARRAY_SIZE(dv10_i2c_bus0_devs));
-       return 0;
-}
-device_initcall(redridge_i2c_init);
index 0b5b646..1e61387 100644 (file)
 /*
- *  Atmel maXTouch Touchscreen Controller Driver
+ * Atmel maXTouch Touchscreen driver
  *
+ * Copyright (C) 2010 Samsung Electronics Co.Ltd
+ * Author: Joonyoung Shim <jy0922.shim@samsung.com>
  *
- *  Copyright (C) 2010 Atmel Corporation
- *  Copyright (C) 2010 Ulf Samuelsson (ulf@atmel.com)
- *  Copyright (C) 2009 Raphael Derosso Pereira <raphaelpereira@gmail.com>
- *  Contains changes by Wind River Systems, 2010-09-29
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License version 2 as
- *  published by the Free Software Foundation.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
  *
  */
 
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/firmware.h>
 #include <linux/i2c.h>
+#include <linux/i2c/atmel_mxt_ts.h>
+#include <linux/input/mt.h>
 #include <linux/interrupt.h>
-#include <linux/input.h>
-#include <linux/debugfs.h>
-#include <linux/cdev.h>
-#include <linux/mutex.h>
 #include <linux/slab.h>
-#include <linux/uaccess.h>
-#include <linux/gpio.h>
-#include <linux/earlysuspend.h>
-#include <linux/pm_runtime.h>
-#include <linux/bitops.h>
-#include <linux/jiffies.h>
-#include <linux/atmel_mxt_ts.h>
-
-#include <linux/delay.h>
-#include <linux/debugfs.h>
-#include <linux/fs.h>
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <asm/uaccess.h>
-#include <linux/time.h>
-#include <linux/sched.h>
-#include <linux/smp.h>
-#include <asm/io.h>
-/* 1-->WINTEK  0-->SINTEK */
-#define TOUCH_PANEL_IS_WINTEK 0
-#define MAGIC_PRODUCT_T38_BYTE7_WINTEK 0x02
-#define MAGIC_PRODUCT_T38_BYTE7_SINTEK 0x03
-#if TOUCH_PANEL_IS_WINTEK
-#define MAGIC_PRODUCT_T38_BYTE7 MAGIC_PRODUCT_T38_BYTE7_WINTEK
-#else /* SINTEK */
-#define MAGIC_PRODUCT_T38_BYTE7 MAGIC_PRODUCT_T38_BYTE7_SINTEK
-#endif
 
-/* Routines for memory access within a 16 bit address space */
-static void mxt_calibrate(struct i2c_client *client);
-static int mxt_read_block(struct i2c_client *client, u16 addr, u16 length,
-                         u8 *value);
-static int mxt_write_byte(struct i2c_client *client, u16 addr, u8 value);
-static int mxt_write_block(struct i2c_client *client, u16 addr, u16 length,
-                          u8 *value);
-#ifdef CONFIG_HAS_EARLYSUSPEND
-void mxt_early_suspend(struct early_suspend *h);
-void mxt_late_resume(struct early_suspend *h);
-#endif
-
-#ifdef CONFIG_DEBUG_FS
-static int  intel_mid_add_debugfs(void);
-static unsigned char reg_add = 0;
-static unsigned char reg_add_offset = 0;
-#endif
-
-#define DRIVER_VERSION "0.9a"
-#define MULTI_TOUCH_ENABLED 1
-#define MXT_RESET_DELAY   65 /* ms */
-static int debug = DEBUG_INFO;
-module_param(debug, int, 0644);
-MODULE_PARM_DESC(debug, "Activate debugging output");
-
-static int stored_size[MXT_MAX_NUM_TOUCHES];
-static int stored_x[MXT_MAX_NUM_TOUCHES];
-static int stored_y[MXT_MAX_NUM_TOUCHES];
-static int iForceUpdateConfigValue = 0;
-static struct mxt_data *mxt_es;
-/* For backup NVM */
-u8 mxt_debug = 1;
-u16 T6_addr;
-u16 T38_addr;
-u8 v20_T38[] = { 11, 10, 26, 1, 0, 0, 0, MAGIC_PRODUCT_T38_BYTE7 };
-u8 arg1 = 0;
-u8 arg2 = 0;
-u8 mxt_cmd = 0;
-u16 low_boundary = 0;
-u16 high_boundary = 0;
-u8 slave_addr = MXT1386_I2C_ADDR1;
-
-/* Device Info descriptor */
-/* Parsed from maXTouch "Id information" inside device */
-struct mxt_device_info {
-       u8   family_id;
-       u8   variant_id;
-       u8   major;
-       u8   minor;
-       u8   build;
-       u8   num_objs;
-       u8   x_size;
-       u8   y_size;
-       char family_name[16];    /* Family name */
-       char variant_name[16];    /* Variant name */
-       u16  num_nodes;           /* Number of sensor nodes */
+/* Version */
+#define MXT_VER_20             20
+#define MXT_VER_21             21
+#define MXT_VER_22             22
+
+/* Slave addresses */
+#define MXT_APP_LOW            0x4a
+#define MXT_APP_HIGH           0x4b
+#define MXT_BOOT_LOW           0x24
+#define MXT_BOOT_HIGH          0x25
+
+/* Firmware */
+#define MXT_FW_NAME            "maxtouch.fw"
+
+/* Registers */
+#define MXT_FAMILY_ID          0x00
+#define MXT_VARIANT_ID         0x01
+#define MXT_VERSION            0x02
+#define MXT_BUILD              0x03
+#define MXT_MATRIX_X_SIZE      0x04
+#define MXT_MATRIX_Y_SIZE      0x05
+#define MXT_OBJECT_NUM         0x06
+#define MXT_OBJECT_START       0x07
+
+#define MXT_OBJECT_SIZE                6
+
+/* Object types */
+#define MXT_DEBUG_DIAGNOSTIC   37
+#define MXT_GEN_MESSAGE                5
+#define MXT_GEN_COMMAND                6
+#define MXT_GEN_POWER          7
+#define MXT_GEN_ACQUIRE                8
+#define MXT_TOUCH_MULTI                9
+#define MXT_TOUCH_KEYARRAY     15
+#define MXT_TOUCH_PROXIMITY    23
+#define MXT_PROCI_GRIPFACE     20
+#define MXT_PROCG_NOISE                22
+#define MXT_PROCI_ONETOUCH     24
+#define MXT_PROCI_TWOTOUCH     27
+#define MXT_PROCI_GRIP         40
+#define MXT_PROCI_PALM         41
+#define MXT_SPT_COMMSCONFIG    18
+#define MXT_SPT_GPIOPWM                19
+#define MXT_SPT_SELFTEST       25
+#define MXT_SPT_CTECONFIG      28
+#define MXT_SPT_USERDATA       38
+#define MXT_SPT_DIGITIZER      43
+#define MXT_SPT_MESSAGECOUNT   44
+
+/* MXT_GEN_COMMAND field */
+#define MXT_COMMAND_RESET      0
+#define MXT_COMMAND_BACKUPNV   1
+#define MXT_COMMAND_CALIBRATE  2
+#define MXT_COMMAND_REPORTALL  3
+#define MXT_COMMAND_DIAGNOSTIC 5
+
+/* MXT_GEN_POWER field */
+#define MXT_POWER_IDLEACQINT   0
+#define MXT_POWER_ACTVACQINT   1
+#define MXT_POWER_ACTV2IDLETO  2
+
+/* MXT_GEN_ACQUIRE field */
+#define MXT_ACQUIRE_CHRGTIME   0
+#define MXT_ACQUIRE_TCHDRIFT   2
+#define MXT_ACQUIRE_DRIFTST    3
+#define MXT_ACQUIRE_TCHAUTOCAL 4
+#define MXT_ACQUIRE_SYNC       5
+#define MXT_ACQUIRE_ATCHCALST  6
+#define MXT_ACQUIRE_ATCHCALSTHR        7
+
+/* MXT_TOUCH_MULTI field */
+#define MXT_TOUCH_CTRL         0
+#define MXT_TOUCH_XORIGIN      1
+#define MXT_TOUCH_YORIGIN      2
+#define MXT_TOUCH_XSIZE                3
+#define MXT_TOUCH_YSIZE                4
+#define MXT_TOUCH_BLEN         6
+#define MXT_TOUCH_TCHTHR       7
+#define MXT_TOUCH_TCHDI                8
+#define MXT_TOUCH_ORIENT       9
+#define MXT_TOUCH_MOVHYSTI     11
+#define MXT_TOUCH_MOVHYSTN     12
+#define MXT_TOUCH_NUMTOUCH     14
+#define MXT_TOUCH_MRGHYST      15
+#define MXT_TOUCH_MRGTHR       16
+#define MXT_TOUCH_AMPHYST      17
+#define MXT_TOUCH_XRANGE_LSB   18
+#define MXT_TOUCH_XRANGE_MSB   19
+#define MXT_TOUCH_YRANGE_LSB   20
+#define MXT_TOUCH_YRANGE_MSB   21
+#define MXT_TOUCH_XLOCLIP      22
+#define MXT_TOUCH_XHICLIP      23
+#define MXT_TOUCH_YLOCLIP      24
+#define MXT_TOUCH_YHICLIP      25
+#define MXT_TOUCH_XEDGECTRL    26
+#define MXT_TOUCH_XEDGEDIST    27
+#define MXT_TOUCH_YEDGECTRL    28
+#define MXT_TOUCH_YEDGEDIST    29
+#define MXT_TOUCH_JUMPLIMIT    30
+
+/* MXT_PROCI_GRIPFACE field */
+#define MXT_GRIPFACE_CTRL      0
+#define MXT_GRIPFACE_XLOGRIP   1
+#define MXT_GRIPFACE_XHIGRIP   2
+#define MXT_GRIPFACE_YLOGRIP   3
+#define MXT_GRIPFACE_YHIGRIP   4
+#define MXT_GRIPFACE_MAXTCHS   5
+#define MXT_GRIPFACE_SZTHR1    7
+#define MXT_GRIPFACE_SZTHR2    8
+#define MXT_GRIPFACE_SHPTHR1   9
+#define MXT_GRIPFACE_SHPTHR2   10
+#define MXT_GRIPFACE_SUPEXTTO  11
+
+/* MXT_PROCI_NOISE field */
+#define MXT_NOISE_CTRL         0
+#define MXT_NOISE_OUTFLEN      1
+#define MXT_NOISE_GCAFUL_LSB   3
+#define MXT_NOISE_GCAFUL_MSB   4
+#define MXT_NOISE_GCAFLL_LSB   5
+#define MXT_NOISE_GCAFLL_MSB   6
+#define MXT_NOISE_ACTVGCAFVALID        7
+#define MXT_NOISE_NOISETHR     8
+#define MXT_NOISE_FREQHOPSCALE 10
+#define MXT_NOISE_FREQ0                11
+#define MXT_NOISE_FREQ1                12
+#define MXT_NOISE_FREQ2                13
+#define MXT_NOISE_FREQ3                14
+#define MXT_NOISE_FREQ4                15
+#define MXT_NOISE_IDLEGCAFVALID        16
+
+/* MXT_SPT_COMMSCONFIG */
+#define MXT_COMMS_CTRL         0
+#define MXT_COMMS_CMD          1
+
+/* MXT_SPT_CTECONFIG field */
+#define MXT_CTE_CTRL           0
+#define MXT_CTE_CMD            1
+#define MXT_CTE_MODE           2
+#define MXT_CTE_IDLEGCAFDEPTH  3
+#define MXT_CTE_ACTVGCAFDEPTH  4
+#define MXT_CTE_VOLTAGE                5
+
+#define MXT_VOLTAGE_DEFAULT    2700000
+#define MXT_VOLTAGE_STEP       10000
+
+/* Define for MXT_GEN_COMMAND */
+#define MXT_BOOT_VALUE         0xa5
+#define MXT_BACKUP_VALUE       0x55
+#define MXT_BACKUP_TIME                25      /* msec */
+#define MXT_RESET_TIME         65      /* msec */
+
+#define MXT_FWRESET_TIME       175     /* msec */
+
+/* Command to unlock bootloader */
+#define MXT_UNLOCK_CMD_MSB     0xaa
+#define MXT_UNLOCK_CMD_LSB     0xdc
+
+/* Bootloader mode status */
+#define MXT_WAITING_BOOTLOAD_CMD       0xc0    /* valid 7 6 bit only */
+#define MXT_WAITING_FRAME_DATA 0x80    /* valid 7 6 bit only */
+#define MXT_FRAME_CRC_CHECK    0x02
+#define MXT_FRAME_CRC_FAIL     0x03
+#define MXT_FRAME_CRC_PASS     0x04
+#define MXT_APP_CRC_FAIL       0x40    /* valid 7 8 bit only */
+#define MXT_BOOT_STATUS_MASK   0x3f
+
+/* Touch status */
+#define MXT_SUPPRESS           (1 << 1)
+#define MXT_AMP                        (1 << 2)
+#define MXT_VECTOR             (1 << 3)
+#define MXT_MOVE               (1 << 4)
+#define MXT_RELEASE            (1 << 5)
+#define MXT_PRESS              (1 << 6)
+#define MXT_DETECT             (1 << 7)
+
+/* Touch orient bits */
+#define MXT_XY_SWITCH          (1 << 0)
+#define MXT_X_INVERT           (1 << 1)
+#define MXT_Y_INVERT           (1 << 2)
+
+/* Touchscreen absolute values */
+#define MXT_MAX_AREA           0xff
+
+#define MXT_MAX_FINGER         10
+
+struct mxt_info {
+       u8 family_id;
+       u8 variant_id;
+       u8 version;
+       u8 build;
+       u8 matrix_xsize;
+       u8 matrix_ysize;
+       u8 object_num;
 };
 
-/* object descriptor table, parsed from maXTouch "object table" */
 struct mxt_object {
-       u16 chip_addr;
-       u8  type;
-       u8  size;
-       u8  instances;
-       u8  num_report_ids;
+       u8 type;
+       u16 start_address;
+       u8 size;
+       u8 instances;
+       u8 num_report_ids;
+
+       /* to map object and message */
+       u8 max_reportid;
 };
 
-
-/* Mapping from report id to object type and instance */
-struct report_id_map {
-       u8  object;
-       u8  instance;
-/*
- * This is the first report ID belonging to object. It enables us to
- * find out easily the touch number: each touch has different report
- * ID (which are assigned to touches in increasing order). By
- * subtracting the first report ID from current, we get the touch
- * number.
- */
-       u8  first_rid;
+struct mxt_message {
+       u8 reportid;
+       u8 message[7];
+       u8 checksum;
 };
 
-
-/* Driver datastructure */
-struct mxt_data {
-       struct i2c_client    *client;
-       struct mutex         dev_mutex;
-       struct input_dev     *touch_input;
-       struct input_dev     *key_input;
-       char                 touch_phys_name[32];
-       char                 key_phys_name[32];
-       int                  irq;
-
-       u16                  last_read_addr;
-       bool                 new_msgs;
-
-       int                  valid_irq_counter;
-       int                  invalid_irq_counter;
-       int                  irq_counter;
-       int                  message_counter;
-       int                  read_fail_counter;
-
-       int                  bytes_to_read;
-
-       u8                   xpos_format;
-       u8                   ypos_format;
-
-       u8                   numtouch;
-
-       struct mxt_device_info  device_info;
-
-       u32                  info_block_crc;
-       u32                  configuration_crc;
-       u16                  report_id_count;
-       struct report_id_map *rid_map;
-       struct mxt_object    *object_table;
-
-       u16                  msg_proc_addr;
-       u8                   message_size;
-
-       u16                  max_x_val;
-       u16                  max_y_val;
-       u16                  orientation;
-
-       void                 (*init_hw)(void);
-       void                 (*exit_hw)(void);
-       u8                   (*valid_interrupt)(void);
-       u8                   (*read_chg)(void);
-
-#ifdef CONFIG_HAS_EARLYSUSPEND
-       u8                   T7[3];
-       struct early_suspend es;
-       bool                 suspended;
-#endif
-       /* Put only non-touch messages to buffer if this is set */
-       char                 nontouch_msg_only;
-
-       int                  prev_key;
-
-       int                  mxt_intr_gpio;
-       int                  mxt_reset_gpio;
-
-       u8                   *message_buf;
-       int                  recal_flag;
-       u64                  timestamp;
-       u16                  finger_pressed;
-       u8                   finger_count;
-       u8                   first_pressed;
-       u8                   grip_suppression;
-       u8                   face_suppression;
-
-       struct point_info    pre_data[10];
+struct mxt_finger {
+       int status;
+       int x;
+       int y;
+       int area;
 };
 
-/*
- * This struct is used for i2c transfers.
- */
-struct mxt_i2c_byte_transfer {
-       __le16 le_addr;
-       u8     data;
-} __attribute__ ((packed));
-
-#define I2C_RETRY_COUNT 5
-#define I2C_PAYLOAD_SIZE 254
-
-/*
- * Check whether we have multi-touch enabled kernel; if not, report just the
- * first touch (on mXT224, the maximum is 10 simultaneous touches).
- * Because just the 1st one is reported, it might seem that the screen is not
- * responding to touch if the first touch is removed while the screen is being
- * touched by another finger, so beware.
- *
- * TODO: investigate if there is any standard set of input events that upper
- * layers are expecting from a touchscreen? These can however be different for
- * different platforms, and customers may have different opinions too about
- * what should be interpreted as right-click, for example.
- *
- */
-
-static const u8        *obj_typ_name[] = {
-       [0]  = "Reserved",
-       [5]  = "GEN_MESSAGEPROCESSOR_T5",
-       [6]  = "GEN_COMMANDPROCESSOR_T6",
-       [7]  = "GEN_POWERCONFIG_T7",
-       [8]  = "GEN_ACQUIRECONFIG_T8",
-       [9]  = "TOUCH_MULTITOUCHSCREEN_T9",
-       [15] = "TOUCH_KEYARRAY_T15",
-       [18] = "SPT_COMMSCONFIG_T18",
-       [19] = "SPT_GPIOPWM_T19",
-       [20] = "PROCI_GRIPFACESUPPRESSION_T20",
-       [22] = "PROCG_NOISESUPPRESSION_T22",
-       [23] = "TOUCH_PROXIMITY_T23",
-       [24] = "PROCI_ONETOUCHGESTUREPROCESSOR_T24",
-       [25] = "SPT_SELFTEST_T25",
-       [27] = "PROCI_TWOTOUCHGESTUREPROCESSOR_T27",
-       [28] = "SPT_CTECONFIG_T28",
-       [37] = "DEBUG_DIAGNOSTICS_T37",
-       [38] = "SPT_USER_DATA_T38",
-       [40] = "PROCI_GRIPSUPPRESSION_T40",
-       [41] = "PROCI_PALMSUPPRESSION_T41",
-       [42] = "PROCI_FACESUPPRESSION_T42",
-       [43] = "SPT_DIGITIZER_T43",
-       [44] = "SPT_MESSAGECOUNT_T44",
+/* Each client has this additional data */
+struct mxt_data {
+       struct i2c_client *client;
+       struct input_dev *input_dev;
+       const struct mxt_platform_data *pdata;
+       struct mxt_object *object_table;
+       struct mxt_info info;
+       struct mxt_finger finger[MXT_MAX_FINGER];
+       unsigned int irq;
+       unsigned int max_x;
+       unsigned int max_y;
 };
 
-/*
- * All entries spare upto 255
- */
-#define RESERVED_T255                             255u
-void mxt_config_init(struct mxt_data *mxt)
+static bool mxt_object_readable(unsigned int type)
 {
-       int err = 0;
-       dev_info(&mxt->client->dev, "In function %s", __func__);
-       /* Fix for current comsumption. */
-       u8 v20_T7[] = { 32, 16, 50 };
-       u8 v20_T8[]  = { 10, 0, 15, 15, 0, 0, 5, 45, 10, 192 };
-#if TOUCH_PANEL_IS_WINTEK
-       u8 v20_T9[] = { 143, 0, 0, 27, 42, 0, 16, 60, 3, 3, 0, 0, 3, 14, 10, 20,
-               20, 10, 31, 3, 255, 4, 0, 0, 0, 0, 0, 0, 64, 0, 15, 15,
-               49, 52 };
-#else /* SINTEK */
-       u8 v20_T9[] = { 143, 0, 0, 28, 42, 0, 16, 60, 3, 3, 0, 0, 3, 14, 10, 20,
-               20, 10, 31, 3, 255, 4, 0, 0, 0, 0, 0, 0, 64, 0, 15, 15,
-               49, 52 };
-#endif
-
-       u8 v20_T15[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
-       u8 v20_T18[] = { 0, 0 };
-       u8 v20_T22[] = { 5, 0, 0, 0, 0, 0, 0, 0, 45, 0, 0, 15, 25, 35, 255, 255,
-               0 };
-       u8 v20_T24[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-               0, 0, 0 };
-       u8 v20_T25[] = { 3, 0, 248, 42, 112, 23, 0, 0, 0, 0, 0, 0, 0, 0 };
-       u8 v20_T27[] = { 0, 0, 0, 0, 0, 0, 0 };
-       u8 v20_T28[] = { 0, 0, 0, 8, 16, 60 };
-       u8 v20_T40[] = { 0, 0, 0, 0, 0 };
-       u8 v20_T41[] = { 1, 0, 0, 35, 5, 20, 170 };
-       u8 v20_T43[] = { 0, 0, 0, 0, 0, 0 };
-
-       if (slave_addr == MXT1386_I2C_ADDR2) { /* 0X4C means Wintek and 0x4D means Sintek */
-               v20_T9[3] = 28;
-               v20_T22[8] = 20;
+       switch (type) {
+       case MXT_GEN_MESSAGE:
+       case MXT_GEN_COMMAND:
+       case MXT_GEN_POWER:
+       case MXT_GEN_ACQUIRE:
+       case MXT_TOUCH_MULTI:
+       case MXT_TOUCH_KEYARRAY:
+       case MXT_TOUCH_PROXIMITY:
+       case MXT_PROCI_GRIPFACE:
+       case MXT_PROCG_NOISE:
+       case MXT_PROCI_ONETOUCH:
+       case MXT_PROCI_TWOTOUCH:
+       case MXT_PROCI_GRIP:
+       case MXT_PROCI_PALM:
+       case MXT_SPT_COMMSCONFIG:
+       case MXT_SPT_GPIOPWM:
+       case MXT_SPT_SELFTEST:
+       case MXT_SPT_CTECONFIG:
+       case MXT_SPT_USERDATA:
+               return true;
+       default:
+               return false;
        }
+}
 
-       u8 i = 0, max_objs = 0, j = 0;
-       u16 addr;
-       struct mxt_object *obj_index;
-
-       dev_dbg(&mxt->client->dev, "In function %s", __func__);
-       max_objs = mxt->device_info.num_objs;
-       obj_index = mxt->object_table;
-
-       for (i = 0; i < max_objs; i++) {
-               addr = obj_index->chip_addr;
-               for (j = 1; j < I2C_RETRY_COUNT; j++) {
-                       err = 1;
-                       switch (obj_index->type) {
-                       case MXT_GEN_POWERCONFIG_T7:
-                               err = mxt_write_block(mxt->client, addr, sizeof(v20_T7), v20_T7);
-                               break;
-                       case MXT_GEN_ACQUIRECONFIG_T8:
-                               err = mxt_write_block(mxt->client, addr, sizeof(v20_T8), v20_T8);
-                               break;
-                       case MXT_TOUCH_MULTITOUCHSCREEN_T9:
-                               err = mxt_write_block(mxt->client, addr, sizeof(v20_T9), v20_T9);
-                               dev_dbg(&mxt->client->dev, "init multitouch object");
-                               break;
-                       case MXT_TOUCH_KEYARRAY_T15:
-                               err = mxt_write_block(mxt->client, addr, sizeof(v20_T15), v20_T15);
-                               break;
-                       case MXT_SPT_COMMSCONFIG_T18:
-                               err = mxt_write_block(mxt->client, addr, sizeof(v20_T18), v20_T18);
-                               break;
-                       case MXT_PROCG_NOISESUPPRESSION_T22:
-                               err = mxt_write_block(mxt->client, addr, sizeof(v20_T22), v20_T22);
-                               break;
-                       case MXT_PROCI_ONETOUCHGESTUREPROCESSOR_T24:
-                               err = mxt_write_block(mxt->client, addr, sizeof(v20_T24), v20_T24);
-                               break;
-                       case MXT_SPT_SELFTEST_T25:
-                               err = mxt_write_block(mxt->client, addr, sizeof(v20_T25), v20_T25);
-                               break;
-                       case MXT_PROCI_TWOTOUCHGESTUREPROCESSOR_T27:
-                               err = mxt_write_block(mxt->client, addr, sizeof(v20_T27), v20_T27);
-                       break;
-                       case MXT_SPT_CTECONFIG_T28:
-                               err = mxt_write_block(mxt->client, addr, sizeof(v20_T28), v20_T28);
-                       break;
-                       case MXT_USER_INFO_T38:
-                               err = mxt_write_block(mxt->client, addr, sizeof(v20_T38), v20_T38);
-                               break;
-                       case MXT_PROCI_GRIPSUPPRESSION_T40:
-                               err = mxt_write_block(mxt->client, addr, sizeof(v20_T40), v20_T40);
-                               break;
-                       case MXT_PROCI_PALMSUPPRESSION_T41:
-                               err = mxt_write_block(mxt->client, addr, sizeof(v20_T41), v20_T41);
-                               break;
-                       case MXT_SPT_DIGITIZER_T43:
-                               err = mxt_write_block(mxt->client, addr, sizeof(v20_T43), v20_T43);
-                               break;
-                       default:
-                               break;
-                       }
-                       if (err > 0)
-                               break;
-               }
-               if (j >= I2C_RETRY_COUNT)
-                       dev_info(&mxt->client->dev,
-                               "touch: config init abnormal,obj_index's type is %d",
-                               obj_index->type);
-
-               obj_index++;
+static bool mxt_object_writable(unsigned int type)
+{
+       switch (type) {
+       case MXT_GEN_COMMAND:
+       case MXT_GEN_POWER:
+       case MXT_GEN_ACQUIRE:
+       case MXT_TOUCH_MULTI:
+       case MXT_TOUCH_KEYARRAY:
+       case MXT_TOUCH_PROXIMITY:
+       case MXT_PROCI_GRIPFACE:
+       case MXT_PROCG_NOISE:
+       case MXT_PROCI_ONETOUCH:
+       case MXT_PROCI_TWOTOUCH:
+       case MXT_PROCI_GRIP:
+       case MXT_PROCI_PALM:
+       case MXT_SPT_GPIOPWM:
+       case MXT_SPT_SELFTEST:
+       case MXT_SPT_CTECONFIG:
+               return true;
+       default:
+               return false;
        }
-       mxt_calibrate(mxt->client);
-       dev_dbg(&mxt->client->dev, "config init Done.");
 }
 
-/* Returns object address in mXT chip, or zero if object is not found */
-static u16 get_object_address(uint8_t object_type,
-                             uint8_t instance,
-                             struct mxt_object *object_table,
-                             int max_objs)
+static void mxt_dump_message(struct device *dev,
+                                 struct mxt_message *message)
 {
-       uint8_t object_table_index = 0;
-       uint8_t address_found = 0;
-       uint16_t address = 0;
-       struct mxt_object *obj;
-
-       while ((object_table_index < max_objs) && !address_found) {
-               obj = &object_table[object_table_index];
-               if (obj->type == object_type) {
-                       address_found = 1;
-                       /* Are there enough instances defined in the FW? */
-                       if (obj->instances >= instance) {
-                               address = obj->chip_addr +
-                                         (obj->size + 1) * instance;
-                       } else {
-                               break;
-                       }
-               }
-               object_table_index++;
-       }
-       return address;
+       dev_dbg(dev, "reportid:\t0x%x\n", message->reportid);
+       dev_dbg(dev, "message1:\t0x%x\n", message->message[0]);
+       dev_dbg(dev, "message2:\t0x%x\n", message->message[1]);
+       dev_dbg(dev, "message3:\t0x%x\n", message->message[2]);
+       dev_dbg(dev, "message4:\t0x%x\n", message->message[3]);
+       dev_dbg(dev, "message5:\t0x%x\n", message->message[4]);
+       dev_dbg(dev, "message6:\t0x%x\n", message->message[5]);
+       dev_dbg(dev, "message7:\t0x%x\n", message->message[6]);
+       dev_dbg(dev, "checksum:\t0x%x\n", message->checksum);
 }
 
-int BackupNVM(struct mxt_data *mxt)
+static int mxt_check_bootloader(struct i2c_client *client,
+                                    unsigned int state)
 {
-       u8 buf[1] = {0x55};
-       u8 T38_buf[8] = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0};
-
-       /* Backup the non-volatile memory (NVM). */
-       T6_addr = get_object_address(MXT_GEN_COMMANDPROCESSOR_T6, 0,
-                       mxt->object_table, mxt->device_info.num_objs);
-       T38_addr = get_object_address(MXT_USER_INFO_T38, 0,
-                       mxt->object_table, mxt->device_info.num_objs);
-
-       pr_info("BackupNVM T6_addr+1=0x%4x, T38_addr=0x%4x.\n", T6_addr+1, T38_addr);
-       mxt_read_block(mxt->client, T38_addr, sizeof(T38_buf), T38_buf);
-
-       if (iForceUpdateConfigValue == 1) {
-                       pr_info("%s force update. ver=%d.%d.%d.%d --> %d.%d.%d.%d\n", \
-                       __func__,                                         \
-                       T38_buf[0], T38_buf[1], T38_buf[2], T38_buf[3],   \
-                       v20_T38[0], v20_T38[1], v20_T38[2], v20_T38[3]);
-       } else {
-               #define PRINT_T38_V20() do {                                      \
-                       pr_info("%s not update. ver=%d.%d.%d.%d (%d)> %d.%d.%d.%d  (%d)\n", \
-                       __func__,                                         \
-                       T38_buf[0], T38_buf[1], T38_buf[2], T38_buf[3], T38_buf[7],  \
-                       v20_T38[0], v20_T38[1], v20_T38[2], v20_T38[3], v20_T38[7]);  \
-               } while (0)
-
-               /* Check T38 previous config version. */
-               if ((T38_buf[0] != 0 && T38_buf[1] != 0) &&
-                       (T38_buf[2] != 0 && T38_buf[3] != 0) &&
-                       (T38_buf[4] == 0 && T38_buf[5] == 0) &&
-                       (T38_buf[6] == 0 && T38_buf[7] == MAGIC_PRODUCT_T38_BYTE7)) {
-                       if (T38_buf[0] > v20_T38[0]) {
-                               PRINT_T38_V20();
-                               return 0;
-                       } else if (T38_buf[0] == v20_T38[0]) {
-                               if (T38_buf[1] > v20_T38[1]) {
-                                       PRINT_T38_V20();
-                                       return 0;
-                               } else if (T38_buf[1] == v20_T38[1]) {
-                                       if (T38_buf[2] > v20_T38[2]) {
-                                               PRINT_T38_V20();
-                                               return 0;
-                                       } else if (T38_buf[2] == v20_T38[2]) {
-                                               if  (T38_buf[3] >= v20_T38[3]) {
-                                                       PRINT_T38_V20();
-                                                       return 0;
-                                               }
-                                       }
-                               }
-                       }
-               } else {
-                        if (T38_buf[7] != MAGIC_PRODUCT_T38_BYTE7) {
-                               pr_info("%s  PRODUCT_T38_BYTE7 diff, force update. ver=%d.%d.%d.%d(%d) --> %d.%d.%d.%d(%d)\n", \
-                               __func__,                                         \
-                               T38_buf[0], T38_buf[1], T38_buf[2], T38_buf[3], T38_buf[7],  \
-                               v20_T38[0], v20_T38[1], v20_T38[2], v20_T38[3], v20_T38[7]);
-                        }
+       u8 val;
 
-               }
-               #undef PRINT_T38_V20
+recheck:
+       if (i2c_master_recv(client, &val, 1) != 1) {
+               dev_err(&client->dev, "%s: i2c recv failed\n", __func__);
+               return -EIO;
        }
 
-       mxt_config_init(mxt);
-
-       if (mxt_write_block(mxt->client, T6_addr+1, sizeof(buf), buf) == 1)
-               pr_info("Backup the configurations to non-volatile memory.\n");
-       else {
-               pr_err("Backup the configurations to non-volatile memory failed!!!\n");
-               return -1;
+       switch (state) {
+       case MXT_WAITING_BOOTLOAD_CMD:
+       case MXT_WAITING_FRAME_DATA:
+               val &= ~MXT_BOOT_STATUS_MASK;
+               break;
+       case MXT_FRAME_CRC_PASS:
+               if (val == MXT_FRAME_CRC_CHECK)
+                       goto recheck;
+               break;
+       default:
+               return -EINVAL;
        }
 
-       /*Reset the IC.*/
-       if (mxt_write_block(mxt->client, T6_addr, sizeof(buf), buf) == 1)
-               pr_info("Software reset the IC.\n");
-       else {
-               pr_err("Software reset the IC failed!!!\n");
-               return -1;
+       if (val != state) {
+               dev_err(&client->dev, "Unvalid bootloader mode state\n");
+               return -EINVAL;
        }
 
-       msleep(400);
-       pr_info("BackupNVM done. ver=%d.%d.%d.%d\n", v20_T38[0], v20_T38[1], v20_T38[2], v20_T38[3]);
        return 0;
 }
 
-/* Calculates the 24-bit CRC sum. */
-static u32 CRC_24(u32 crc, u8 byte1, u8 byte2)
+static int mxt_unlock_bootloader(struct i2c_client *client)
 {
-       static const u32 crcpoly = 0x80001B;
-       u32 result;
-       u32 data_word;
-
-       data_word = ((((u16) byte2) << 8u) | byte1);
-       result = ((crc << 1u) ^ data_word);
-       if (result & 0x1000000)
-               result ^= crcpoly;
-       return result;
-}
+       u8 buf[2];
 
-/* Calibrate rz*/
-static void mxt_calibrate(struct i2c_client *client)
-{
-       u16 base_addr;
-       struct mxt_data *mxt;
+       buf[0] = MXT_UNLOCK_CMD_LSB;
+       buf[1] = MXT_UNLOCK_CMD_MSB;
 
-       mxt = i2c_get_clientdata(client);
-       dev_dbg(&mxt->client->dev, "In function %s", __func__);
+       if (i2c_master_send(client, buf, 2) != 2) {
+               dev_err(&client->dev, "%s: i2c send failed\n", __func__);
+               return -EIO;
+       }
 
-       base_addr = get_object_address(MXT_GEN_COMMANDPROCESSOR_T6,
-                               0, mxt->object_table,
-                               mxt->device_info.num_objs);
-       base_addr += MXT_ADR_T6_CALIBRATE;
-       mxt_write_byte(mxt->client, base_addr, 0x55);
+       return 0;
 }
 
-
-/*
- * Reads a block of bytes from given address from mXT chip. If we are
- * reading from message window, and previous read was from message window,
- * there's no need to write the address pointer: the mXT chip will
- * automatically set the address pointer back to message window start.
- */
-
-static int mxt_read_block(struct i2c_client *client,
-                  u16 addr,
-                  u16 length,
-                  u8 *value)
+static int mxt_fw_write(struct i2c_client *client,
+                            const u8 *data, unsigned int frame_size)
 {
-       struct i2c_adapter *adapter = client->adapter;
-       struct i2c_msg msg[2];
-       __le16  le_addr;
-       struct mxt_data *mxt;
-       int err;
-
-       mxt = i2c_get_clientdata(client);
-
-       if (mxt != NULL) {
-               if ((mxt->last_read_addr == addr) &&
-                       (addr == mxt->msg_proc_addr)) {
-                       pm_runtime_get_sync(&client->dev);
-                       if  (i2c_master_recv(client, value, length) == length)
-                               err = length;
-                       else
-                               err = -EIO;
-                       pm_runtime_put(&client->dev);
-                       return err;
-               } else {
-                       mxt->last_read_addr = addr;
-               }
+       if (i2c_master_send(client, data, frame_size) != frame_size) {
+               dev_err(&client->dev, "%s: i2c send failed\n", __func__);
+               return -EIO;
        }
 
-       dev_dbg(&client->dev, "Writing address pointer & reading %d bytes"
-               " in on i2c transaction...\n", length);
-
-/* FIH { */
-/* Avoid stop delay */
-#if 0
-       le_addr = cpu_to_le16(addr);
-       msg[0].addr  = client->addr;
-       msg[0].flags = 0x00;
-       msg[0].len   = 2;
-       msg[0].buf   = (u8 *) &le_addr;
-
-       msg[1].addr  = client->addr;
-       msg[1].flags = I2C_M_RD;
-       msg[1].len   = length;
-       msg[1].buf   = (u8 *) value;
-       pm_runtime_get_sync(&client->dev);
-       if  (i2c_transfer(adapter, msg, 2) == 2)
-               err = length;
-       else
-               err = -EIO;
-       pm_runtime_put(&client->dev);
-#else
+       return 0;
+}
+
+static int __mxt_read_reg(struct i2c_client *client,
+                              u16 reg, u16 len, void *val)
 {
-       u8 reg[2];
-       reg[0] = addr & 0xFF;
-       reg[1] = (addr>>8) & 0xFF;
-
-       err = i2c_master_send(client, (u8 *)reg, 2);
-       if (err == 2)
-               err = 0;
-       else {
-               msleep(100); /* For deep sleep mode */
-               err = i2c_master_send(client, (u8 *)reg, 2);
-               if (err == 2)
-                       err = 0;
-               else
-                       err = -EIO;
+       struct i2c_msg xfer[2];
+       u8 buf[2];
+
+       buf[0] = reg & 0xff;
+       buf[1] = (reg >> 8) & 0xff;
+
+       /* Write register */
+       xfer[0].addr = client->addr;
+       xfer[0].flags = 0;
+       xfer[0].len = 2;
+       xfer[0].buf = buf;
+
+       /* Read data */
+       xfer[1].addr = client->addr;
+       xfer[1].flags = I2C_M_RD;
+       xfer[1].len = len;
+       xfer[1].buf = val;
+
+       if (i2c_transfer(client->adapter, xfer, 2) != 2) {
+               dev_err(&client->dev, "%s: i2c transfer failed\n", __func__);
+               return -EIO;
        }
 
-       if (err < 0)
-               return err;
-
-       err = i2c_master_recv(client, (u8 *)value, length);
-       if (err == length)
-               err = length;
-       else
-               err = -EIO;
-}
-#endif
-/* FIH } */
-       return err;
+       return 0;
 }
 
-
-/* Writes one byte to given address in mXT chip. */
-
-static int mxt_write_byte(struct i2c_client *client, u16 addr, u8 value)
+static int mxt_read_reg(struct i2c_client *client, u16 reg, u8 *val)
 {
-
-       struct mxt_data *mxt;
-       struct mxt_i2c_byte_transfer i2c_byte_transfer;
-       int err;
-
-       mxt = i2c_get_clientdata(client);
-       if (mxt != NULL)
-               mxt->last_read_addr = -1;
-       i2c_byte_transfer.le_addr = cpu_to_le16(addr);
-       i2c_byte_transfer.data = value;
-
-       if (i2c_master_send(client, (u8 *) &i2c_byte_transfer, 3) == 3)
-               err = 0;
-       else
-               err = -EIO;
-
-       return err;
+       return __mxt_read_reg(client, reg, 1, val);
 }
 
-/* Writes a block of bytes (max 256) to given address in mXT chip. */
-static int mxt_write_block(struct i2c_client *client,
-               u16 addr, u16 length, u8 *value)
+static int mxt_write_reg(struct i2c_client *client, u16 reg, u8 val)
 {
-       int i;
-       struct {
-               __le16  le_addr;
-               u8      data[256];
-       } i2c_block_transfer;
-       struct mxt_data *mxt;
-
-       dev_dbg(&client->dev, "Writing %d bytes to %d...", length, addr);
-       if (length > 256)
-               return -EINVAL;
+       u8 buf[3];
 
-       mxt = i2c_get_clientdata(client);
-       if (mxt != NULL)
-               mxt->last_read_addr = -1;
+       buf[0] = reg & 0xff;
+       buf[1] = (reg >> 8) & 0xff;
+       buf[2] = val;
 
-       memcpy(i2c_block_transfer.data, value, length);
-       i2c_block_transfer.le_addr = cpu_to_le16(addr);
-       i = i2c_master_send(client, (u8 *) &i2c_block_transfer, length + 2);
-       if (i == (length + 2))
-               return length;
-       else
+       if (i2c_master_send(client, buf, 3) != 3) {
+               dev_err(&client->dev, "%s: i2c send failed\n", __func__);
                return -EIO;
+       }
+
+       return 0;
 }
 
-/* Calculates the CRC value for mXT infoblock. */
-int calculate_infoblock_crc(u32 *crc_result, u8 *data, int crc_area_size)
+static int mxt_read_object_table(struct i2c_client *client,
+                                     u16 reg, u8 *object_buf)
 {
-       u32 crc = 0;
-       int i;
-
-       pr_debug("atmel_mxt224 In function %s", __func__);
-       for (i = 0; i < (crc_area_size - 1); i = i + 2)
-               crc = CRC_24(crc, *(data + i), *(data + i + 1));
-       /* If uneven size, pad with zero */
-       if (crc_area_size & 0x0001)
-               crc = CRC_24(crc, *(data + i), 0);
-       /* Return only 24 bits of CRC. */
-       *crc_result = (crc & 0x00FFFFFF);
-
-       return 0;
+       return __mxt_read_reg(client, reg, MXT_OBJECT_SIZE,
+                                  object_buf);
 }
 
-static void report_mt(struct mxt_data *mxt)
+static struct mxt_object *
+mxt_get_object(struct mxt_data *data, u8 type)
 {
+       struct mxt_object *object;
        int i;
-       int active_touches = 0;
-
-       for (i = 0; i < mxt->numtouch; i++) {
-               if (!stored_size[i])
-                       continue;
 
-               active_touches++;
-               input_report_abs(mxt->touch_input,
-                               ABS_MT_TRACKING_ID,
-                               i);
-               input_report_abs(mxt->touch_input,
-                               ABS_MT_TOUCH_MAJOR,
-                               stored_size[i]);
-               input_report_abs(mxt->touch_input,
-                               ABS_MT_POSITION_X,
-                               stored_x[i]);
-               input_report_abs(mxt->touch_input,
-                               ABS_MT_POSITION_Y,
-                               stored_y[i]);
-               input_mt_sync(mxt->touch_input);
+       for (i = 0; i < data->info.object_num; i++) {
+               object = data->object_table + i;
+               if (object->type == type)
+                       return object;
        }
 
-       if (active_touches == 0)
-               input_mt_sync(mxt->touch_input);
-       input_sync(mxt->touch_input);
+       dev_err(&data->client->dev, "Invalid object type\n");
+       return NULL;
 }
 
-static void process_T9_message(u8 *message, struct mxt_data *mxt)
+static int mxt_read_message(struct mxt_data *data,
+                                struct mxt_message *message)
 {
-       struct  input_dev *input;
-       struct device *dev = &mxt->client->dev;
-       u8  status;
-       u16 xpos = 0xFFFF;
-       u16 ypos = 0xFFFF;
-       u8  touch_size = 255;
-       u8  touch_number;
-       u8  amplitude;
-       u8  report_id;
-       input = mxt->touch_input;
-       status = message[MXT_MSG_T9_STATUS];
-       report_id = message[0];
-
-       if (status & MXT_MSGB_T9_SUPPRESS) {
-               /* Touch has been suppressed by grip/face */
-               /* detection                              */
-               dev_dbg(&mxt->client->dev, "SUPRESS");
-       } else {
-/* FIH { */
-/* Correct coordinate */
-#if 0
-               xpos = message[MXT_MSG_T9_XPOSMSB] * 16 +
-                       ((message[MXT_MSG_T9_XYPOSLSB] >> 4) & 0xF);
-               ypos = message[MXT_MSG_T9_YPOSMSB] * 16 +
-                       ((message[MXT_MSG_T9_XYPOSLSB] >> 0) & 0xF);
-               printk(KERN_INFO "[TOUCH] X=%d, Y=%d\n", xpos, ypos);
-
-               if (mxt->max_x_val < 1024)
-                               xpos = xpos >> 2;
-
-               if (mxt->max_y_val < 1024)
-                               ypos = ypos >> 2;
-
-               printk(KERN_INFO "[TOUCH] [X=%d, Y=%d] max_x=%d , max_y=%d\n", xpos, ypos, mxt->max_x_val, mxt->max_y_val);
-#else
-               xpos = message[MXT_MSG_T9_XPOSMSB] * 16 +
-                       ((message[MXT_MSG_T9_XYPOSLSB] >> 4) & 0xF);
-               ypos = message[MXT_MSG_T9_YPOSMSB] * 4 +
-                       ((message[MXT_MSG_T9_XYPOSLSB] >> 6) & 0x3);
-               printk(KERN_INFO "[TOUCH] X=%d, Y=%d\n", xpos, ypos);
-
-#if 0
-               xpos = xpos*1024*9/12800 + 51;
-               ypos = ypos*1024*9/8000 + 51;
-               printk(KERN_INFO "[TOUCH] [X=%d, Y=%d]\n", xpos, ypos);
-#else
-               xpos = (xpos)*1024/1280;
-               if (xpos > 1024)
-                       xpos = 1024;
-               if (xpos < 0)
-                       xpos = 0;
-               ypos = (ypos)*1024/800;
-               if (ypos > 1024)
-                       ypos = 1024;
-               if (ypos < 0)
-                       ypos = 0;
-               printk(KERN_INFO "[TOUCH] [X=%d, Y=%d]\n", xpos, ypos);
-#endif
+       struct mxt_object *object;
+       u16 reg;
 
-#endif
+       object = mxt_get_object(data, MXT_GEN_MESSAGE);
+       if (!object)
+               return -EINVAL;
 
+       reg = object->start_address;
+       return __mxt_read_reg(data->client, reg,
+                       sizeof(struct mxt_message), message);
+}
 
+static int mxt_read_object(struct mxt_data *data,
+                               u8 type, u8 offset, u8 *val)
+{
+       struct mxt_object *object;
+       u16 reg;
 
+       object = mxt_get_object(data, type);
+       if (!object)
+               return -EINVAL;
 
-/* FIH } */
+       reg = object->start_address;
+       return __mxt_read_reg(data->client, reg + offset, 1, val);
+}
 
-               touch_number = message[MXT_MSG_REPORTID] -
-                       mxt->rid_map[report_id].first_rid;
+static int mxt_write_object(struct mxt_data *data,
+                                u8 type, u8 offset, u8 val)
+{
+       struct mxt_object *object;
+       u16 reg;
 
-               stored_x[touch_number] = xpos;
-               stored_y[touch_number] = ypos;
+       object = mxt_get_object(data, type);
+       if (!object)
+               return -EINVAL;
 
-               if (status & MXT_MSGB_T9_DETECT) {
-                       /*
-                        * TODO: more precise touch size calculation?
-                        * mXT224 reports the number of touched nodes,
-                        * so the exact value for touch ellipse major
-                        * axis length would be 2*sqrt(touch_size/pi)
-                        * (assuming round touch shape).
-                        */
-                       touch_size = message[MXT_MSG_T9_TCHAREA];
-                       touch_size = touch_size >> 2;
-                       if (!touch_size)
-                               touch_size = 1;
-                       stored_size[touch_number] = touch_size;
-                       if (status & MXT_MSGB_T9_AMP)
-                               /* Amplitude of touch has changed */
-                               amplitude = message[MXT_MSG_T9_TCHAMPLITUDE];
+       reg = object->start_address;
+       return mxt_write_reg(data->client, reg + offset, val);
+}
 
-                       printk(KERN_INFO, "DETECT:%s%s%s%s",
-                               ((status & MXT_MSGB_T9_PRESS) ? " PRESS" : ""),
-                               ((status & MXT_MSGB_T9_MOVE) ? " MOVE" : ""),
-                               ((status & MXT_MSGB_T9_AMP) ? " AMP" : ""),
-                               ((status & MXT_MSGB_T9_VECTOR) ? " VECT" : ""));
-               } else if (status & MXT_MSGB_T9_RELEASE) {
-                       printk(KERN_INFO, "RELEASE");
+static void mxt_input_report(struct mxt_data *data, int single_id)
+{
+       struct mxt_finger *finger = data->finger;
+       struct input_dev *input_dev = data->input_dev;
+       int status = finger[single_id].status;
+       int finger_num = 0;
+       int id;
+
+       for (id = 0; id < MXT_MAX_FINGER; id++) {
+               if (!finger[id].status)
+                       continue;
 
-                       /* The previously reported touch has been removed.*/
-                       stored_size[touch_number] = 0;
+               input_mt_slot(input_dev, id);
+               input_mt_report_slot_state(input_dev, MT_TOOL_FINGER,
+                               finger[id].status != MXT_RELEASE);
+
+               if (finger[id].status != MXT_RELEASE) {
+                       finger_num++;
+                       input_report_abs(input_dev, ABS_MT_TOUCH_MAJOR,
+                                       finger[id].area);
+                       input_report_abs(input_dev, ABS_MT_POSITION_X,
+                                       finger[id].x);
+                       input_report_abs(input_dev, ABS_MT_POSITION_Y,
+                                       finger[id].y);
+               } else {
+                       finger[id].status = 0;
                }
+       }
+
+       input_report_key(input_dev, BTN_TOUCH, finger_num > 0);
 
-               printk(KERN_INFO, "X=%d, Y=%d, touch number=%d, TOUCHSIZE=%d",
-                       xpos, ypos, touch_number, stored_size[touch_number]);
+       if (status != MXT_RELEASE) {
+               input_report_abs(input_dev, ABS_X, finger[single_id].x);
+               input_report_abs(input_dev, ABS_Y, finger[single_id].y);
        }
+
+       input_sync(input_dev);
 }
 
-void process_key_message(u8 *message, struct mxt_data *mxt)
+static void mxt_input_touchevent(struct mxt_data *data,
+                                     struct mxt_message *message, int id)
 {
-       /*key up*/
-       if (message[1] == 0 && message[2] == 0 && message[3] == 0 && message[4] == 0) {
-               if (mxt->prev_key == 0) {
-                       dev_dbg(&mxt->client->dev, "No previous key");
-               } else {
-                       input_report_key(mxt->key_input, mxt->prev_key, 0);
-                       dev_dbg(&mxt->client->dev,
-                                "Report key %d up", mxt->prev_key);
-                       mxt->prev_key = 0;
+       struct mxt_finger *finger = data->finger;
+       struct device *dev = &data->client->dev;
+       u8 status = message->message[0];
+       int x;
+       int y;
+       int area;
+
+       /* Check the touch is present on the screen */
+       if (!(status & MXT_DETECT)) {
+               if (status & MXT_RELEASE) {
+                       dev_dbg(dev, "[%d] released\n", id);
+
+                       finger[id].status = MXT_RELEASE;
+                       mxt_input_report(data, id);
                }
-               input_sync(mxt->key_input);
                return;
        }
 
-printk(KERN_INFO "message[1]=%d, message[2]=%d, message[3]=%d, message[4]=%d", message[1], message[2], message[3], message[4]);
-
-       /*key down*/
-       if (message[1] == 128 && message[2] == 0 && message[3] == 2 && message[4] == 0) {
-               input_report_key(mxt->key_input, KEY_BACK, 1);
-               dev_dbg(&mxt->client->dev,
-                       "Report BACK(%d) key DOWN.", KEY_BACK);
-               mxt->prev_key = KEY_BACK;
-       } else if (message[1] == 128 && message[2] == 0 && message[3] == 4 && message[4] == 0) {
-               input_report_key(mxt->key_input, KEY_MENU, 1);
-               dev_dbg(&mxt->client->dev,
-                        "Report MENU(%d) key DOWN.", KEY_MENU);
-               mxt->prev_key = KEY_MENU;
-       } else if (message[1] == 128 && message[2] == 0 && message[3] == 8 && message[4] == 0) {
-               input_report_key(mxt->key_input, KEY_HOME, 1);
-               dev_dbg(&mxt->client->dev,
-                       "Report HOME(%d) key DOWN.", KEY_HOME);
-               mxt->prev_key = KEY_HOME;
-       } else if (message[1] == 128 && message[2] == 8 && message[3] == 0 && message[4] == 0) {
-               input_report_key(mxt->key_input, KEY_SEARCH, 1);
-               dev_dbg(&mxt->client->dev,
-                       "Report SEARCH(%d) key DOWN.", KEY_SEARCH);
-               mxt->prev_key = KEY_SEARCH;
-       }
-       input_sync(mxt->key_input);
-}
+       /* Check only AMP detection */
+       if (!(status & (MXT_PRESS | MXT_MOVE)))
+               return;
 
-static int process_message(u8 *message, u8 object, struct mxt_data *mxt)
-{
-       struct i2c_client *client;
-       u8  status;
-       u16 xpos = 0xFFFF;
-       u16 ypos = 0xFFFF;
-       u8  event;
-       u8  direction;
-       u16 distance;
-       u8  length;
-       u8  report_id;
-       static u8 error_cond;
-       client = mxt->client;
-       length = mxt->message_size;
-       report_id = message[0];
-
-       switch (object) {
-       case MXT_GEN_COMMANDPROCESSOR_T6:
-               status = message[1];
-
-               if (status & MXT_MSGB_T6_COMSERR) {
-                       if ((!error_cond) & MXT_MSGB_T6_COMSERR) {
-                               dev_err(&client->dev, "maXTouch checksum error\n");
-                               error_cond |= MXT_MSGB_T6_COMSERR;
-                       }
-               }
-               if (status & MXT_MSGB_T6_CFGERR) {
-                       /*
-                        * Configuration error. A proper configuration
-                        * needs to be written to chip and backed up. Refer
-                        * to protocol document for further info.
-                        */
-                       if ((!error_cond) & MXT_MSGB_T6_CFGERR) {
-                               dev_err(&client->dev, "maXTouch configuration error\n");
-                               error_cond |= MXT_MSGB_T6_CFGERR;
-                       }
-               }
-               if (status & MXT_MSGB_T6_CAL) {
-                       /* Calibration in action, no need to react */
-                       dev_info(&client->dev, "maXTouch calibration in progress\n");
-               }
-               if (status & MXT_MSGB_T6_SIGERR) {
-                       /*
-                        * Signal acquisition error, something is seriously
-                        * wrong, not much we can in the driver to correct
-                        * this
-                        */
-                       if ((!error_cond) & MXT_MSGB_T6_SIGERR) {
-                               dev_err(&client->dev, "maXTouch acquisition error\n");
-                               error_cond |= MXT_MSGB_T6_SIGERR;
-                       }
-               }
-               if (status & MXT_MSGB_T6_OFL) {
-                       /*
-                        * Cycle overflow, the acquisition is too short.
-                        * Can happen temporarily when there's a complex
-                        * touch shape on the screen requiring lots of
-                        * processing.
-                        */
-                       dev_err(&client->dev, "maXTouch cycle overflow\n");
-               }
-               if (status & MXT_MSGB_T6_RESET) {
-                       /* Chip has reseted, no need to react. */
-                       dev_info(&client->dev, "maXTouch chip reset\n");
-               }
-               if (status == 0) {
-                       /* Chip status back to normal. */
-                       dev_info(&client->dev, "maXTouch status normal\n");
-                       error_cond = 0;
-               }
-               break;
+       x = (message->message[1] << 4) | ((message->message[3] >> 4) & 0xf);
+       y = (message->message[2] << 4) | ((message->message[3] & 0xf));
+       if (data->max_x < 1024)
+               x = x >> 2;
+       if (data->max_y < 1024)
+               y = y >> 2;
 
-       case MXT_TOUCH_KEYARRAY_T15:
-               dev_dbg(&client->dev, "key value, message[1]=%d, "
-                       "message[2]=%d, message[3]=%d, message[4]=%d",
-                        message[1], message[2], message[3], message[4]);
-               process_key_message(message, mxt);
-               break;
+       area = message->message[4];
 
-       case MXT_TOUCH_MULTITOUCHSCREEN_T9:
-               process_T9_message(message, mxt);
-               report_mt(mxt);
-               break;
+       dev_dbg(dev, "[%d] %s x: %d, y: %d, area: %d\n", id,
+               status & MXT_MOVE ? "moved" : "pressed",
+               x, y, area);
 
-       case MXT_SPT_GPIOPWM_T19:
-               if (debug >= DEBUG_TRACE)
-                       dev_info(&client->dev, "Receiving GPIO message\n");
-               break;
+       finger[id].status = status & MXT_MOVE ?
+                               MXT_MOVE : MXT_PRESS;
+       finger[id].x = x;
+       finger[id].y = y;
+       finger[id].area = area;
 
-       case MXT_PROCI_GRIPFACESUPPRESSION_T20:
-               if (debug >= DEBUG_TRACE)
-                       dev_info(&client->dev, "Receiving face suppression msg\n");
-               break;
+       mxt_input_report(data, id);
+}
 
-       case MXT_PROCG_NOISESUPPRESSION_T22:
-               if (debug >= DEBUG_TRACE)
-                       dev_info(&client->dev, "Receiving noise suppression msg\n");
-               status = message[MXT_MSG_T22_STATUS];
-               if (status & MXT_MSGB_T22_FHCHG) {
-                       if (debug >= DEBUG_TRACE)
-                               dev_info(&client->dev, "maXTouch: Freq changed\n");
-               }
-               if (status & MXT_MSGB_T22_GCAFERR) {
-                       if (debug >= DEBUG_TRACE)
-                               dev_info(&client->dev, "maXTouch: High noise level\n");
-               }
-               if (status & MXT_MSGB_T22_FHERR) {
-                       if (debug >= DEBUG_TRACE)
-                               dev_info(&client->dev,
-                                       "maXTouch: Freq changed - Noise level too high\n");
+static irqreturn_t mxt_interrupt(int irq, void *dev_id)
+{
+       struct mxt_data *data = dev_id;
+       struct mxt_message message;
+       struct mxt_object *object;
+       struct device *dev = &data->client->dev;
+       int id;
+       u8 reportid;
+       u8 max_reportid;
+       u8 min_reportid;
+
+       do {
+               if (mxt_read_message(data, &message)) {
+                       dev_err(dev, "Failed to read message\n");
+                       goto end;
                }
-               break;
 
-       case MXT_PROCI_ONETOUCHGESTUREPROCESSOR_T24:
-               if (debug >= DEBUG_TRACE)
-                       dev_info(&client->dev,
-                               "Receiving one-touch gesture msg\n");
-
-               event = message[MXT_MSG_T24_STATUS] & 0x0F;
-               xpos = message[MXT_MSG_T24_XPOSMSB] * 16 +
-                       ((message[MXT_MSG_T24_XYPOSLSB] >> 4) & 0x0F);
-               ypos = message[MXT_MSG_T24_YPOSMSB] * 16 +
-                       ((message[MXT_MSG_T24_XYPOSLSB] >> 0) & 0x0F);
-               xpos >>= 2;
-               ypos >>= 2;
-               direction = message[MXT_MSG_T24_DIR];
-               distance = message[MXT_MSG_T24_DIST] +
-                          (message[MXT_MSG_T24_DIST + 1] << 16);
-
-               input_event(mxt->touch_input, EV_MSC, MSC_GESTURE,
-                               (event << 24) | (direction << 16) | distance);
-               input_event(mxt->touch_input, EV_MSC, MSC_GESTURE,
-                               (xpos << 16) | ypos);
-               break;
+               reportid = message.reportid;
 
-       case MXT_SPT_SELFTEST_T25:
-               if (debug >= DEBUG_TRACE)
-                       dev_info(&client->dev,
-                               "Receiving Self-Test msg\n");
-
-               if (message[MXT_MSG_T25_STATUS] == MXT_MSGR_T25_RUN_ALL_TESTS) {
-                       if (debug >= DEBUG_TRACE)
-                               dev_info(&client->dev,
-                                       "maXTouch: Self-Test OK\n");
-
-               } else  {
-                       dev_err(&client->dev,
-                               "maXTouch: Self-Test Failed [%02x]:"
-                               "{%02x,%02x,%02x,%02x,%02x}\n",
-                               message[MXT_MSG_T25_STATUS],
-                               message[MXT_MSG_T25_STATUS + 0],
-                               message[MXT_MSG_T25_STATUS + 1],
-                               message[MXT_MSG_T25_STATUS + 2],
-                               message[MXT_MSG_T25_STATUS + 3],
-                               message[MXT_MSG_T25_STATUS + 4]
-                               );
-               }
-               break;
+               /* whether reportid is thing of MXT_TOUCH_MULTI */
+               object = mxt_get_object(data, MXT_TOUCH_MULTI);
+               if (!object)
+                       goto end;
 
-       case MXT_PROCI_TWOTOUCHGESTUREPROCESSOR_T27:
-               if (debug >= DEBUG_TRACE)
-                       dev_info(&client->dev, "Receiving 2-touch gesture message\n");
-
-               event = message[MXT_MSG_T27_STATUS] & 0xF0;
-               xpos = message[MXT_MSG_T27_XPOSMSB] * 16 +
-                       ((message[MXT_MSG_T27_XYPOSLSB] >> 4) & 0x0F);
-               ypos = message[MXT_MSG_T27_YPOSMSB] * 16 +
-                       ((message[MXT_MSG_T27_XYPOSLSB] >> 0) & 0x0F);
-               xpos >>= 2;
-               ypos >>= 2;
-               direction = message[MXT_MSG_T27_ANGLE];
-               distance = message[MXT_MSG_T27_SEPARATION] +
-                          (message[MXT_MSG_T27_SEPARATION + 1] << 16);
-
-               input_event(mxt->touch_input, EV_MSC, MSC_GESTURE,
-                               (event << 24) | (direction << 16) | distance);
-               input_event(mxt->touch_input, EV_MSC, MSC_GESTURE,
-                               (xpos << 16) | ypos);
-               break;
-       case MXT_SPT_CTECONFIG_T28:
-               if (debug >= DEBUG_TRACE)
-                       dev_info(&client->dev, "Receiving CTE message...\n");
-               status = message[MXT_MSG_T28_STATUS];
-               if (status & MXT_MSGB_T28_CHKERR)
-                       dev_err(&client->dev,  "maXTouch: Power-Up CRC failure\n");
-               break;
-       default:
-               if (debug >= DEBUG_TRACE)
-                       dev_info(&client->dev, "maXTouch: Unknown message!\n");
-               break;
-       }
+               max_reportid = object->max_reportid;
+               min_reportid = max_reportid - object->num_report_ids + 1;
+               id = reportid - min_reportid;
 
-       return 0;
+               if (reportid >= min_reportid && reportid <= max_reportid)
+                       mxt_input_touchevent(data, &message, id);
+               else
+                       mxt_dump_message(dev, &message);
+       } while (reportid != 0xff);
+
+end:
+       return IRQ_HANDLED;
 }
 
-/*
- * Processes messages when the interrupt line (CHG) is asserted. Keeps
- * reading messages until a message with report ID 0xFF is received,
- * which indicates that there is no more new messages.
- *
- */
-static void mxt_worker(struct mxt_data *mxt)
+static int mxt_check_reg_init(struct mxt_data *data)
 {
-       struct i2c_client *client;
-       u8      *message;
-       u16     message_length;
-       u16     message_addr;
-       u8      report_id;
-       u8      object;
-       int     error;
-       int     i;
-       int     intr_value;
-
-       client         = mxt->client;
-       message        = mxt->message_buf;
-       message_addr   = mxt->msg_proc_addr;
-       message_length = mxt->message_size;
-
-       if (message_length >= 256) {
-               dev_err(&client->dev, "Message length > 256 bytes not supported\n");
-               return;
+       const struct mxt_platform_data *pdata = data->pdata;
+       struct mxt_object *object;
+       struct device *dev = &data->client->dev;
+       int index = 0;
+       int i, j, config_offset;
+
+       if (!pdata->config) {
+               dev_dbg(dev, "No cfg data defined, skipping reg init\n");
+               return 0;
        }
 
-       dev_dbg(&client->dev, "maXTouch worker active:\n");
-       do {
-               /* Read next message, reread on failure. */
-               mxt->message_counter++;
-               for (i = 1; i < I2C_RETRY_COUNT; i++) {
-                       error = mxt_read_block(client, message_addr,
-                                       message_length - 1, message);
-                       if (error >= 0)
-                               break;
-                       mxt->read_fail_counter++;
-                       dev_err(&client->dev, "Failure reading maxTouch device\n");
-               }
-               if (error < 0)
-                       return;
-
-               report_id = message[0];
-
-               if (reg_add > 0)
-                       dev_info(
-                       &client->dev,
-                       "Atmel Debug info message[0]=%d,message[1]=%d,message[2]=%d,message[3]=%d"
-                       "message[4]=%d,message[5]=%d,message[6]=%d,message[7]=%d,message_length=%d",
-                       message[0], message[1], message[2], message[3],
-                       message[4], message[5], message[6], message[7], message_length);
-
-               if ((report_id != MXT_END_OF_MESSAGES) && (report_id != 0)) {
-                       /* Get type of object and process the message */
-                       object = mxt->rid_map[report_id].object;
-                       process_message(message, object, mxt);
+       for (i = 0; i < data->info.object_num; i++) {
+               object = data->object_table + i;
+
+               if (!mxt_object_writable(object->type))
+                       continue;
+
+               for (j = 0; j < object->size + 1; j++) {
+                       config_offset = index + j;
+                       if (config_offset > pdata->config_length) {
+                               dev_err(dev, "Not enough config data!\n");
+                               return -EINVAL;
+                       }
+                       mxt_write_object(data, object->type, j,
+                                        pdata->config[config_offset]);
                }
-               /*dev_dbg(&client->dev, "chgline: %d\n", mxt->read_chg());*/
-               intr_value = gpio_get_value(mxt->mxt_intr_gpio);
-       } while (intr_value == 0);
+               index += object->size + 1;
+       }
+
+       return 0;
 }
 
-/*
- * The maXTouch device will signal the host about a new message by asserting
- * the CHG line. This ISR schedules a worker routine to read the message when
- * that happens.
- */
-static irqreturn_t mxt_irq_handler(int irq, void *_mxt)
+static int mxt_make_highchg(struct mxt_data *data)
 {
-       struct mxt_data *mxt = _mxt;
-
-       mxt->irq_counter++;
-       if (mxt->valid_interrupt()) {
-               mxt->valid_irq_counter++;
+       struct device *dev = &data->client->dev;
+       struct mxt_message message;
+       int count = 10;
+       int error;
 
-               mutex_lock(&mxt->dev_mutex);
-               mxt_worker(mxt);
-               mutex_unlock(&mxt->dev_mutex);
-       } else {
-               mxt->invalid_irq_counter++;
-               return IRQ_NONE;
+       /* Read dummy message to make high CHG pin */
+       do {
+               error = mxt_read_message(data, &message);
+               if (error)
+                       return error;
+       } while (message.reportid != 0xff && --count);
+
+       if (!count) {
+               dev_err(dev, "CHG pin isn't cleared\n");
+               return -EBUSY;
        }
 
-       return IRQ_HANDLED;
+       return 0;
 }
 
-/******************************************************************************/
-/* Initialization of driver                                                   */
-/******************************************************************************/
+static void mxt_handle_pdata(struct mxt_data *data)
+{
+       const struct mxt_platform_data *pdata = data->pdata;
+       u8 voltage;
+
+       /* Set touchscreen lines */
+       mxt_write_object(data, MXT_TOUCH_MULTI, MXT_TOUCH_XSIZE,
+                       pdata->x_line);
+       mxt_write_object(data, MXT_TOUCH_MULTI, MXT_TOUCH_YSIZE,
+                       pdata->y_line);
+
+       /* Set touchscreen orient */
+       mxt_write_object(data, MXT_TOUCH_MULTI, MXT_TOUCH_ORIENT,
+                       pdata->orient);
+
+       /* Set touchscreen burst length */
+       mxt_write_object(data, MXT_TOUCH_MULTI,
+                       MXT_TOUCH_BLEN, pdata->blen);
+
+       /* Set touchscreen threshold */
+       mxt_write_object(data, MXT_TOUCH_MULTI,
+                       MXT_TOUCH_TCHTHR, pdata->threshold);
+
+       /* Set touchscreen resolution */
+       mxt_write_object(data, MXT_TOUCH_MULTI,
+                       MXT_TOUCH_XRANGE_LSB, (pdata->x_size - 1) & 0xff);
+       mxt_write_object(data, MXT_TOUCH_MULTI,
+                       MXT_TOUCH_XRANGE_MSB, (pdata->x_size - 1) >> 8);
+       mxt_write_object(data, MXT_TOUCH_MULTI,
+                       MXT_TOUCH_YRANGE_LSB, (pdata->y_size - 1) & 0xff);
+       mxt_write_object(data, MXT_TOUCH_MULTI,
+                       MXT_TOUCH_YRANGE_MSB, (pdata->y_size - 1) >> 8);
+
+       /* Set touchscreen voltage */
+       if (pdata->voltage) {
+               if (pdata->voltage < MXT_VOLTAGE_DEFAULT) {
+                       voltage = (MXT_VOLTAGE_DEFAULT - pdata->voltage) /
+                               MXT_VOLTAGE_STEP;
+                       voltage = 0xff - voltage + 1;
+               } else
+                       voltage = (pdata->voltage - MXT_VOLTAGE_DEFAULT) /
+                               MXT_VOLTAGE_STEP;
+
+               mxt_write_object(data, MXT_SPT_CTECONFIG,
+                               MXT_CTE_VOLTAGE, voltage);
+       }
+}
 
-static int __devinit mxt_identify(struct i2c_client *client,
-                                 struct mxt_data *mxt,
-                                 u8 *id_block_data)
+static int mxt_get_info(struct mxt_data *data)
 {
-       u8 buf[7];
+       struct i2c_client *client = data->client;
+       struct mxt_info *info = &data->info;
        int error;
-       int identified;
+       u8 val;
 
-       identified = 0;
+       error = mxt_read_reg(client, MXT_FAMILY_ID, &val);
+       if (error)
+               return error;
+       info->family_id = val;
 
-       /* Read Device info to check if chip is valid */
-       error = mxt_read_block(client, MXT_ADDR_INFO_BLOCK, MXT_ID_BLOCK_SIZE,
-                              (u8 *) buf);
+       error = mxt_read_reg(client, MXT_VARIANT_ID, &val);
+       if (error)
+               return error;
+       info->variant_id = val;
 
-       if (error < 0) {
-               client->addr = MXT1386_I2C_ADDR2;
-               slave_addr = MXT1386_I2C_ADDR2;
-               printk(KERN_INFO "[TOUCH] switch slave address to 0x%02x", client->addr);
-               error = mxt_read_block(client, MXT_ADDR_INFO_BLOCK, MXT_ID_BLOCK_SIZE, (u8 *) buf);
-       }
+       error = mxt_read_reg(client, MXT_VERSION, &val);
+       if (error)
+               return error;
+       info->version = val;
 
-       if (error < 0) {
-               mxt->read_fail_counter++;
-               dev_err(&client->dev, "Failure accessing maXTouch device\n");
-               return -EIO;
-       }
+       error = mxt_read_reg(client, MXT_BUILD, &val);
+       if (error)
+               return error;
+       info->build = val;
 
-       memcpy(id_block_data, buf, MXT_ID_BLOCK_SIZE);
-
-       mxt->device_info.family_id  = buf[0];
-       mxt->device_info.variant_id = buf[1];
-       mxt->device_info.major      = ((buf[2] >> 4) & 0x0F);
-       mxt->device_info.minor      = (buf[2] & 0x0F);
-       mxt->device_info.build      = buf[3];
-       mxt->device_info.x_size     = buf[4];
-       mxt->device_info.y_size     = buf[5];
-       mxt->device_info.num_objs   = buf[6];
-       mxt->device_info.num_nodes  = mxt->device_info.x_size *
-                                     mxt->device_info.y_size;
-
-       /*
-        * Check Family & Variant Info; warn if not recognized but
-        * still continue.
-        */
-
-       /* MXT224 */
-       if (mxt->device_info.family_id == MXT224_FAMILYID) {
-               strcpy(mxt->device_info.family_name, "atmel_mxt224");
-
-               if (mxt->device_info.variant_id == MXT224_CAL_VARIANTID) {
-                       strcpy(mxt->device_info.variant_name, "Calibrated");
-               } else if (mxt->device_info.variant_id ==
-                       MXT224_UNCAL_VARIANTID) {
-                       strcpy(mxt->device_info.variant_name, "Uncalibrated");
-               } else {
-                       dev_err(&client->dev,
-                               "Warning: maXTouch Variant ID [%d] not supported\n",
-                               mxt->device_info.variant_id);
-                       strcpy(mxt->device_info.variant_name, "UNKNOWN");
-                       /* identified = -ENXIO; */
-               }
+       error = mxt_read_reg(client, MXT_OBJECT_NUM, &val);
+       if (error)
+               return error;
+       info->object_num = val;
 
-       /* MXT1386 */
-       } else if (mxt->device_info.family_id == MXT1386_FAMILYID) {
-/* FIH { */
-#if 0
-               strcpy(mxt->device_info.family_name, "mXT1386");
-#else
-               strcpy(mxt->device_info.family_name, "mxt1386");
-#endif
-/* FIH } */
+       return 0;
+}
 
-               if (mxt->device_info.variant_id == MXT1386_CAL_VARIANTID) {
-                       strcpy(mxt->device_info.variant_name, "Calibrated");
-               } else {
-                       dev_err(&client->dev,
-                               "Warning: maXTouch Variant ID [%d] not "
-                               "supported\n",
-                               mxt->device_info.variant_id);
-                       strcpy(mxt->device_info.variant_name, "UNKNOWN");
-                       /* identified = -ENXIO; */
+static int mxt_get_object_table(struct mxt_data *data)
+{
+       int error;
+       int i;
+       u16 reg;
+       u8 reportid = 0;
+       u8 buf[MXT_OBJECT_SIZE];
+
+       for (i = 0; i < data->info.object_num; i++) {
+               struct mxt_object *object = data->object_table + i;
+
+               reg = MXT_OBJECT_START + MXT_OBJECT_SIZE * i;
+               error = mxt_read_object_table(data->client, reg, buf);
+               if (error)
+                       return error;
+
+               object->type = buf[0];
+               object->start_address = (buf[2] << 8) | buf[1];
+               object->size = buf[3];
+               object->instances = buf[4];
+               object->num_report_ids = buf[5];
+
+               if (object->num_report_ids) {
+                       reportid += object->num_report_ids *
+                                       (object->instances + 1);
+                       object->max_reportid = reportid;
                }
-       /* Unknown family ID! */
-       } else {
-               dev_err(&client->dev,
-                       "Warning: maXTouch Family ID [%d] not supported\n",
-                       mxt->device_info.family_id);
-               strcpy(mxt->device_info.family_name, "UNKNOWN");
-               strcpy(mxt->device_info.variant_name, "UNKNOWN");
-               /* identified = -ENXIO; */
        }
 
-       dev_info(
-               &client->dev,
-               "Atmel maXTouch (Family %s (%X), Variant %s (%X)) Firmware "
-               "version [%d.%d] Build %d\n",
-               mxt->device_info.family_name,
-               mxt->device_info.family_id,
-               mxt->device_info.variant_name,
-               mxt->device_info.variant_id,
-               mxt->device_info.major,
-               mxt->device_info.minor,
-               mxt->device_info.build
-       );
-       dev_info(
-               &client->dev,
-               "Atmel maXTouch Configuration "
-               "[X: %d] x [Y: %d]\n",
-               mxt->device_info.x_size,
-               mxt->device_info.y_size
-       );
-       return identified;
+       return 0;
 }
 
-/*
- * Reads the object table from maXTouch chip to get object data like
- * address, size, report id. For Info Block CRC calculation, already read
- * id data is passed to this function too (Info Block consists of the ID
- * block and object table).
- *
- */
-static int __devinit mxt_read_object_table(struct i2c_client *client,
-                                          struct mxt_data *mxt,
-                                          u8 *raw_id_data)
+static int mxt_initialize(struct mxt_data *data)
 {
-       u16     report_id_count;
-       u8      buf[MXT_OBJECT_TABLE_ELEMENT_SIZE];
-       u8      *raw_ib_data;
-       u8      object_type;
-       u16     object_address;
-       u16     object_size;
-       u8      object_instances;
-       u8      object_report_ids;
-       u16     object_info_address;
-       u32     crc;
-       u32     calculated_crc;
-       int     i;
-       int     error;
-
-       u8      object_instance;
-       u8      object_report_id;
-       u8      report_id;
-       int     first_report_id;
-       int     ib_pointer;
-       struct mxt_object *object_table;
-       dev_dbg(&mxt->client->dev, "maXTouch driver reading configuration\n");
-
-       object_table = kzalloc(sizeof(struct mxt_object) *
-                              mxt->device_info.num_objs,
-                              GFP_KERNEL);
-       if (object_table == NULL) {
-               printk(KERN_WARNING "maXTouch: Memory allocation failed!\n");
-               error = -ENOMEM;
-               goto err_object_table_alloc;
+       struct i2c_client *client = data->client;
+       struct mxt_info *info = &data->info;
+       int error;
+       u8 val;
+
+       error = mxt_get_info(data);
+       if (error)
+               return error;
+
+       data->object_table = kcalloc(info->object_num,
+                                    sizeof(struct mxt_object),
+                                    GFP_KERNEL);
+       if (!data->object_table) {
+               dev_err(&client->dev, "Failed to allocate memory\n");
+               return -ENOMEM;
        }
 
-       raw_ib_data = kmalloc(MXT_OBJECT_TABLE_ELEMENT_SIZE *
-                       mxt->device_info.num_objs + MXT_ID_BLOCK_SIZE,
-                       GFP_KERNEL);
-       if (raw_ib_data == NULL) {
-               printk(KERN_WARNING "maXTouch: Memory allocation failed!\n");
-               error = -ENOMEM;
-               goto err_ib_alloc;
-       }
+       /* Get object table information */
+       error = mxt_get_object_table(data);
+       if (error)
+               return error;
+
+       /* Check register init values */
+       error = mxt_check_reg_init(data);
+       if (error)
+               return error;
+
+       mxt_handle_pdata(data);
+
+       /* Backup to memory */
+       mxt_write_object(data, MXT_GEN_COMMAND,
+                       MXT_COMMAND_BACKUPNV,
+                       MXT_BACKUP_VALUE);
+       msleep(MXT_BACKUP_TIME);
+
+       /* Soft reset */
+       mxt_write_object(data, MXT_GEN_COMMAND,
+                       MXT_COMMAND_RESET, 1);
+       msleep(MXT_RESET_TIME);
+
+       /* Update matrix size at info struct */
+       error = mxt_read_reg(client, MXT_MATRIX_X_SIZE, &val);
+       if (error)
+               return error;
+       info->matrix_xsize = val;
+
+       error = mxt_read_reg(client, MXT_MATRIX_Y_SIZE, &val);
+       if (error)
+               return error;
+       info->matrix_ysize = val;
+
+       dev_info(&client->dev,
+                       "Family ID: %d Variant ID: %d Version: %d Build: %d\n",
+                       info->family_id, info->variant_id, info->version,
+                       info->build);
+
+       dev_info(&client->dev,
+                       "Matrix X Size: %d Matrix Y Size: %d Object Num: %d\n",
+                       info->matrix_xsize, info->matrix_ysize,
+                       info->object_num);
 
-       /* Copy the ID data for CRC calculation. */
-       memcpy(raw_ib_data, raw_id_data, MXT_ID_BLOCK_SIZE);
-       ib_pointer = MXT_ID_BLOCK_SIZE;
+       return 0;
+}
 
-       mxt->object_table = object_table;
+static void mxt_calc_resolution(struct mxt_data *data)
+{
+       unsigned int max_x = data->pdata->x_size - 1;
+       unsigned int max_y = data->pdata->y_size - 1;
 
-       dev_dbg(&mxt->client->dev, "maXTouch driver Memory allocated\n");
+       if (data->pdata->orient & MXT_XY_SWITCH) {
+               data->max_x = max_y;
+               data->max_y = max_x;
+       } else {
+               data->max_x = max_x;
+               data->max_y = max_y;
+       }
+}
 
-       object_info_address = MXT_ADDR_OBJECT_TABLE;
+static ssize_t mxt_object_show(struct device *dev,
+                                   struct device_attribute *attr, char *buf)
+{
+       struct mxt_data *data = dev_get_drvdata(dev);
+       struct mxt_object *object;
+       int count = 0;
+       int i, j;
+       int error;
+       u8 val;
 
-       report_id_count = 0;
-       for (i = 0; i < mxt->device_info.num_objs; i++) {
-               dev_dbg(&mxt->client->dev, "Reading maXTouch at [0x%04x]: ",
-                         object_info_address);
+       for (i = 0; i < data->info.object_num; i++) {
+               object = data->object_table + i;
 
-               error = mxt_read_block(client, object_info_address,
-                                      MXT_OBJECT_TABLE_ELEMENT_SIZE, buf);
+               count += sprintf(buf + count,
+                               "Object Table Element %d(Type %d)\n",
+                               i + 1, object->type);
 
-               if (error < 0) {
-                       mxt->read_fail_counter++;
-                       dev_err(&client->dev,
-                               "maXTouch Object %d could not be read\n", i);
-                       error = -EIO;
-                       goto err_object_read;
+               if (!mxt_object_readable(object->type)) {
+                       count += sprintf(buf + count, "\n");
+                       continue;
                }
 
-               memcpy(raw_ib_data + ib_pointer, buf,
-                      MXT_OBJECT_TABLE_ELEMENT_SIZE);
-               ib_pointer += MXT_OBJECT_TABLE_ELEMENT_SIZE;
-
-               object_type       =  buf[0];
-               object_address    = (buf[2] << 8) + buf[1];
-               object_size       =  buf[3] + 1;
-               object_instances  =  buf[4] + 1;
-               object_report_ids =  buf[5];
-               dev_dbg(&mxt->client->dev, "Type=%03d, Address=0x%04x, "
-                         "Size=0x%02x, %d instances, %d report id's\n",
-                         object_type,
-                         object_address,
-                         object_size,
-                         object_instances,
-                         object_report_ids
-               );
-
-               /* TODO: check whether object is known and supported? */
-
-               /* Save frequently needed info. */
-               if (object_type == MXT_GEN_MESSAGEPROCESSOR_T5) {
-                       mxt->msg_proc_addr = object_address;
-                       mxt->message_size = object_size;
-               }
+               for (j = 0; j < object->size + 1; j++) {
+                       error = mxt_read_object(data,
+                                               object->type, j, &val);
+                       if (error)
+                               return error;
 
-               object_table[i].type            = object_type;
-               object_table[i].chip_addr       = object_address;
-               object_table[i].size            = object_size;
-               object_table[i].instances       = object_instances;
-               object_table[i].num_report_ids  = object_report_ids;
-               report_id_count += object_instances * object_report_ids;
+                       count += sprintf(buf + count,
+                                       "  Byte %d: 0x%x (%d)\n", j, val, val);
+               }
 
-               object_info_address += MXT_OBJECT_TABLE_ELEMENT_SIZE;
+               count += sprintf(buf + count, "\n");
        }
 
-       mxt->rid_map =
-               kzalloc(sizeof(struct report_id_map) * (report_id_count + 1),
-                       /* allocate for report_id 0, even if not used */
-                       GFP_KERNEL);
-       if (mxt->rid_map == NULL) {
-               printk(KERN_WARNING "maXTouch: Can't allocate memory!\n");
-               error = -ENOMEM;
-               goto err_rid_map_alloc;
-       }
+       return count;
+}
 
-       mxt->message_buf = kmalloc(256, GFP_KERNEL);
-       if (mxt->message_buf == NULL) {
-               printk(KERN_WARNING "Error allocating memory\n");
-               error = -ENOMEM;
-               goto err_msg_alloc3;
-       }
+static int mxt_load_fw(struct device *dev, const char *fn)
+{
+       struct mxt_data *data = dev_get_drvdata(dev);
+       struct i2c_client *client = data->client;
+       const struct firmware *fw = NULL;
+       unsigned int frame_size;
+       unsigned int pos = 0;
+       int ret;
 
-       mxt->report_id_count = report_id_count;
-       if (report_id_count > 254) {    /* 0 & 255 are reserved */
-                       dev_err(&client->dev,
-                               "Too many maXTouch report id's [%d]\n",
-                               report_id_count);
-                       error = -ENXIO;
-                       goto err_max_rid;
+       ret = request_firmware(&fw, fn, dev);
+       if (ret) {
+               dev_err(dev, "Unable to open firmware %s\n", fn);
+               return ret;
        }
 
-       /* Create a mapping from report id to object type */
-       report_id = 1; /* Start from 1, 0 is reserved. */
-
-       /* Create table associating report id's with objects & instances */
-       for (i = 0; i < mxt->device_info.num_objs; i++) {
-               for (object_instance = 0;
-                               object_instance < object_table[i].instances;
-                               object_instance++) {
-                       first_report_id = report_id;
-                       for (object_report_id = 0;
-                            object_report_id < object_table[i].num_report_ids;
-                            object_report_id++) {
-                               mxt->rid_map[report_id].object =
-                                       object_table[i].type;
-                               mxt->rid_map[report_id].instance =
-                                       object_instance;
-                               mxt->rid_map[report_id].first_rid =
-                                       first_report_id;
-                               report_id++;
-                       }
-               }
-       }
+       /* Change to the bootloader mode */
+       mxt_write_object(data, MXT_GEN_COMMAND,
+                       MXT_COMMAND_RESET, MXT_BOOT_VALUE);
+       msleep(MXT_RESET_TIME);
 
-       /* Read 3 byte CRC */
-       error = mxt_read_block(client, object_info_address, 3, buf);
-       if (error < 0) {
-               mxt->read_fail_counter++;
-               dev_err(&client->dev, "Error reading CRC\n");
-       }
+       /* Change to slave address of bootloader */
+       if (client->addr == MXT_APP_LOW)
+               client->addr = MXT_BOOT_LOW;
+       else
+               client->addr = MXT_BOOT_HIGH;
 
-       crc = (buf[2] << 16) | (buf[1] << 8) | buf[0];
+       ret = mxt_check_bootloader(client, MXT_WAITING_BOOTLOAD_CMD);
+       if (ret)
+               goto out;
 
-       if (calculate_infoblock_crc(&calculated_crc, raw_ib_data,
-                                   ib_pointer)) {
-               printk(KERN_WARNING "Error while calculating CRC!\n");
-               calculated_crc = 0;
-       }
-       kfree(raw_ib_data);
+       /* Unlock bootloader */
+       mxt_unlock_bootloader(client);
 
-       dev_dbg(&mxt->client->dev, "\nReported info block CRC = 0x%6X\n", crc);
-       dev_dbg(&mxt->client->dev, "Calculated info block CRC = 0x%6X\n\n",
-                      calculated_crc);
+       while (pos < fw->size) {
+               ret = mxt_check_bootloader(client,
+                                               MXT_WAITING_FRAME_DATA);
+               if (ret)
+                       goto out;
 
-       if (crc == calculated_crc) {
-               mxt->info_block_crc = crc;
-       } else {
-               mxt->info_block_crc = 0;
-               pr_err("maXTouch: Info block CRC invalid!\n");
-       }
+               frame_size = ((*(fw->data + pos) << 8) | *(fw->data + pos + 1));
 
-       if (debug >= DEBUG_VERBOSE) {
-
-               dev_info(&client->dev, "maXTouch: %d Objects\n",
-                               mxt->device_info.num_objs);
-
-               for (i = 0; i < mxt->device_info.num_objs; i++) {
-                       dev_info(&client->dev, "Type:\t\t\t[%d]: %s\n",
-                                object_table[i].type,
-                                obj_typ_name[object_table[i].type]);
-                       dev_info(&client->dev, "\tAddress:\t0x%04X\n",
-                               object_table[i].chip_addr);
-                       dev_info(&client->dev, "\tSize:\t\t%d Bytes\n",
-                               object_table[i].size);
-                       dev_info(&client->dev, "\tInstances:\t%d\n",
-                               object_table[i].instances);
-                       dev_info(&client->dev, "\tReport Id's:\t%d\n",
-                               object_table[i].num_report_ids);
-               }
+               /* We should add 2 at frame size as the the firmware data is not
+                * included the CRC bytes.
+                */
+               frame_size += 2;
+
+               /* Write one frame to device */
+               mxt_fw_write(client, fw->data + pos, frame_size);
+
+               ret = mxt_check_bootloader(client,
+                                               MXT_FRAME_CRC_PASS);
+               if (ret)
+                       goto out;
+
+               pos += frame_size;
+
+               dev_dbg(dev, "Updated %d bytes / %zd bytes\n", pos, fw->size);
        }
 
-       return 0;
-err_msg_alloc3:
-       kfree(mxt->message_buf);
-err_max_rid:
-       kfree(mxt->rid_map);
-err_rid_map_alloc:
-err_object_read:
-       kfree(raw_ib_data);
-err_ib_alloc:
-       kfree(object_table);
-err_object_table_alloc:
-       return error;
-}
+out:
+       release_firmware(fw);
 
+       /* Change to slave address of application */
+       if (client->addr == MXT_BOOT_LOW)
+               client->addr = MXT_APP_LOW;
+       else
+               client->addr = MXT_APP_HIGH;
 
-static u8 mxt_valid_interrupt_dummy(void)
-{
-       return 1;
+       return ret;
 }
 
-static int __devinit mxt_probe(struct i2c_client *client,
-                              const struct i2c_device_id *id)
+static ssize_t mxt_update_fw_store(struct device *dev,
+                                       struct device_attribute *attr,
+                                       const char *buf, size_t count)
 {
-       struct mxt_data          *mxt;
-       struct mxt_platform_data *pdata;
-       struct input_dev         *touch_input;
-       struct input_dev         *key_input;
-       u8 *id_data;
-       int error, gpio_intr, i;
-       u16 base_addr;
-
-       pr_info("atmel_mxt224: mxt_probe\n");
-
-       if (client == NULL) {
-               pr_debug("maXTouch: client == NULL\n");
-               return  -EINVAL;
-       } else if (client->adapter == NULL) {
-               pr_debug("maXTouch: client->adapter == NULL\n");
-               return  -EINVAL;
-       } else if (&client->dev == NULL) {
-               pr_debug("maXTouch: client->dev == NULL\n");
-               return  -EINVAL;
-       } else if (&client->adapter->dev == NULL) {
-               pr_debug("maXTouch: client->adapter->dev == NULL\n");
-               return  -EINVAL;
-       } else if (id == NULL) {
-               pr_debug("maXTouch: id == NULL\n");
-               return  -EINVAL;
-       }
+       struct mxt_data *data = dev_get_drvdata(dev);
+       int error;
 
-       dev_dbg(&client->dev, "maXTouch driver v. %s\n", DRIVER_VERSION);
-       dev_dbg(&client->dev, "\t \"%s\"\n", client->name);
-       dev_dbg(&client->dev, "\taddr:\t0x%04x\n", client->addr);
-       dev_dbg(&client->dev, "\tirq:\t%d\n", client->irq);
-       dev_dbg(&client->dev, "\tflags:\t0x%04x\n", client->flags);
-       dev_dbg(&client->dev, "\tadapter:\"%s\"\n", client->adapter->name);
-       dev_dbg(&client->dev, "\tdevice:\t\"%s\"\n", client->dev.init_name);
-
-       /* Check if the I2C bus supports BYTE transfer */
-       error = i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE);
-       if (!error) {
-               dev_err(&client->dev, "%s adapter not supported\n",
-                               dev_driver_string(&client->adapter->dev));
-               return -ENODEV;
-       }
+       disable_irq(data->irq);
 
-       dev_dbg(&client->dev, "maXTouch driver functionality OK\n");
+       error = mxt_load_fw(dev, MXT_FW_NAME);
+       if (error) {
+               dev_err(dev, "The firmware update failed(%d)\n", error);
+               count = error;
+       } else {
+               dev_dbg(dev, "The firmware update succeeded\n");
 
-       /* Allocate structure - we need it to identify device */
-       mxt = kzalloc(sizeof(struct mxt_data), GFP_KERNEL);
-       if (mxt == NULL) {
-               dev_err(&client->dev, "insufficient memory\n");
-               error = -ENOMEM;
-               goto err_mxt_alloc;
-       }
+               /* Wait for reset */
+               msleep(MXT_FWRESET_TIME);
 
-       id_data = kmalloc(MXT_ID_BLOCK_SIZE, GFP_KERNEL);
-       if (id_data == NULL) {
-               dev_err(&client->dev, "insufficient memory\n");
-               error = -ENOMEM;
-               goto err_id_alloc;
-       }
+               kfree(data->object_table);
+               data->object_table = NULL;
 
-       touch_input = input_allocate_device();
-       if (!touch_input) {
-               dev_err(&client->dev, "error allocating touch input device\n");
-               error = -ENOMEM;
-               goto err_touch_input_dev_alloc;
+               mxt_initialize(data);
        }
 
-       key_input = input_allocate_device();
-       if (!key_input) {
-               dev_err(&client->dev, "error allocating key input device");
-               error = -ENOMEM;
-               goto err_key_input_dev_alloc;
-       }
+       enable_irq(data->irq);
 
-       /* Initialize Platform data */
-       pdata = client->dev.platform_data;
-       if (pdata == NULL) {
-               dev_err(&client->dev, "platform data is required!\n");
-               error = -EINVAL;
-               goto err_pdata;
-       }
-       if (debug >= DEBUG_TRACE)
-               printk(KERN_INFO "Platform OK: pdata = 0x%08x\n",
-                      (unsigned int) pdata);
-
-       mutex_init(&mxt->dev_mutex);
-       mxt->read_fail_counter = 0;
-       mxt->message_counter   = 0;
-       mxt->max_x_val         = pdata->max_x;
-       mxt->max_y_val         = pdata->max_y;
-       mxt->orientation       = pdata->orientation;
-       mxt->mxt_intr_gpio     = pdata->irq;
-       mxt->mxt_reset_gpio    = pdata->reset;
-
-       error = gpio_request(mxt->mxt_intr_gpio, 0);
-       if (error < 0)
-               pr_err("Failed to request GPIO%d (MaxTouch-interrupt) error=%d\n",
-                       mxt->mxt_intr_gpio, error);
-
-       error = gpio_direction_input(mxt->mxt_intr_gpio);
-       if (error) {
-               pr_err("Failed to set interrupt direction, error=%d\n", error);
-               gpio_free(mxt->mxt_intr_gpio);
-       }
+       error = mxt_make_highchg(data);
+       if (error)
+               return error;
 
-       error = gpio_request(mxt->mxt_reset_gpio, "MaxTouch-reset");
-       if (error < 0)
-               pr_err("Failed to request GPIO%d (MaxTouch-reset) error=%d\n",
-                       mxt->mxt_reset_gpio, error);
+       return count;
+}
 
-       error = gpio_direction_output(mxt->mxt_reset_gpio, 1);
-       if (error) {
-               pr_info("Failed to set reset direction, error=%d\n", error);
-               gpio_free(mxt->mxt_reset_gpio);
-       }
+static DEVICE_ATTR(object, 0444, mxt_object_show, NULL);
+static DEVICE_ATTR(update_fw, 0664, NULL, mxt_update_fw_store);
 
-       /* maXTouch wants 40mSec minimum after reset to get organized */
-       gpio_set_value(mxt->mxt_reset_gpio, 1);
-       msleep(40);
-/* FIH { */
-/* Wait for interrupt and delay for unstable reset status */
-#if 1
-{
-       int i = 0;
+static struct attribute *mxt_attrs[] = {
+       &dev_attr_object.attr,
+       &dev_attr_update_fw.attr,
+       NULL
+};
 
-       for (i = 0; i < 10; i++) {
-               printk(KERN_INFO "Polling GPIO%d (MaxTouch-intr). retry=%d\n", mxt->mxt_intr_gpio, i);
-               if (gpio_get_value(mxt->mxt_intr_gpio) == LOW)
-                       break;
-               msleep(50);
-       }
+static const struct attribute_group mxt_attr_group = {
+       .attrs = mxt_attrs,
+};
 
-       /* msleep(10000); */
+static void mxt_start(struct mxt_data *data)
+{
+       /* Touch enable */
+       mxt_write_object(data,
+                       MXT_TOUCH_MULTI, MXT_TOUCH_CTRL, 0x83);
 }
-#endif
-/* FIH } */
-
-       /* Get data that is defined in board specific code. */
-       mxt->init_hw = pdata->init_platform_hw;
-       mxt->exit_hw = pdata->exit_platform_hw;
-       mxt->read_chg = pdata->read_chg;
 
-       if (pdata->valid_interrupt != NULL)
-               mxt->valid_interrupt = pdata->valid_interrupt;
-       else
-               mxt->valid_interrupt = mxt_valid_interrupt_dummy;
+static void mxt_stop(struct mxt_data *data)
+{
+       /* Touch disable */
+       mxt_write_object(data,
+                       MXT_TOUCH_MULTI, MXT_TOUCH_CTRL, 0);
+}
 
-       if (mxt->init_hw != NULL)
-               mxt->init_hw();
+static int mxt_input_open(struct input_dev *dev)
+{
+       struct mxt_data *data = input_get_drvdata(dev);
 
-       if (debug >= DEBUG_TRACE)
-               printk(KERN_INFO "maXTouch driver identifying chip\n");
+       mxt_start(data);
 
-       if (mxt_identify(client, mxt, id_data) < 0) {
-               dev_err(&client->dev, "Chip could not be identified\n");
-               error = -ENODEV;
-               goto err_identify;
-       }
-       /* Chip is valid and active. */
-       if (debug >= DEBUG_TRACE)
-               printk(KERN_INFO "maXTouch driver allocating input device\n");
-
-       mxt->client      = client;
-       mxt->touch_input = touch_input;
-       mxt->key_input   = key_input;
-
-       snprintf(mxt->touch_phys_name, sizeof(mxt->touch_phys_name),
-                "%s/input0", dev_name(&client->dev));
-       snprintf(mxt->key_phys_name, sizeof(mxt->key_phys_name),
-                "%s/input1", dev_name(&client->dev));
-
-       /* Touch input parameter */
-       touch_input->name       = "mxt224_touchscreen_0";
-       touch_input->phys       = mxt->touch_phys_name;
-       touch_input->id.bustype = BUS_I2C;
-       touch_input->dev.parent = &client->dev;
-
-       /* Key input parameter */
-       key_input->name         = "mxt224_key_0";
-       key_input->phys         = mxt->key_phys_name;
-
-       /* Multitouch */
-       input_set_abs_params(touch_input, ABS_MT_POSITION_X, TS_MIN_X, TS_MAX_X, 0, 0);
-       input_set_abs_params(touch_input, ABS_MT_POSITION_Y, TS_MIN_Y, TS_MAX_Y, 0, 0);
-       input_set_abs_params(touch_input, ABS_MT_TOUCH_MAJOR, 0, MXT_MAX_TOUCH_SIZE,
-                            0, 0);
-       input_set_abs_params(touch_input, ABS_MT_TRACKING_ID, 0,
-                            MXT_MAX_NUM_TOUCHES, 0, 0);
-
-       __set_bit(EV_ABS, touch_input->evbit);
-       __set_bit(EV_SYN, touch_input->evbit);
-
-       /* Function key*/
-       __set_bit(EV_KEY,     key_input->evbit);
-       __set_bit(KEY_HOME,   key_input->keybit);
-       __set_bit(KEY_MENU,   key_input->keybit);
-       __set_bit(KEY_BACK,   key_input->keybit);
-       __set_bit(KEY_SEARCH, key_input->keybit);
-
-       i2c_set_clientdata(client, mxt);
-       input_set_drvdata(touch_input, mxt);
-       input_set_drvdata(key_input, mxt);
-
-       error = input_register_device(mxt->touch_input);
-       if (error < 0) {
-               dev_err(&client->dev, "Failed to register touch input device\n");
-               goto err_register_touch_device;
-       }
+       return 0;
+}
 
-       error = input_register_device(mxt->key_input);
-       if (error < 0) {
-               dev_err(&client->dev, "Failed to register key input device in mxt224\n");
-               goto err_register_key_device;
-       }
+static void mxt_input_close(struct input_dev *dev)
+{
+       struct mxt_data *data = input_get_drvdata(dev);
 
-       mxt->message_buf = NULL;
-       error = mxt_read_object_table(client, mxt, id_data);
-       if (error < 0)
-               goto err_read_ot;
-
-       BackupNVM(mxt);
-       msleep(40);
-
-       mxt->prev_key = 0;
-
-       if (pdata->numtouch)
-               mxt->numtouch = pdata->numtouch;
-       mxt->irq                 = gpio_to_irq(mxt->mxt_intr_gpio);
-       mxt->valid_irq_counter   = 0;
-       mxt->invalid_irq_counter = 0;
-       mxt->irq_counter         = 0;
-
-       if (mxt->irq) {
-               error = request_threaded_irq(mxt->irq, NULL,
-                                   mxt_irq_handler,
-                                   IRQF_TRIGGER_FALLING,
-                                   client->dev.driver->name,
-                                   mxt);
-               if (error < 0) {
-                       dev_err(&client->dev,
-                               "failed to allocate irq %d\n", mxt->irq);
-                       goto err_irq;
-               }
-       }
+       mxt_stop(data);
+}
 
-       mutex_lock(&mxt->dev_mutex);
-       gpio_intr = gpio_get_value(mxt->mxt_intr_gpio);
-       while (gpio_intr == 0) {
-               for (i = 1; i < I2C_RETRY_COUNT; i++) {
-                       error = mxt_read_block(mxt->client, mxt->msg_proc_addr,
-                                       mxt->message_size, mxt->message_buf);
-                       if (error >= 0)
-                               break;
-                       dev_info(&client->dev, "flush the buffer failed in the probe function\n");
+static int __devinit mxt_probe(struct i2c_client *client,
+               const struct i2c_device_id *id)
+{
+       const struct mxt_platform_data *pdata = client->dev.platform_data;
+       struct mxt_data *data;
+       struct input_dev *input_dev;
+       int error;
 
-               }
-               gpio_intr = gpio_get_value(mxt->mxt_intr_gpio);
+       if (!pdata)
+               return -EINVAL;
 
-       }
-       mutex_unlock(&mxt->dev_mutex);
-
-       /* Store the number of multi-touches allowed, default was 0. */
-       base_addr = get_object_address(MXT_TOUCH_MULTITOUCHSCREEN_T9,
-                       0, mxt->object_table, mxt->device_info.num_objs);
-       base_addr += MXT_ADR_T9_NUMTOUCH;
-
-       error = mxt_write_byte(mxt->client, base_addr, mxt->numtouch);
-       if (error < 0) {
-               dev_err(&client->dev,
-                       "Multi-touch init failure, T9 object, error = %d\n",
-                       error);
-               goto err_irq;
+       data = kzalloc(sizeof(struct mxt_data), GFP_KERNEL);
+       input_dev = input_allocate_device();
+       if (!data || !input_dev) {
+               dev_err(&client->dev, "Failed to allocate memory\n");
+               error = -ENOMEM;
+               goto err_free_mem;
        }
 
-       kfree(id_data);
+       input_dev->name = "Atmel maXTouch Touchscreen";
+       input_dev->id.bustype = BUS_I2C;
+       input_dev->dev.parent = &client->dev;
+       input_dev->open = mxt_input_open;
+       input_dev->close = mxt_input_close;
+
+       data->client = client;
+       data->input_dev = input_dev;
+       data->pdata = pdata;
+       data->irq = client->irq;
+
+       mxt_calc_resolution(data);
+
+       __set_bit(EV_ABS, input_dev->evbit);
+       __set_bit(EV_KEY, input_dev->evbit);
+       __set_bit(BTN_TOUCH, input_dev->keybit);
+
+       /* For single touch */
+       input_set_abs_params(input_dev, ABS_X,
+                            0, data->max_x, 0, 0);
+       input_set_abs_params(input_dev, ABS_Y,
+                            0, data->max_y, 0, 0);
+
+       /* For multi touch */
+       input_mt_init_slots(input_dev, MXT_MAX_FINGER);
+       input_set_abs_params(input_dev, ABS_MT_TOUCH_MAJOR,
+                            0, MXT_MAX_AREA, 0, 0);
+       input_set_abs_params(input_dev, ABS_MT_POSITION_X,
+                            0, data->max_x, 0, 0);
+       input_set_abs_params(input_dev, ABS_MT_POSITION_Y,
+                            0, data->max_y, 0, 0);
+
+       input_set_drvdata(input_dev, data);
+       i2c_set_clientdata(client, data);
+
+       error = mxt_initialize(data);
+       if (error)
+               goto err_free_object;
+
+       error = request_threaded_irq(client->irq, NULL, mxt_interrupt,
+                       pdata->irqflags, client->dev.driver->name, data);
+       if (error) {
+               dev_err(&client->dev, "Failed to register interrupt\n");
+               goto err_free_object;
+       }
 
-#ifdef CONFIG_DEBUG_FS
-       error = intel_mid_add_debugfs();
-       if (error < 0)
-               printk(KERN_ERR "failed to initialize  intel_mid debugfs\n");
+       error = mxt_make_highchg(data);
+       if (error)
+               goto err_free_irq;
 
-#endif
+       error = input_register_device(input_dev);
+       if (error)
+               goto err_free_irq;
 
-#ifdef CONFIG_HAS_EARLYSUSPEND
-       mxt->suspended  = false;
-       mxt->T7[0]      = 32;
-       mxt->T7[1]      = 15;
-       mxt->T7[2]      = 50;
-       mxt->es.level   = EARLY_SUSPEND_LEVEL_BLANK_SCREEN + 1;
-       mxt->es.suspend = mxt_early_suspend;
-       mxt->es.resume  = mxt_late_resume;
-       register_early_suspend(&mxt->es);
-       mxt_es          = mxt;
-#endif
+       error = sysfs_create_group(&client->dev.kobj, &mxt_attr_group);
+       if (error)
+               goto err_unregister_device;
 
        return 0;
 
-err_irq:
-       kfree(mxt->rid_map);
-       kfree(mxt->object_table);
-err_read_ot:
-err_register_key_device:
-err_register_touch_device:
-err_identify:
-err_pdata:
-       input_free_device(key_input);
-err_key_input_dev_alloc:
-       input_free_device(touch_input);
-err_touch_input_dev_alloc:
-       kfree(id_data);
-err_id_alloc:
-       if (mxt->exit_hw != NULL)
-               mxt->exit_hw();
-       kfree(mxt);
-err_mxt_alloc:
+err_unregister_device:
+       input_unregister_device(input_dev);
+       input_dev = NULL;
+err_free_irq:
+       free_irq(client->irq, data);
+err_free_object:
+       kfree(data->object_table);
+err_free_mem:
+       input_free_device(input_dev);
+       kfree(data);
        return error;
 }
 
 static int __devexit mxt_remove(struct i2c_client *client)
 {
-       struct mxt_data *mxt;
-
-       mxt = i2c_get_clientdata(client);
-
-       if (mxt != NULL) {
-               if (mxt->exit_hw != NULL)
-                       mxt->exit_hw();
-
-               if (mxt->irq)
-                       free_irq(mxt->irq, mxt);
-#ifdef CONFIG_HAS_EARLYSUSPEND
-               unregister_early_suspend(&mxt->es);
-#endif
-               input_unregister_device(mxt->key_input);
-               input_unregister_device(mxt->touch_input);
-               kfree(mxt->rid_map);
-               kfree(mxt->object_table);
-               kfree(mxt->message_buf);
-       }
-       kfree(mxt);
+       struct mxt_data *data = i2c_get_clientdata(client);
 
-       if (debug >= DEBUG_TRACE)
-               dev_info(&client->dev, "Touchscreen unregistered\n");
+       sysfs_remove_group(&client->dev.kobj, &mxt_attr_group);
+       free_irq(data->irq, data);
+       input_unregister_device(data->input_dev);
+       kfree(data->object_table);
+       kfree(data);
 
        return 0;
 }
 
-#if defined(CONFIG_PM)
+#ifdef CONFIG_PM
 static int mxt_suspend(struct device *dev)
 {
-       struct mxt_data *mxt = dev_get_drvdata(dev);
-
-       dev_dbg(dev, "In function %s", __func__);
-
-       if (device_may_wakeup(dev))
-               enable_irq_wake(mxt->irq);
-
-       return 0;
-}
+       struct i2c_client *client = to_i2c_client(dev);
+       struct mxt_data *data = i2c_get_clientdata(client);
+       struct input_dev *input_dev = data->input_dev;
 
-static int mxt_resume(struct device *dev)
-{
-       struct mxt_data *mxt = dev_get_drvdata(dev);
+       mutex_lock(&input_dev->mutex);
 
-       dev_dbg(dev, "In function %s", __func__);
+       if (input_dev->users)
+               mxt_stop(data);
 
-       if (device_may_wakeup(dev))
-               disable_irq_wake(mxt->irq);
+       mutex_unlock(&input_dev->mutex);
 
        return 0;
 }
-#else
-#define mxt_suspend NULL
-#define mxt_resume NULL
-#endif
 
-#ifdef CONFIG_HAS_EARLYSUSPEND
-void mxt_early_suspend(struct early_suspend *h)
+static int mxt_resume(struct device *dev)
 {
-       u16 pwcfg_addr;
-       u8 buf[3] = {0, 0, 0};
-       u8 err;
+       struct i2c_client *client = to_i2c_client(dev);
+       struct mxt_data *data = i2c_get_clientdata(client);
+       struct input_dev *input_dev = data->input_dev;
 
-       disable_irq(mxt_es->irq);
+       /* Soft reset */
+       mxt_write_object(data, MXT_GEN_COMMAND,
+                       MXT_COMMAND_RESET, 1);
 
-       mutex_lock(&mxt_es->dev_mutex);
+       msleep(MXT_RESET_TIME);
 
+       mutex_lock(&input_dev->mutex);
 
-       pwcfg_addr = get_object_address(MXT_GEN_POWERCONFIG_T7,
-                               0, mxt_es->object_table,
-                               mxt_es->device_info.num_objs);
-       mxt_read_block(mxt_es->client, pwcfg_addr, 3, mxt_es->T7);
-       err = mxt_write_block(mxt_es->client, pwcfg_addr, 3, buf);
-       if (err > 0)
-               dev_info(&mxt_es->client->dev, "Driver enter deep sleep mode.");
-       else
-               dev_info(&mxt_es->client->dev,
-                        "Driver can't enter deep sleep mode [%d].", err);
-       /* clear touch state when suspending */
-       memset(stored_size, 0, mxt_es->numtouch * sizeof(stored_size[0]));
-       report_mt(mxt_es);
+       if (input_dev->users)
+               mxt_start(data);
 
-       mxt_es->suspended = true;
+       mutex_unlock(&input_dev->mutex);
 
-       mutex_unlock(&mxt_es->dev_mutex);
+       return 0;
 }
 
-void mxt_late_resume(struct early_suspend *h)
-{
-       int gpio_intr;
-       u16 pwcfg_addr;
-       u8 err;
-       u8 i;
-
-       enable_irq(mxt_es->irq);
-       mutex_lock(&mxt_es->dev_mutex);
-
-       pwcfg_addr = get_object_address(MXT_GEN_POWERCONFIG_T7,
-                       0,
-                       mxt_es->object_table,
-                       mxt_es->device_info.num_objs);
-/* FIH { */
-#if 0
-       err = mxt_write_block(mxt_es->client, pwcfg_addr, 3, mxt_es->T7);
-#else
-       for (i = 0; i < I2C_RETRY_COUNT; i++) {
-               err = mxt_write_block(mxt_es->client, pwcfg_addr, 3, mxt_es->T7);
-               if (err == 3)
-                       break;
-               msleep(100);
-       }
-#endif
-/* FIH } */
-       if (err > 0)
-               dev_info(&mxt_es->client->dev, "resume from early suspend");
-       else
-               dev_info(&mxt_es->client->dev, "fail to late resume");
-
-       msleep(25);
-       gpio_intr = gpio_get_value(mxt_es->mxt_intr_gpio);
-       while (gpio_intr == 0) {
-               for (i = 1; i < I2C_RETRY_COUNT; i++) {
-                       err = mxt_read_block(mxt_es->client,
-                                               mxt_es->msg_proc_addr,
-                                               mxt_es->message_size,
-                                               mxt_es->message_buf);
-                       if (err >= 0)
-                               break;
-                       dev_info(&mxt_es->client->dev, "flush the buffer failed in the resume function\n");
-
-               }
-               gpio_intr = gpio_get_value(mxt_es->mxt_intr_gpio);
-
-       }
-       mxt_calibrate(mxt_es->client);
-       mxt_es->suspended = false;
-       mutex_unlock(&mxt_es->dev_mutex);
-
-}
-#endif
-
 static const struct dev_pm_ops mxt_pm_ops = {
-       .suspend = mxt_suspend,
-       .resume  = mxt_resume,
+       .suspend        = mxt_suspend,
+       .resume         = mxt_resume,
 };
+#endif
 
-static const struct i2c_device_id mxt_idtable[] = {
-       {TOUCH_DEVICE_NAME, 1,},
+static const struct i2c_device_id mxt_id[] = {
+       { "qt602240_ts", 0 },
+       { "atmel_mxt_ts", 0 },
+       { "mXT224", 0 },
        { }
 };
-
-MODULE_DEVICE_TABLE(i2c, mxt_idtable);
+MODULE_DEVICE_TABLE(i2c, mxt_id);
 
 static struct i2c_driver mxt_driver = {
        .driver = {
-               .name   = TOUCH_DEVICE_NAME,
-               .owner  = THIS_MODULE,
+               .name   = "atmel_mxt_ts",
+               .owner  = THIS_MODULE,
 #ifdef CONFIG_PM
-               .pm = &mxt_pm_ops,
+               .pm     = &mxt_pm_ops,
 #endif
        },
-
-       .id_table       = mxt_idtable,
        .probe          = mxt_probe,
        .remove         = __devexit_p(mxt_remove),
+       .id_table       = mxt_id,
 };
 
 static int __init mxt_init(void)
 {
-       int err;
-
-       err = i2c_add_driver(&mxt_driver);
-       if (err) {
-               printk(KERN_WARNING "Adding maXTouch driver(Here for mxt224) failed "
-                      "(errno = %d)\n", err);
-       } else {
-               printk(KERN_INFO "Successfully added driver %s\n",
-                         mxt_driver.driver.name);
-       }
-       return err;
+       return i2c_add_driver(&mxt_driver);
 }
 
-static void __exit mxt_cleanup(void)
+static void __exit mxt_exit(void)
 {
        i2c_del_driver(&mxt_driver);
 }
 
+module_init(mxt_init);
+module_exit(mxt_exit);
 
-late_initcall(mxt_init);
-module_exit(mxt_cleanup);
-
-MODULE_AUTHOR("Iiro Valkonen");
-MODULE_DESCRIPTION("Driver for Atmel maXTouch Touchscreen Controller");
+/* Module information */
+MODULE_AUTHOR("Joonyoung Shim <jy0922.shim@samsung.com>");
+MODULE_DESCRIPTION("Atmel maXTouch Touchscreen driver");
 MODULE_LICENSE("GPL");
-
-
-#ifdef CONFIG_DEBUG_FS
-/******************************************************************************
-debugfs for touch driver, contain four debug files:
-
-1.sread
-       can be read and write.
-       write: set the address of a single register to be accessed;
-       read: return the content of the register.
-2.swrite
-       can be write only.
-       write: set the value of the corresponding register, and the register's
-       address is determined by 'write' operation of 'single_read' file.
-3.sread_offset
-       can be write only
-       write:set the offset of the register
-*********************************************************************************/
-
-
-static int intel_mid_single_read_get(void *data, u64 *val)
-{
-       int ret, gpio_intr, gpio_rst;
-       u16 addr;
-       addr = get_object_address(reg_add,
-                       0,
-                       mxt_es->object_table,
-                       mxt_es->device_info.num_objs)+reg_add_offset;
-
-       ret = mxt_read_block(mxt_es->client, addr, 1, (u8 *)val);
-       if (ret < 0)
-               printk(KERN_ERR "intel_touch debugfs read_set err add=0x%x\n", reg_add);
-       gpio_intr = gpio_get_value(mxt_es->mxt_intr_gpio);
-       gpio_rst = gpio_get_value(mxt_es->mxt_reset_gpio);
-       printk("touch interrupt value = %d,gpio_rst = %d\n", gpio_intr, gpio_rst);
-       return 0;
-}
-
-static int intel_mid_single_read_set(void *data, u64 val)
-{
-       reg_add = (u8)val;
-       return 0;
-}
-
-DEFINE_SIMPLE_ATTRIBUTE(intel_mid_single_read_reg_fops,
-                               intel_mid_single_read_get,
-                               intel_mid_single_read_set, "0x%02llx\n");
-
-static int intel_mid_single_read_set_offset(void *data, u64 val)
-{
-       reg_add_offset = (u8)val;
-       return 0;
-}
-
-DEFINE_SIMPLE_ATTRIBUTE(intel_mid_single_read_reg_offset_fops,
-                               NULL, intel_mid_single_read_set_offset,
-                               "0x%02llx\n");
-
-static int intel_mid_single_write_set(void *data, u64 val)
-{
-       int ret;
-       u16 addr;
-       uint8_t data1[1] = {0};
-       data1[0] = (u8)val;
-       addr = get_object_address(reg_add,
-                       0,
-                       mxt_es->object_table,
-                       mxt_es->device_info.num_objs)+reg_add_offset;
-
-       ret = mxt_write_block(mxt_es->client, addr, 1, data1);
-
-       if (ret < 0)
-               printk(KERN_ERR "intel_touch debugfs write err add=0x%x\n", reg_add);
-       return 0;
-}
-
-DEFINE_SIMPLE_ATTRIBUTE(intel_mid_single_write_reg_fops,
-                               NULL, intel_mid_single_write_set, "0x%02llx\n");
-
-
-static int  intel_mid_add_debugfs(void)
-{
-       struct dentry *root;
-
-       root = debugfs_create_dir("touch_debug", NULL);
-
-       if (IS_ERR(root))
-               /* Don't complain -- debugfs just isn't enabled */
-               return -1;
-       if (!root)
-               /* Complain -- debugfs is enabled, but it failed to
-               * create the directory. */
-               goto err;
-
-       if (!debugfs_create_file("sread", S_IWUGO|S_IRUGO, root, NULL, &intel_mid_single_read_reg_fops))
-               goto err;
-
-       if (!debugfs_create_file ("sread_offset", S_IWUGO|S_IRUGO, root, NULL, &intel_mid_single_read_reg_offset_fops))
-               goto err;
-
-       if (!debugfs_create_file ("swrite", S_IWUGO, root, NULL, &intel_mid_single_write_reg_fops))
-               goto err;
-
-       return 0;
-err:
-       debugfs_remove_recursive(root);
-       printk(KERN_ERR "failed to initialize  intel_mid debugfs\n");
-       return -1;
-}
-
-#endif
diff --git a/include/linux/atmel_mxt_ts.h b/include/linux/atmel_mxt_ts.h
deleted file mode 100644 (file)
index c5253a8..0000000
+++ /dev/null
@@ -1,377 +0,0 @@
-/*
- *  Atmel maXTouch header file
- *
- *  Copyright (c) 2010 Atmel Corporation
- *  Copyright (C) 2010 Ulf Samuelsson (ulf@atmel.com)
- *  Contains changes by Wind River Systems, 2010-09-29
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License version 2 as
- *  published by the Free Software Foundation.
- *
- *  See the file "COPYING" in the main directory of this archive
- *  for more details.
- *
- *  Modified by Richard Zhu(jianxin.zhu@borqs.com) 05/19/2011
- */
-#include <linux/ioctl.h>
-
-#define        MXT224_I2C_ADDR1                                0x4A
-#define        MXT224_I2C_ADDR2                                0x4B
-#define        MXT1386_I2C_ADDR1                               0x4C
-#define        MXT1386_I2C_ADDR2                               0x4D
-#define        MXT1386_I2C_ADDR3                               0x5A
-#define        MXT1386_I2C_ADDR4                               0x5B
-
-/*
- * Select this address from above depending on what maXTouch
- * chip you have and how it's address pins are configured;
- * see datasheet.
- */
-
-#define MXT_I2C_ADDRESS                                 MXT1386_I2C_ADDR1
-
-#define MXT_BL_ADDRESS                                  0x25
-
-#define        MXT224_FAMILYID                                 0x80
-#define MXT1386_FAMILYID                                0xA0
-
-#define        MXT224_CAL_VARIANTID                            0x01
-#define MXT224_UNCAL_VARIANTID                          0x00
-#define MXT1386_CAL_VARIANTID                           0x00
-
-#define MXT_MAX_REPORTED_WIDTH                          255
-#define MXT_MAX_REPORTED_PRESSURE                       255
-#define MXT_MAX_TOUCH_SIZE                              255
-#define MXT_MAX_NUM_TOUCHES                             10
-
-/* Fixed addresses inside maXTouch device */
-#define        MXT_ADDR_INFO_BLOCK                             0
-#define        MXT_ADDR_OBJECT_TABLE                           7
-#define MXT_ID_BLOCK_SIZE                               7
-#define        MXT_OBJECT_TABLE_ELEMENT_SIZE                   6
-
-/* Object types */
-#define        MXT_DEBUG_DELTAS_T2                             2
-#define        MXT_DEBUG_REFERENCES_T3                         3
-#define        MXT_GEN_MESSAGEPROCESSOR_T5                     5
-#define        MXT_GEN_COMMANDPROCESSOR_T6                     6
-#define        MXT_GEN_POWERCONFIG_T7                          7
-#define        MXT_GEN_ACQUIRECONFIG_T8                        8
-#define        MXT_TOUCH_MULTITOUCHSCREEN_T9                   9
-#define MXT_TOUCH_SINGLETOUCHSCREEN_T10                 10
-#define MXT_TOUCH_XSLIDER_T11                           11
-#define MXT_TOUCH_YSLIDER_T12                           12
-#define MXT_TOUCH_XWHEEL_T13                            13
-#define MXT_TOUCH_YWHEEL_T14                            14
-#define        MXT_TOUCH_KEYARRAY_T15                          15
-#define MXT_SPT_COMMSCONFIG_T18                                18
-#define        MXT_SPT_GPIOPWM_T19                             19
-#define        MXT_PROCI_GRIPFACESUPPRESSION_T20               20
-#define        MXT_PROCG_NOISESUPPRESSION_T22                  22
-#define        MXT_TOUCH_PROXIMITY_T23                         23
-#define        MXT_PROCI_ONETOUCHGESTUREPROCESSOR_T24          24
-#define        MXT_SPT_SELFTEST_T25                            25
-#define MXT_DEBUG_CTERANGE_T26                         26
-#define        MXT_PROCI_TWOTOUCHGESTUREPROCESSOR_T27          27
-#define        MXT_SPT_CTECONFIG_T28                           28
-#define        MXT_TOUCH_KEYSET_T31                            31
-#define        MXT_TOUCH_XSLIDERSET_T32                        32
-#define        MXT_DEBUG_DIAGNOSTIC_T37                        37
-#define        MXT_USER_INFO_T38                               38
-#define MXT_PROCI_GRIPSUPPRESSION_T40       40
-#define MXT_PROCI_PALMSUPPRESSION_T41       41
-#define MXT_SPT_DIGITIZER_T43               43
-
-
-/*
- * If a message is read from mXT when there's no new messages available,
- * the report ID of the message will be 0xFF.
- */
-#define        MXT_END_OF_MESSAGES                             0xFF
-
-
-/* GEN_COMMANDPROCESSOR_T6 Register offsets from T6 base address */
-#define        MXT_ADR_T6_RESET                                0x00
-#define        MXT_ADR_T6_BACKUPNV                             0x01
-#define        MXT_ADR_T6_CALIBRATE                            0x02
-#define        MXT_ADR_T6_REPORTALL                            0x03
-#define        MXT_ADR_T6_RESERVED                             0x04
-#define        MXT_ADR_T6_DIAGNOSTIC                           0x05
-
-/* T6 Debug Diagnostics Commands */
-#define        MXT_CMD_T6_PAGE_UP          0x01
-#define        MXT_CMD_T6_PAGE_DOWN        0x02
-#define        MXT_CMD_T6_DELTAS_MODE      0x10
-#define        MXT_CMD_T6_REFERENCES_MODE  0x11
-#define        MXT_CMD_T6_CTE_MODE         0x31
-
-/* T6 Backup Command */
-#define MXT_CMD_T6_BACKUP           0x55
-
-/* SPT_DEBUG_DIAGNOSTIC_T37 Register offsets from T37 base address */
-#define MXT_ADR_T37_PAGE                                0x01
-#define        MXT_ADR_T37_DATA                                0x02
-
-
-
-/************************************************************************
- * MESSAGE OBJECTS ADDRESS FIELDS
- *
- ************************************************************************/
-#define MXT_MSG_REPORTID                                0x00
-
-
-/* MXT_GEN_MESSAGEPROCESSOR_T5 Message address definitions             */
-#define        MXT_MSG_T5_REPORTID                             0x00
-#define        MXT_MSG_T5_MESSAGE                              0x01
-#define        MXT_MSG_T5_CHECKSUM                             0x08
-
-/* MXT_GEN_COMMANDPROCESSOR_T6 Message address definitions             */
-#define        MXT_MSG_T6_STATUS                               0x01
-#define                MXT_MSGB_T6_COMSERR             0x04
-#define                MXT_MSGB_T6_CFGERR              0x08
-#define                MXT_MSGB_T6_CAL                 0x10
-#define                MXT_MSGB_T6_SIGERR              0x20
-#define                MXT_MSGB_T6_OFL                 0x40
-#define                MXT_MSGB_T6_RESET               0x80
-/* Three bytes */
-#define        MXT_MSG_T6_CHECKSUM                             0x02
-
-/* MXT_GEN_POWERCONFIG_T7 NO Message address definitions               */
-/* MXT_GEN_ACQUIRECONFIG_T8 Message address definitions                        */
-/* MXT_TOUCH_MULTITOUCHSCREEN_T9 Message address definitions           */
-
-#define T8_CFG_CHRGTIME                         0
-/* Reserved */
-#define T8_CFG_TCHDRIFT                         2
-#define T8_CFG_DRIFTST                          3
-#define T8_CFG_TCHAUTOCAL                       4
-#define T8_CFG_SYNC                             5
-#define T8_CFG_ATCHCALST                        6
-#define T8_CFG_ATCHCALSTHR                      7
-#define T8_CFG_ATCHFRCCALTHR                    8 /* FW v2.x */
-#define T8_CFG_ATCHFRCCALRATIO                  9 /* FW v2.x */
-
-#define        MXT_MSG_T9_STATUS                               0x01
-/* Status bit field */
-#define                MXT_MSGB_T9_SUPPRESS            0x02
-#define                MXT_MSGB_T9_AMP                 0x04
-#define                MXT_MSGB_T9_VECTOR              0x08
-#define                MXT_MSGB_T9_MOVE                0x10
-#define                MXT_MSGB_T9_RELEASE             0x20
-#define                MXT_MSGB_T9_PRESS               0x40
-#define                MXT_MSGB_T9_DETECT              0x80
-
-#define        MXT_MSG_T9_XPOSMSB                              0x02
-#define        MXT_MSG_T9_YPOSMSB                              0x03
-#define        MXT_MSG_T9_XYPOSLSB                             0x04
-#define        MXT_MSG_T9_TCHAREA                              0x05
-#define        MXT_MSG_T9_TCHAMPLITUDE                         0x06
-#define        MXT_MSG_T9_TCHVECTOR                            0x07
-#define MXT_MSG_T9_ORIENT                              0x09
-/* ORIENT field settings. */
-#define MXT_MSGB_T9_ORIENT_NORMAL_ORIENT               0X00
-#define MXT_MSGB_T9_ORIENT_HORZ_FLIP                   0x02
-#define MXT_MSGB_T9_ORIENT_VERT_FLIP                   0x04
-#define MXT_MSGB_T9_ORIENT_ROTATE_180                  0x06
-#define MXT_MSGB_T9_ORIENT_DIAG_X0_Y0_XMAX_YMAX                0x01
-#define MXT_MSGB_T9_ORIENT_ROTATE_90_CCWISE            0x03
-#define MXT_MSGB_T9_ORIENT_ROTATE_90_CWISE             0x05
-#define MXT_MSGB_T9_ORIENT_DIAG_X0_YMAX_XMAX_Y0                0x07
-
-#define        MXT_ADR_T9_NUMTOUCH                             0x0e
-
-/* MXT_SPT_GPIOPWM_T19 Message address definitions                     */
-#define        MXT_MSG_T19_STATUS                              0x01
-
-/* MXT_PROCI_GRIPFACESUPPRESSION_T20 Message address definitions       */
-#define        MXT_MSG_T20_STATUS                              0x01
-#define                MXT_MSGB_T20_FACE_SUPPRESS      0x01
-/* MXT_PROCG_NOISESUPPRESSION_T22 Message address definitions          */
-#define        MXT_MSG_T22_STATUS                              0x01
-#define                MXT_MSGB_T22_FHCHG              0x01
-#define                MXT_MSGB_T22_GCAFERR            0x04
-#define                MXT_MSGB_T22_FHERR              0x08
-#define        MXT_MSG_T22_GCAFDEPTH                           0x02
-
-/* MXT_TOUCH_PROXIMITY_T23 Message address definitions                 */
-#define        MXT_MSG_T23_STATUS                              0x01
-#define                MXT_MSGB_T23_FALL               0x20
-#define                MXT_MSGB_T23_RISE               0x40
-#define                MXT_MSGB_T23_DETECT             0x80
-/* 16 bit */
-#define        MXT_MSG_T23_PROXDELTA                           0x02
-
-/* MXT_PROCI_ONETOUCHGESTUREPROCESSOR_T24 Message address definitions  */
-#define        MXT_MSG_T24_STATUS                              0x01
-#define        MXT_MSG_T24_XPOSMSB                             0x02
-#define        MXT_MSG_T24_YPOSMSB                             0x03
-#define        MXT_MSG_T24_XYPOSLSB                            0x04
-#define        MXT_MSG_T24_DIR                                 0x05
-/* 16 bit */
-#define        MXT_MSG_T24_DIST                                0x06
-
-/* MXT_SPT_SELFTEST_T25 Message address definitions                    */
-#define        MXT_ADR_T25_CTRL                                0x00
-#define        MXT_MSG_T25_STATUS                              0x01
-#define        MXT_ADR_T25_CMD                                 0x01
-
-/* 5 Bytes */
-#define                MXT_MSGR_T25_INVALID_TEST       0xFD
-#define                MXT_MSGR_T25_PIN_FAULT          0x11
-#define                MXT_MSGR_T25_SIGNAL_LIMIT_FAULT 0x17
-#define                MXT_MSGR_T25_GAIN_ERROR         0x20
-#define                MXT_MSGR_T25_RUN_ALL_TESTS      0xFE
-#define        MXT_MSG_T25_INFO                                0x02
-
-/* MXT_PROCI_TWOTOUCHGESTUREPROCESSOR_T27 Message address definitions  */
-#define        MXT_MSG_T27_STATUS                      0x01
-#define                MXT_MSGB_T27_ROTATEDIR          0x10
-#define                MXT_MSGB_T27_PINCH              0x20
-#define                MXT_MSGB_T27_ROTATE             0x40
-#define                MXT_MSGB_T27_STRETCH            0x80
-#define        MXT_MSG_T27_XPOSMSB                     0x02
-#define        MXT_MSG_T27_YPOSMSB                     0x03
-#define        MXT_MSG_T27_XYPOSLSB                    0x04
-#define        MXT_MSG_T27_ANGLE                       0x05
-
-/* 16 bit */
-#define        MXT_MSG_T27_SEPARATION                          0x06
-
-/* MXT_SPT_CTECONFIG_T28 Message address definitions                   */
-#define        MXT_MSG_T28_STATUS                              0x01
-#define        MXT_MSGB_T28_CHKERR             0x01
-
-
-/* One Touch Events */
-#define        MXT_GESTURE_RESERVED            0x00
-#define        MXT_GESTURE_PRESS               0x01
-#define        MXT_GESTURE_RELEASE             0x02
-#define        MXT_GESTURE_TAP                 0x03
-#define        MXT_GESTURE_DOUBLE_TAP          0x04
-#define        MXT_GESTURE_FLICK               0x05
-#define        MXT_GESTURE_DRAG                0x06
-#define        MXT_GESTURE_SHORT_PRESS         0x07
-#define        MXT_GESTURE_LONG_PRESS          0x08
-#define        MXT_GESTURE_REPEAT_PRESS        0x09
-#define        MXT_GESTURE_TAP_AND_PRESS       0x0a
-#define        MXT_GESTURE_THROW               0x0b
-
-/* Two-touch events */
-#define MXT_GESTURE_STRETCH             (1 << 7)
-#define MXT_GESTURE_ROTATE              (1 << 6)
-#define MXT_GESTURE_PINCH               (1 << 5)
-#define MXT_GESTURE_ROTATEDIR           (1 << 4)
-
-
-
-/* Bootloader states */
-#define WAITING_BOOTLOAD_COMMAND   0xC0
-#define WAITING_FRAME_DATA         0x80
-#define APP_CRC_FAIL               0x40
-#define FRAME_CRC_CHECK            0x02
-#define FRAME_CRC_PASS             0x04
-#define FRAME_CRC_FAIL             0x03
-
-#define MXT_MAX_FRAME_SIZE         276
-
-/* Debug levels */
-#define DEBUG_INFO     1
-#define DEBUG_VERBOSE  2
-#define DEBUG_MESSAGES 5
-#define DEBUG_RAW      8
-#define DEBUG_TRACE   10
-
-/* IOCTL commands */
-/* TODO: get correct numbers! */
-#define MXT_IOC_MAGIC 'x'
-
-/* Sets the internal address pointer */
-#define MXT_SET_ADDRESS_IOCTL  _IO(MXT_IOC_MAGIC, 1)
-/* Resets the device */
-#define MXT_RESET_IOCTL        _IO(MXT_IOC_MAGIC, 2)
-/* Calibrates the device */
-#define MXT_CALIBRATE_IOCTL    _IO(MXT_IOC_MAGIC, 3)
-/* Backups the current state of registers to NVM */
-#define MXT_BACKUP_IOCTL       _IO(MXT_IOC_MAGIC, 4)
-/* Only non-touch messages can be read from the message buffer
- * (/dev/maXTouch_messages)*/
-#define MXT_NONTOUCH_MSG_IOCTL _IO(MXT_IOC_MAGIC, 5)
-/* All messages can be read from the message buffer */
-#define MXT_ALL_MSG_IOCTL      _IO(MXT_IOC_MAGIC, 6)
-/* self test */
-#define MXT_SELF_TEST_IOCTL    _IO(MXT_IOC_MAGIC, 7)
-
-/* Message buffer size. This is a ring buffer, and when full, the oldest entry
-   will be overwritten. */
-#define MXT_MESSAGE_BUFFER_SIZE  128
-
-/* TODO: */
-/* Bootloader specific function prototypes. */
-#if 0
-static int mxt_read_byte_bl(struct i2c_client *client, u8 *value);
-static int mxt_read_block_bl(struct i2c_client *client, u16 length, u8 *value);
-static int mxt_write_byte_bl(struct i2c_client *client, u8 value);
-static int mxt_write_block_bl(struct i2c_client *client, u16 length, u8 *value);
-#endif
-
-/**
- * struct mxt_platform_data - includes platform specific information
- * related to Atmel maXTouch touchscreen controller.
- *
- * @numtouch:           Number of simultaneous touches supported
- * @init_platform_hw(): Initialization function, which can for example
- *                      trigger a hardware reset by toggling a GPIO pin
- * @exit_platform_hw(): Function to run when the driver is unloaded.
- * @valid_interrupt():  Function that checks the validity of the interrupt -
- *                      function that check the validity of a interrupt (by
- *                      reading the changeline interrupt pin and checking that
- *                      it really is low for example).
- * @max_x:              Reported X range
- * @max_y:              Reported Y range
- */
-
-struct mxt_platform_data {
-       u8    numtouch; /* Number of touches to report  */
-       void  (*init_platform_hw)(void);
-       void  (*exit_platform_hw)(void);
-       int   max_x;    /* The default reported X range   */
-       int   max_y;    /* The default reported Y range   */
-       int   orientation; /* The default orientation */
-       u8    (*valid_interrupt) (void);
-       u8    (*read_chg) (void);
-       u16   reset;
-       u16   irq;
-};
-
-void   mxt_hw_reset(void);
-
-/* Add by Richard zhu(jianxin.zhu@borqs.com) */
-#define TOUCH_DEVICE_NAME                              "mxt1386"
-#define LOW                             0
-#define HIGH                            1
-#define FALSE                           0
-#define TRUE                            1
-#define TS_MAX_X                                               1023
-#define TS_MIN_X                                               0
-#define TS_MAX_Y                                               1023
-#define TS_MIN_Y                                               0
-
-/* anti-touch calibration */
-#define RECALIB_NEED                            0
-#define RECALIB_NG                              1
-#define RECALIB_DONE                            2
-
-struct point_info {
-       int x;
-       int y;
-       int num;
-       int first_area;
-       int last_area;
-};
-
-enum touch_state {
-       NO_TOUCH = 0,
-       PRESS_TOUCH_AREA,
-};