mirror of
https://git.proxmox.com/git/fwupd
synced 2025-05-15 20:31:59 +00:00
ccgx: Wait for hardware to settle when coming out of reset
This commit is contained in:
parent
3990a71401
commit
fd7f13f905
@ -122,6 +122,78 @@ typedef enum {
|
|||||||
CY_I2C_DATA_CONFIG_NAK = 1 << 1, /* only for read */
|
CY_I2C_DATA_CONFIG_NAK = 1 << 1, /* only for read */
|
||||||
} CyI2CDataConfigBits;
|
} CyI2CDataConfigBits;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
HPI_DEV_REG_DEVICE_MODE = 0,
|
||||||
|
HPI_DEV_REG_BOOT_MODE_REASON,
|
||||||
|
HPI_DEV_REG_SI_ID,
|
||||||
|
HPI_DEV_REG_SI_ID_LSB,
|
||||||
|
HPI_DEV_REG_BL_LAST_ROW,
|
||||||
|
HPI_DEV_REG_BL_LAST_ROW_LSB,
|
||||||
|
HPI_DEV_REG_INTR_ADDR,
|
||||||
|
HPI_DEV_REG_JUMP_TO_BOOT,
|
||||||
|
HPI_DEV_REG_RESET_ADDR,
|
||||||
|
HPI_DEV_REG_RESET_CMD,
|
||||||
|
HPI_DEV_REG_ENTER_FLASH_MODE,
|
||||||
|
HPI_DEV_REG_VALIDATE_FW_ADDR,
|
||||||
|
HPI_DEV_REG_FLASH_READ_WRITE,
|
||||||
|
HPI_DEV_REG_FLASH_READ_WRITE_CMD,
|
||||||
|
HPI_DEV_REG_FLASH_ROW,
|
||||||
|
HPI_DEV_REG_FLASH_ROW_LSB,
|
||||||
|
HPI_DEV_REG_ALL_VERSION,
|
||||||
|
HPI_DEV_REG_ALL_VERSION_BYTE_1,
|
||||||
|
HPI_DEV_REG_ALL_VERSION_BYTE_2,
|
||||||
|
HPI_DEV_REG_ALL_VERSION_BYTE_3,
|
||||||
|
HPI_DEV_REG_ALL_VERSION_BYTE_4,
|
||||||
|
HPI_DEV_REG_ALL_VERSION_BYTE_5,
|
||||||
|
HPI_DEV_REG_ALL_VERSION_BYTE_6,
|
||||||
|
HPI_DEV_REG_ALL_VERSION_BYTE_7,
|
||||||
|
HPI_DEV_REG_ALL_VERSION_BYTE_8,
|
||||||
|
HPI_DEV_REG_ALL_VERSION_BYTE_9,
|
||||||
|
HPI_DEV_REG_ALL_VERSION_BYTE_10,
|
||||||
|
HPI_DEV_REG_ALL_VERSION_BYTE_11,
|
||||||
|
HPI_DEV_REG_ALL_VERSION_BYTE_12,
|
||||||
|
HPI_DEV_REG_ALL_VERSION_BYTE_13,
|
||||||
|
HPI_DEV_REG_ALL_VERSION_BYTE_14,
|
||||||
|
HPI_DEV_REG_ALL_VERSION_BYTE_15,
|
||||||
|
HPI_DEV_REG_FW_2_VERSION,
|
||||||
|
HPI_DEV_REG_FW_2_VERSION_BYTE_1,
|
||||||
|
HPI_DEV_REG_FW_2_VERSION_BYTE_2,
|
||||||
|
HPI_DEV_REG_FW_2_VERSION_BYTE_3,
|
||||||
|
HPI_DEV_REG_FW_2_VERSION_BYTE_4,
|
||||||
|
HPI_DEV_REG_FW_2_VERSION_BYTE_5,
|
||||||
|
HPI_DEV_REG_FW_2_VERSION_BYTE_6,
|
||||||
|
HPI_DEV_REG_FW_2_VERSION_BYTE_7,
|
||||||
|
HPI_DEV_REG_FW_BIN_LOC,
|
||||||
|
HPI_DEV_REG_FW_1_BIN_LOC_LSB,
|
||||||
|
HPI_DEV_REG_FW_2_BIN_LOC_MSB,
|
||||||
|
HPI_DEV_REG_FW_2_BIN_LOC_LSB,
|
||||||
|
HPI_DEV_REG_PORT_ENABLE,
|
||||||
|
HPI_DEV_SPACE_REG_LEN,
|
||||||
|
HPI_DEV_REG_RESPONSE = 0x007E,
|
||||||
|
HPI_DEV_REG_FLASH_MEM = 0x0200
|
||||||
|
} HPIDevReg;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
HPI_REG_SECTION_DEV = 0, /* device information */
|
||||||
|
HPI_REG_SECTION_PORT_0, /* USB-PD Port 0 related */
|
||||||
|
HPI_REG_SECTION_PORT_1, /* USB-PD Port 1 related */
|
||||||
|
HPI_REG_SECTION_ALL /* select all registers */
|
||||||
|
} HPIRegSection;
|
||||||
|
|
||||||
|
typedef struct __attribute__((packed)) {
|
||||||
|
guint16 event_code;
|
||||||
|
guint16 event_length;
|
||||||
|
guint8 event_data[128];
|
||||||
|
} HPIEvent;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
HPI_REG_PART_REG = 0, /* register region */
|
||||||
|
HPI_REG_PART_DATA = 1, /* data memory */
|
||||||
|
HPI_REG_PART_FLASH = 2, /* flash memory */
|
||||||
|
HPI_REG_PART_PDDATA_READ = 4, /* read data memory */
|
||||||
|
HPI_REG_PART_PDDATA_WRITE = 8, /* write data memory */
|
||||||
|
} HPIRegPart;
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
CY_PD_REG_DEVICE_MODE_ADDR,
|
CY_PD_REG_DEVICE_MODE_ADDR,
|
||||||
CY_PD_BOOT_MODE_REASON,
|
CY_PD_BOOT_MODE_REASON,
|
||||||
@ -166,3 +238,107 @@ typedef enum {
|
|||||||
#define PD_I2CM_USB_EP_BULK_IN 0x83
|
#define PD_I2CM_USB_EP_BULK_IN 0x83
|
||||||
#define PD_I2CM_USB_EP_INTR_IN 0x84
|
#define PD_I2CM_USB_EP_INTR_IN 0x84
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
/* responses */
|
||||||
|
CY_PD_RESP_NO_RESPONSE,
|
||||||
|
CY_PD_RESP_SUCCESS = 0x02,
|
||||||
|
CY_PD_RESP_FLASH_DATA_AVAILABLE,
|
||||||
|
CY_PD_RESP_INVALID_COMMAND = 0x05,
|
||||||
|
CY_PD_RESP_COLLISION_DETECTED,
|
||||||
|
CY_PD_RESP_FLASH_UPDATE_FAILED,
|
||||||
|
CY_PD_RESP_INVALID_FW,
|
||||||
|
CY_PD_RESP_INVALID_ARGUMENTS,
|
||||||
|
CY_PD_RESP_NOT_SUPPORTED,
|
||||||
|
CY_PD_RESP_TRANSACTION_FAILED = 0x0C,
|
||||||
|
CY_PD_RESP_PD_COMMAND_FAILED,
|
||||||
|
CY_PD_RESP_UNDEFINED,
|
||||||
|
CY_PD_RESP_RA_DETECT = 0x10,
|
||||||
|
CY_PD_RESP_RA_REMOVED,
|
||||||
|
|
||||||
|
/* device specific events */
|
||||||
|
CY_PD_RESP_RESET_COMPLETE = 0x80,
|
||||||
|
CY_PD_RESP_MESSAGE_QUEUE_OVERFLOW,
|
||||||
|
|
||||||
|
/* type-c specific events */
|
||||||
|
CY_PD_RESP_OVER_CURRENT_DETECTED,
|
||||||
|
CY_PD_RESP_OVER_VOLTAGE_DETECTED,
|
||||||
|
CY_PD_RESP_TYPC_C_CONNECTED,
|
||||||
|
CY_PD_RESP_TYPE_C_DISCONNECTED,
|
||||||
|
|
||||||
|
/* pd specific events and asynchronous messages */
|
||||||
|
CY_PD_RESP_PD_CONTRACT_ESTABLISHED,
|
||||||
|
CY_PD_RESP_DR_SWAP,
|
||||||
|
CY_PD_RESP_PR_SWAP,
|
||||||
|
CY_PD_RESP_VCON_SWAP,
|
||||||
|
CY_PD_RESP_PS_RDY,
|
||||||
|
CY_PD_RESP_GOTOMIN,
|
||||||
|
CY_PD_RESP_ACCEPT_MESSAGE,
|
||||||
|
CY_PD_RESP_REJECT_MESSAGE,
|
||||||
|
CY_PD_RESP_WAIT_MESSAGE,
|
||||||
|
CY_PD_RESP_HARD_RESET,
|
||||||
|
CY_PD_RESP_VDM_RECEIVED,
|
||||||
|
CY_PD_RESP_SRC_CAP_RCVD,
|
||||||
|
CY_PD_RESP_SINK_CAP_RCVD,
|
||||||
|
CY_PD_RESP_DP_ALTERNATE_MODE,
|
||||||
|
CY_PD_RESP_DP_DEVICE_CONNECTED,
|
||||||
|
CY_PD_RESP_DP_DEVICE_NOT_CONNECTED,
|
||||||
|
CY_PD_RESP_DP_SID_NOT_FOUND,
|
||||||
|
CY_PD_RESP_MULTIPLE_SVID_DISCOVERED,
|
||||||
|
CY_PD_RESP_DP_FUNCTION_NOT_SUPPORTED,
|
||||||
|
CY_PD_RESP_DP_PORT_CONFIG_NOT_SUPPORTED,
|
||||||
|
CY_PD_HARD_RESET_SENT,
|
||||||
|
CY_PD_SOFT_RESET_SENT,
|
||||||
|
CY_PD_CABLE_RESET_SENT,
|
||||||
|
CY_PD_SOURCE_DISBALED_STATE_ENTERED,
|
||||||
|
CY_PD_SENDER_RESPONSE_TIMER_TIMEOUT,
|
||||||
|
CY_PD_NO_VDM_RESPONSE_RECEIVED
|
||||||
|
} CyPDResp;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
HPI_RESPONSE_NO_RESPONSE,
|
||||||
|
HPI_RESPONSE_SUCCESS = 0x02,
|
||||||
|
HPI_RESPONSE_FLASH_DATA_AVAILABLE,
|
||||||
|
HPI_RESPONSE_INVALID_COMMAND = 0x05,
|
||||||
|
HPI_RESPONSE_FLASH_UPDATE_FAILED = 0x07,
|
||||||
|
HPI_RESPONSE_INVALID_FW,
|
||||||
|
HPI_RESPONSE_INVALID_ARGUMENT,
|
||||||
|
HPI_RESPONSE_NOT_SUPPORTED,
|
||||||
|
HPI_RESPONSE_PD_TRANSACTION_FAILED = 0x0C,
|
||||||
|
HPI_RESPONSE_PD_COMMAND_FAILED,
|
||||||
|
HPI_RESPONSE_UNDEFINED_ERROR = 0x0F,
|
||||||
|
HPI_EVENT_RESET_COMPLETE = 0x80,
|
||||||
|
HPI_EVENT_MSG_OVERFLOW,
|
||||||
|
HPI_EVENT_OC_DETECT,
|
||||||
|
HPI_EVENT_OV_DETECT,
|
||||||
|
HPI_EVENT_CONNECT_DETECT,
|
||||||
|
HPI_EVENT_DISCONNECT_DETECT,
|
||||||
|
HPI_EVENT_NEGOTIATION_COMPLETE,
|
||||||
|
HPI_EVENT_SWAP_COMPLETE,
|
||||||
|
HPI_EVENT_PS_RDY_RECEIVED = 0x8A,
|
||||||
|
HPI_EVENT_GOTO_MIN_RECEIVED,
|
||||||
|
HPI_EVENT_ACCEPT_RECEIVED,
|
||||||
|
HPI_EVENT_REJECT_RECEIVED,
|
||||||
|
HPI_EVENT_WAIT_RECEIVED,
|
||||||
|
HPI_EVENT_HARD_RESET_RECEIVED,
|
||||||
|
HPI_EVENT_VDM_RECEIVED = 0x90,
|
||||||
|
HPI_EVENT_SOURCE_CAP_RECEIVED,
|
||||||
|
HPI_EVENT_SINK_CAP_RECEIVED,
|
||||||
|
HPI_EVENT_DP_MODE_ENTERED,
|
||||||
|
HPI_EVENT_DP_STATUS_UPDATE,
|
||||||
|
HPI_EVENT_DP_SID_NOT_FOUND = 0x96,
|
||||||
|
HPI_EVENT_DP_MANY_SID_FOUND,
|
||||||
|
HPI_EVENT_DP_NO_CABLE_SUPPORT,
|
||||||
|
HPI_EVENT_DP_NO_UFP_SUPPORT,
|
||||||
|
HPI_EVENT_HARD_RESET_SENT,
|
||||||
|
HPI_EVENT_SOFT_RESET_SENT,
|
||||||
|
HPI_EVENT_CABLE_RESET_SENT,
|
||||||
|
HPI_EVENT_SOURCE_DISABLED,
|
||||||
|
HPI_EVENT_SENDER_TIMEOUT,
|
||||||
|
HPI_EVENT_VDM_NO_RESPONSE,
|
||||||
|
HPI_EVENT_UNEXPECTED_VOLTAGE,
|
||||||
|
HPI_EVENT_ERROR_RECOVERY,
|
||||||
|
HPI_EVENT_EMCA_DETECT = 0xA6,
|
||||||
|
HPI_EVENT_RP_CHANGE_DETECT = 0xAA,
|
||||||
|
HPI_EVENT_TB_ENTERED = 0xB0,
|
||||||
|
HPI_EVENT_TB_EXITED
|
||||||
|
} HPIResp;
|
||||||
|
@ -33,6 +33,9 @@ struct _FuCcgxHpiDevice
|
|||||||
|
|
||||||
G_DEFINE_TYPE (FuCcgxHpiDevice, fu_ccgx_hpi_device, FU_TYPE_USB_DEVICE)
|
G_DEFINE_TYPE (FuCcgxHpiDevice, fu_ccgx_hpi_device, FU_TYPE_USB_DEVICE)
|
||||||
|
|
||||||
|
#define HPI_CMD_SETUP_EVENT_WAIT_TIME_MS 200
|
||||||
|
#define HPI_CMD_RESET_COMPLETE_DELAY_US 150000
|
||||||
|
|
||||||
static void
|
static void
|
||||||
fu_ccgx_hpi_device_to_string (FuDevice *device, guint idt, GString *str)
|
fu_ccgx_hpi_device_to_string (FuDevice *device, guint idt, GString *str)
|
||||||
{
|
{
|
||||||
@ -305,6 +308,212 @@ fu_ccgx_hpi_device_reg_read (FuCcgxHpiDevice *self,
|
|||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
fu_ccgx_hpi_device_reg_write (FuCcgxHpiDevice *self,
|
||||||
|
guint16 addr,
|
||||||
|
guint8 *buf,
|
||||||
|
guint16 bufsz,
|
||||||
|
GError **error)
|
||||||
|
{
|
||||||
|
g_autofree guint8 *bufhw = g_malloc0 (bufsz + self->hpi_addrsz + 1);
|
||||||
|
for (guint32 i = 0; i < self->hpi_addrsz; i++)
|
||||||
|
bufhw[i] = (guint8) (addr >> (8*i));
|
||||||
|
memcpy (&bufhw[self->hpi_addrsz], buf, bufsz);
|
||||||
|
if (!fu_ccgx_hpi_device_i2c_write (self, bufhw, bufsz + self->hpi_addrsz,
|
||||||
|
CY_I2C_DATA_CONFIG_STOP | CY_I2C_DATA_CONFIG_NAK,
|
||||||
|
error)) {
|
||||||
|
g_prefix_error (error, "reg write error: ");
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
fu_ccgx_hpi_device_clear_intr (FuCcgxHpiDevice *self,
|
||||||
|
HPIRegSection section,
|
||||||
|
GError **error)
|
||||||
|
{
|
||||||
|
guint8 intr = 0;
|
||||||
|
for (guint8 i = 0; i <= self->num_ports; i++) {
|
||||||
|
if (i == section || section == HPI_REG_SECTION_ALL)
|
||||||
|
intr |= 1 << i;
|
||||||
|
}
|
||||||
|
if (!fu_ccgx_hpi_device_reg_write (self, HPI_DEV_REG_INTR_ADDR,
|
||||||
|
&intr, sizeof(intr),
|
||||||
|
error)) {
|
||||||
|
g_prefix_error (error, "failed to clear interrupt: ");
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static guint16
|
||||||
|
fu_ccgx_hpi_device_reg_addr_gen (guint8 section, guint8 part, guint8 addr)
|
||||||
|
{
|
||||||
|
return (((guint16) section) << 12) | (((guint16) part) << 8) | addr;
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
fu_ccgx_hpi_device_read_event_reg (FuCcgxHpiDevice *self,
|
||||||
|
HPIRegSection section,
|
||||||
|
HPIEvent *event,
|
||||||
|
GError **error)
|
||||||
|
{
|
||||||
|
|
||||||
|
if (section != HPI_REG_SECTION_DEV) {
|
||||||
|
guint16 reg_addr;
|
||||||
|
guint8 buf[4] = { 0x0 };
|
||||||
|
|
||||||
|
/* first read the response register */
|
||||||
|
reg_addr = fu_ccgx_hpi_device_reg_addr_gen (section,
|
||||||
|
HPI_REG_PART_PDDATA_READ,
|
||||||
|
0);
|
||||||
|
if (!fu_ccgx_hpi_device_reg_read (self,
|
||||||
|
reg_addr,
|
||||||
|
buf, sizeof(buf),
|
||||||
|
error)) {
|
||||||
|
g_prefix_error (error, "read response reg error:");
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* byte 1 is reserved and should read as zero */
|
||||||
|
buf[1] = 0;
|
||||||
|
memcpy ((guint8 *) event, buf, sizeof(buf));
|
||||||
|
if (event->event_length != 0) {
|
||||||
|
reg_addr = fu_ccgx_hpi_device_reg_addr_gen (section,
|
||||||
|
HPI_REG_PART_PDDATA_READ,
|
||||||
|
sizeof(buf));
|
||||||
|
if (!fu_ccgx_hpi_device_reg_read (self,
|
||||||
|
reg_addr,
|
||||||
|
event->event_data,
|
||||||
|
event->event_length,
|
||||||
|
error)) {
|
||||||
|
g_prefix_error (error, "read event data error:");
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
guint8 buf[2] = { 0x0 };
|
||||||
|
if (!fu_ccgx_hpi_device_reg_read (self,
|
||||||
|
CY_PD_REG_RESPONSE_ADDR,
|
||||||
|
buf, sizeof(buf),
|
||||||
|
error)) {
|
||||||
|
g_prefix_error (error, "read response reg error:");
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
event->event_code = buf[0];
|
||||||
|
event->event_length = buf[1];
|
||||||
|
if (event->event_length != 0) {
|
||||||
|
/* read the data memory */
|
||||||
|
if (!fu_ccgx_hpi_device_reg_read (self,
|
||||||
|
CY_PD_REG_BOOTDATA_MEMORY_ADDR,
|
||||||
|
event->event_data,
|
||||||
|
event->event_length,
|
||||||
|
error)) {
|
||||||
|
g_prefix_error (error, "read event data error:");
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* success */
|
||||||
|
return fu_ccgx_hpi_device_clear_intr (self, section, error);
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
fu_ccgx_hpi_device_app_read_intr_reg (FuCcgxHpiDevice *self,
|
||||||
|
HPIRegSection section,
|
||||||
|
HPIEvent *event_array,
|
||||||
|
guint8 *event_count,
|
||||||
|
GError **error)
|
||||||
|
{
|
||||||
|
guint16 reg_addr;
|
||||||
|
guint8 event_count_tmp = 0;
|
||||||
|
guint8 intr_reg = 0;
|
||||||
|
|
||||||
|
reg_addr = fu_ccgx_hpi_device_reg_addr_gen (HPI_REG_SECTION_DEV,
|
||||||
|
HPI_REG_PART_REG,
|
||||||
|
HPI_DEV_REG_INTR_ADDR);
|
||||||
|
if (!fu_ccgx_hpi_device_reg_read (self,
|
||||||
|
reg_addr,
|
||||||
|
&intr_reg,
|
||||||
|
sizeof(intr_reg),
|
||||||
|
error)) {
|
||||||
|
g_prefix_error (error, "read intr reg error: ");
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* device section will not come here */
|
||||||
|
for (guint8 i = 0; i <= self->num_ports; i++) {
|
||||||
|
/* check if this section is needed */
|
||||||
|
if (section == i || section == HPI_REG_SECTION_ALL) {
|
||||||
|
/* check whether this section has any event/response */
|
||||||
|
if ((1 << i) & intr_reg) {
|
||||||
|
if (!fu_ccgx_hpi_device_read_event_reg (self,
|
||||||
|
section,
|
||||||
|
&event_array[i],
|
||||||
|
error)) {
|
||||||
|
g_prefix_error (error, "read event error: ");
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
event_count_tmp++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (event_count != NULL)
|
||||||
|
*event_count = event_count_tmp;
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
fu_ccgx_hpi_device_wait_for_event (FuCcgxHpiDevice *self,
|
||||||
|
HPIRegSection section,
|
||||||
|
HPIEvent *event_array,
|
||||||
|
guint32 timeout_ms,
|
||||||
|
GError **error)
|
||||||
|
{
|
||||||
|
guint8 event_count = 0;
|
||||||
|
g_autoptr(GTimer) start_time = g_timer_new ();
|
||||||
|
do {
|
||||||
|
if (!fu_ccgx_hpi_device_app_read_intr_reg (self,
|
||||||
|
section,
|
||||||
|
event_array,
|
||||||
|
&event_count,
|
||||||
|
error))
|
||||||
|
return FALSE;
|
||||||
|
if (event_count > 0)
|
||||||
|
return TRUE;
|
||||||
|
} while (g_timer_elapsed (start_time, NULL) * 1000.f <= timeout_ms);
|
||||||
|
|
||||||
|
/* timed out */
|
||||||
|
g_set_error (error,
|
||||||
|
G_IO_ERROR,
|
||||||
|
G_IO_ERROR_TIMED_OUT,
|
||||||
|
"failed to wait for event in %ums",
|
||||||
|
timeout_ms);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
fu_ccgx_hpi_device_get_event (FuCcgxHpiDevice *self,
|
||||||
|
HPIRegSection reg_section,
|
||||||
|
CyPDResp *event,
|
||||||
|
guint32 io_timeout,
|
||||||
|
GError **error )
|
||||||
|
{
|
||||||
|
HPIEvent event_array[HPI_REG_SECTION_ALL + 1] = { 0x0 };
|
||||||
|
if (!fu_ccgx_hpi_device_wait_for_event (self,
|
||||||
|
reg_section,
|
||||||
|
event_array,
|
||||||
|
io_timeout,
|
||||||
|
error)) {
|
||||||
|
g_prefix_error (error, "failed to get event: ");
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
*event = event_array[reg_section].event_code;
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
fu_ccgx_hpi_device_attach (FuDevice *device, GError **error)
|
fu_ccgx_hpi_device_attach (FuDevice *device, GError **error)
|
||||||
{
|
{
|
||||||
@ -412,8 +621,10 @@ fu_ccgx_hpi_device_setup (FuDevice *device, GError **error)
|
|||||||
{
|
{
|
||||||
FuCcgxHpiDevice *self = FU_CCGX_HPI_DEVICE (device);
|
FuCcgxHpiDevice *self = FU_CCGX_HPI_DEVICE (device);
|
||||||
CyI2CConfig i2c_config = { 0x0 };
|
CyI2CConfig i2c_config = { 0x0 };
|
||||||
|
guint32 hpi_event = 0;
|
||||||
guint8 mode = 0;
|
guint8 mode = 0;
|
||||||
g_autofree gchar *instance_id = NULL;
|
g_autofree gchar *instance_id = NULL;
|
||||||
|
g_autoptr(GError) error_local = NULL;
|
||||||
|
|
||||||
/* set the new config */
|
/* set the new config */
|
||||||
if (!fu_ccgx_hpi_device_get_i2c_config (self, &i2c_config, error)) {
|
if (!fu_ccgx_hpi_device_get_i2c_config (self, &i2c_config, error)) {
|
||||||
@ -492,6 +703,23 @@ fu_ccgx_hpi_device_setup (FuDevice *device, GError **error)
|
|||||||
fu_device_add_flag (FU_DEVICE (self), FWUPD_DEVICE_FLAG_UPDATABLE);
|
fu_device_add_flag (FU_DEVICE (self), FWUPD_DEVICE_FLAG_UPDATABLE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* if we are coming back from reset, wait for hardware to settle */
|
||||||
|
if (!fu_ccgx_hpi_device_get_event (self,
|
||||||
|
HPI_REG_SECTION_DEV,
|
||||||
|
&hpi_event,
|
||||||
|
HPI_CMD_SETUP_EVENT_WAIT_TIME_MS,
|
||||||
|
&error_local)) {
|
||||||
|
if (!g_error_matches (error_local,
|
||||||
|
G_IO_ERROR,
|
||||||
|
G_IO_ERROR_TIMED_OUT)) {
|
||||||
|
g_propagate_error (error, g_steal_pointer (&error_local));
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (hpi_event == CY_PD_RESP_RESET_COMPLETE)
|
||||||
|
g_usleep (HPI_CMD_RESET_COMPLETE_DELAY_US);
|
||||||
|
}
|
||||||
|
|
||||||
/* success */
|
/* success */
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user