aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDuson Lin2015-06-08 18:39:35 -0500
committerDmitry Torokhov2015-06-08 19:12:24 -0500
commit12018ac3d679d6a3c6c738ac805797fe4dd43912 (patch)
tree2ac3ab6688915aebb8c00bec0b543605b1dc48a9 /drivers/input/mouse/elan_i2c_core.c
parent85919a00e55f90e72405e707eb23c930b8d8db91 (diff)
downloadkernel-omap-12018ac3d679d6a3c6c738ac805797fe4dd43912.tar.gz
kernel-omap-12018ac3d679d6a3c6c738ac805797fe4dd43912.tar.xz
kernel-omap-12018ac3d679d6a3c6c738ac805797fe4dd43912.zip
Input: elan_i2c - add support for multi IC type and iap format
In order to support multiple IC types for i2c/smbus protocol, add get ic type command and use this data when checking firmware page count and signature address. Signed-off-by: Duson Lin <dusonlin@emc.com.tw> Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
Diffstat (limited to 'drivers/input/mouse/elan_i2c_core.c')
-rw-r--r--drivers/input/mouse/elan_i2c_core.c45
1 files changed, 40 insertions, 5 deletions
diff --git a/drivers/input/mouse/elan_i2c_core.c b/drivers/input/mouse/elan_i2c_core.c
index fd5068b2542d..b4cfd18cdaca 100644
--- a/drivers/input/mouse/elan_i2c_core.c
+++ b/drivers/input/mouse/elan_i2c_core.c
@@ -4,7 +4,7 @@
4 * Copyright (c) 2013 ELAN Microelectronics Corp. 4 * Copyright (c) 2013 ELAN Microelectronics Corp.
5 * 5 *
6 * Author: 林政維 (Duson Lin) <dusonlin@emc.com.tw> 6 * Author: 林政維 (Duson Lin) <dusonlin@emc.com.tw>
7 * Version: 1.5.7 7 * Version: 1.5.8
8 * 8 *
9 * Based on cyapa driver: 9 * Based on cyapa driver:
10 * copyright (c) 2011-2012 Cypress Semiconductor, Inc. 10 * copyright (c) 2011-2012 Cypress Semiconductor, Inc.
@@ -40,7 +40,7 @@
40#include "elan_i2c.h" 40#include "elan_i2c.h"
41 41
42#define DRIVER_NAME "elan_i2c" 42#define DRIVER_NAME "elan_i2c"
43#define ELAN_DRIVER_VERSION "1.5.7" 43#define ELAN_DRIVER_VERSION "1.5.8"
44#define ETP_MAX_PRESSURE 255 44#define ETP_MAX_PRESSURE 255
45#define ETP_FWIDTH_REDUCE 90 45#define ETP_FWIDTH_REDUCE 90
46#define ETP_FINGER_WIDTH 15 46#define ETP_FINGER_WIDTH 15
@@ -83,6 +83,9 @@ struct elan_tp_data {
83 u16 fw_checksum; 83 u16 fw_checksum;
84 int pressure_adjustment; 84 int pressure_adjustment;
85 u8 mode; 85 u8 mode;
86 u8 ic_type;
87 u16 fw_vaildpage_count;
88 u16 fw_signature_address;
86 89
87 bool irq_wake; 90 bool irq_wake;
88 91
@@ -91,6 +94,29 @@ struct elan_tp_data {
91 bool baseline_ready; 94 bool baseline_ready;
92}; 95};
93 96
97static int elan_get_fwinfo(u8 ic_type, u16 *vaildpage_count,
98 u16 *signature_address)
99{
100 switch(ic_type) {
101 case 0x09:
102 *vaildpage_count = 768;
103 break;
104 case 0x0D:
105 *vaildpage_count = 896;
106 break;
107 default:
108 /* unknown ic type clear value */
109 *vaildpage_count = 0;
110 *signature_address = 0;
111 return -ENXIO;
112 }
113
114 *signature_address =
115 (*vaildpage_count * ETP_FW_PAGE_SIZE) - ETP_FW_SIGNATURE_SIZE;
116
117 return 0;
118}
119
94static int elan_enable_power(struct elan_tp_data *data) 120static int elan_enable_power(struct elan_tp_data *data)
95{ 121{
96 int repeat = ETP_RETRY_COUNT; 122 int repeat = ETP_RETRY_COUNT;
@@ -221,7 +247,8 @@ static int elan_query_device_info(struct elan_tp_data *data)
221 if (error) 247 if (error)
222 return error; 248 return error;
223 249
224 error = data->ops->get_sm_version(data->client, &data->sm_version); 250 error = data->ops->get_sm_version(data->client, &data->ic_type,
251 &data->sm_version);
225 if (error) 252 if (error)
226 return error; 253 return error;
227 254
@@ -234,6 +261,14 @@ static int elan_query_device_info(struct elan_tp_data *data)
234 if (error) 261 if (error)
235 return error; 262 return error;
236 263
264 error = elan_get_fwinfo(data->ic_type, &data->fw_vaildpage_count,
265 &data->fw_signature_address);
266 if (error) {
267 dev_err(&data->client->dev,
268 "unknown ic type %d\n", data->ic_type);
269 return error;
270 }
271
237 return 0; 272 return 0;
238} 273}
239 274
@@ -318,7 +353,7 @@ static int __elan_update_firmware(struct elan_tp_data *data,
318 iap_start_addr = get_unaligned_le16(&fw->data[ETP_IAP_START_ADDR * 2]); 353 iap_start_addr = get_unaligned_le16(&fw->data[ETP_IAP_START_ADDR * 2]);
319 354
320 boot_page_count = (iap_start_addr * 2) / ETP_FW_PAGE_SIZE; 355 boot_page_count = (iap_start_addr * 2) / ETP_FW_PAGE_SIZE;
321 for (i = boot_page_count; i < ETP_FW_VAILDPAGE_COUNT; i++) { 356 for (i = boot_page_count; i < data->fw_vaildpage_count; i++) {
322 u16 checksum = 0; 357 u16 checksum = 0;
323 const u8 *page = &fw->data[i * ETP_FW_PAGE_SIZE]; 358 const u8 *page = &fw->data[i * ETP_FW_PAGE_SIZE];
324 359
@@ -454,7 +489,7 @@ static ssize_t elan_sysfs_update_fw(struct device *dev,
454 } 489 }
455 490
456 /* Firmware file must match signature data */ 491 /* Firmware file must match signature data */
457 fw_signature = &fw->data[ETP_FW_SIGNATURE_ADDRESS]; 492 fw_signature = &fw->data[data->fw_signature_address];
458 if (memcmp(fw_signature, signature, sizeof(signature)) != 0) { 493 if (memcmp(fw_signature, signature, sizeof(signature)) != 0) {
459 dev_err(dev, "signature mismatch (expected %*ph, got %*ph)\n", 494 dev_err(dev, "signature mismatch (expected %*ph, got %*ph)\n",
460 (int)sizeof(signature), signature, 495 (int)sizeof(signature), signature,