From 99b8c80aee48227f900fc8883e71df050da5faa5 Mon Sep 17 00:00:00 2001 From: "Thomas H.P. Andersen" Date: Tue, 29 Sep 2020 00:53:52 +0200 Subject: [PATCH] device: add firmware major/minor This adds fields to the device struct to store the firmware version on the device. It is also exposed over dbus to the clients. The firmware of a device can define the protocol or memory layout that should be used to talk to the device. Several devices can query the firmware version via separate commands and we can use this information in the drivers to change behavior of the driver based on the device firmware. The firmware version is also exposed over dbus so that it is easily available for users via e.g. ratbagctl. It can also be used in piper to warn users that a known bug in a firmware version can cause problems when trying to configure with libratbag. --- doc/dbus.rst | 14 ++++++++++++++ ratbagd/ratbagd-device.c | 36 ++++++++++++++++++++++++++++++++++++ src/libratbag-private.h | 3 +++ src/libratbag.c | 12 ++++++++++++ src/libratbag.h | 18 ++++++++++++++++++ tools/ratbagctl.in.in | 2 ++ tools/ratbagd.py | 10 ++++++++++ 7 files changed, 95 insertions(+) diff --git a/doc/dbus.rst b/doc/dbus.rst index be023f3e..62c5ad41 100644 --- a/doc/dbus.rst +++ b/doc/dbus.rst @@ -151,6 +151,20 @@ known to ratbagd. Vendor or product IDs of 0 are valid IDs (e.g. used used by test devices). +.. attribute:: FirmwareMajor + + :type: i + :flags: read-only, constant + + The device's firmware major version. + +.. attribute:: FirmwareMinor + + :type: i + :flags: read-only, constant + + The device's firmware minor version. + .. attribute:: Name :type: s diff --git a/ratbagd/ratbagd-device.c b/ratbagd/ratbagd-device.c index b58cb4bf..61282e85 100644 --- a/ratbagd/ratbagd-device.c +++ b/ratbagd/ratbagd-device.c @@ -220,9 +220,45 @@ ratbag_device_get_model(sd_bus *bus, return sd_bus_message_append(reply, "s", model); } +static int +ratbag_device_get_firmware_major(sd_bus *bus, + const char *path, + const char *interface, + const char *property, + sd_bus_message *reply, + void *userdata, + sd_bus_error *error) +{ + struct ratbagd_device *device = userdata; + int version = ratbag_device_get_firmware_major_version(device->lib_device); + + CHECK_CALL(sd_bus_message_append(reply, "i", version)); + + return 0; +} + +static int +ratbag_device_get_firmware_minor(sd_bus *bus, + const char *path, + const char *interface, + const char *property, + sd_bus_message *reply, + void *userdata, + sd_bus_error *error) +{ + struct ratbagd_device *device = userdata; + int version = ratbag_device_get_firmware_minor_version(device->lib_device); + + CHECK_CALL(sd_bus_message_append(reply, "i", version)); + + return 0; +} + const sd_bus_vtable ratbagd_device_vtable[] = { SD_BUS_VTABLE_START(0), SD_BUS_PROPERTY("Model", "s", ratbag_device_get_model, 0, SD_BUS_VTABLE_PROPERTY_CONST), + SD_BUS_PROPERTY("FirmwareMajor", "i", ratbag_device_get_firmware_major, 0, SD_BUS_VTABLE_PROPERTY_CONST), + SD_BUS_PROPERTY("FirmwareMinor", "i", ratbag_device_get_firmware_minor, 0, SD_BUS_VTABLE_PROPERTY_CONST), SD_BUS_PROPERTY("Name", "s", ratbagd_device_get_device_name, 0, SD_BUS_VTABLE_PROPERTY_CONST), SD_BUS_PROPERTY("Profiles", "ao", ratbagd_device_get_profiles, 0, SD_BUS_VTABLE_PROPERTY_CONST), SD_BUS_METHOD("Commit", "", "u", ratbagd_device_commit, SD_BUS_VTABLE_UNPRIVILEGED), diff --git a/src/libratbag-private.h b/src/libratbag-private.h index 7a9ab5ac..b6ff3ade 100644 --- a/src/libratbag-private.h +++ b/src/libratbag-private.h @@ -147,6 +147,9 @@ struct ratbag_device { unsigned num_buttons; unsigned num_leds; + int firmware_major; + int firmware_minor; + void *drv_data; struct list link; diff --git a/src/libratbag.c b/src/libratbag.c index ef9aa8bd..020fba37 100644 --- a/src/libratbag.c +++ b/src/libratbag.c @@ -545,6 +545,18 @@ ratbag_device_get_product_id(const struct ratbag_device *device) return device->ids.product; } +LIBRATBAG_EXPORT int32_t +ratbag_device_get_firmware_major_version(const struct ratbag_device *device) +{ + return device->firmware_major; +} + +LIBRATBAG_EXPORT int32_t +ratbag_device_get_firmware_minor_version(const struct ratbag_device *device) +{ + return device->firmware_minor; +} + LIBRATBAG_EXPORT uint32_t ratbag_device_get_product_version(const struct ratbag_device *device) { diff --git a/src/libratbag.h b/src/libratbag.h index 666af95d..85de0878 100644 --- a/src/libratbag.h +++ b/src/libratbag.h @@ -421,6 +421,24 @@ ratbag_device_set_user_data(struct ratbag_device *device, void *userdata); void* ratbag_device_get_user_data(const struct ratbag_device *device); +/** + * @ingroup device + * + * @param device A previously initialized ratbag device + * @return The firmware major version of the device. + */ +int32_t +ratbag_device_get_firmware_major_version(const struct ratbag_device *device); + +/** + * @ingroup device + * + * @param device A previously initialized ratbag device + * @return The firmware minor version of the device. + */ +int32_t +ratbag_device_get_firmware_minor_version(const struct ratbag_device *device); + /** * @ingroup device * diff --git a/tools/ratbagctl.in.in b/tools/ratbagctl.in.in index 7ba9f73e..5d4e95eb 100755 --- a/tools/ratbagctl.in.in +++ b/tools/ratbagctl.in.in @@ -212,6 +212,8 @@ def print_device(d, level): print(" " * level + "{} - {}".format(d.id, d.name)) print(" " * level + " Model: {}".format(d.model)) + if d.firmware_major > 0 or d.firmware_minor > 0: + print(" " * level + " Firmware version: {}.{}".format(d.firmware_major, d.firmware_minor)) print(" " * level + " Number of Buttons: {}".format(len(p.buttons))) print(" " * level + " Number of Leds: {}".format(len(p.leds))) print(" " * level + "Number of Profiles: {}".format(len(d.profiles))) diff --git a/tools/ratbagd.py b/tools/ratbagd.py index 3041fea6..2b259772 100644 --- a/tools/ratbagd.py +++ b/tools/ratbagd.py @@ -342,6 +342,16 @@ class RatbagdDevice(_RatbagdDBus): """The unique identifier for this device model.""" return self._get_dbus_property("Model") + @GObject.Property + def firmware_major(self): + """The firmware major version.""" + return self._get_dbus_property("FirmwareMajor") + + @GObject.Property + def firmware_minor(self): + """The firmware minor version.""" + return self._get_dbus_property("FirmwareMinor") + @GObject.Property def name(self): """The device name, usually provided by the kernel."""