|
@@ -4,7 +4,7 @@
|
|
* Copyright (c) 2013 ELAN Microelectronics Corp.
|
|
* Copyright (c) 2013 ELAN Microelectronics Corp.
|
|
*
|
|
*
|
|
* Author: 林政維 (Duson Lin) <dusonlin@emc.com.tw>
|
|
* Author: 林政維 (Duson Lin) <dusonlin@emc.com.tw>
|
|
- * Version: 1.5.5
|
|
|
|
|
|
+ * Version: 1.5.6
|
|
*
|
|
*
|
|
* Based on cyapa driver:
|
|
* Based on cyapa driver:
|
|
* copyright (c) 2011-2012 Cypress Semiconductor, Inc.
|
|
* copyright (c) 2011-2012 Cypress Semiconductor, Inc.
|
|
@@ -40,7 +40,7 @@
|
|
#include "elan_i2c.h"
|
|
#include "elan_i2c.h"
|
|
|
|
|
|
#define DRIVER_NAME "elan_i2c"
|
|
#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_PRESSURE_OFFSET 25
|
|
#define ETP_MAX_PRESSURE 255
|
|
#define ETP_MAX_PRESSURE 255
|
|
#define ETP_FWIDTH_REDUCE 90
|
|
#define ETP_FWIDTH_REDUCE 90
|
|
@@ -312,7 +312,7 @@ static int __elan_update_firmware(struct elan_tp_data *data,
|
|
iap_start_addr = get_unaligned_le16(&fw->data[ETP_IAP_START_ADDR * 2]);
|
|
iap_start_addr = get_unaligned_le16(&fw->data[ETP_IAP_START_ADDR * 2]);
|
|
|
|
|
|
boot_page_count = (iap_start_addr * 2) / ETP_FW_PAGE_SIZE;
|
|
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;
|
|
u16 checksum = 0;
|
|
const u8 *page = &fw->data[i * ETP_FW_PAGE_SIZE];
|
|
const u8 *page = &fw->data[i * ETP_FW_PAGE_SIZE];
|
|
|
|
|
|
@@ -434,10 +434,11 @@ static ssize_t elan_sysfs_update_fw(struct device *dev,
|
|
struct device_attribute *attr,
|
|
struct device_attribute *attr,
|
|
const char *buf, size_t count)
|
|
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;
|
|
const struct firmware *fw;
|
|
int error;
|
|
int error;
|
|
|
|
+ const u8 *fw_signature;
|
|
|
|
+ static const u8 signature[] = {0xAA, 0x55, 0xCC, 0x33, 0xFF, 0xFF};
|
|
|
|
|
|
error = request_firmware(&fw, ETP_FW_NAME, dev);
|
|
error = request_firmware(&fw, ETP_FW_NAME, dev);
|
|
if (error) {
|
|
if (error) {
|
|
@@ -446,10 +447,12 @@ static ssize_t elan_sysfs_update_fw(struct device *dev,
|
|
return 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;
|
|
error = -EBADF;
|
|
goto out_release_fw;
|
|
goto out_release_fw;
|
|
}
|
|
}
|