From 304d207117bb82db7f38303ba402c6f1be1112a8 Mon Sep 17 00:00:00 2001 From: Vincent Palatin Date: Thu, 24 May 2012 21:39:12 +0000 Subject: Split communication functions from host tools Preparatory work to re-use the tools on ARM boards using I2C communications. Signed-off-by: Vincent Palatin BUG=None TEST=make BOARD=link && make BOARD=bds && make BOard=DAISY Change-Id: I31d41f30c3231a4a9349b939bf6bba871ed4c383 --- util/build.mk | 1 + util/comm-host.h | 29 ++++++++++++++ util/comm-lpc.c | 119 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ util/ectool.c | 103 +---------------------------------------------- util/lbplay.c | 69 +------------------------------- 5 files changed, 153 insertions(+), 168 deletions(-) create mode 100644 util/comm-host.h create mode 100644 util/comm-lpc.c (limited to 'util') diff --git a/util/build.mk b/util/build.mk index a3aa636b06..393d6f492b 100644 --- a/util/build.mk +++ b/util/build.mk @@ -7,4 +7,5 @@ # host-util-bin=ectool lbplay +host-util-common=comm-lpc build-util-bin=ec_uartd stm32mon diff --git a/util/comm-host.h b/util/comm-host.h new file mode 100644 index 0000000000..9647a06218 --- /dev/null +++ b/util/comm-host.h @@ -0,0 +1,29 @@ +/* Copyright (c) 2012 The Chromium OS Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#ifndef COMM_HOST_H +#define COMM_HOST_H + +#include + +/* Perform initializations needed for subsequent requests + * + * returns 0 in case of success or error code. */ +int comm_init(void); + +/* Sends a command to the EC. Returns the command status code, or + * -1 if other error. */ +int ec_command(int command, const void *indata, int insize, + void *outdata, int outsize); + +/* Returns the content of the EC information area mapped as "memory". + * + * the offsets are defined by the EC_MEMMAP_ constants. */ +uint8_t read_mapped_mem8(uint8_t offset); +uint16_t read_mapped_mem16(uint8_t offset); +uint32_t read_mapped_mem32(uint8_t offset); +int read_mapped_string(uint8_t offset, char *buf); + +#endif /* COMM_HOST_H */ diff --git a/util/comm-lpc.c b/util/comm-lpc.c new file mode 100644 index 0000000000..1eff85c4e1 --- /dev/null +++ b/util/comm-lpc.c @@ -0,0 +1,119 @@ +/* Copyright (c) 2012 The Chromium OS Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include +#include +#include +#include + +#include "comm-host.h" +#include "ec_commands.h" + + +int comm_init(void) +{ + /* Request I/O privilege */ + if (iopl(3) < 0) { + perror("Error getting I/O privilege"); + return -3; + } + return 0; +} + + +/* Waits for the EC to be unbusy. Returns 0 if unbusy, non-zero if + * timeout. */ +static int wait_for_ec(int status_addr, int timeout_usec) +{ + int i; + for (i = 0; i < timeout_usec; i += 10) { + usleep(10); /* Delay first, in case we just sent a command */ + if (!(inb(status_addr) & EC_LPC_STATUS_BUSY_MASK)) + return 0; + } + return -1; /* Timeout */ +} + +/* Sends a command to the EC. Returns the command status code, or + * -1 if other error. */ +int ec_command(int command, const void *indata, int insize, + void *outdata, int outsize) { + uint8_t *d; + int i; + + /* TODO: add command line option to use kernel command/param window */ + int cmd_addr = EC_LPC_ADDR_USER_CMD; + int data_addr = EC_LPC_ADDR_USER_DATA; + int param_addr = EC_LPC_ADDR_USER_PARAM; + + if (insize > EC_PARAM_SIZE || outsize > EC_PARAM_SIZE) { + fprintf(stderr, "Data size too big\n"); + return -1; + } + + if (wait_for_ec(cmd_addr, 1000000)) { + fprintf(stderr, "Timeout waiting for EC ready\n"); + return -1; + } + + /* Write data, if any */ + /* TODO: optimized copy using outl() */ + for (i = 0, d = (uint8_t *)indata; i < insize; i++, d++) + outb(*d, param_addr + i); + + outb(command, cmd_addr); + + if (wait_for_ec(cmd_addr, 1000000)) { + fprintf(stderr, "Timeout waiting for EC response\n"); + return -1; + } + + /* Check result */ + i = inb(data_addr); + if (i) { + fprintf(stderr, "EC returned error result code %d\n", i); + return i; + } + + /* Read data, if any */ + /* TODO: optimized copy using outl() */ + for (i = 0, d = (uint8_t *)outdata; i < outsize; i++, d++) + *d = inb(param_addr + i); + + return 0; +} + + +uint8_t read_mapped_mem8(uint8_t offset) +{ + return inb(EC_LPC_ADDR_MEMMAP + offset); +} + + +uint16_t read_mapped_mem16(uint8_t offset) +{ + return inw(EC_LPC_ADDR_MEMMAP + offset); +} + + +uint32_t read_mapped_mem32(uint8_t offset) +{ + return inl(EC_LPC_ADDR_MEMMAP + offset); +} + + +int read_mapped_string(uint8_t offset, char *buf) +{ + int c; + + for (c = 0; c < EC_MEMMAP_TEXT_MAX; c++) { + buf[c] = inb(EC_LPC_ADDR_MEMMAP + offset + c); + if (buf[c] == 0) + return c; + } + + buf[EC_MEMMAP_TEXT_MAX-1] = 0; + return EC_MEMMAP_TEXT_MAX; +} diff --git a/util/ectool.c b/util/ectool.c index 98b85f22f4..a129791ca0 100644 --- a/util/ectool.c +++ b/util/ectool.c @@ -12,6 +12,7 @@ #include #include "battery.h" +#include "comm-host.h" #include "ec_commands.h" #include "lightbar.h" #include "system.h" @@ -175,103 +176,6 @@ static char *read_file(const char *filename, int *size) } -/* Waits for the EC to be unbusy. Returns 0 if unbusy, non-zero if - * timeout. */ -int wait_for_ec(int status_addr, int timeout_usec) -{ - int i; - for (i = 0; i < timeout_usec; i += 10) { - usleep(10); /* Delay first, in case we just sent a command */ - if (!(inb(status_addr) & EC_LPC_STATUS_BUSY_MASK)) - return 0; - } - return -1; /* Timeout */ -} - - -/* Sends a command to the EC. Returns the command status code, or - * -1 if other error. */ -int ec_command(int command, const void *indata, int insize, - void *outdata, int outsize) { - uint8_t *d; - int i; - - /* TODO: add command line option to use kernel command/param window */ - int cmd_addr = EC_LPC_ADDR_USER_CMD; - int data_addr = EC_LPC_ADDR_USER_DATA; - int param_addr = EC_LPC_ADDR_USER_PARAM; - - if (insize > EC_PARAM_SIZE || outsize > EC_PARAM_SIZE) { - fprintf(stderr, "Data size too big\n"); - return -1; - } - - if (wait_for_ec(cmd_addr, 1000000)) { - fprintf(stderr, "Timeout waiting for EC ready\n"); - return -1; - } - - /* Write data, if any */ - /* TODO: optimized copy using outl() */ - for (i = 0, d = (uint8_t *)indata; i < insize; i++, d++) - outb(*d, param_addr + i); - - outb(command, cmd_addr); - - if (wait_for_ec(cmd_addr, 1000000)) { - fprintf(stderr, "Timeout waiting for EC response\n"); - return -1; - } - - /* Check result */ - i = inb(data_addr); - if (i) { - fprintf(stderr, "EC returned error result code %d\n", i); - return i; - } - - /* Read data, if any */ - /* TODO: optimized copy using outl() */ - for (i = 0, d = (uint8_t *)outdata; i < outsize; i++, d++) - *d = inb(param_addr + i); - - return 0; -} - - -uint8_t read_mapped_mem8(uint8_t offset) -{ - return inb(EC_LPC_ADDR_MEMMAP + offset); -} - - -uint16_t read_mapped_mem16(uint8_t offset) -{ - return inw(EC_LPC_ADDR_MEMMAP + offset); -} - - -uint32_t read_mapped_mem32(uint8_t offset) -{ - return inl(EC_LPC_ADDR_MEMMAP + offset); -} - - -int read_mapped_string(uint8_t offset, char *buf) -{ - int c; - - for (c = 0; c < EC_MEMMAP_TEXT_MAX; c++) { - buf[c] = inb(EC_LPC_ADDR_MEMMAP + offset + c); - if (buf[c] == 0) - return c; - } - - buf[EC_MEMMAP_TEXT_MAX-1] = 0; - return EC_MEMMAP_TEXT_MAX; -} - - int is_string_printable(const char *buf) { while (*buf) { @@ -1582,11 +1486,8 @@ int main(int argc, char *argv[]) return -2; } - /* Request I/O privilege */ - if (iopl(3) < 0) { - perror("Error getting I/O privilege"); + if (comm_init() < 0) return -3; - } /* Handle commands */ for (cmd = commands; cmd->name; cmd++) { diff --git a/util/lbplay.c b/util/lbplay.c index 6e0ceefcba..71511c581c 100644 --- a/util/lbplay.c +++ b/util/lbplay.c @@ -10,6 +10,7 @@ #include #include +#include "comm-host.h" #include "lightbar.h" #include "ec_commands.h" @@ -17,68 +18,6 @@ #define BUILD_ASSERT(cond) ((void)sizeof(char[1 - 2*!(cond)])) #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) -/* Waits for the EC to be unbusy. Returns 0 if unbusy, non-zero if - * timeout. */ -static int wait_for_ec(int status_addr, int timeout_usec) -{ - int i; - for (i = 0; i < timeout_usec; i += 10) { - usleep(10); /* Delay first, in case we just sent a command */ - if (!(inb(status_addr) & EC_LPC_STATUS_BUSY_MASK)) - return 0; - } - return -1; /* Timeout */ -} - - -/* Sends a command to the EC. Returns the command status code, or - * -1 if other error. */ -static int ec_command(int command, const void *indata, int insize, - void *outdata, int outsize) { - uint8_t *d; - int i; - - /* TODO: add command line option to use kernel command/param window */ - int cmd_addr = EC_LPC_ADDR_USER_CMD; - int data_addr = EC_LPC_ADDR_USER_DATA; - int param_addr = EC_LPC_ADDR_USER_PARAM; - - if (insize > EC_PARAM_SIZE || outsize > EC_PARAM_SIZE) { - fprintf(stderr, "Data size too big\n"); - return -1; - } - - if (wait_for_ec(cmd_addr, 1000000)) { - fprintf(stderr, "Timeout waiting for EC ready\n"); - return -1; - } - - /* Write data, if any */ - /* TODO: optimized copy using outl() */ - for (i = 0, d = (uint8_t *)indata; i < insize; i++, d++) - outb(*d, param_addr + i); - - outb(command, cmd_addr); - - if (wait_for_ec(cmd_addr, 1000000)) { - fprintf(stderr, "Timeout waiting for EC response\n"); - return -1; - } - - /* Check result */ - i = inb(data_addr); - if (i) { - fprintf(stderr, "EC returned error result code %d\n", i); - return i; - } - - /* Read data, if any */ - /* TODO: optimized copy using outl() */ - for (i = 0, d = (uint8_t *)outdata; i < outsize; i++, d++) - *d = inb(param_addr + i); - - return 0; -} static const struct { uint8_t insize; @@ -201,12 +140,8 @@ int main(int argc, char **argv) BUILD_ASSERT(ARRAY_SIZE(lb_command_paramcount) == LIGHTBAR_NUM_CMDS); - /* Request I/O privilege */ - if (iopl(3) < 0) { - perror("Error getting I/O privilege"); + if (comm_init() < 0) return -3; - } - /* Tell the EC to let us drive. */ lightbar_sequence(LIGHTBAR_STOP); -- cgit v1.2.1