diff --git a/common/dev/include/tca9555.h b/common/dev/include/tca9555.h new file mode 100644 index 0000000000..b67bf9bd5b --- /dev/null +++ b/common/dev/include/tca9555.h @@ -0,0 +1,68 @@ +#ifndef __tca9555__ +#define __tca9555__ + +#include + +// Refer to Table3 Command byte +typedef enum +{ + /* Read byte Protocol*/ + TCA9555_INPUT_PORT0 = 0x00, + TCA9555_INPUT_PORT1 = 0x01, + + /* Read-write Protocol */ + /* default val: 11111111 */ + TCA9555_OUTPUT_PORT0 = 0x02, //config gpio I/O status + TCA9555_OUTPUT_PORT1 = 0x03, + TCA9555_CONFIG_PORT0 = 0x06, //config gpio direction + TCA9555_CONFIG_PORT1 = 0x07, + TCA9555_REG_ADDR_MAX + +} tca9555_reg_addr_t; + +/** + * @brief I2C slave address + */ +typedef enum { + TCA9555_ADDR_A2L_A1L_A0L = 0x20, + TCA9555_ADDR_A2L_A1L_A0H, + TCA9555_ADDR_A2L_A1H_A0L, + TCA9555_ADDR_A2L_A1H_A0H, + TCA9555_ADDR_A2H_A1L_A0L, + TCA9555_ADDR_A2H_A1L_A0H, + TCA9555_ADDR_A2H_A1H_A0L, + TCA9555_ADDR_A2H_A1H_A0H, + TCA9555_ADDR_MAX +} tca9555_addr_t; + +/** + * @brief TCA9555 GPIO mode + */ +typedef enum { + TCA9555_GPIO_OUTPUT = 0, + TCA9555_GPIO_INPUT = 1 +} tca9555_gpio_mode_t; + + +typedef enum { + P1V8_ASIC_PG_R = 0, + P0V8_ASICA_PWRGD, + P0V8_ASICD_PWRGD, + P0V9_ASICA_PWRGD, + PWRGD_PVDDQ_AB, + PVPP_AB_PG_R, + PVTT_AB_PG_R, + TCA9555_GPIO_P07, + PWRGD_PVDDQ_CD, + PVPP_CD_PG_R, + PVTT_CD_PG_R, + P0V9_ASICA_FT_R, + P0V8_ASICD_FT_R, + P0V8_ASICA_FT_R, + P5V_STBY_PG, + TCA9555_GPIO_P17, + TCA9555_GPIO_MAX +} tca9555_gpio_pin_t2; + + +#endif diff --git a/common/dev/tca9555.c b/common/dev/tca9555.c new file mode 100644 index 0000000000..0ed03f62d4 --- /dev/null +++ b/common/dev/tca9555.c @@ -0,0 +1,89 @@ +#include +#include + +#include "tca9555.h" +#include "sensor.h" +#include "hal_i2c.h" + +#define I2C_RETRY 5 + +bool tca9555_config_gpio_direction(uint8_t sensor_num, void *args) +{ + if (!args || (sensor_num > SENSOR_NUM_MAX)) { + return false; + } + + sensor_cfg *cfg = &sensor_config[sensor_config_index_map[sensor_num]]; + struct tca9555 *p = (struct tca9555 *)args; + + uint8_t retry = 5; + I2C_MSG msg = { 0 }; + + msg.bus = cfg->port; + /* change address to 7-bit */ + msg.target_addr = p->regs; + msg.tx_len = 1; + msg.data[0] = p->gpio_direction; + + if (i2c_master_write(&msg, retry)) + return false; + + return true; +} + + +uint8_t tca9555_read(uint8_t sensor_num, int *reading) +{ + if (!reading || (sensor_num > SENSOR_NUM_MAX)) { + return SENSOR_UNSPECIFIED_ERROR; + } + + uint8_t retry = 5; + I2C_MSG msg = { 0 }; + + msg.bus = sensor_config[sensor_config_index_map[sensor_num]].port; //i2c + msg.target_addr = sensor_config[sensor_config_index_map[sensor_num]].target_addr;// i/o expander address + msg.tx_len = 1; + msg.rx_len = 1; + msg.data[0] = sensor_config[sensor_config_index_map[sensor_num]].offset; //TCA9555_OUTPUT_PORT0 + + if (i2c_master_read(&msg, retry)) + return SENSOR_FAIL_TO_ACCESS; + + sensor_val *sval = (sensor_val *)reading; + sval->integer = msg.data[0]; + sval->fraction = 0; + + return SENSOR_READ_SUCCESS; +} + +bool tca9555_write(uint8_t sensor_num, int *reading) +{ + if (!reading || (sensor_num > SENSOR_NUM_MAX)) { + return SENSOR_UNSPECIFIED_ERROR; + } + + uint8_t retry = 5; + I2C_MSG msg = { 0 }; + + msg.bus = sensor_config[sensor_config_index_map[sensor_num]].port; //i2c + msg.target_addr = sensor_config[sensor_config_index_map[sensor_num]].target_addr;// i/o expander address + msg.tx_len = 1; + msg.rx_len = 1; + msg.data[0] = sensor_config[sensor_config_index_map[sensor_num]].offset; //TCA9555_OUTPUT_PORT0 + //msg.data[1] = sensor_config[sensor_config_index_map[sensor_num]].offset; //write data + + if (i2c_master_write(&msg, retry)) + return false; + return true; +} + +uint8_t tca9555_init(uint8_t sensor_num) +{ + if (sensor_num > SENSOR_NUM_MAX) { + return SENSOR_INIT_UNSPECIFIED_ERROR; + } + + sensor_config[sensor_config_index_map[sensor_num]].read = tca9555_read; + return SENSOR_INIT_SUCCESS; +} diff --git a/common/service/sensor/sensor.c b/common/service/sensor/sensor.c index ac15354ddd..9f14c7fe95 100644 --- a/common/service/sensor/sensor.c +++ b/common/service/sensor/sensor.c @@ -65,6 +65,8 @@ SENSOR_DRIVE_INIT_DECLARE(xdpe12284c); SENSOR_DRIVE_INIT_DECLARE(raa229621); SENSOR_DRIVE_INIT_DECLARE(nct7718w); SENSOR_DRIVE_INIT_DECLARE(ltc4286); +SENSOR_DRIVE_INIT_DECLARE(tca9555); + struct sensor_drive_api { enum SENSOR_DEV dev; @@ -93,6 +95,7 @@ struct sensor_drive_api { SENSOR_DRIVE_TYPE_INIT_MAP(raa229621), SENSOR_DRIVE_TYPE_INIT_MAP(nct7718w), SENSOR_DRIVE_TYPE_INIT_MAP(ltc4286), + SENSOR_DRIVE_TYPE_INIT_MAP(tca9555), }; static void init_sensor_num(void) diff --git a/common/service/sensor/sensor.h b/common/service/sensor/sensor.h index 10c841b6b0..32d91f28db 100644 --- a/common/service/sensor/sensor.h +++ b/common/service/sensor/sensor.h @@ -83,6 +83,7 @@ enum SENSOR_DEV { sensor_dev_raa229621 = 0x15, sensor_dev_nct7718w = 0x16, sensor_dev_ltc4286 = 0x17, + sensor_dev_tca9555 = 0x18, sensor_dev_max }; @@ -101,6 +102,13 @@ struct tca9548 { uint8_t chan; }; +struct tca9555 { + uint8_t regs; + uint8_t gpio_direction; +}; + + + static inline int calculate_accurate_MBR(uint8_t sensor_num, int val) { // for better accuracy, enlarge SDR to two byte scale if (SDR_M(sensor_num) == 0) { @@ -280,6 +288,10 @@ typedef struct _ina233_init_arg_ { bool is_init; } ina233_init_arg; +typedef struct _tca9555_init_arg_ { + bool is_init; +} tca9555_init_arg; + typedef struct _max16550a_init_arg_ { float r_load; } max16550a_init_arg; diff --git a/meta-facebook/yv35-hd/src/platform/plat_fru.c b/meta-facebook/yv35-hd/src/platform/plat_fru.c index 11098e777d..8a02b9937f 100644 --- a/meta-facebook/yv35-hd/src/platform/plat_fru.c +++ b/meta-facebook/yv35-hd/src/platform/plat_fru.c @@ -1,6 +1,7 @@ #include #include "fru.h" #include "plat_fru.h" +#include "hal_i2c.h" const EEPROM_CFG plat_fru_config[] = { { @@ -21,9 +22,24 @@ const EEPROM_CFG plat_fru_config[] = { FRU_START, FRU_SIZE, }, + { + NV_ATMEL_24C128, + RF_FRU_ID, + RF_FRU_PORT, + RF_FRU_ADDR, + FRU_DEV_ACCESS_BYTE, + FRU_START, + FRU_SIZE, + RF_MUX_PRSNT, + RF_FRU_MUX_ADDR, + RF_FRU_MUX_CHAN, + }, }; void pal_load_fru_config(void) { memcpy(fru_config, plat_fru_config, sizeof(plat_fru_config)); } + + + diff --git a/meta-facebook/yv35-hd/src/platform/plat_fru.h b/meta-facebook/yv35-hd/src/platform/plat_fru.h index ace15a9869..351b97a4c7 100644 --- a/meta-facebook/yv35-hd/src/platform/plat_fru.h +++ b/meta-facebook/yv35-hd/src/platform/plat_fru.h @@ -4,14 +4,23 @@ #define MB_FRU_PORT 0x01 #define MB_FRU_ADDR 0x54 +#define RF_FRU_PORT 0x02 +#define RF_FRU_ADDR 0xA8 >> 1 +#define RF_MUX_PRSNT 1 +#define RF_FRU_MUX_ADDR 0xe2 >> 1 +#define RF_FRU_MUX_CHAN 2 + #define DPV2_FRU_PORT 0x08 #define DPV2_FRU_ADDR 0x51 enum { MB_FRU_ID, DPV2_FRU_ID, + RF_FRU_ID, // OTHER_FRU_ID, MAX_FRU_ID, }; +bool mux_fru_read(void); + #endif