vli: Add a FuVliDevice as a subclass to FuVliUsbhubDevice

At the moment this doe not do anything clever, but other device types will
derive from the base class in the future.
This commit is contained in:
Richard Hughes 2019-12-17 10:28:09 +00:00
parent 62b84d4c5b
commit b02d9988ad
5 changed files with 137 additions and 34 deletions

View File

@ -0,0 +1,74 @@
/*
* Copyright (C) 2017-2019 VIA Corporation
* Copyright (C) 2019 Richard Hughes <richard@hughsie.com>
*
* 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;
}

View File

@ -0,0 +1,29 @@
/*
* Copyright (C) 2019 Richard Hughes <richard@hughsie.com>
*
* 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);

View File

@ -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;
}

View File

@ -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,

View File

@ -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',