mirror of
https://github.com/Telecominfraproject/OpenCellular.git
synced 2026-01-10 17:41:54 +00:00
Add memory-mapped data support for I2C and SPI protocols
And fix returning memory-mapped string length on LPC as well. BUG=chrome-os-partner:11090 TEST=manual from EC, 'hostevent set 0x40000' from host, 'ectool eventget' --> should print 0x40000 Signed-off-by: Randall Spangler <rspangler@chromium.org> Change-Id: I9edbd0a1468b5d4160ce67c471332226e51fa868 Reviewed-on: https://gerrit.chromium.org/gerrit/26719 Reviewed-by: Simon Glass <sjg@chromium.org>
This commit is contained in:
@@ -227,7 +227,7 @@ void lpc_comx_put_char(int c)
|
||||
*/
|
||||
static void update_host_event_status(void) {
|
||||
uint32_t *mapped_raw_events =
|
||||
(uint32_t *)(lpc_get_memmap_range() + EC_MEMMAP_HOST_EVENTS);
|
||||
(uint32_t *)host_get_memmap(EC_MEMMAP_HOST_EVENTS);
|
||||
|
||||
int need_sci = 0;
|
||||
int need_smi = 0;
|
||||
|
||||
@@ -515,7 +515,7 @@ void power_button_task(void)
|
||||
static int power_button_init(void)
|
||||
{
|
||||
/* Set up memory-mapped switch positions */
|
||||
memmap_switches = lpc_get_memmap_range() + EC_MEMMAP_SWITCHES;
|
||||
memmap_switches = host_get_memmap(EC_MEMMAP_SWITCHES);
|
||||
*memmap_switches = 0;
|
||||
if (get_lid_open()) {
|
||||
debounced_lid_open = 1;
|
||||
@@ -633,7 +633,7 @@ DECLARE_CONSOLE_COMMAND(lidclose, command_lidclose,
|
||||
|
||||
static int command_mmapinfo(int argc, char **argv)
|
||||
{
|
||||
uint8_t *memmap_switches = lpc_get_memmap_range() + EC_MEMMAP_SWITCHES;
|
||||
uint8_t *memmap_switches = host_get_memmap(EC_MEMMAP_SWITCHES);
|
||||
uint8_t val = *memmap_switches;
|
||||
int i;
|
||||
const char *explanation[] = {
|
||||
|
||||
@@ -5,13 +5,12 @@
|
||||
|
||||
/* PWM control module for Chrome EC */
|
||||
|
||||
#include "board.h"
|
||||
#include "common.h"
|
||||
#include "console.h"
|
||||
#include "gpio.h"
|
||||
#include "hooks.h"
|
||||
#include "host_command.h"
|
||||
#include "lpc.h"
|
||||
#include "ec_commands.h"
|
||||
#include "pwm.h"
|
||||
#include "registers.h"
|
||||
#include "task.h"
|
||||
@@ -103,11 +102,10 @@ int pwm_set_keyboard_backlight(int percent)
|
||||
return EC_SUCCESS;
|
||||
}
|
||||
|
||||
static void update_lpc_mapped_memory(void)
|
||||
static void update_mapped_memory(void)
|
||||
{
|
||||
int i, r;
|
||||
uint16_t *mapped = (uint16_t *)(lpc_get_memmap_range() +
|
||||
EC_MEMMAP_FAN);
|
||||
uint16_t *mapped = (uint16_t *)host_get_memmap(EC_MEMMAP_FAN);
|
||||
|
||||
for (i = 0; i < 4; ++i)
|
||||
mapped[i] = 0xffff;
|
||||
@@ -140,7 +138,7 @@ void pwm_task(void)
|
||||
{
|
||||
while (1) {
|
||||
check_fan_failure();
|
||||
update_lpc_mapped_memory();
|
||||
update_mapped_memory();
|
||||
usleep(1000000);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,14 +8,14 @@
|
||||
|
||||
#include "battery.h"
|
||||
#include "battery_pack.h"
|
||||
#include "board.h"
|
||||
#include "charge_state.h"
|
||||
#include "charger.h"
|
||||
#include "chipset.h"
|
||||
#include "common.h"
|
||||
#include "console.h"
|
||||
#include "gpio.h"
|
||||
#include "host_command.h"
|
||||
#include "lpc.h"
|
||||
#include "ec_commands.h"
|
||||
#include "power_button.h"
|
||||
#include "power_led.h"
|
||||
#include "printf.h"
|
||||
@@ -41,37 +41,34 @@ static void update_battery_info(void)
|
||||
int batt_serial;
|
||||
|
||||
/* Design Capacity of Full */
|
||||
battery_design_capacity((int *)(lpc_get_memmap_range() +
|
||||
EC_MEMMAP_BATT_DCAP));
|
||||
battery_design_capacity((int *)host_get_memmap(EC_MEMMAP_BATT_DCAP));
|
||||
|
||||
/* Design Voltage */
|
||||
battery_design_voltage((int *)(lpc_get_memmap_range() +
|
||||
EC_MEMMAP_BATT_DVLT));
|
||||
battery_design_voltage((int *)host_get_memmap(EC_MEMMAP_BATT_DVLT));
|
||||
|
||||
/* Last Full Charge Capacity */
|
||||
battery_full_charge_capacity((int *)(lpc_get_memmap_range() +
|
||||
EC_MEMMAP_BATT_LFCC));
|
||||
battery_full_charge_capacity(
|
||||
(int *)host_get_memmap(EC_MEMMAP_BATT_LFCC));
|
||||
|
||||
/* Cycle Count */
|
||||
battery_cycle_count((int *)(lpc_get_memmap_range() +
|
||||
EC_MEMMAP_BATT_CCNT));
|
||||
battery_cycle_count((int *)host_get_memmap(EC_MEMMAP_BATT_CCNT));
|
||||
|
||||
/* Battery Manufacturer string */
|
||||
batt_str = (char *)(lpc_get_memmap_range() + EC_MEMMAP_BATT_MFGR);
|
||||
batt_str = (char *)host_get_memmap(EC_MEMMAP_BATT_MFGR);
|
||||
memset(batt_str, 0, EC_MEMMAP_TEXT_MAX);
|
||||
battery_manufacturer_name(batt_str, EC_MEMMAP_TEXT_MAX);
|
||||
|
||||
/* Battery Model string */
|
||||
batt_str = (char *)(lpc_get_memmap_range() + EC_MEMMAP_BATT_MODEL);
|
||||
batt_str = (char *)host_get_memmap(EC_MEMMAP_BATT_MODEL);
|
||||
memset(batt_str, 0, EC_MEMMAP_TEXT_MAX);
|
||||
battery_device_name(batt_str, EC_MEMMAP_TEXT_MAX);
|
||||
|
||||
/* Battery Type string */
|
||||
batt_str = (char *)(lpc_get_memmap_range() + EC_MEMMAP_BATT_TYPE);
|
||||
batt_str = (char *)host_get_memmap(EC_MEMMAP_BATT_TYPE);
|
||||
battery_device_chemistry(batt_str, EC_MEMMAP_TEXT_MAX);
|
||||
|
||||
/* Smart battery serial number is 16 bits */
|
||||
batt_str = (char *)(lpc_get_memmap_range() + EC_MEMMAP_BATT_SERIAL);
|
||||
batt_str = (char *)host_get_memmap(EC_MEMMAP_BATT_SERIAL);
|
||||
memset(batt_str, 0, EC_MEMMAP_TEXT_MAX);
|
||||
if (battery_serial_number(&batt_serial) == 0)
|
||||
snprintf(batt_str, EC_MEMMAP_TEXT_MAX, "%04X", batt_serial);
|
||||
@@ -474,14 +471,13 @@ void charge_state_machine_task(void)
|
||||
ctx.charger = charger_get_info();
|
||||
|
||||
/* Setup LPC direct memmap */
|
||||
ctx.memmap_batt_volt = (uint32_t *)(lpc_get_memmap_range() +
|
||||
EC_MEMMAP_BATT_VOLT);
|
||||
ctx.memmap_batt_rate = (uint32_t *)(lpc_get_memmap_range() +
|
||||
EC_MEMMAP_BATT_RATE);
|
||||
ctx.memmap_batt_cap = (uint32_t *)(lpc_get_memmap_range() +
|
||||
EC_MEMMAP_BATT_CAP);
|
||||
ctx.memmap_batt_flags = (uint8_t *)(lpc_get_memmap_range() +
|
||||
EC_MEMMAP_BATT_FLAG);
|
||||
ctx.memmap_batt_volt =
|
||||
(uint32_t *)host_get_memmap(EC_MEMMAP_BATT_VOLT);
|
||||
ctx.memmap_batt_rate =
|
||||
(uint32_t *)host_get_memmap(EC_MEMMAP_BATT_RATE);
|
||||
ctx.memmap_batt_cap =
|
||||
(uint32_t *)host_get_memmap(EC_MEMMAP_BATT_CAP);
|
||||
ctx.memmap_batt_flags = host_get_memmap(EC_MEMMAP_BATT_FLAG);
|
||||
|
||||
while (1) {
|
||||
|
||||
|
||||
@@ -23,6 +23,18 @@
|
||||
|
||||
static int host_command[2];
|
||||
|
||||
#ifndef CONFIG_LPC
|
||||
static uint8_t host_memmap[EC_MEMMAP_SIZE];
|
||||
#endif
|
||||
|
||||
uint8_t *host_get_memmap(int offset)
|
||||
{
|
||||
#ifdef CONFIG_LPC
|
||||
return lpc_get_memmap_range() + offset;
|
||||
#else
|
||||
return host_memmap + offset;
|
||||
#endif
|
||||
}
|
||||
|
||||
void host_command_received(int slot, int command)
|
||||
{
|
||||
@@ -93,6 +105,32 @@ static int host_command_read_test(uint8_t *data, int *resp_size)
|
||||
}
|
||||
DECLARE_HOST_COMMAND(EC_CMD_READ_TEST, host_command_read_test);
|
||||
|
||||
#ifndef CONFIG_LPC
|
||||
/*
|
||||
* Host command to read memory map is not needed on LPC, because LPC can
|
||||
* directly map the data to the host's memory space.
|
||||
*/
|
||||
static int host_command_read_memmap(uint8_t *data, int *resp_size)
|
||||
{
|
||||
struct ec_params_read_memmap *p = (struct ec_params_read_memmap *)data;
|
||||
struct ec_response_read_memmap *r =
|
||||
(struct ec_response_read_memmap *)data;
|
||||
|
||||
/* Copy params out of data before we overwrite it with output */
|
||||
uint8_t offset = p->offset;
|
||||
uint8_t size = p->size;
|
||||
|
||||
if (size > sizeof(r->data) || offset > EC_MEMMAP_SIZE ||
|
||||
offset + size > EC_MEMMAP_SIZE)
|
||||
return EC_RES_INVALID_PARAM;
|
||||
|
||||
memcpy(r->data, host_get_memmap(offset), size);
|
||||
|
||||
*resp_size = size;
|
||||
return EC_RES_SUCCESS;
|
||||
}
|
||||
DECLARE_HOST_COMMAND(EC_CMD_READ_MEMMAP, host_command_read_memmap);
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_LPC
|
||||
/* ACPI query event handler. Note that the returned value is NOT actually
|
||||
@@ -114,7 +152,7 @@ static int host_command_acpi_query_event(uint8_t *data, int *resp_size)
|
||||
return 0;
|
||||
}
|
||||
DECLARE_HOST_COMMAND(EC_CMD_ACPI_QUERY_EVENT, host_command_acpi_query_event);
|
||||
#endif
|
||||
#endif /* CONFIG_LPC */
|
||||
|
||||
|
||||
/* Finds a command by command number. Returns the command structure, or NULL if
|
||||
|
||||
@@ -5,14 +5,13 @@
|
||||
|
||||
/* Temperature sensor module for Chrome EC */
|
||||
|
||||
#include "board.h"
|
||||
#include "chip_temp_sensor.h"
|
||||
#include "chipset.h"
|
||||
#include "common.h"
|
||||
#include "console.h"
|
||||
#include "gpio.h"
|
||||
#include "i2c.h"
|
||||
#include "lpc.h"
|
||||
#include "ec_commands.h"
|
||||
#include "host_command.h"
|
||||
#include "peci.h"
|
||||
#include "task.h"
|
||||
#include "temp_sensor.h"
|
||||
@@ -74,10 +73,10 @@ static void poll_fast_sensors(void)
|
||||
}
|
||||
|
||||
|
||||
static void update_lpc_mapped_memory(void)
|
||||
static void update_mapped_memory(void)
|
||||
{
|
||||
int i, t;
|
||||
uint8_t *mapped = lpc_get_memmap_range() + EC_MEMMAP_TEMP_SENSOR;
|
||||
uint8_t *mapped = host_get_memmap(EC_MEMMAP_TEMP_SENSOR);
|
||||
|
||||
memset(mapped, 0xff, 16);
|
||||
|
||||
@@ -104,7 +103,7 @@ void temp_sensor_task(void)
|
||||
poll_fast_sensors();
|
||||
}
|
||||
poll_slow_sensors();
|
||||
update_lpc_mapped_memory();
|
||||
update_mapped_memory();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -257,6 +257,22 @@ struct ec_params_board_version {
|
||||
uint16_t board_version; /* A monotonously incrementing number. */
|
||||
} __packed;
|
||||
|
||||
/*
|
||||
* Read memory-mapped data.
|
||||
*
|
||||
* This is an alternate interface to memory-mapped data for bus protocols
|
||||
* which don't support direct-mapped memory - I2C, SPI, etc.
|
||||
*/
|
||||
#define EC_CMD_READ_MEMMAP 0x07
|
||||
|
||||
struct ec_params_read_memmap {
|
||||
uint8_t offset; /* Offset in memmap (EC_MEMMAP_*) */
|
||||
uint8_t size; /* Size to read in bytes */
|
||||
} __packed;
|
||||
|
||||
struct ec_response_read_memmap {
|
||||
uint32_t data[EC_PARAM_SIZE];
|
||||
} __packed;
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Flash commands */
|
||||
|
||||
@@ -21,6 +21,17 @@ struct host_command {
|
||||
int (*handler)(uint8_t *data, int *response_size);
|
||||
};
|
||||
|
||||
/**
|
||||
* Return a pointer to the memory-mapped buffer.
|
||||
*
|
||||
* This buffer is EC_MEMMAP_SIZE bytes long, is writable at any time, and the
|
||||
* host can read it at any time.
|
||||
*
|
||||
* @param offset Offset within the range to return
|
||||
* @return pointer to the buffer at that offset
|
||||
*/
|
||||
uint8_t *host_get_memmap(int offset);
|
||||
|
||||
/**
|
||||
* Process a host command and return its response
|
||||
*
|
||||
|
||||
@@ -29,6 +29,11 @@ int ec_command(int command, const void *indata, int insize,
|
||||
uint8_t read_mapped_mem8(uint8_t offset);
|
||||
uint16_t read_mapped_mem16(uint8_t offset);
|
||||
uint32_t read_mapped_mem32(uint8_t offset);
|
||||
/*
|
||||
* Read a memory-mapped string at the specified offset and store into buf,
|
||||
* which must be at least size EC_MEMMAP_TEXT_MAX. Returns the length of
|
||||
* the copied string, not counting the terminating '\0', or <0 if error.
|
||||
*/
|
||||
int read_mapped_string(uint8_t offset, char *buf);
|
||||
|
||||
#endif /* COMM_HOST_H */
|
||||
|
||||
@@ -186,30 +186,70 @@ done:
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
uint8_t read_mapped_mem8(uint8_t offset)
|
||||
{
|
||||
/* Not implemented */
|
||||
return 0xff;
|
||||
}
|
||||
struct ec_params_read_memmap p;
|
||||
uint8_t val;
|
||||
|
||||
p.offset = offset;
|
||||
p.size = sizeof(val);
|
||||
|
||||
if (ec_command(EC_CMD_READ_MEMMAP, &p, sizeof(p),
|
||||
&val, sizeof(val)) < 0)
|
||||
return 0xff;
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
uint16_t read_mapped_mem16(uint8_t offset)
|
||||
{
|
||||
/* Not implemented */
|
||||
return 0xffff;
|
||||
}
|
||||
struct ec_params_read_memmap p;
|
||||
uint16_t val;
|
||||
|
||||
p.offset = offset;
|
||||
p.size = sizeof(val);
|
||||
|
||||
if (ec_command(EC_CMD_READ_MEMMAP, &p, sizeof(p),
|
||||
&val, sizeof(val)) < 0)
|
||||
return 0xffff;
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
uint32_t read_mapped_mem32(uint8_t offset)
|
||||
{
|
||||
/* Not implemented */
|
||||
return 0xffffffff;
|
||||
}
|
||||
struct ec_params_read_memmap p;
|
||||
uint32_t val;
|
||||
|
||||
p.offset = offset;
|
||||
p.size = sizeof(val);
|
||||
|
||||
if (ec_command(EC_CMD_READ_MEMMAP, &p, sizeof(p),
|
||||
&val, sizeof(val)) < 0)
|
||||
return 0xffffffff;
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
int read_mapped_string(uint8_t offset, char *buf)
|
||||
{
|
||||
strncpy(buf, "NOT IMPLEMENTED", EC_MEMMAP_TEXT_MAX);
|
||||
return sizeof("NOT IMPLEMENTED");
|
||||
struct ec_params_read_memmap p;
|
||||
int c;
|
||||
|
||||
p.offset = offset;
|
||||
p.size = EC_MEMMAP_TEXT_MAX;
|
||||
|
||||
if (ec_command(EC_CMD_READ_MEMMAP, &p, sizeof(p),
|
||||
buf, EC_MEMMAP_TEXT_MAX) < 0) {
|
||||
*buf = 0;
|
||||
return -1;
|
||||
}
|
||||
|
||||
for (c = 0; c < EC_MEMMAP_TEXT_MAX; c++) {
|
||||
if (buf[c] == 0)
|
||||
return c;
|
||||
}
|
||||
|
||||
buf[EC_MEMMAP_TEXT_MAX - 1] = 0;
|
||||
return EC_MEMMAP_TEXT_MAX - 1;
|
||||
}
|
||||
|
||||
@@ -157,6 +157,6 @@ int read_mapped_string(uint8_t offset, char *buf)
|
||||
return c;
|
||||
}
|
||||
|
||||
buf[EC_MEMMAP_TEXT_MAX-1] = 0;
|
||||
return EC_MEMMAP_TEXT_MAX;
|
||||
buf[EC_MEMMAP_TEXT_MAX - 1] = 0;
|
||||
return EC_MEMMAP_TEXT_MAX - 1;
|
||||
}
|
||||
|
||||
@@ -1487,32 +1487,22 @@ int cmd_battery(int argc, char *argv[])
|
||||
printf("Battery info:\n");
|
||||
|
||||
rv = read_mapped_string(EC_MEMMAP_BATT_MFGR, batt_text);
|
||||
if (rv) {
|
||||
if (!is_string_printable(batt_text))
|
||||
goto cmd_error;
|
||||
printf(" OEM name: %s\n", batt_text);
|
||||
}
|
||||
if (rv < 0 || !is_string_printable(batt_text))
|
||||
goto cmd_error;
|
||||
printf(" OEM name: %s\n", batt_text);
|
||||
|
||||
rv = read_mapped_string(EC_MEMMAP_BATT_MODEL, batt_text);
|
||||
if (rv) {
|
||||
if (!is_string_printable(batt_text))
|
||||
goto cmd_error;
|
||||
printf(" Model number: %s\n", batt_text);
|
||||
}
|
||||
if (rv < 0 || !is_string_printable(batt_text))
|
||||
goto cmd_error;
|
||||
printf(" Model number: %s\n", batt_text);
|
||||
|
||||
rv = read_mapped_string(EC_MEMMAP_BATT_TYPE, batt_text);
|
||||
if (rv) {
|
||||
if (!is_string_printable(batt_text))
|
||||
goto cmd_error;
|
||||
printf(" Chemistry : %s\n", batt_text);
|
||||
}
|
||||
if (rv < 0 || !is_string_printable(batt_text))
|
||||
goto cmd_error;
|
||||
printf(" Chemistry : %s\n", batt_text);
|
||||
|
||||
rv = read_mapped_string(EC_MEMMAP_BATT_SERIAL, batt_text);
|
||||
if (rv) {
|
||||
if (!is_string_printable(batt_text))
|
||||
goto cmd_error;
|
||||
printf(" Serial number: %s\n", batt_text);
|
||||
}
|
||||
printf(" Serial number: %s\n", batt_text);
|
||||
|
||||
val = read_mapped_mem32(EC_MEMMAP_BATT_DCAP);
|
||||
if (!is_battery_range(val))
|
||||
|
||||
Reference in New Issue
Block a user