summaryrefslogtreecommitdiff
path: root/extra/touchpad_updater/touchpad_updater.c
diff options
context:
space:
mode:
authorChun-Ta Lin <itspeter@google.com>2017-06-21 15:14:37 +0800
committerchrome-bot <chrome-bot@chromium.org>2017-11-24 02:39:04 -0800
commitf326fb05b564b0975a9870b2831f9372539202db (patch)
tree30aae36290a70e21b502f387f2636370259f0176 /extra/touchpad_updater/touchpad_updater.c
parentbfa592f1673948469eca8f532da69462c4ecdbe6 (diff)
downloadchrome-ec-f326fb05b564b0975a9870b2831f9372539202db.tar.gz
hammer: enable large block reading on usb i2c passthru.
Originally, i2c passthru is limited to use I2C_XFER_SINGLE flag where it can only read at most 255 bytes at a time. For application that requires larger i2c bus reading, we change the flag setting and the command protocol. TEST=old ./touchpad_updater still works (previous protocol) TEST=new ./touchpad_updater can get more than 500 bytes per transaction TEST=Debug message only print when -d assigned. ./touchpad_updater -d TEST=Manually change #define CONFIG_USB_I2C_MAX_READ_COUNT (1024 - 6) to #define CONFIG_USB_I2C_MAX_READ_COUNT (1024 - 4) and trigger POWER_OF_TWO assertion. BRANCH=none BUG=b:35587174, b:63993891 Change-Id: Id75b11ea49ba89bab8e18af24d47219030c778c5 Signed-off-by: Chun-Ta Lin <itspeter@google.com> Reviewed-on: https://chromium-review.googlesource.com/542716 Commit-Ready: Chun-ta Lin <itspeter@chromium.org> Tested-by: Chun-ta Lin <itspeter@chromium.org> Reviewed-by: Nicolas Boichat <drinkcat@chromium.org>
Diffstat (limited to 'extra/touchpad_updater/touchpad_updater.c')
-rw-r--r--extra/touchpad_updater/touchpad_updater.c73
1 files changed, 58 insertions, 15 deletions
diff --git a/extra/touchpad_updater/touchpad_updater.c b/extra/touchpad_updater/touchpad_updater.c
index b54f348c2b..059ddb0933 100644
--- a/extra/touchpad_updater/touchpad_updater.c
+++ b/extra/touchpad_updater/touchpad_updater.c
@@ -21,6 +21,7 @@
static uint16_t vid = 0x18d1; /* Google */
static uint16_t pid = 0x5022; /* Hammer */
static uint8_t ep_num = 4; /* console endpoint */
+static uint8_t extended_i2c_exercise; /* non-zero to exercise */
static char *firmware_binary = "144.0_2.0.bin"; /* firmware blob */
/* Firmware binary blob related */
@@ -40,7 +41,7 @@ static int le_bytes_to_int(uint8_t *buf)
/* Command line parsing related */
static char *progname;
-static char *short_opts = ":f:v:p:e:h";
+static char *short_opts = ":f:v:p:e:hd";
static const struct option long_opts[] = {
/* name hasarg *flag val */
{"file", 1, NULL, 'f'},
@@ -48,6 +49,7 @@ static const struct option long_opts[] = {
{"pid", 1, NULL, 'p'},
{"ep", 1, NULL, 'e'},
{"help", 0, NULL, 'h'},
+ {"debug", 0, NULL, 'd'},
{NULL, 0, NULL, 0},
};
@@ -63,6 +65,8 @@ static void usage(int errs)
" -v,--vid HEXVAL Vendor ID (default %04x)\n"
" -p,--pid HEXVAL Product ID (default %04x)\n"
" -e,--ep NUM Endpoint (default %d)\n"
+ " -d,--debug Exercise extended read I2C over USB\n"
+ " and print verbose debug messages.\n"
" -h,--help Show this message\n"
"\n", progname, firmware_binary, vid, pid, ep_num);
@@ -107,6 +111,9 @@ static void parse_cmdline(int argc, char *argv[])
errorcnt++;
}
break;
+ case 'd':
+ extended_i2c_exercise = 1;
+ break;
case 'h':
usage(errorcnt);
break;
@@ -136,8 +143,8 @@ static void parse_cmdline(int argc, char *argv[])
}
/* USB transfer related */
-static uint8_t rx_buf[128];
-static uint8_t tx_buf[128];
+static uint8_t rx_buf[1024];
+static uint8_t tx_buf[1024];
static struct libusb_device_handle *devh;
static struct libusb_transfer *rx_transfer;
@@ -272,8 +279,8 @@ static int check_read_status(int r, int expected, int actual)
printf("Warning: Defined error code (%d) returned.\n", r);
}
- if (r) {
- printf("Dumping the receive buffer:\n");
+ if (r || extended_i2c_exercise) {
+ printf("\nDumping the receive buffer:\n");
printf(" Recv %d bytes from USB hosts.\n", actual);
for (i = 0; i < actual; ++i)
printf(" [%2d]bytes: 0x%0x\n", i, rx_buf[i]);
@@ -282,26 +289,40 @@ static int check_read_status(int r, int expected, int actual)
}
#define MAX_USB_PACKET_SIZE 64
+#define PRIMITIVE_READING_SIZE 60
static int libusb_single_write_and_read(
uint8_t *to_write, uint16_t write_length,
- uint8_t *to_read, uint8_t read_length)
+ uint8_t *to_read, uint16_t read_length)
{
int r;
int tx_ready;
int remains;
int sent_bytes = 0;
int actual_length = -1;
+ int offset = read_length > PRIMITIVE_READING_SIZE ? 6 : 4;
tx_transfer = rx_transfer = 0;
- memmove(tx_buf + 4, to_write, write_length);
+ memmove(tx_buf + offset, to_write, write_length);
tx_buf[0] = I2C_PORT_ON_HAMMER;
tx_buf[1] = I2C_ADDRESS_ON_HAMMER;
tx_buf[2] = write_length;
- tx_buf[3] = read_length;
+ if (read_length > PRIMITIVE_READING_SIZE) {
+ tx_buf[3] = (read_length & 0x7f) | (1 << 7);
+ tx_buf[4] = read_length >> 7;
+ if (extended_i2c_exercise) {
+ printf("Triggering extended reading."
+ "rc:%0x, rc1:%0x\n",
+ tx_buf[3], tx_buf[4]);
+ printf("Expecting %d Bytes.\n",
+ (tx_buf[3] & 0x7f) | (tx_buf[4] << 7));
+ }
+ } else {
+ tx_buf[3] = read_length;
+ }
- while (sent_bytes < (4 + write_length)) {
- tx_ready = remains = (4 + write_length) - sent_bytes;
+ while (sent_bytes < (offset + write_length)) {
+ tx_ready = remains = (offset + write_length) - sent_bytes;
if (tx_ready > MAX_USB_PACKET_SIZE)
tx_ready = MAX_USB_PACKET_SIZE;
@@ -312,7 +333,8 @@ static int libusb_single_write_and_read(
if (r == 0 && actual_length == tx_ready) {
r = libusb_bulk_transfer(devh,
(ep_num | LIBUSB_ENDPOINT_IN),
- rx_buf, 128, &actual_length, 0);
+ rx_buf, sizeof(rx_buf),
+ &actual_length, 0);
}
r = check_read_status(
r, (remains == tx_ready) ? read_length : 0,
@@ -526,6 +548,16 @@ static uint16_t elan_update_firmware(void)
return checksum;
}
+static void pretty_print_buffer(uint8_t *buf, int len)
+{
+ int i;
+
+ printf("Buffer = 0x");
+ for (i = 0; i < len; ++i)
+ printf("%02X", buf[i]);
+ printf("\n");
+}
+
int main(int argc, char *argv[])
{
uint16_t local_checksum;
@@ -537,7 +569,7 @@ int main(int argc, char *argv[])
/*
* Judge IC type and get page count first.
- *Then check the FW file.
+ * Then check the FW file.
*/
fw_page_count = elan_get_ic_page_count();
fw_size = fw_page_count * FW_PAGE_SIZE;
@@ -545,15 +577,26 @@ int main(int argc, char *argv[])
/* Read the FW file */
FILE *f = fopen(firmware_binary, "rb");
-
- if (!(f && fread(fw_data, 1, fw_size, f) == (unsigned int)fw_size))
- printf("Failed to read firmware from %s\n", firmware_binary);
+ if (!f)
+ request_exit("Cannot find binary: %s\n", firmware_binary);
+ if (fread(fw_data, 1, fw_size, f) != (unsigned int)fw_size)
+ request_exit("binary size mismatch, expect %d\n", fw_size);
/*
* It is possible that you are not able to get firmware info. This
* might due to an incomplete update last time
*/
elan_get_fw_info();
+
+ if (extended_i2c_exercise) {
+ /*
+ * Trigger an I2C transaction of expecting reading > 60 bytes.
+ * source: https://goo.gl/pSxESS
+ */
+ elan_write_and_read(0x0002, rx_buf, 118, 0, 0);
+ pretty_print_buffer(rx_buf, 118);
+ }
+
/* Get the trackpad ready for receiving update */
elan_prepare_for_update();