* Copyright (c) 2013 ELAN Microelectronics Corp.
  *
  * Author: 林政維 (Duson Lin) <dusonlin@emc.com.tw>
- * Version: 1.5.5
  *
  * Based on cyapa driver:
  * copyright (c) 2011-2012 Cypress Semiconductor, Inc.
 #define ETP_FW_IAP_PAGE_ERR    (1 << 5)
 #define ETP_FW_IAP_INTF_ERR    (1 << 4)
 #define ETP_FW_PAGE_SIZE       64
-#define ETP_FW_PAGE_COUNT      768
-#define ETP_FW_SIZE            (ETP_FW_PAGE_SIZE * ETP_FW_PAGE_COUNT)
+#define ETP_FW_VAILDPAGE_COUNT 768
+#define ETP_FW_SIGNATURE_SIZE  6
+#define ETP_FW_SIGNATURE_ADDRESS       0xBFFA
 
 struct i2c_client;
 struct completion;
 
  * Copyright (c) 2013 ELAN Microelectronics Corp.
  *
  * Author: 林政維 (Duson Lin) <dusonlin@emc.com.tw>
- * Version: 1.5.5
+ * Version: 1.5.6
  *
  * Based on cyapa driver:
  * copyright (c) 2011-2012 Cypress Semiconductor, Inc.
 #include "elan_i2c.h"
 
 #define DRIVER_NAME            "elan_i2c"
-#define ELAN_DRIVER_VERSION    "1.5.5"
+#define ELAN_DRIVER_VERSION    "1.5.6"
 #define ETP_PRESSURE_OFFSET    25
 #define ETP_MAX_PRESSURE       255
 #define ETP_FWIDTH_REDUCE      90
        iap_start_addr = get_unaligned_le16(&fw->data[ETP_IAP_START_ADDR * 2]);
 
        boot_page_count = (iap_start_addr * 2) / ETP_FW_PAGE_SIZE;
-       for (i = boot_page_count; i < ETP_FW_PAGE_COUNT; i++) {
+       for (i = boot_page_count; i < ETP_FW_VAILDPAGE_COUNT; i++) {
                u16 checksum = 0;
                const u8 *page = &fw->data[i * ETP_FW_PAGE_SIZE];
 
                                    struct device_attribute *attr,
                                    const char *buf, size_t count)
 {
-       struct i2c_client *client = to_i2c_client(dev);
-       struct elan_tp_data *data = i2c_get_clientdata(client);
+       struct elan_tp_data *data = dev_get_drvdata(dev);
        const struct firmware *fw;
        int error;
+       const u8 *fw_signature;
+       static const u8 signature[] = {0xAA, 0x55, 0xCC, 0x33, 0xFF, 0xFF};
 
        error = request_firmware(&fw, ETP_FW_NAME, dev);
        if (error) {
                return error;
        }
 
-       /* Firmware must be exactly PAGE_NUM * PAGE_SIZE bytes */
-       if (fw->size != ETP_FW_SIZE) {
-               dev_err(dev, "invalid firmware size = %zu, expected %d.\n",
-                       fw->size, ETP_FW_SIZE);
+       /* Firmware file must match signature data */
+       fw_signature = &fw->data[ETP_FW_SIGNATURE_ADDRESS];
+       if (memcmp(fw_signature, signature, sizeof(signature)) != 0) {
+               dev_err(dev, "signature mismatch (expected %*ph, got %*ph)\n",
+                       (int)sizeof(signature), signature,
+                       (int)sizeof(signature), fw_signature);
                error = -EBADF;
                goto out_release_fw;
        }