mirror of
https://github.com/Telecominfraproject/OpenCellular.git
synced 2026-01-09 17:11:42 +00:00
samus: add options for device passthru and interface
This allows sending host commands to the PD chip through the EC. The --interface option allows forcing a particular host interface. This is necessary at present because the crosec device driver doesn't support host protocol v3 so only has 8-bit command numbers. BUG=chrome-os-partner:30079 BRANCH=none TEST=from EC console, ectool version -> prints EC version ectool --interface=lpc --dev=0 version -> prints EC version ectool --interface=lpc --dev=1 version -> prints PD version ectool --interface=lpc --dev=2 version -> prints error ectool --interface=i2c version -> can't find EC ectool --interface=dev version -> prints EC version Change-Id: I9dd10578dac77e3e104d19e2f37759814eec6ca2 Signed-off-by: Randall Spangler <rspangler@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/207948
This commit is contained in:
committed by
chrome-internal-fetch
parent
9ef82030e6
commit
241cc62685
@@ -130,7 +130,7 @@ int main(int argc, char *argv[])
|
||||
{
|
||||
extern uint8_t data[] asm("_payload_start");
|
||||
|
||||
if (comm_init() < 0)
|
||||
if (comm_init(COMM_ALL) < 0)
|
||||
return -3;
|
||||
|
||||
flash_partition(EC_IMAGE_RW, data + CONFIG_FW_RW_OFF,
|
||||
|
||||
@@ -102,7 +102,7 @@ int comm_init_dev(void)
|
||||
return 3;
|
||||
}
|
||||
|
||||
ec_command = ec_command_dev;
|
||||
ec_command_proto = ec_command_dev;
|
||||
if (ec_readmem_dev(EC_MEMMAP_ID, 2, version) == 2 &&
|
||||
version[0] == 'E' && version[1] == 'C')
|
||||
ec_readmem = ec_readmem_dev;
|
||||
|
||||
@@ -11,15 +11,16 @@
|
||||
#include "comm-host.h"
|
||||
#include "ec_commands.h"
|
||||
|
||||
int (*ec_command)(int command, int version,
|
||||
const void *outdata, int outsize,
|
||||
void *indata, int insize);
|
||||
int (*ec_command_proto)(int command, int version,
|
||||
const void *outdata, int outsize,
|
||||
void *indata, int insize);
|
||||
|
||||
int (*ec_readmem)(int offset, int bytes, void *dest);
|
||||
|
||||
int ec_max_outsize, ec_max_insize;
|
||||
void *ec_outbuf;
|
||||
void *ec_inbuf;
|
||||
static int command_offset;
|
||||
|
||||
int comm_init_dev(void) __attribute__((weak));
|
||||
int comm_init_lpc(void) __attribute__((weak));
|
||||
@@ -58,21 +59,36 @@ static int fake_readmem(int offset, int bytes, void *dest)
|
||||
return EC_MEMMAP_TEXT_MAX - 1;
|
||||
}
|
||||
|
||||
int comm_init(void)
|
||||
void set_command_offset(int offset)
|
||||
{
|
||||
command_offset = offset;
|
||||
}
|
||||
|
||||
int ec_command(int command, int version,
|
||||
const void *outdata, int outsize,
|
||||
void *indata, int insize)
|
||||
{
|
||||
/* Offset command code to support sub-devices */
|
||||
return ec_command_proto(command_offset + command, version,
|
||||
outdata, outsize,
|
||||
indata, insize);
|
||||
}
|
||||
|
||||
int comm_init(int interfaces)
|
||||
{
|
||||
/* Default memmap access */
|
||||
ec_readmem = fake_readmem;
|
||||
|
||||
/* Prefer new /dev method */
|
||||
if (comm_init_dev && !comm_init_dev())
|
||||
if ((interfaces & COMM_DEV) && comm_init_dev && !comm_init_dev())
|
||||
goto init_ok;
|
||||
|
||||
/* Fallback to direct LPC on x86 */
|
||||
if (comm_init_lpc && !comm_init_lpc())
|
||||
if ((interfaces & COMM_LPC) && comm_init_lpc && !comm_init_lpc())
|
||||
goto init_ok;
|
||||
|
||||
/* Fallback to direct i2c on ARM */
|
||||
if (comm_init_i2c && !comm_init_i2c())
|
||||
if ((interfaces & COMM_I2C) && comm_init_i2c && !comm_init_i2c())
|
||||
goto init_ok;
|
||||
|
||||
/* Give up */
|
||||
|
||||
@@ -25,19 +25,45 @@ extern int ec_max_outsize, ec_max_insize;
|
||||
extern void *ec_outbuf;
|
||||
extern void *ec_inbuf;
|
||||
|
||||
/* Interfaces to allow for comm_init() */
|
||||
enum comm_interface {
|
||||
COMM_DEV = (1 << 0),
|
||||
COMM_LPC = (1 << 1),
|
||||
COMM_I2C = (1 << 2),
|
||||
COMM_ALL = -1
|
||||
};
|
||||
|
||||
/**
|
||||
* Perform initializations needed for subsequent requests
|
||||
*
|
||||
* returns 0 in case of success or error code. */
|
||||
int comm_init(void);
|
||||
* @param interfaces Interfaces to try; use COMM_ALL to try all of them.
|
||||
* @return 0 in case of success, or error code.
|
||||
*/
|
||||
int comm_init(int interfaces);
|
||||
|
||||
/**
|
||||
* Send a command to the EC. Returns the length of output data returned (0 if
|
||||
* none), or negative on error.
|
||||
*/
|
||||
extern int (*ec_command)(int command, int version,
|
||||
const void *outdata, int outsize, /* to the EC */
|
||||
void *indata, int insize); /* from the EC */
|
||||
int ec_command(int command, int version,
|
||||
const void *outdata, int outsize, /* to the EC */
|
||||
void *indata, int insize); /* from the EC */
|
||||
|
||||
/**
|
||||
* Set the offset to be applied to the command number when ec_command() calls
|
||||
* ec_command_proto().
|
||||
*/
|
||||
void set_command_offset(int offset);
|
||||
|
||||
/**
|
||||
* Send a command to the EC. Returns the length of output data returned (0 if
|
||||
* none), or negative on error. This is the low-level interface implemented
|
||||
* by the protocol-specific driver. DO NOT call this version directly from
|
||||
* anywhere but ec_command(), or the --device option will not work.
|
||||
*/
|
||||
extern int (*ec_command_proto)(int command, int version,
|
||||
const void *outdata, int outsize, /* to EC */
|
||||
void *indata, int insize); /* from EC */
|
||||
|
||||
/**
|
||||
* Return the content of the EC information area mapped as "memory".
|
||||
|
||||
@@ -206,7 +206,7 @@ int comm_init_i2c(void)
|
||||
|
||||
free(file_path);
|
||||
|
||||
ec_command = ec_command_i2c;
|
||||
ec_command_proto = ec_command_i2c;
|
||||
ec_max_outsize = ec_max_insize = EC_PROTO2_MAX_PARAM_SIZE;
|
||||
|
||||
return 0;
|
||||
|
||||
@@ -289,7 +289,7 @@ int comm_init_lpc(void)
|
||||
|
||||
if (i & EC_HOST_CMD_FLAG_VERSION_3) {
|
||||
/* Protocol version 3 */
|
||||
ec_command = ec_command_lpc_3;
|
||||
ec_command_proto = ec_command_lpc_3;
|
||||
ec_max_outsize = EC_LPC_HOST_PACKET_SIZE -
|
||||
sizeof(struct ec_host_request);
|
||||
ec_max_insize = EC_LPC_HOST_PACKET_SIZE -
|
||||
@@ -297,7 +297,7 @@ int comm_init_lpc(void)
|
||||
|
||||
} else if (i & EC_HOST_CMD_FLAG_LPC_ARGS_SUPPORTED) {
|
||||
/* Protocol version 2 */
|
||||
ec_command = ec_command_lpc;
|
||||
ec_command_proto = ec_command_lpc;
|
||||
ec_max_outsize = ec_max_insize = EC_PROTO2_MAX_PARAM_SIZE;
|
||||
|
||||
} else {
|
||||
|
||||
@@ -342,7 +342,7 @@ int comm_init_lpc(void)
|
||||
|
||||
if (i & EC_HOST_CMD_FLAG_VERSION_3) {
|
||||
/* Protocol version 3 */
|
||||
ec_command = ec_command_lpc_3;
|
||||
ec_command_proto = ec_command_lpc_3;
|
||||
ec_max_outsize = EC_LPC_HOST_PACKET_SIZE -
|
||||
sizeof(struct ec_host_request);
|
||||
ec_max_insize = EC_LPC_HOST_PACKET_SIZE -
|
||||
@@ -350,7 +350,7 @@ int comm_init_lpc(void)
|
||||
|
||||
} else if (i & EC_HOST_CMD_FLAG_LPC_ARGS_SUPPORTED) {
|
||||
/* Protocol version 2 */
|
||||
ec_command = ec_command_lpc;
|
||||
ec_command_proto = ec_command_lpc;
|
||||
ec_max_outsize = ec_max_insize = EC_PROTO2_MAX_PARAM_SIZE;
|
||||
|
||||
} else {
|
||||
|
||||
@@ -25,12 +25,13 @@
|
||||
|
||||
/* Command line options */
|
||||
enum {
|
||||
OPT_HELP = '?',
|
||||
OPT_DEV = 1000,
|
||||
OPT_INTERFACE,
|
||||
};
|
||||
|
||||
static struct option long_opts[] = {
|
||||
{"dev", 1, 0, OPT_DEV},
|
||||
{"interface", 1, 0, OPT_INTERFACE},
|
||||
{NULL, 0, 0, 0}
|
||||
};
|
||||
|
||||
@@ -216,7 +217,8 @@ int parse_bool(const char *s, int *dest)
|
||||
|
||||
void print_help(const char *prog, int print_cmds)
|
||||
{
|
||||
printf("Usage: %s [--dev=n] <command> [params]\n\n",
|
||||
printf("Usage: %s [--dev=n] [--interface=dev|lpc|i2c] <command> "
|
||||
"[params]\n\n",
|
||||
prog);
|
||||
if (print_cmds)
|
||||
puts(help_str);
|
||||
@@ -4540,6 +4542,7 @@ int main(int argc, char *argv[])
|
||||
{
|
||||
const struct command *cmd;
|
||||
int dev = 0;
|
||||
int interfaces = COMM_ALL;
|
||||
int rv = 1;
|
||||
int parse_error = 0;
|
||||
char *e;
|
||||
@@ -4561,6 +4564,19 @@ int main(int argc, char *argv[])
|
||||
parse_error = 1;
|
||||
}
|
||||
break;
|
||||
|
||||
case OPT_INTERFACE:
|
||||
if (!strcasecmp(optarg, "dev")) {
|
||||
interfaces = COMM_DEV;
|
||||
} else if (!strcasecmp(optarg, "lpc")) {
|
||||
interfaces = COMM_LPC;
|
||||
} else if (!strcasecmp(optarg, "i2c")) {
|
||||
interfaces = COMM_I2C;
|
||||
} else {
|
||||
fprintf(stderr, "Invalid --interface\n");
|
||||
parse_error = 1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4574,11 +4590,10 @@ int main(int argc, char *argv[])
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/*
|
||||
* --dev support is coming in the next patch. For now this is a
|
||||
* placeholder used in testing getopt_long()
|
||||
*/
|
||||
if (dev != 0) {
|
||||
/* Handle sub-devices command offset */
|
||||
if (dev > 0 && dev < 4) {
|
||||
set_command_offset(EC_CMD_PASSTHRU_OFFSET(dev));
|
||||
} else if (dev != 0) {
|
||||
fprintf(stderr, "Bad device number %d\n", dev);
|
||||
parse_error = 1;
|
||||
}
|
||||
@@ -4593,7 +4608,7 @@ int main(int argc, char *argv[])
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (comm_init()) {
|
||||
if (comm_init(interfaces)) {
|
||||
fprintf(stderr, "Couldn't find EC\n");
|
||||
goto out;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user