openinput is a project that provides firmware for input devices like mice, keyboards, etc. The main focus of the project is to provide a good end-user experience, from configuration drivers to firmware updates to overall reliability.

We hope to enable the community share and develop their creativity by allowing them to build and tinker with devices without having to worry about troublesome technical issues like software support, etc. openinput provides the underlying framework required to make all this possible.

State of the project¶

Currently, we have a working target implementation using the Linux UHID API, which allows you to have full software testing of the protocol using real drivers. We are working on the STM32F1 target, which should provide official firmware support for the Steelseries Rival 310.

The protocol is also a work in progress. The base format and basic function discovery functions are defined, implemented in the firmware and implemented in a libratbag driver.


  • Linux UHID target 👍

  • Steelseries Rival 310 target 👍

  • Custom hardware target (supporting USB full speed - 8kHz report rate) 👍

  • Custom wireless target (device + receiver) 🔨

  • libratbag driver (allows use in piper) 👍

  • fwupd plugin (firmware updates)

  • Linux driver for native functions (battery reporting, etc.)

  • Linux driver for multiplexing devices (multiple devices connected to a single receiver)




Work in progress

Getting started¶

Building the firmware¶

To build the openinput firmware you will first need to install the dependencies required to run the build system.

You will also need a copy of the GCC compiler, binutils and a standard C library for your target architecture.

  • Native (pacman -S gcc binutils glibc)
    • Linux UHID (linux-uhid)

  • arm-none-eabi (pacman -S arm-none-eabi-gcc arm-none-eabi-binutils arm-none-eabi-newlib)
    • STM32F1 (stm32f1-generic)
      • Bluepill

      • Steelseries Rival 310

    • EFM32

After having all requirements met we can build! First we will run to generate a for our target and then we will invoke ninja to actually do the building. will clone the necessary submodules by default, you can pass the --no-fetch/-n option to disable this behavior.

$ ./ linux-uhid
$ ninja

After this, you should have your shiny new object in build/out.