mirror of
https://git.proxmox.com/git/fwupd
synced 2025-08-08 01:14:43 +00:00
flashrom: add lspcon-i2c-spi programmer support
Created lspcon-i2c-spi flashrom device that uses udev to detect i2c devices that can be updated with the lspcon-i2c-spi flashrom programmer. This change implements the logic from crrev.com/c/2792124 adapted to the upstream flashrom plugin.
This commit is contained in:
parent
0b9b7ecc84
commit
fe073a304d
@ -39,7 +39,7 @@ The coreboot DMI version string always starts with `CBET`.
|
|||||||
GUID Generation
|
GUID Generation
|
||||||
---------------
|
---------------
|
||||||
|
|
||||||
These device uses hardware ID values which are derived from SMBIOS.
|
Internal device uses hardware ID values which are derived from SMBIOS.
|
||||||
|
|
||||||
* HardwareID-3
|
* HardwareID-3
|
||||||
* HardwareID-4
|
* HardwareID-4
|
||||||
@ -47,9 +47,12 @@ These device uses hardware ID values which are derived from SMBIOS.
|
|||||||
* HardwareID-6
|
* HardwareID-6
|
||||||
* HardwareID-10
|
* HardwareID-10
|
||||||
|
|
||||||
These device uses hardware ID values which are derived from SMBIOS. They should
|
They should match the values provided by `fwupdtool hwids` or the
|
||||||
match the values provided by `fwupdtool hwids` or the `ComputerHardwareIds.exe`
|
`ComputerHardwareIds.exe` Windows utility.
|
||||||
Windows utility.
|
|
||||||
|
lspcon-i2c-spi devices use the customized DeviceInstanceId values, e.g.
|
||||||
|
|
||||||
|
* FLASHROM-LSPCON-I2C-SPI\VEN_1AF8&DEV_0175
|
||||||
|
|
||||||
Update Behavior
|
Update Behavior
|
||||||
---------------
|
---------------
|
||||||
|
@ -32,3 +32,14 @@ VersionFormat=number
|
|||||||
[0ee5867c-93f0-5fb4-adf1-9d686ea1183a]
|
[0ee5867c-93f0-5fb4-adf1-9d686ea1183a]
|
||||||
Branch=coreboot
|
Branch=coreboot
|
||||||
VersionFormat=number
|
VersionFormat=number
|
||||||
|
|
||||||
|
# match all devices with this udev subsystem
|
||||||
|
[I2C]
|
||||||
|
Plugin = flashrom
|
||||||
|
|
||||||
|
# Parade PS175
|
||||||
|
[1AF80175:00]
|
||||||
|
Plugin=flashrom
|
||||||
|
FlashromProgrammer=lspcon_i2c_spi
|
||||||
|
Name=PS175
|
||||||
|
Vendor=Parade
|
||||||
|
126
plugins/flashrom/fu-flashrom-lspcon-i2c-spi-device.c
Normal file
126
plugins/flashrom/fu-flashrom-lspcon-i2c-spi-device.c
Normal file
@ -0,0 +1,126 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2021 Daniel Campello <campello@chromium.org>
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: LGPL-2.1+
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "config.h"
|
||||||
|
|
||||||
|
#include "fu-flashrom-device.h"
|
||||||
|
#include "fu-flashrom-lspcon-i2c-spi-device.h"
|
||||||
|
|
||||||
|
#include <libflashrom.h>
|
||||||
|
|
||||||
|
#define I2C_PATH_REGEX "/i2c-([0-9]+)/"
|
||||||
|
#define HID_LENGTH 8
|
||||||
|
#define DEVICE_GUID_FORMAT "FLASHROM-LSPCON-I2C-SPI\\VEN_%s&DEV_%s"
|
||||||
|
|
||||||
|
struct _FuFlashromLspconI2cSpiDevice {
|
||||||
|
FuFlashromDevice parent_instance;
|
||||||
|
gint bus_number;
|
||||||
|
};
|
||||||
|
|
||||||
|
G_DEFINE_TYPE (FuFlashromLspconI2cSpiDevice, fu_flashrom_lspcon_i2c_spi_device,
|
||||||
|
FU_TYPE_FLASHROM_DEVICE)
|
||||||
|
|
||||||
|
static void
|
||||||
|
fu_flashrom_lspcon_i2c_spi_device_init (FuFlashromLspconI2cSpiDevice *self)
|
||||||
|
{
|
||||||
|
fu_device_add_flag (FU_DEVICE (self), FWUPD_DEVICE_FLAG_UPDATABLE);
|
||||||
|
fu_device_set_version_format (FU_DEVICE (self), FWUPD_VERSION_FORMAT_PAIR);
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
fu_flashrom_lspcon_i2c_spi_device_probe (FuDevice *device, GError **error)
|
||||||
|
{
|
||||||
|
FuFlashromLspconI2cSpiDevice *self = FU_FLASHROM_LSPCON_I2C_SPI_DEVICE (device);
|
||||||
|
FuFlashromDevice *flashrom_device = FU_FLASHROM_DEVICE (device);
|
||||||
|
FuDeviceClass *klass =
|
||||||
|
FU_DEVICE_CLASS (fu_flashrom_lspcon_i2c_spi_device_parent_class);
|
||||||
|
g_autoptr(GRegex) regex = NULL;
|
||||||
|
g_autoptr(GMatchInfo) info = NULL;
|
||||||
|
const gchar *path = NULL;
|
||||||
|
|
||||||
|
/* FuFlashromDevice->probe */
|
||||||
|
if (!klass->probe (device, error))
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
if (g_strcmp0 (fu_flashrom_device_get_programmer_name (flashrom_device),
|
||||||
|
"lspcon_i2c_spi") != 0) {
|
||||||
|
g_set_error_literal (error,
|
||||||
|
FWUPD_ERROR,
|
||||||
|
FWUPD_ERROR_NOT_SUPPORTED,
|
||||||
|
"invalid programmer");
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* get bus number out of sysfs path */
|
||||||
|
path = fu_udev_device_get_sysfs_path (FU_UDEV_DEVICE (device));
|
||||||
|
regex = g_regex_new (I2C_PATH_REGEX, 0, 0, error);
|
||||||
|
if (regex && g_regex_match_full (regex, path, -1, 0, 0, &info, error)) {
|
||||||
|
self->bus_number = g_ascii_strtoll ( g_match_info_fetch (info, 1),
|
||||||
|
NULL, 10);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
fu_flashrom_lspcon_i2c_spi_device_open (FuDevice *device,
|
||||||
|
GError **error)
|
||||||
|
{
|
||||||
|
FuFlashromLspconI2cSpiDevice *self = FU_FLASHROM_LSPCON_I2C_SPI_DEVICE (device);
|
||||||
|
FuFlashromDevice *flashrom_device = FU_FLASHROM_DEVICE (device);
|
||||||
|
FuDeviceClass *klass =
|
||||||
|
FU_DEVICE_CLASS (fu_flashrom_lspcon_i2c_spi_device_parent_class);
|
||||||
|
g_autofree gchar *temp = NULL;
|
||||||
|
|
||||||
|
/* flashrom_programmer_init() mutates the programmer_args string. */
|
||||||
|
temp = g_strdup_printf ("bus=%d", self->bus_number);
|
||||||
|
fu_flashrom_device_set_programmer_args (flashrom_device, temp);
|
||||||
|
|
||||||
|
return klass->open (device, error);
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
fu_flashrom_lspcon_i2c_spi_device_setup (FuDevice *device, GError **error)
|
||||||
|
{
|
||||||
|
const gchar *hw_id = NULL;
|
||||||
|
g_autofree gchar *vid = NULL;
|
||||||
|
g_autofree gchar *pid = NULL;
|
||||||
|
g_autofree gchar *vendor_id = NULL;
|
||||||
|
g_autofree gchar *temp = NULL;
|
||||||
|
g_autofree gchar *guid = NULL;
|
||||||
|
|
||||||
|
hw_id = fu_udev_device_get_sysfs_attr (FU_UDEV_DEVICE (device), "name", error);
|
||||||
|
if (hw_id == NULL) {
|
||||||
|
g_set_error_literal (error,
|
||||||
|
FWUPD_ERROR,
|
||||||
|
FWUPD_ERROR_NOT_SUPPORTED,
|
||||||
|
"HID not found");
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
vid = g_strndup (hw_id, HID_LENGTH / 2);
|
||||||
|
pid = g_strndup (&hw_id[HID_LENGTH / 2], HID_LENGTH / 2);
|
||||||
|
vendor_id = g_strdup_printf ("I2C:%s", vid);
|
||||||
|
fu_device_add_vendor_id (device, vendor_id);
|
||||||
|
|
||||||
|
temp = g_strdup_printf (DEVICE_GUID_FORMAT, vid, pid);
|
||||||
|
fu_device_add_instance_id (device, temp);
|
||||||
|
guid = fwupd_guid_hash_string (temp);
|
||||||
|
fu_device_add_guid (device, guid);
|
||||||
|
|
||||||
|
/* TODO: Get the real version number. */
|
||||||
|
fu_device_set_version (device, "0.0");
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
fu_flashrom_lspcon_i2c_spi_device_class_init (FuFlashromLspconI2cSpiDeviceClass *klass)
|
||||||
|
{
|
||||||
|
FuDeviceClass *klass_device = FU_DEVICE_CLASS (klass);
|
||||||
|
klass_device->probe = fu_flashrom_lspcon_i2c_spi_device_probe;
|
||||||
|
klass_device->open = fu_flashrom_lspcon_i2c_spi_device_open;
|
||||||
|
klass_device->setup = fu_flashrom_lspcon_i2c_spi_device_setup;
|
||||||
|
}
|
15
plugins/flashrom/fu-flashrom-lspcon-i2c-spi-device.h
Normal file
15
plugins/flashrom/fu-flashrom-lspcon-i2c-spi-device.h
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2021 Daniel Campello <campello@chromium.org>
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: LGPL-2.1+
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "fu-flashrom-device.h"
|
||||||
|
|
||||||
|
#define FU_TYPE_FLASHROM_LSPCON_I2C_SPI_DEVICE \
|
||||||
|
(fu_flashrom_lspcon_i2c_spi_device_get_type ())
|
||||||
|
G_DECLARE_FINAL_TYPE (FuFlashromLspconI2cSpiDevice,
|
||||||
|
fu_flashrom_lspcon_i2c_spi_device, FU,
|
||||||
|
FLASHROM_LSPCON_I2C_SPI_DEVICE, FuFlashromDevice)
|
@ -26,6 +26,7 @@
|
|||||||
|
|
||||||
#include "fu-plugin-vfuncs.h"
|
#include "fu-plugin-vfuncs.h"
|
||||||
#include "fu-flashrom-internal-device.h"
|
#include "fu-flashrom-internal-device.h"
|
||||||
|
#include "fu-flashrom-lspcon-i2c-spi-device.h"
|
||||||
|
|
||||||
#include <libflashrom.h>
|
#include <libflashrom.h>
|
||||||
|
|
||||||
@ -40,6 +41,8 @@ fu_plugin_init (FuPlugin *plugin)
|
|||||||
fu_plugin_add_rule (plugin, FU_PLUGIN_RULE_METADATA_SOURCE, "linux_lockdown");
|
fu_plugin_add_rule (plugin, FU_PLUGIN_RULE_METADATA_SOURCE, "linux_lockdown");
|
||||||
fu_plugin_add_rule (plugin, FU_PLUGIN_RULE_CONFLICTS, "coreboot"); /* obsoleted */
|
fu_plugin_add_rule (plugin, FU_PLUGIN_RULE_CONFLICTS, "coreboot"); /* obsoleted */
|
||||||
fu_plugin_add_flag (plugin, FWUPD_PLUGIN_FLAG_REQUIRE_HWID);
|
fu_plugin_add_flag (plugin, FWUPD_PLUGIN_FLAG_REQUIRE_HWID);
|
||||||
|
fu_plugin_set_device_gtype (plugin, FU_TYPE_FLASHROM_LSPCON_I2C_SPI_DEVICE);
|
||||||
|
fu_context_add_udev_subsystem (ctx, "i2c");
|
||||||
fu_context_add_quirk_key (ctx, "FlashromProgrammer");
|
fu_context_add_quirk_key (ctx, "FlashromProgrammer");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -10,6 +10,7 @@ shared_module('fu_plugin_flashrom',
|
|||||||
sources : [
|
sources : [
|
||||||
'fu-flashrom-device.c',
|
'fu-flashrom-device.c',
|
||||||
'fu-flashrom-internal-device.c',
|
'fu-flashrom-internal-device.c',
|
||||||
|
'fu-flashrom-lspcon-i2c-spi-device.c',
|
||||||
'fu-plugin-flashrom.c',
|
'fu-plugin-flashrom.c',
|
||||||
],
|
],
|
||||||
include_directories : [
|
include_directories : [
|
||||||
|
Loading…
Reference in New Issue
Block a user