diff --git a/plugins/ccgx/fu-ccgx-common.c b/plugins/ccgx/fu-ccgx-common.c index 811b96c1f..c9f5d6f81 100644 --- a/plugins/ccgx/fu-ccgx-common.c +++ b/plugins/ccgx/fu-ccgx-common.c @@ -8,6 +8,19 @@ #include "fu-ccgx-common.h" +gchar * +fu_ccgx_version_to_string (guint32 val) +{ + /* 16 bits: application type [LSB] + * 8 bits: build number + * 4 bits: minor version + * 4 bits: major version [MSB] */ + return g_strdup_printf ("%u.%u.%u", + (val >> 28) & 0x0f, + (val >> 24) & 0x0f, + (val >> 16) & 0xff); +} + const gchar * fu_ccgx_fw_mode_to_string (FWMode val) { diff --git a/plugins/ccgx/fu-ccgx-common.h b/plugins/ccgx/fu-ccgx-common.h index 1bb4a26e8..d52fd871e 100644 --- a/plugins/ccgx/fu-ccgx-common.h +++ b/plugins/ccgx/fu-ccgx-common.h @@ -31,4 +31,5 @@ typedef enum { FW_MODE_LAST } FWMode; +gchar *fu_ccgx_version_to_string (guint32 val); const gchar *fu_ccgx_fw_mode_to_string (FWMode val); diff --git a/plugins/ccgx/fu-ccgx-hpi-common.h b/plugins/ccgx/fu-ccgx-hpi-common.h index c30f92ae5..c53155401 100644 --- a/plugins/ccgx/fu-ccgx-hpi-common.h +++ b/plugins/ccgx/fu-ccgx-hpi-common.h @@ -156,6 +156,9 @@ typedef enum { CY_PD_REG_FWDATA_MEMEORY_ADDR = 0xC0, } CyPDReg; +#define HPI_DEVICE_VERSION_SIZE_HPIV1 16 +#define HPI_DEVICE_VERSION_SIZE_HPIV2 24 + #define PD_I2C_USB_EP_BULK_OUT 0x01 #define PD_I2C_USB_EP_BULK_IN 0x82 #define PD_I2C_USB_EP_INTR_IN 0x83 diff --git a/plugins/ccgx/fu-ccgx-hpi-device.c b/plugins/ccgx/fu-ccgx-hpi-device.c index 34e63f9d0..d876a5eda 100644 --- a/plugins/ccgx/fu-ccgx-hpi-device.c +++ b/plugins/ccgx/fu-ccgx-hpi-device.c @@ -436,6 +436,43 @@ fu_ccgx_hpi_device_setup (FuDevice *device, GError **error) if (!fu_ccgx_hpi_device_ensure_silicon_id (self, error)) return FALSE; + /* get correct version if not in boot mode */ + if (self->fw_mode != FW_MODE_BOOT) { + guint16 bufsz; + guint32 ver_fw1 = 0; + guint32 ver_fw2 = 0; + guint8 bufver[HPI_DEVICE_VERSION_SIZE_HPIV2] = { 0x0 }; + + bufsz = self->hpi_addrsz == 1 ? HPI_DEVICE_VERSION_SIZE_HPIV1 : + HPI_DEVICE_VERSION_SIZE_HPIV2; + if (!fu_ccgx_hpi_device_reg_read (self, + CY_PD_GET_VERSION, + bufver, bufsz, + error)) { + g_prefix_error (error, "get version error: "); + return FALSE; + } + if (!fu_common_read_uint32_safe (bufver, sizeof(bufver), + 0x0c, &ver_fw1, + G_LITTLE_ENDIAN, error)) + return FALSE; + if (!fu_common_read_uint32_safe (bufver, sizeof(bufver), + 0x14, &ver_fw2, + G_LITTLE_ENDIAN, error)) + return FALSE; + /* these seem swapped, but we can only update the "other" image + * whilst running in the current image */ + if (self->fw_mode == FW_MODE_FW2) { + g_autofree gchar *version = fu_ccgx_version_to_string (ver_fw1); + fu_device_set_version_raw (device, ver_fw1); + fu_device_set_version (device, version); + } else if (self->fw_mode == FW_MODE_FW1) { + g_autofree gchar *version = fu_ccgx_version_to_string (ver_fw2); + fu_device_set_version_raw (device, ver_fw2); + fu_device_set_version (device, version); + } + } + /* success */ return TRUE; } @@ -552,6 +589,7 @@ fu_ccgx_hpi_device_init (FuCcgxHpiDevice *self) self->ep_intr_in = PD_I2C_USB_EP_INTR_IN; fu_device_set_protocol (FU_DEVICE (self), "com.cypress.ccgx"); fu_device_set_install_duration (FU_DEVICE (self), 60); + fu_device_set_version_format (FU_DEVICE (self), FWUPD_VERSION_FORMAT_TRIPLET); fu_device_add_flag (FU_DEVICE (self), FWUPD_DEVICE_FLAG_REQUIRE_AC); fu_device_add_flag (FU_DEVICE (self), FWUPD_DEVICE_FLAG_DUAL_IMAGE); fu_device_add_flag (FU_DEVICE (self), FWUPD_DEVICE_FLAG_CAN_VERIFY_IMAGE);