summaryrefslogtreecommitdiff
path: root/driver/touchpad_elan.c
diff options
context:
space:
mode:
Diffstat (limited to 'driver/touchpad_elan.c')
-rw-r--r--driver/touchpad_elan.c209
1 files changed, 101 insertions, 108 deletions
diff --git a/driver/touchpad_elan.c b/driver/touchpad_elan.c
index 6df4f0f7de..05c081a84a 100644
--- a/driver/touchpad_elan.c
+++ b/driver/touchpad_elan.c
@@ -1,4 +1,4 @@
-/* Copyright 2016 The Chromium OS Authors. All rights reserved.
+/* Copyright 2016 The ChromiumOS Authors
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
@@ -25,73 +25,73 @@
/* Console output macros */
#define CPUTS(outstr) cputs(CC_TOUCHPAD, outstr)
-#define CPRINTF(format, args...) cprintf(CC_TOUCHPAD, format, ## args)
-#define CPRINTS(format, args...) cprints(CC_TOUCHPAD, format, ## args)
+#define CPRINTF(format, args...) cprintf(CC_TOUCHPAD, format, ##args)
+#define CPRINTS(format, args...) cprints(CC_TOUCHPAD, format, ##args)
-#define TASK_EVENT_POWER TASK_EVENT_CUSTOM_BIT(0)
+#define TASK_EVENT_POWER TASK_EVENT_CUSTOM_BIT(0)
/******************************************************************************/
/* How to talk to the controller */
/******************************************************************************/
-#define ELAN_VENDOR_ID 0x04f3
+#define ELAN_VENDOR_ID 0x04f3
-#define ETP_I2C_RESET 0x0100
-#define ETP_I2C_WAKE_UP 0x0800
-#define ETP_I2C_SLEEP 0x0801
+#define ETP_I2C_RESET 0x0100
+#define ETP_I2C_WAKE_UP 0x0800
+#define ETP_I2C_SLEEP 0x0801
-#define ETP_I2C_STAND_CMD 0x0005
-#define ETP_I2C_UNIQUEID_CMD 0x0101
-#define ETP_I2C_FW_VERSION_CMD 0x0102
-#define ETP_I2C_OSM_VERSION_CMD 0x0103
-#define ETP_I2C_XY_TRACENUM_CMD 0x0105
-#define ETP_I2C_MAX_X_AXIS_CMD 0x0106
-#define ETP_I2C_MAX_Y_AXIS_CMD 0x0107
-#define ETP_I2C_RESOLUTION_CMD 0x0108
-#define ETP_I2C_IAP_VERSION_CMD 0x0110
-#define ETP_I2C_PRESSURE_CMD 0x010A
-#define ETP_I2C_SET_CMD 0x0300
-#define ETP_I2C_IAP_TYPE_CMD 0x0304
-#define ETP_I2C_POWER_CMD 0x0307
-#define ETP_I2C_FW_CHECKSUM_CMD 0x030F
+#define ETP_I2C_STAND_CMD 0x0005
+#define ETP_I2C_UNIQUEID_CMD 0x0101
+#define ETP_I2C_FW_VERSION_CMD 0x0102
+#define ETP_I2C_OSM_VERSION_CMD 0x0103
+#define ETP_I2C_XY_TRACENUM_CMD 0x0105
+#define ETP_I2C_MAX_X_AXIS_CMD 0x0106
+#define ETP_I2C_MAX_Y_AXIS_CMD 0x0107
+#define ETP_I2C_RESOLUTION_CMD 0x0108
+#define ETP_I2C_IAP_VERSION_CMD 0x0110
+#define ETP_I2C_PRESSURE_CMD 0x010A
+#define ETP_I2C_SET_CMD 0x0300
+#define ETP_I2C_IAP_TYPE_CMD 0x0304
+#define ETP_I2C_POWER_CMD 0x0307
+#define ETP_I2C_FW_CHECKSUM_CMD 0x030F
-#define ETP_ENABLE_ABS 0x0001
+#define ETP_ENABLE_ABS 0x0001
-#define ETP_DISABLE_POWER 0x0001
+#define ETP_DISABLE_POWER 0x0001
-#define ETP_I2C_REPORT_LEN 34
+#define ETP_I2C_REPORT_LEN 34
-#define ETP_MAX_FINGERS 5
-#define ETP_FINGER_DATA_LEN 5
+#define ETP_MAX_FINGERS 5
+#define ETP_FINGER_DATA_LEN 5
-#define ETP_PRESSURE_OFFSET 25
-#define ETP_FWIDTH_REDUCE 90
+#define ETP_PRESSURE_OFFSET 25
+#define ETP_FWIDTH_REDUCE 90
-#define ETP_REPORT_ID 0x5D
-#define ETP_REPORT_ID_OFFSET 2
-#define ETP_TOUCH_INFO_OFFSET 3
-#define ETP_FINGER_DATA_OFFSET 4
-#define ETP_HOVER_INFO_OFFSET 30
-#define ETP_MAX_REPORT_LEN 34
+#define ETP_REPORT_ID 0x5D
+#define ETP_REPORT_ID_OFFSET 2
+#define ETP_TOUCH_INFO_OFFSET 3
+#define ETP_FINGER_DATA_OFFSET 4
+#define ETP_HOVER_INFO_OFFSET 30
+#define ETP_MAX_REPORT_LEN 34
-#define ETP_IAP_START_ADDR 0x0083
+#define ETP_IAP_START_ADDR 0x0083
-#define ETP_I2C_IAP_RESET_CMD 0x0314
-#define ETP_I2C_IAP_RESET 0xF0F0
-#define ETP_I2C_IAP_CTRL_CMD 0x0310
-#define ETP_I2C_MAIN_MODE_ON BIT(9)
-#define ETP_I2C_IAP_CMD 0x0311
-#define ETP_I2C_IAP_PASSWORD 0x1EA5
+#define ETP_I2C_IAP_RESET_CMD 0x0314
+#define ETP_I2C_IAP_RESET 0xF0F0
+#define ETP_I2C_IAP_CTRL_CMD 0x0310
+#define ETP_I2C_MAIN_MODE_ON BIT(9)
+#define ETP_I2C_IAP_CMD 0x0311
+#define ETP_I2C_IAP_PASSWORD 0x1EA5
-#define ETP_I2C_IAP_REG_L 0x01
-#define ETP_I2C_IAP_REG_H 0x06
+#define ETP_I2C_IAP_REG_L 0x01
+#define ETP_I2C_IAP_REG_H 0x06
-#define ETP_FW_IAP_PAGE_ERR BIT(5)
-#define ETP_FW_IAP_INTF_ERR BIT(4)
+#define ETP_FW_IAP_PAGE_ERR BIT(5)
+#define ETP_FW_IAP_INTF_ERR BIT(4)
#ifdef CONFIG_USB_UPDATE
/* The actual FW_SIZE depends on IC. */
-#define FW_SIZE CONFIG_TOUCHPAD_VIRTUAL_SIZE
+#define FW_SIZE CONFIG_TOUCHPAD_VIRTUAL_SIZE
#endif
struct {
@@ -124,8 +124,8 @@ static int elan_tp_read_cmd(uint16_t reg, uint16_t *val)
buf[1] = reg >> 8;
return i2c_xfer(CONFIG_TOUCHPAD_I2C_PORT,
- CONFIG_TOUCHPAD_I2C_ADDR_FLAGS,
- buf, sizeof(buf), (uint8_t *)val, sizeof(*val));
+ CONFIG_TOUCHPAD_I2C_ADDR_FLAGS, buf, sizeof(buf),
+ (uint8_t *)val, sizeof(*val));
}
static int elan_tp_write_cmd(uint16_t reg, uint16_t val)
@@ -138,8 +138,8 @@ static int elan_tp_write_cmd(uint16_t reg, uint16_t val)
buf[3] = val >> 8;
return i2c_xfer(CONFIG_TOUCHPAD_I2C_PORT,
- CONFIG_TOUCHPAD_I2C_ADDR_FLAGS,
- buf, sizeof(buf), NULL, 0);
+ CONFIG_TOUCHPAD_I2C_ADDR_FLAGS, buf, sizeof(buf), NULL,
+ 0);
}
/* Power is on by default. */
@@ -171,7 +171,7 @@ out:
return rv;
}
-static int finger_status[ETP_MAX_FINGERS] = {0};
+static int finger_status[ETP_MAX_FINGERS] = { 0 };
/*
* Timestamp of last interrupt (32 bits are enough as we divide the value by 100
@@ -192,15 +192,14 @@ static int elan_tp_read_report(void)
int i, ri;
uint8_t touch_info;
uint8_t hover_info;
- uint8_t *finger = tp_buf+ETP_FINGER_DATA_OFFSET;
+ uint8_t *finger = tp_buf + ETP_FINGER_DATA_OFFSET;
struct usb_hid_touchpad_report report;
uint16_t timestamp;
/* Compute and save timestamp early in case another interrupt comes. */
timestamp = irq_ts / USB_HID_TOUCHPAD_TIMESTAMP_UNIT;
- rv = i2c_xfer(CONFIG_TOUCHPAD_I2C_PORT,
- CONFIG_TOUCHPAD_I2C_ADDR_FLAGS,
+ rv = i2c_xfer(CONFIG_TOUCHPAD_I2C_PORT, CONFIG_TOUCHPAD_I2C_ADDR_FLAGS,
NULL, 0, tp_buf, ETP_I2C_REPORT_LEN);
if (rv) {
@@ -221,14 +220,14 @@ static int elan_tp_read_report(void)
hover_info = tp_buf[ETP_HOVER_INFO_OFFSET];
for (i = 0; i < ETP_MAX_FINGERS; i++) {
- int valid = touch_info & (1 << (3+i));
+ int valid = touch_info & (1 << (3 + i));
if (valid) {
int width = finger[3] & 0x0f;
int height = (finger[3] & 0xf0) >> 4;
int pressure = finger[4] + elan_tp_params.pressure_adj;
pressure = DIV_ROUND_NEAREST(pressure * pressure_mult,
- pressure_div);
+ pressure_div);
width = MIN(4095, width * elan_tp_params.width_x);
height = MIN(4095, height * elan_tp_params.width_y);
@@ -240,8 +239,8 @@ static int elan_tp_read_report(void)
report.finger[ri].id = i;
report.finger[ri].width = width;
report.finger[ri].height = height;
- report.finger[ri].x =
- ((finger[0] & 0xf0) << 4) | finger[1];
+ report.finger[ri].x = ((finger[0] & 0xf0) << 4) |
+ finger[1];
report.finger[ri].y =
elan_tp_params.max_y -
(((finger[0] & 0x0f) << 8) | finger[2]);
@@ -331,8 +330,7 @@ static void elan_tp_init(void)
elan_tp_write_cmd(ETP_I2C_STAND_CMD, ETP_I2C_RESET);
msleep(100);
- rv = i2c_xfer(CONFIG_TOUCHPAD_I2C_PORT,
- CONFIG_TOUCHPAD_I2C_ADDR_FLAGS,
+ rv = i2c_xfer(CONFIG_TOUCHPAD_I2C_PORT, CONFIG_TOUCHPAD_I2C_ADDR_FLAGS,
NULL, 0, val, sizeof(val));
CPRINTS("reset rv %d buf=%04x", rv, *((uint16_t *)val));
@@ -347,7 +345,7 @@ static void elan_tp_init(void)
goto out;
rv = elan_tp_read_cmd(ETP_I2C_IAP_VERSION_CMD,
- &elan_tp_params.iap_version);
+ &elan_tp_params.iap_version);
CPRINTS("%s: iap_version:%04X.", __func__, elan_tp_params.iap_version);
elan_tp_params.iap_version >>= 8;
if (rv)
@@ -389,22 +387,22 @@ static void elan_tp_init(void)
if (rv)
goto out;
- dpi_x = 10*val[0] + 790;
- dpi_y = 10*val[1] + 790;
+ dpi_x = 10 * val[0] + 790;
+ dpi_y = 10 * val[1] + 790;
- CPRINTS("max=%d/%d width=%d/%d adj=%d dpi=%d/%d",
- elan_tp_params.max_x, elan_tp_params.max_y,
- elan_tp_params.width_x, elan_tp_params.width_y,
- elan_tp_params.pressure_adj, dpi_x, dpi_y);
+ CPRINTS("max=%d/%d width=%d/%d adj=%d dpi=%d/%d", elan_tp_params.max_x,
+ elan_tp_params.max_y, elan_tp_params.width_x,
+ elan_tp_params.width_y, elan_tp_params.pressure_adj, dpi_x,
+ dpi_y);
#ifdef CONFIG_USB_HID_TOUCHPAD
/* Validity check dimensions provided at build time. */
if (elan_tp_params.max_x != CONFIG_USB_HID_TOUCHPAD_LOGICAL_MAX_X ||
elan_tp_params.max_y != CONFIG_USB_HID_TOUCHPAD_LOGICAL_MAX_Y ||
calc_physical_dimension(dpi_x, elan_tp_params.max_x) !=
- CONFIG_USB_HID_TOUCHPAD_PHYSICAL_MAX_X ||
+ CONFIG_USB_HID_TOUCHPAD_PHYSICAL_MAX_X ||
calc_physical_dimension(dpi_y, elan_tp_params.max_y) !=
- CONFIG_USB_HID_TOUCHPAD_PHYSICAL_MAX_Y) {
+ CONFIG_USB_HID_TOUCHPAD_PHYSICAL_MAX_Y) {
CPRINTS("*** TP mismatch!");
}
#endif
@@ -469,7 +467,7 @@ static int elan_read_write_iap_type(void)
uint16_t val;
if (elan_tp_write_cmd(ETP_I2C_IAP_TYPE_CMD,
- elan_tp_params.page_size / 2))
+ elan_tp_params.page_size / 2))
return EC_ERROR_UNKNOWN;
if (elan_tp_read_cmd(ETP_I2C_IAP_TYPE_CMD, &val))
@@ -477,7 +475,6 @@ static int elan_read_write_iap_type(void)
if (val == elan_tp_params.page_size / 2)
return EC_SUCCESS;
-
}
return EC_ERROR_UNKNOWN;
}
@@ -527,7 +524,7 @@ static int elan_prepare_for_update(void)
static int touchpad_update_page(const uint8_t *data)
{
- const uint8_t cmd[2] = {ETP_I2C_IAP_REG_L, ETP_I2C_IAP_REG_H};
+ const uint8_t cmd[2] = { ETP_I2C_IAP_REG_L, ETP_I2C_IAP_REG_H };
uint16_t checksum = 0;
uint16_t rx_buf;
int i, rv;
@@ -539,13 +536,13 @@ static int touchpad_update_page(const uint8_t *data)
i2c_lock(CONFIG_TOUCHPAD_I2C_PORT, 1);
rv = i2c_xfer_unlocked(CONFIG_TOUCHPAD_I2C_PORT,
- CONFIG_TOUCHPAD_I2C_ADDR_FLAGS,
- cmd, sizeof(cmd), NULL, 0, I2C_XFER_START);
+ CONFIG_TOUCHPAD_I2C_ADDR_FLAGS, cmd, sizeof(cmd),
+ NULL, 0, I2C_XFER_START);
if (rv)
goto fail;
rv = i2c_xfer_unlocked(CONFIG_TOUCHPAD_I2C_PORT,
- CONFIG_TOUCHPAD_I2C_ADDR_FLAGS,
- data, elan_tp_params.page_size, NULL, 0, 0);
+ CONFIG_TOUCHPAD_I2C_ADDR_FLAGS, data,
+ elan_tp_params.page_size, NULL, 0, 0);
if (rv)
goto fail;
rv = i2c_xfer_unlocked(CONFIG_TOUCHPAD_I2C_PORT,
@@ -564,8 +561,7 @@ fail:
rv = elan_tp_read_cmd(ETP_I2C_IAP_CTRL_CMD, &rx_buf);
if (rv || (rx_buf & (ETP_FW_IAP_PAGE_ERR | ETP_FW_IAP_INTF_ERR))) {
- CPRINTS("%s: IAP reports failed write : %x.",
- __func__, rx_buf);
+ CPRINTS("%s: IAP reports failed write : %x.", __func__, rx_buf);
return EC_ERROR_UNKNOWN;
}
return 0;
@@ -580,8 +576,8 @@ int touchpad_update_write(int offset, int size, const uint8_t *data)
if (offset == 0) {
/* Verify the IC type is aligned with defined firmware size */
- if (elan_tp_params.page_size * elan_tp_params.page_count
- != FW_SIZE) {
+ if (elan_tp_params.page_size * elan_tp_params.page_count !=
+ FW_SIZE) {
CPRINTS("%s: IC(%d*%d) size and FW_SIZE(%d) mismatch",
__func__, elan_tp_params.page_count,
elan_tp_params.page_size, FW_SIZE);
@@ -599,7 +595,8 @@ int touchpad_update_write(int offset, int size, const uint8_t *data)
if (offset <= (ETP_IAP_START_ADDR * 2) &&
(ETP_IAP_START_ADDR * 2) < (offset + size)) {
iap_addr = ((data[ETP_IAP_START_ADDR * 2 - offset + 1] << 8) |
- data[ETP_IAP_START_ADDR * 2 - offset]) << 1;
+ data[ETP_IAP_START_ADDR * 2 - offset])
+ << 1;
CPRINTS("%s: payload starts from 0x%x.", __func__, iap_addr);
}
@@ -608,7 +605,7 @@ int touchpad_update_write(int offset, int size, const uint8_t *data)
return EC_ERROR_INVAL;
for (addr = offset; addr < (offset + size);
- addr += elan_tp_params.page_size) {
+ addr += elan_tp_params.page_size) {
if (iap_addr > addr) /* Skip chunk */
continue;
rv = touchpad_update_page(data + addr - offset);
@@ -632,21 +629,17 @@ int touchpad_update_write(int offset, int size, const uint8_t *data)
#define TOUCHPAD_ELAN_DEBUG_CMD_LENGTH 50
#define TOUCHPAD_ELAN_DEBUG_NUM_CMD 2
-static const uint8_t
-allowed_command_hashes[TOUCHPAD_ELAN_DEBUG_NUM_CMD][SHA256_DIGEST_SIZE] = {
- {
- 0x0a, 0xf6, 0x37, 0x03, 0x93, 0xb2, 0xde, 0x8c,
- 0x56, 0x7b, 0x86, 0xba, 0xa6, 0x79, 0xe3, 0xa3,
- 0x8b, 0xc7, 0x15, 0xf2, 0x53, 0xcf, 0x71, 0x8b,
- 0x3d, 0xe4, 0x81, 0xf9, 0xd9, 0xa8, 0x78, 0x48
- },
- {
- 0xac, 0xe5, 0xbf, 0x17, 0x1f, 0xde, 0xce, 0x76,
- 0x0c, 0x0e, 0xf8, 0xa2, 0xe9, 0x67, 0x2d, 0xc9,
- 0x1b, 0xd4, 0xba, 0x34, 0x51, 0xca, 0xf6, 0x6d,
- 0x7b, 0xb2, 0x1f, 0x14, 0x82, 0x1c, 0x0b, 0x74
- },
-};
+static const uint8_t allowed_command_hashes
+ [TOUCHPAD_ELAN_DEBUG_NUM_CMD][SHA256_DIGEST_SIZE] = {
+ { 0x0a, 0xf6, 0x37, 0x03, 0x93, 0xb2, 0xde, 0x8c,
+ 0x56, 0x7b, 0x86, 0xba, 0xa6, 0x79, 0xe3, 0xa3,
+ 0x8b, 0xc7, 0x15, 0xf2, 0x53, 0xcf, 0x71, 0x8b,
+ 0x3d, 0xe4, 0x81, 0xf9, 0xd9, 0xa8, 0x78, 0x48 },
+ { 0xac, 0xe5, 0xbf, 0x17, 0x1f, 0xde, 0xce, 0x76,
+ 0x0c, 0x0e, 0xf8, 0xa2, 0xe9, 0x67, 0x2d, 0xc9,
+ 0x1b, 0xd4, 0xba, 0x34, 0x51, 0xca, 0xf6, 0x6d,
+ 0x7b, 0xb2, 0x1f, 0x14, 0x82, 0x1c, 0x0b, 0x74 },
+ };
/* Debugging commands need to allocate a <=1k buffer. */
SHARED_MEM_CHECK_SIZE(1024);
@@ -677,8 +670,8 @@ int touchpad_debug(const uint8_t *param, unsigned int param_size,
uint8_t *command_hash;
unsigned int offset = param[1];
unsigned int write_length = param[2];
- unsigned int read_length =
- ((unsigned int)param[3] << 8) | param[4];
+ unsigned int read_length = ((unsigned int)param[3] << 8) |
+ param[4];
int i;
int match;
int rv;
@@ -688,13 +681,14 @@ int touchpad_debug(const uint8_t *param, unsigned int param_size,
return EC_RES_INVALID_PARAM;
SHA256_init(&ctx);
- SHA256_update(&ctx, param+5, TOUCHPAD_ELAN_DEBUG_CMD_LENGTH-5);
+ SHA256_update(&ctx, param + 5,
+ TOUCHPAD_ELAN_DEBUG_CMD_LENGTH - 5);
command_hash = SHA256_final(&ctx);
match = 0;
for (i = 0; i < TOUCHPAD_ELAN_DEBUG_NUM_CMD; i++) {
if (!memcmp(command_hash, allowed_command_hashes[i],
- sizeof(allowed_command_hashes[i]))) {
+ sizeof(allowed_command_hashes[i]))) {
match = 1;
break;
}
@@ -711,8 +705,8 @@ int touchpad_debug(const uint8_t *param, unsigned int param_size,
buffer_size = read_length;
if (read_length > 0) {
- if (shared_mem_acquire(buffer_size,
- (char **)&buffer) != EC_SUCCESS) {
+ if (shared_mem_acquire(buffer_size, (char **)&buffer) !=
+ EC_SUCCESS) {
buffer = NULL;
buffer_size = 0;
return EC_RES_BUSY;
@@ -722,9 +716,8 @@ int touchpad_debug(const uint8_t *param, unsigned int param_size,
}
rv = i2c_xfer(CONFIG_TOUCHPAD_I2C_PORT,
- CONFIG_TOUCHPAD_I2C_ADDR_FLAGS,
- &param[offset], write_length,
- buffer, read_length);
+ CONFIG_TOUCHPAD_I2C_ADDR_FLAGS, &param[offset],
+ write_length, buffer, read_length);
if (rv)
return EC_RES_BUS_ERROR;
@@ -796,7 +789,7 @@ static void touchpad_power_control(void)
#ifdef CONFIG_USB_SUSPEND
enable = enable &&
- (!usb_is_suspended() || usb_is_remote_wakeup_enabled());
+ (!usb_is_suspended() || usb_is_remote_wakeup_enabled());
#endif
#ifdef CONFIG_TABLET_MODE