diff --git a/common/battery_commands.c b/common/battery_commands.c deleted file mode 100644 index c4f282c699..0000000000 --- a/common/battery_commands.c +++ /dev/null @@ -1,105 +0,0 @@ -/* 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. - * - * Battery host commands for Chrome EC - */ - - -#include "host_command.h" -#include "smart_battery.h" -#include "battery.h" - -static inline uint8_t hex2asc(uint8_t hex) -{ - return hex + ((hex > 9) ? 'A' : '0'); -} - -enum lpc_status battery_command_get_info(uint8_t *data) -{ - struct lpc_response_battery_info *r = - (struct lpc_response_battery_info *)data; - int val; - - if (battery_design_capacity(&val)) - return EC_LPC_RESULT_ERROR; - r->design_capacity = val; - r->design_capacity_warning = val * BATTERY_LEVEL_WARNING / 100; - r->design_capacity_low = val * BATTERY_LEVEL_LOW / 100; - - if (battery_full_charge_capacity(&val)) - return EC_LPC_RESULT_ERROR; - r->last_full_charge_capacity = val; - - if (battery_design_voltage(&val)) - return EC_LPC_RESULT_ERROR; - r->design_output_voltage = val; - - if (battery_cycle_count(&val)) - return EC_LPC_RESULT_ERROR; - r->cycle_count = val; - - return EC_LPC_RESULT_SUCCESS; -} -DECLARE_HOST_COMMAND(EC_LPC_COMMAND_BATTERY_INFO, - battery_command_get_info); - -enum lpc_status battery_command_get_type(uint8_t *data) -{ - struct lpc_response_battery_text *r = - (struct lpc_response_battery_text *)data; - - if (battery_device_chemistry(r->text, sizeof(r->text))) - return EC_LPC_RESULT_ERROR; - - return EC_LPC_RESULT_SUCCESS; -} -DECLARE_HOST_COMMAND(EC_LPC_COMMAND_BATTERY_TYPE, - battery_command_get_type); - -enum lpc_status battery_command_get_model_number(uint8_t *data) -{ - struct lpc_response_battery_text *r = - (struct lpc_response_battery_text *)data; - - if (battery_device_name(r->text, sizeof(r->text))) - return EC_LPC_RESULT_ERROR; - - return EC_LPC_RESULT_SUCCESS; -} -DECLARE_HOST_COMMAND(EC_LPC_COMMAND_BATTERY_MODEL_NUMBER, - battery_command_get_model_number); - -enum lpc_status battery_command_get_serial_number(uint8_t *data) -{ - struct lpc_response_battery_text *r = - (struct lpc_response_battery_text *)data; - int serial; - - if (battery_serial_number(&serial)) - return EC_LPC_RESULT_ERROR; - - /* Smart battery serial number is 16 bits */ - r->text[0] = hex2asc(0xf & (serial >> 12)); - r->text[1] = hex2asc(0xf & (serial >> 8)); - r->text[2] = hex2asc(0xf & (serial >> 4)); - r->text[3] = hex2asc(0xf & serial); - r->text[4] = 0; - - return EC_LPC_RESULT_SUCCESS; -} -DECLARE_HOST_COMMAND(EC_LPC_COMMAND_BATTERY_SERIAL_NUMBER, - battery_command_get_serial_number); - -enum lpc_status battery_command_get_oem(uint8_t *data) -{ - struct lpc_response_battery_text *r = - (struct lpc_response_battery_text *)data; - - if (battery_manufacturer_name(r->text, sizeof(r->text))) - return EC_LPC_RESULT_ERROR; - - return EC_LPC_RESULT_SUCCESS; -} -DECLARE_HOST_COMMAND(EC_LPC_COMMAND_BATTERY_OEM, - battery_command_get_oem); diff --git a/common/build.mk b/common/build.mk index e018804b63..0cb7c401e7 100644 --- a/common/build.mk +++ b/common/build.mk @@ -16,8 +16,7 @@ common-$(CONFIG_LPC)+=port80.o host_event_commands.o common-$(CONFIG_POWER_LED)+=power_led.o common-$(CONFIG_PSTORE)+=pstore_commands.o common-$(CONFIG_PWM)+=pwm_commands.o -common-$(CONFIG_SMART_BATTERY)+=smart_battery.o charge_state.o \ - battery_commands.o +common-$(CONFIG_SMART_BATTERY)+=smart_battery.o charge_state.o common-$(CONFIG_TASK_GAIAPOWER)+=gaia_power.o common-$(CONFIG_TASK_HOSTCMD)+=host_command.o common-$(CONFIG_TASK_I8042CMD)+=i8042.o keyboard.o diff --git a/common/charge_state.c b/common/charge_state.c index 29ea4bba9c..3f28b1daee 100644 --- a/common/charge_state.c +++ b/common/charge_state.c @@ -101,6 +101,53 @@ static inline int get_ac(void) return gpio_get_level(GPIO_AC_PRESENT); } +/* Battery information used to fill ACPI _BIF and/or _BIX */ +static void update_battery_info(void) +{ + char *batt_str; + int batt_serial; + + /* Design Capacity of Full */ + battery_design_capacity((int *)(lpc_get_memmap_range() + + EC_LPC_MEMMAP_BATT_DCAP)); + + /* Design Voltage */ + battery_design_voltage((int *)(lpc_get_memmap_range() + + EC_LPC_MEMMAP_BATT_DVLT)); + + /* Last Full Charge Capacity */ + battery_full_charge_capacity((int *)(lpc_get_memmap_range() + + EC_LPC_MEMMAP_BATT_LFCC)); + + /* Cycle Count */ + battery_cycle_count((int *)(lpc_get_memmap_range() + + EC_LPC_MEMMAP_BATT_CCNT)); + + /* Battery Manufacturer string */ + batt_str = (char *)(lpc_get_memmap_range() + EC_LPC_MEMMAP_BATT_MFGR); + memset(batt_str, 0, EC_LPC_MEMMAP_TEXT_MAX); + battery_manufacturer_name(batt_str, EC_LPC_MEMMAP_TEXT_MAX); + + /* Battery Model string */ + batt_str = (char *)(lpc_get_memmap_range() + EC_LPC_MEMMAP_BATT_MODEL); + memset(batt_str, 0, EC_LPC_MEMMAP_TEXT_MAX); + battery_device_name(batt_str, EC_LPC_MEMMAP_TEXT_MAX); + + /* Battery Type string */ + batt_str = (char *)(lpc_get_memmap_range() + EC_LPC_MEMMAP_BATT_TYPE); + battery_device_chemistry(batt_str, EC_LPC_MEMMAP_TEXT_MAX); + + /* Smart battery serial number is 16 bits */ + batt_str = (char *)(lpc_get_memmap_range() + EC_LPC_MEMMAP_BATT_SERIAL); + memset(batt_str, 0, EC_LPC_MEMMAP_TEXT_MAX); + if (battery_serial_number(&batt_serial) == 0) { + *batt_str++ = hex2asc(0xf & (batt_serial >> 12)); + *batt_str++ = hex2asc(0xf & (batt_serial >> 8)); + *batt_str++ = hex2asc(0xf & (batt_serial >> 4)); + *batt_str++ = hex2asc(0xf & batt_serial); + } +} + /* Common handler for charging states. * This handler gets battery charging parameters, charger state, ac state, * and timestamp. It also fills memory map and issues power events on state @@ -171,7 +218,8 @@ static int state_common(struct power_state_context *ctx) if (rv) curr->error |= F_BATTERY_CURRENT; /* Memory mapped value: discharge rate */ - *ctx->memmap_batt_rate = batt->current < 0 ? -batt->current : 0; + *ctx->memmap_batt_rate = batt->current < 0 ? + -batt->current : batt->current; rv = battery_desired_voltage(&batt->desired_voltage); if (rv) @@ -255,6 +303,13 @@ static enum power_state state_init(struct power_state_context *ctx) if (ctx->curr.error) return PWR_STATE_ERROR; + /* Update static battery info */ + update_battery_info(); + + /* Send battery event to host */ + lpc_set_host_events(EC_LPC_HOST_EVENT_MASK( + EC_LPC_HOST_EVENT_BATTERY)); + return PWR_STATE_IDLE; } diff --git a/include/lpc_commands.h b/include/lpc_commands.h index 1f77b9b58c..46212ff73e 100644 --- a/include/lpc_commands.h +++ b/include/lpc_commands.h @@ -38,16 +38,25 @@ #define EC_LPC_ADDR_MEMMAP 0x900 #define EC_LPC_MEMMAP_SIZE 256 +#define EC_LPC_MEMMAP_TEXT_MAX 8 /* Size of a string in the memory map */ /* The offset address of each type of data in mapped memory. */ #define EC_LPC_MEMMAP_TEMP_SENSOR 0x00 #define EC_LPC_MEMMAP_FAN 0x10 -#define EC_LPC_MEMMAP_BATT_VOLT 0x20 -#define EC_LPC_MEMMAP_BATT_RATE 0x24 -#define EC_LPC_MEMMAP_BATT_CAP 0x28 -#define EC_LPC_MEMMAP_BATT_FLAG 0x2c #define EC_LPC_MEMMAP_SWITCHES 0x30 #define EC_LPC_MEMMAP_HOST_EVENTS 0x34 +#define EC_LPC_MEMMAP_BATT_VOLT 0x40 /* Battery Present Voltage */ +#define EC_LPC_MEMMAP_BATT_RATE 0x44 /* Battery Present Rate */ +#define EC_LPC_MEMMAP_BATT_CAP 0x48 /* Battery Remaining Capacity */ +#define EC_LPC_MEMMAP_BATT_FLAG 0x4c /* Battery State, defined below */ +#define EC_LPC_MEMMAP_BATT_DCAP 0x50 /* Battery Design Capacity */ +#define EC_LPC_MEMMAP_BATT_DVLT 0x54 /* Battery Design Voltage */ +#define EC_LPC_MEMMAP_BATT_LFCC 0x58 /* Battery Last Full Charge Capacity */ +#define EC_LPC_MEMMAP_BATT_CCNT 0x5c /* Battery Cycle Count */ +#define EC_LPC_MEMMAP_BATT_MFGR 0x60 /* Battery Manufacturer String */ +#define EC_LPC_MEMMAP_BATT_MODEL 0x68 /* Battery Model Number String */ +#define EC_LPC_MEMMAP_BATT_SERIAL 0x70 /* Battery Serial Number String */ +#define EC_LPC_MEMMAP_BATT_TYPE 0x78 /* Battery Type String */ /* Battery bit flags at EC_LPC_MEMMAP_BATT_FLAG. */ #define EC_BATT_FLAG_AC_PRESENT 0x01 @@ -398,45 +407,6 @@ struct lpc_response_thermal_get_threshold { /* Toggling automatic fan control */ #define EC_LPC_COMMAND_THERMAL_AUTO_FAN_CTRL 0x52 -/*****************************************************************************/ -/* Battery commands */ - -/* Maximum asciiz length of battery text data */ -#define EC_LPC_BATT_TEXT_MAX 32 - -/* Get battery info */ -#define EC_LPC_COMMAND_BATTERY_INFO 0x60 -struct lpc_response_battery_info { - uint32_t design_capacity; - uint32_t last_full_charge_capacity; - uint32_t design_output_voltage; - uint32_t design_capacity_warning; - uint32_t design_capacity_low; - uint32_t cycle_count; -} __attribute__ ((packed)); - -/* Following 4 battery commands use the same response data type - * BATTERY_TYPE - * BATTERY_MODEL_NUMBER - * BATTERY_MODEL_NUMBER - * BATTERY_SERIAL_NUMBER - */ -struct lpc_response_battery_text { - char text[EC_LPC_BATT_TEXT_MAX]; -} __attribute__ ((packed)); - -/* Get battery chemistry */ -#define EC_LPC_COMMAND_BATTERY_TYPE 0x61 - -/* Get battery model number */ -#define EC_LPC_COMMAND_BATTERY_MODEL_NUMBER 0x62 - -/* Get battery serial number */ -#define EC_LPC_COMMAND_BATTERY_SERIAL_NUMBER 0x63 - -/* Get battery OEM name */ -#define EC_LPC_COMMAND_BATTERY_OEM 0x64 - /*****************************************************************************/ /* Host event commands */ diff --git a/include/util.h b/include/util.h index 5a76a66a72..d11b3a587f 100644 --- a/include/util.h +++ b/include/util.h @@ -45,6 +45,11 @@ #define DIV_ROUND_UP(x, y) (((x) + ((y) - 1)) / (y)) #define DIV_ROUND_NEAREST(x, y) (((x) + ((y) / 2)) / (y)) +static inline uint8_t hex2asc(uint8_t hex) +{ + return hex + ((hex > 9) ? 'A' : '0'); +} + /* Standard library functions */ int atoi(const char *nptr); int isdigit(int c); diff --git a/util/ectool.c b/util/ectool.c index dcfe3a375d..749eee2cb9 100644 --- a/util/ectool.c +++ b/util/ectool.c @@ -10,6 +10,7 @@ #include #include "lpc_commands.h" +#include "battery.h" #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) /* Don't use a macro where an inline will do... */ @@ -243,6 +244,21 @@ uint32_t read_mapped_mem32(uint8_t offset) } +int read_mapped_string(uint8_t offset, char *buf) +{ + int c; + + for (c = 0; c < EC_LPC_MEMMAP_TEXT_MAX; c++) { + buf[c] = inb(EC_LPC_ADDR_MEMMAP + offset + c); + if (buf[c] == 0) + return c; + } + + buf[EC_LPC_MEMMAP_TEXT_MAX-1] = 0; + return EC_LPC_MEMMAP_TEXT_MAX; +} + + void print_help(const char *prog) { printf("Usage: %s [params]\n\n", prog); @@ -1171,52 +1187,41 @@ int cmd_switches(int argc, char *argv[]) int cmd_battery(int argc, char *argv[]) { - struct lpc_response_battery_info batt_info; - struct lpc_response_battery_text batt_text; + char batt_text[EC_LPC_MEMMAP_TEXT_MAX]; int rv; printf("Battery info:\n"); - rv = ec_command(EC_LPC_COMMAND_BATTERY_OEM, - NULL, 0, &batt_text, sizeof(batt_text)); + rv = read_mapped_string(EC_LPC_MEMMAP_BATT_MFGR, batt_text); if (rv) - return rv; - printf(" OEM name: %s\n", batt_text.text); + printf(" OEM name: %s\n", batt_text); - rv = ec_command(EC_LPC_COMMAND_BATTERY_MODEL_NUMBER, - NULL, 0, &batt_text, sizeof(batt_text)); + rv = read_mapped_string(EC_LPC_MEMMAP_BATT_MODEL, batt_text); if (rv) - return rv; - printf(" Model number: %s\n", batt_text.text); + printf(" Model number: %s\n", batt_text); - rv = ec_command(EC_LPC_COMMAND_BATTERY_TYPE, - NULL, 0, &batt_text, sizeof(batt_text)); + rv = read_mapped_string(EC_LPC_MEMMAP_BATT_TYPE, batt_text); if (rv) - return rv; - printf(" Chemistry: %s\n", batt_text.text); + printf(" Chemistry : %s\n", batt_text); - rv = ec_command(EC_LPC_COMMAND_BATTERY_SERIAL_NUMBER, - NULL, 0, &batt_text, sizeof(batt_text)); + rv = read_mapped_string(EC_LPC_MEMMAP_BATT_SERIAL, batt_text); if (rv) - return rv; - printf(" Serial number: %s\n", batt_text.text); + printf(" Serial number: %s\n", batt_text); - rv = ec_command(EC_LPC_COMMAND_BATTERY_INFO, - NULL, 0, &batt_info, sizeof(batt_info)); - if (rv) - return rv; printf(" Design capacity: %u mAh\n", - batt_info.design_capacity); + read_mapped_mem32(EC_LPC_MEMMAP_BATT_DCAP)); printf(" Last full charge: %u mAh\n", - batt_info.last_full_charge_capacity); + read_mapped_mem32(EC_LPC_MEMMAP_BATT_LFCC)); printf(" Design output voltage %u mV\n", - batt_info.design_output_voltage); + read_mapped_mem32(EC_LPC_MEMMAP_BATT_DVLT)); printf(" Design capacity warning %u mAh\n", - batt_info.design_capacity_warning); + read_mapped_mem32(EC_LPC_MEMMAP_BATT_DCAP) * + BATTERY_LEVEL_WARNING / 100); printf(" Design capacity low %u mAh\n", - batt_info.design_capacity_low); + read_mapped_mem32(EC_LPC_MEMMAP_BATT_DCAP) * + BATTERY_LEVEL_LOW / 100); printf(" Cycle count %u\n", - batt_info.cycle_count); + read_mapped_mem32(EC_LPC_MEMMAP_BATT_CCNT)); return 0; }