diff --git a/plugins/vli/fu-vli-device.c b/plugins/vli/fu-vli-device.c new file mode 100644 index 000000000..1949c85e8 --- /dev/null +++ b/plugins/vli/fu-vli-device.c @@ -0,0 +1,74 @@ +/* + * Copyright (C) 2017-2019 VIA Corporation + * Copyright (C) 2019 Richard Hughes + * + * SPDX-License-Identifier: LGPL-2.1+ + */ + +#include "config.h" + +#include "fu-vli-device.h" + +typedef struct { + FuUsbDevice parent_instance; + FuVliDeviceKind kind; +} FuVliDevicePrivate; + +G_DEFINE_TYPE_WITH_PRIVATE (FuVliDevice, fu_vli_device, FU_TYPE_USB_DEVICE) + +#define GET_PRIVATE(o) (fu_vli_device_get_instance_private (o)) + +void +fu_vli_device_set_kind (FuVliDevice *self, FuVliDeviceKind device_kind) +{ + FuVliDevicePrivate *priv = GET_PRIVATE (self); + priv->kind = device_kind; +} + +FuVliDeviceKind +fu_vli_device_get_kind (FuVliDevice *self) +{ + FuVliDevicePrivate *priv = GET_PRIVATE (self); + return priv->kind; +} + +static void +fu_vli_device_to_string (FuDevice *device, guint idt, GString *str) +{ + FuVliDeviceClass *klass = FU_VLI_DEVICE_GET_CLASS (device); + FuVliDevice *self = FU_VLI_DEVICE (device); + FuVliDevicePrivate *priv = GET_PRIVATE (self); + fu_common_string_append_kv (str, idt, "DeviceKind", + fu_vli_common_device_kind_to_string (priv->kind)); + + /* subclassed further */ + if (klass->to_string != NULL) + return klass->to_string (self, idt, str); +} + +static gboolean +fu_vli_device_setup (FuDevice *device, GError **error) +{ + FuVliDevice *self = FU_VLI_DEVICE (device); + FuVliDeviceClass *klass = FU_VLI_DEVICE_GET_CLASS (device); + + /* subclassed further */ + if (klass->setup != NULL) + return klass->setup (self, error); + + /* success */ + return TRUE; +} + +static void +fu_vli_device_init (FuVliDevice *self) +{ +} + +static void +fu_vli_device_class_init (FuVliDeviceClass *klass) +{ + FuDeviceClass *klass_device = FU_DEVICE_CLASS (klass); + klass_device->to_string = fu_vli_device_to_string; + klass_device->setup = fu_vli_device_setup; +} diff --git a/plugins/vli/fu-vli-device.h b/plugins/vli/fu-vli-device.h new file mode 100644 index 000000000..efa79f054 --- /dev/null +++ b/plugins/vli/fu-vli-device.h @@ -0,0 +1,29 @@ +/* + * Copyright (C) 2019 Richard Hughes + * + * SPDX-License-Identifier: LGPL-2.1+ + */ + +#pragma once + +#include "fu-plugin.h" + +#include "fu-vli-common.h" + +#define FU_TYPE_VLI_DEVICE (fu_vli_device_get_type ()) +G_DECLARE_DERIVABLE_TYPE (FuVliDevice, fu_vli_device, FU, VLI_DEVICE, FuUsbDevice) + +struct _FuVliDeviceClass +{ + FuUsbDeviceClass parent_class; + gboolean (*setup) (FuVliDevice *self, + GError **error); + void (*to_string) (FuVliDevice *self, + guint idt, + GString *str); +}; + +void fu_vli_device_set_kind (FuVliDevice *self, + FuVliDeviceKind device_kind); +FuVliDeviceKind fu_vli_device_get_kind (FuVliDevice *self); + diff --git a/plugins/vli/fu-vli-usbhub-device.c b/plugins/vli/fu-vli-usbhub-device.c index fceddfeee..6e7e7de1a 100644 --- a/plugins/vli/fu-vli-usbhub-device.c +++ b/plugins/vli/fu-vli-usbhub-device.c @@ -24,8 +24,7 @@ struct _FuVliUsbhubDevice { - FuUsbDevice parent_instance; - FuVliDeviceKind kind; + FuVliDevice parent_instance; gboolean disable_powersave; guint8 update_protocol; FuVliUsbhubHeader hd1_hdr; /* factory */ @@ -42,7 +41,7 @@ struct _FuVliUsbhubDevice guint8 spi_cmd_write_status; }; -G_DEFINE_TYPE (FuVliUsbhubDevice, fu_vli_usbhub_device, FU_TYPE_USB_DEVICE) +G_DEFINE_TYPE (FuVliUsbhubDevice, fu_vli_usbhub_device, FU_TYPE_VLI_DEVICE) static gchar * fu_vli_usbhub_device_get_flash_id_str (FuVliUsbhubDevice *self) @@ -57,11 +56,9 @@ fu_vli_usbhub_device_get_flash_id_str (FuVliUsbhubDevice *self) } static void -fu_vli_usbhub_device_to_string (FuDevice *device, guint idt, GString *str) +fu_vli_usbhub_device_to_string (FuVliDevice *device, guint idt, GString *str) { FuVliUsbhubDevice *self = FU_VLI_USBHUB_DEVICE (device); - fu_common_string_append_kv (str, idt, "DeviceKind", - fu_vli_common_device_kind_to_string (self->kind)); fu_common_string_append_kb (str, idt, "DisablePowersave", self->disable_powersave); fu_common_string_append_kx (str, idt, "UpdateProtocol", self->update_protocol); if (self->flash_id != 0x0) { @@ -691,38 +688,38 @@ fu_vli_usbhub_device_guess_kind (FuVliUsbhubDevice *self, GError **error) g_debug ("b820Q7Q8 = 0x%02x", b820Q7Q8); if (chipid2 == 0x35 && chipid1 == 0x07) { - self->kind = FU_VLI_DEVICE_KIND_VL210; + fu_vli_device_set_kind (FU_VLI_DEVICE (self), FU_VLI_DEVICE_KIND_VL210); } else if (chipid2 == 0x35 && chipid1 == 0x18) { if (b820Q7Q8 & (1 << 2)) - self->kind = FU_VLI_DEVICE_KIND_VL820Q8; + fu_vli_device_set_kind (FU_VLI_DEVICE (self), FU_VLI_DEVICE_KIND_VL820Q8); else - self->kind = FU_VLI_DEVICE_KIND_VL820Q7; + fu_vli_device_set_kind (FU_VLI_DEVICE (self), FU_VLI_DEVICE_KIND_VL820Q7); } else if (chipid2 == 0x35 && chipid1 == 0x31) { - self->kind = FU_VLI_DEVICE_KIND_VL815; + fu_vli_device_set_kind (FU_VLI_DEVICE (self), FU_VLI_DEVICE_KIND_VL815); } else if (chipid2 == 0x35 && chipid1 == 0x38) { - self->kind = FU_VLI_DEVICE_KIND_VL817; + fu_vli_device_set_kind (FU_VLI_DEVICE (self), FU_VLI_DEVICE_KIND_VL817); } else if (chipid2 == 0x35 && chipid1 == 0x45) { - self->kind = FU_VLI_DEVICE_KIND_VL211; + fu_vli_device_set_kind (FU_VLI_DEVICE (self), FU_VLI_DEVICE_KIND_VL211); } else if (chipid22 == 0x35 && chipid12 == 0x53) { - self->kind = FU_VLI_DEVICE_KIND_VL120; + fu_vli_device_set_kind (FU_VLI_DEVICE (self), FU_VLI_DEVICE_KIND_VL120); } else if (chipid2 == 0x35 && chipid1 == 0x57) { - self->kind = FU_VLI_DEVICE_KIND_VL819; + fu_vli_device_set_kind (FU_VLI_DEVICE (self), FU_VLI_DEVICE_KIND_VL819); } else if (tPid == 0x810) { - self->kind = FU_VLI_DEVICE_KIND_VL810; + fu_vli_device_set_kind (FU_VLI_DEVICE (self), FU_VLI_DEVICE_KIND_VL810); } else if (tPid == 0x811) { - self->kind = FU_VLI_DEVICE_KIND_VL811; + fu_vli_device_set_kind (FU_VLI_DEVICE (self), FU_VLI_DEVICE_KIND_VL811); } else if ((b811P812 & ((1 << 5) | (1 << 4))) == 0) { if (chipver == 0x10) - self->kind = FU_VLI_DEVICE_KIND_VL811PB0; + fu_vli_device_set_kind (FU_VLI_DEVICE (self), FU_VLI_DEVICE_KIND_VL811PB0); else - self->kind = FU_VLI_DEVICE_KIND_VL811PB3; + fu_vli_device_set_kind (FU_VLI_DEVICE (self), FU_VLI_DEVICE_KIND_VL811PB3); } else if ((b811P812 & ((1 << 5) | (1 << 4))) == (1 << 4)) { - self->kind = FU_VLI_DEVICE_KIND_VL812Q4S; + fu_vli_device_set_kind (FU_VLI_DEVICE (self), FU_VLI_DEVICE_KIND_VL812Q4S); } else if ((b811P812 & ((1 << 5) | (1 << 4))) == ((1 << 5) | (1 << 4))) { if (chipver == 0x10) - self->kind = FU_VLI_DEVICE_KIND_VL812B0; + fu_vli_device_set_kind (FU_VLI_DEVICE (self), FU_VLI_DEVICE_KIND_VL812B0); else - self->kind = FU_VLI_DEVICE_KIND_VL812B3; + fu_vli_device_set_kind (FU_VLI_DEVICE (self), FU_VLI_DEVICE_KIND_VL812B3); } else { g_set_error (error, G_IO_ERROR, @@ -863,14 +860,14 @@ fu_vli_usbhub_device_i2c_setup (FuVliUsbhubDevice *self, GError **error) } static gboolean -fu_vli_usbhub_device_setup (FuDevice *device, GError **error) +fu_vli_usbhub_device_setup (FuVliDevice *device, GError **error) { FuVliUsbhubDevice *self = FU_VLI_USBHUB_DEVICE (device); GUsbDevice *usb_device = fu_usb_device_get_dev (FU_USB_DEVICE (self)); g_autoptr(GError) error_tmp = NULL; /* try to read a block of data which will fail for 813-type devices */ - if (fu_device_has_custom_flag (device, "needs-unlock-legacy813") && + if (fu_device_has_custom_flag (FU_DEVICE (self), "needs-unlock-legacy813") && !fu_vli_usbhub_device_spi_read_data (self, 0x0, (guint8 *) &self->hd1_hdr, sizeof(self->hd1_hdr), &error_tmp)) { g_warning ("failed to read, trying to unlock 813: %s", error_tmp->message); @@ -883,7 +880,7 @@ fu_vli_usbhub_device_setup (FuDevice *device, GError **error) } g_debug ("813 unlock OK"); /* VL813 & VL210 have same PID (0x0813), and only VL813 can reply */ - self->kind = FU_VLI_DEVICE_KIND_VL813; + fu_vli_device_set_kind (FU_VLI_DEVICE (self), FU_VLI_DEVICE_KIND_VL813); } else { if (!fu_vli_usbhub_device_guess_kind (self, error)) return FALSE; @@ -911,12 +908,12 @@ fu_vli_usbhub_device_setup (FuDevice *device, GError **error) g_usb_device_get_pid (usb_device), flash_id, g_usb_device_get_release (usb_device)); - fu_device_add_instance_id (device, devid2); + fu_device_add_instance_id (FU_DEVICE (self), devid2); devid1 = g_strdup_printf ("USB\\VID_%04X&PID_%04X&SPI_%s", g_usb_device_get_vid (usb_device), g_usb_device_get_pid (usb_device), flash_id); - fu_device_add_instance_id (device, devid1); + fu_device_add_instance_id (FU_DEVICE (self), devid1); } @@ -964,13 +961,13 @@ fu_vli_usbhub_device_setup (FuDevice *device, GError **error) } /* detect the PD child */ - if (fu_device_has_custom_flag (device, "has-shared-spi-pd")) { + if (fu_device_has_custom_flag (FU_DEVICE (self), "has-shared-spi-pd")) { if (!fu_vli_usbhub_device_pd_setup (self, error)) return FALSE; } /* detect the I²C child */ - if (fu_device_has_custom_flag (device, "has-shared-spi-i2c")) { + if (fu_device_has_custom_flag (FU_DEVICE (self), "has-shared-spi-i2c")) { if (!fu_vli_usbhub_device_i2c_setup (self, error)) return FALSE; } @@ -1015,13 +1012,13 @@ fu_vli_usbhub_device_prepare_firmware (FuDevice *device, if (!fu_firmware_parse (firmware, fw, flags, error)) return NULL; device_kind = fu_vli_usbhub_firmware_get_device_kind (FU_VLI_USBHUB_FIRMWARE (firmware)); - if (self->kind != device_kind) { + if (fu_vli_device_get_kind (FU_VLI_DEVICE (self)) != device_kind) { g_set_error (error, FWUPD_ERROR, FWUPD_ERROR_INVALID_FILE, "firmware incompatible, got %s, expected %s", fu_vli_common_device_kind_to_string (device_kind), - fu_vli_common_device_kind_to_string (self->kind)); + fu_vli_common_device_kind_to_string (fu_vli_device_get_kind (FU_VLI_DEVICE (self)))); return NULL; } device_id = fu_vli_usbhub_firmware_get_device_id (FU_VLI_USBHUB_FIRMWARE (firmware)); @@ -1511,12 +1508,13 @@ static void fu_vli_usbhub_device_class_init (FuVliUsbhubDeviceClass *klass) { FuDeviceClass *klass_device = FU_DEVICE_CLASS (klass); - klass_device->to_string = fu_vli_usbhub_device_to_string; + FuVliDeviceClass *klass_vli_device = FU_VLI_DEVICE_CLASS (klass); klass_device->set_quirk_kv = fu_vli_usbhub_device_set_quirk_kv; klass_device->probe = fu_vli_usbhub_device_probe; - klass_device->setup = fu_vli_usbhub_device_setup; klass_device->read_firmware = fu_vli_usbhub_device_read_firmware; klass_device->write_firmware = fu_vli_usbhub_device_write_firmware; klass_device->prepare_firmware = fu_vli_usbhub_device_prepare_firmware; klass_device->attach = fu_vli_usbhub_device_attach; + klass_vli_device->to_string = fu_vli_usbhub_device_to_string; + klass_vli_device->setup = fu_vli_usbhub_device_setup; } diff --git a/plugins/vli/fu-vli-usbhub-device.h b/plugins/vli/fu-vli-usbhub-device.h index 6bfe64fd4..17ab63c99 100644 --- a/plugins/vli/fu-vli-usbhub-device.h +++ b/plugins/vli/fu-vli-usbhub-device.h @@ -8,14 +8,15 @@ #include "fu-plugin.h" +#include "fu-vli-device.h" #include "fu-vli-usbhub-i2c-common.h" #define FU_TYPE_VLI_USBHUB_DEVICE (fu_vli_usbhub_device_get_type ()) -G_DECLARE_FINAL_TYPE (FuVliUsbhubDevice, fu_vli_usbhub_device, FU, VLI_USBHUB_DEVICE, FuUsbDevice) +G_DECLARE_FINAL_TYPE (FuVliUsbhubDevice, fu_vli_usbhub_device, FU, VLI_USBHUB_DEVICE, FuVliDevice) struct _FuVliUsbhubDeviceClass { - FuUsbDeviceClass parent_class; + FuVliDeviceClass parent_class; }; gboolean fu_vli_usbhub_device_spi_erase (FuVliUsbhubDevice *self, diff --git a/plugins/vli/meson.build b/plugins/vli/meson.build index 0f08074d6..5c6f4763a 100644 --- a/plugins/vli/meson.build +++ b/plugins/vli/meson.build @@ -12,6 +12,7 @@ shared_module('fu_plugin_vli', sources : [ 'fu-plugin-vli.c', 'fu-vli-common.c', + 'fu-vli-device.c', 'fu-vli-usbhub-common.c', 'fu-vli-usbhub-device.c', 'fu-vli-usbhub-firmware.c',