spring: Add host command to read power info

Getting voltage and current can be handy when verifying hardware design.
Let's add host command to do this.

BUG=chrome-os-partner:17880
TEST=Manual on Spring
BRANCH=none

Change-Id: I4d4f6a42a9d0f917292d092e132ccd9ce3367fd6
Signed-off-by: Vic Yang <victoryang@chromium.org>
Reviewed-on: https://gerrit.chromium.org/gerrit/43508
Reviewed-by: Vincent Palatin <vpalatin@chromium.org>
This commit is contained in:
Vic Yang
2013-02-19 13:33:33 +08:00
committed by ChromeBot
parent 2e64bed323
commit aab9accfce
7 changed files with 149 additions and 4 deletions

View File

@@ -9,8 +9,10 @@
#include "common.h"
#include "console.h"
#include "dma.h"
#include "ec_commands.h"
#include "gpio.h"
#include "hooks.h"
#include "host_command.h"
#include "i2c.h"
#include "lp5562.h"
#include "pmu_tpschrome.h"
@@ -333,3 +335,21 @@ int board_battery_led(enum charging_state state)
return lp5562_set_color(color);
}
/*****************************************************************************/
/* Host commands */
static int power_command_info(struct host_cmd_handler_args *args)
{
struct ec_response_power_info *r = args->response;
r->voltage_ac = adc_read_channel(ADC_CH_USB_VBUS_SNS);
r->voltage_system = pmu_adc_read(ADC_VAC) * 17000 / 1024;
r->current_system = pmu_adc_read(ADC_IAC) * 20 * 33 / 1024;
r->usb_dev_type = board_get_usb_dev_type();
r->usb_current_limit = board_get_usb_current_limit();
args->response_size = sizeof(*r);
return EC_RES_SUCCESS;
}
DECLARE_HOST_COMMAND(EC_CMD_POWER_INFO, power_command_info, EC_VER_MASK(0));

View File

@@ -168,6 +168,12 @@ void board_usb_charge_update(int force_update);
/* Update battery LED color */
int board_battery_led(enum charging_state state);
/* Get USB port device type */
int board_get_usb_dev_type(void);
/* Get USB port current limit */
int board_get_usb_current_limit(void);
#endif /* !__ASSEMBLER__ */
#endif /* __BOARD_H */

View File

@@ -35,6 +35,9 @@
#define I_LIMIT_2400MA 25
#define I_LIMIT_3000MA 0
static int current_dev_type = TSU6721_TYPE_NONE;
static int current_pwm_duty;
static enum ilim_config current_ilim_config = ILIM_CONFIG_MANUAL_OFF;
static const int apple_charger_type[4] = {I_LIMIT_500MA,
@@ -149,6 +152,7 @@ void board_pwm_duty_cycle(int percent)
if (percent > 100)
percent = 100;
STM32_TIM_CCR1(3) = (percent * STM32_TIM_ARR(3)) / 100;
current_pwm_duty = percent;
}
void usb_charge_interrupt(enum gpio_signal signal)
@@ -158,11 +162,9 @@ void usb_charge_interrupt(enum gpio_signal signal)
static void usb_device_change(int dev_type)
{
static int last_dev_type;
if (last_dev_type == dev_type)
if (current_dev_type == dev_type)
return;
last_dev_type = dev_type;
current_dev_type = dev_type;
/* Supply VBUS if needed */
if (dev_type & POWERED_DEVICE_TYPE)
@@ -228,6 +230,17 @@ void board_usb_charge_update(int force_update)
usb_device_change(tsu6721_get_device_type());
}
int board_get_usb_dev_type(void)
{
return current_dev_type;
}
int board_get_usb_current_limit(void)
{
/* Approximate value by PWM duty cycle */
return 3012 - 29 * current_pwm_duty;
}
/*
* Console command for debugging.
* TODO(victoryang): Remove after charging control is done.

View File

@@ -85,6 +85,11 @@
#define FET_CTRL_BASE (FET1_CTRL - 1)
/* AD control register bits */
#define AD_CTRL_ENADREF (1 << 4)
#define AD_CTRL_ADEOC (1 << 5)
#define AD_CTRL_ADSTART (1 << 6)
void __board_hard_reset(void)
{
CPRINTF("This board is not capable of a hard reset.\n");
@@ -401,6 +406,48 @@ int pmu_enable_fet(int fet_id, int enable, int *power_good)
return EC_SUCCESS;
}
int pmu_adc_read(int adc_idx)
{
int ctrl;
int val1, val2;
int rv;
rv = pmu_read(AD_CTRL, &ctrl);
if (rv)
return rv;
ctrl |= AD_CTRL_ENADREF;
rv = pmu_write(AD_CTRL, ctrl);
if (rv)
return rv;
msleep(20);
ctrl = (ctrl & ~0xf) | adc_idx;
rv = pmu_write(AD_CTRL, ctrl);
if (rv)
return rv;
udelay(150);
ctrl |= AD_CTRL_ADSTART;
rv = pmu_write(AD_CTRL, ctrl);
if (rv)
return rv;
udelay(200);
do {
rv = pmu_read(AD_CTRL, &ctrl);
if (rv)
return rv;
} while (!(ctrl & AD_CTRL_ADEOC));
rv = pmu_read(AD_OUT1, &val1) | pmu_read(AD_OUT2, &val2);
if (rv)
return rv;
rv = pmu_write(AD_CTRL, ctrl & ~AD_CTRL_ENADREF);
return (val2 << 8) | val1;
}
void pmu_irq_handler(enum gpio_signal signal)
{
#ifdef CONFIG_AC_POWER_STATUS

View File

@@ -1241,6 +1241,22 @@ struct ec_response_ldo_get {
uint8_t state;
} __packed;
/*****************************************************************************/
/* Power info. */
/*
* Get power info.
*/
#define EC_CMD_POWER_INFO 0x9d
struct ec_response_power_info {
uint32_t usb_dev_type;
uint16_t voltage_ac;
uint16_t voltage_system;
uint16_t current_system;
uint16_t usb_current_limit;
} __packed;
/*****************************************************************************/
/* Temporary debug commands. TODO: remove this crosbug.com/p/13849 */

View File

@@ -74,6 +74,21 @@ enum FASTCHARGE_TIMEOUT {
#define FET_LCD_PANEL 6
#define FET_TS 7
#define ADC_VAC 0
#define ADC_VBAT 1
#define ADC_IAC 2
#define ADC_IBAT 3
#define ADC_IDCDC1 4
#define ADC_IDCDC2 5
#define ADC_IDCDC3 6
#define ADC_IFET1 7
#define ADC_IFET2 8
#define ADC_IFET3 9
#define ADC_IFET4 10
#define ADC_IFET5 11
#define ADC_IFET6 12
#define ADC_IFET7 13
/**
* Clear tps65090 IRQ register
@@ -169,6 +184,13 @@ int pmu_set_term_voltage(enum TPS_TEMPERATURE_RANGE range,
*/
int pmu_low_current_charging(int enable);
/**
* Read ADC channel
*
* @param adc_idx Index of ADC channel
*/
int pmu_adc_read(int adc_idx);
/**
* Handles interrupts from tpschrome
*

View File

@@ -100,6 +100,8 @@ const char help_str[] =
" Various lightbar control commands\n"
" port80flood\n"
" Rapidly write bytes to port 80\n"
" powerinfo\n"
" Prints power-related information\n"
" pstoreinfo\n"
" Prints information on the EC host persistent storage\n"
" pstoreread <offset> <size> <outfile>\n"
@@ -1501,6 +1503,24 @@ int cmd_kbpress(int argc, char *argv[])
}
int cmd_power_info(int argc, char *argv[])
{
struct ec_response_power_info r;
int rv;
rv = ec_command(EC_CMD_POWER_INFO, 0, NULL, 0, &r, sizeof(r));
if (rv < 0)
return rv;
printf("AC Voltage: %d mV\n", r.voltage_ac);
printf("System Voltage: %d mV\n", r.voltage_system);
printf("System Current: %d mA\n", r.current_system);
printf("USB Device Type: 0x%x\n", r.usb_dev_type);
printf("USB Current Limit: %d mA\n", r.usb_current_limit);
return 0;
}
int cmd_pstore_info(int argc, char *argv[])
{
struct ec_response_pstore_info r;
@@ -2748,6 +2768,7 @@ const struct command commands[] = {
{"lightbar", cmd_lightbar},
{"keyconfig", cmd_keyconfig},
{"keyscan", cmd_keyscan},
{"powerinfo", cmd_power_info},
{"pstoreinfo", cmd_pstore_info},
{"pstoreread", cmd_pstore_read},
{"pstorewrite", cmd_pstore_write},