Cr50: I2CM: Enable i2c master for accessing INA chips

On both Reef and Gru there are INA (shunt bus voltage monitor) ICs
connected to the Cr50 I2C master bus. The use case for these chips is
in a lab setting using case closed debugging. Power to the INA chips
is controlled by a separate Cr50 gpio signal.

By default, the INAs are powered off and the I2C master bus is not
connected. A function ina_connect() is provided which needs to be
called prior to attempting to access the INAs via I2C.

BRANCH=none
BUG=chrome-os-partner:57059
TEST=manual
Tested both Reef and Gru. Verified that console command 'ccd ina
on|off' works as expected and that can repeatedly read registers on
the INA using the following command "i2cxfer r16 0 0x40 0".
Read 0x2771 [10097] which is the default value. In addition
wrote register 14 (bits 15:1 are writeable) and verified the value was
able to read the value back which was written.

Change-Id: I670f7897555dae29642264531599dc4471c52bbd
Signed-off-by: Scott <scollyer@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/394168
Commit-Ready: Scott Collyer <scollyer@chromium.org>
Tested-by: Scott Collyer <scollyer@chromium.org>
Reviewed-by: Bill Richardson <wfrichar@chromium.org>
This commit is contained in:
Scott
2016-10-04 12:52:31 -07:00
committed by chrome-bot
parent 8c370fedba
commit 7bfcb41d2c
5 changed files with 82 additions and 5 deletions

View File

@@ -12,9 +12,11 @@
#include "flash_config.h"
#include "gpio.h"
#include "hooks.h"
#include "i2c.h"
#include "i2cs.h"
#include "init_chip.h"
#include "nvmem.h"
#include "rdd.h"
#include "registers.h"
#include "signed_header.h"
#include "spi.h"
@@ -73,11 +75,19 @@ uint32_t nvmem_user_sizes[NVMEM_NUM_USERS] = {
static uint32_t board_properties;
static uint8_t reboot_request_posted;
/* I2C Port definition */
const struct i2c_port_t i2c_ports[] = {
{"master", I2C_PORT_MASTER, 100,
GPIO_I2C_SCL_INA, GPIO_I2C_SDA_INA},
};
const unsigned int i2c_ports_used = ARRAY_SIZE(i2c_ports);
void post_reboot_request(void)
{
/* Reboot the device next time TPM reset is requested. */
reboot_request_posted = 1;
}
/*
* There's no way to trigger on both rising and falling edges, so force a
* compiler error if we try. The workaround is to use the pinmux to connect
@@ -595,6 +605,9 @@ static void servo_attached(void)
/* Disconnect AP and EC UART when servo is attached */
uartn_tx_disconnect(UART_AP);
uartn_tx_disconnect(UART_EC);
/* Disconnect i2cm interface to ina */
ina_disconnect();
}
void device_state_on(enum gpio_signal signal)

View File

@@ -213,7 +213,10 @@ enum nvmem_users {
#define CONFIG_USB_FW_UPDATE
#define CONFIG_I2C
#define CONFIG_I2C_MASTER
#define CONFIG_I2C_SLAVE
#define CONFIG_TPM_I2CS
#define I2C_PORT_MASTER 0
#endif /* __CROS_EC_BOARD_H */

View File

@@ -41,12 +41,15 @@ GPIO(SPI_MOSI, PIN(0, 7), GPIO_INPUT)
GPIO(SPI_CLK, PIN(0, 8), GPIO_INPUT)
GPIO(SPI_CS_L, PIN(0, 9), GPIO_INPUT)
/* Control the load switch powering the INA 3.3V rail */
GPIO(EN_PP3300_INA_L, PIN(1, 9), GPIO_ODR_HIGH)
/* GPIOs used for Cr50 strapping options */
GPIO(STRAP0, PIN(0, 10), GPIO_INPUT)
/* Control the load switch powering the INA 3.3V rail */
GPIO(EN_PP3300_INA_L, PIN(0, 11), GPIO_ODR_HIGH)
/* GPIOs used for I2CM pins for INAs */
GPIO(I2C_SCL_INA, PIN(0, 12), GPIO_INPUT)
GPIO(I2C_SDA_INA, PIN(0, 13), GPIO_INPUT)
/* Unimplemented signals which we need to emulate for now */
/* TODO(wfrichar): Half the boards don't use this signal. Take it out. */
UNIMPLEMENTED(ENTERING_RW)
@@ -71,7 +74,8 @@ PINMUX(GPIO(SYS_RST_L_OUT), M0, DIO_INPUT)
PINMUX(GPIO(CCD_MODE_L), M1, DIO_INPUT)
PINMUX(GPIO(BATT_PRES_L), M2, 0)
PINMUX(GPIO(STRAP0), A1, DIO_INPUT)
PINMUX(GPIO(I2C_SCL_INA), B0, DIO_INPUT)
PINMUX(GPIO(I2C_SDA_INA), B1, DIO_INPUT)
/* UARTs */
PINMUX(FUNC(UART0_TX), A0, DIO_OUTPUT) /* Cr50 console */
PINMUX(FUNC(UART0_RX), A13, DIO_INPUT | DIO_WAKE_FALLING)

View File

@@ -8,6 +8,7 @@
#include "device_state.h"
#include "gpio.h"
#include "hooks.h"
#include "i2c.h"
#include "rbox.h"
#include "rdd.h"
#include "registers.h"
@@ -94,6 +95,45 @@ void uartn_tx_disconnect(int uart)
uart_select_tx(uart, 0);
}
void ina_connect(void)
{
/* Apply power to INA chips */
gpio_set_level(GPIO_EN_PP3300_INA_L, 0);
/* Allow enough time for power rail to come up */
usleep(25);
/*
* Connect B0/B1 pads to I2C0 input SDA/SCL. Note, that the inputs
* for these pads are already enabled for the gpio signals I2C_SCL_INA
* and I2C_SDA_INA in gpio.inc.
*/
GWRITE(PINMUX, I2C0_SDA_SEL, GC_PINMUX_DIOB1_SEL);
GWRITE(PINMUX, I2C0_SCL_SEL, GC_PINMUX_DIOB0_SEL);
/* Connect I2CS SDA/SCL output to B1/B0 pads */
GWRITE(PINMUX, DIOB1_SEL, GC_PINMUX_I2C0_SDA_SEL);
GWRITE(PINMUX, DIOB0_SEL, GC_PINMUX_I2C0_SCL_SEL);
/*
* Initialize the i2cm module after the INAs are powered and the signal
* lines are connected.
*/
i2cm_init();
}
void ina_disconnect(void)
{
/* Disonnect I2C0 SDA/SCL output to B1/B0 pads */
GWRITE(PINMUX, DIOB1_SEL, 0);
GWRITE(PINMUX, DIOB0_SEL, 0);
/* Disconnect B1/B0 pads to I2C0 input SDA/SCL */
GWRITE(PINMUX, I2C0_SDA_SEL, 0);
GWRITE(PINMUX, I2C0_SCL_SEL, 0);
/* Disable power to INA chips */
gpio_set_level(GPIO_EN_PP3300_INA_L, 1);
}
void rdd_attached(void)
{
/* Indicate case-closed debug mode (active low) */
@@ -198,6 +238,17 @@ static int command_ccd(int argc, char **argv)
ec_uart_enabled = 0;
uartn_tx_disconnect(UART_EC);
}
} else if (!strcasecmp("ina", argv[1]) && argc > 2) {
if (!parse_bool(argv[2], &val))
return EC_ERROR_PARAM2;
if (val) {
ina_connect();
ccprintf("CCD: INAs enabled\n");
} else {
ina_disconnect();
ccprintf("CCD: INAs disabled\n");
}
} else if (argc == 2) {
if (!parse_bool(argv[1], &val))
return EC_ERROR_PARAM1;
@@ -217,7 +268,7 @@ static int command_ccd(int argc, char **argv)
return EC_SUCCESS;
}
DECLARE_CONSOLE_COMMAND(ccd, command_ccd,
"[uart] [<BOOLEAN>]",
"[uart|ina] [<BOOLEAN>]",
"Get/set the case closed debug state");
static int command_sys_rst(int argc, char **argv)

View File

@@ -18,4 +18,10 @@ void rdd_attached(void);
* cable is detached.
*/
int is_utmi_wakeup_allowed(void);
/* Power up INAs and initialize I2C0 interface */
void ina_connect(void);
/* Disconnect I2C0 interface and powerdown INAs */
void ina_disconnect(void);
#endif /* __CROS_RDD_H */