Skip to content

feat(Hardware Support): Qualcomm SSC sensors through FastRPC#590

Draft
gio3k wants to merge 11 commits into
ShadowBlip:mainfrom
gio3k:dev/gio/ssc
Draft

feat(Hardware Support): Qualcomm SSC sensors through FastRPC#590
gio3k wants to merge 11 commits into
ShadowBlip:mainfrom
gio3k:dev/gio/ssc

Conversation

@gio3k
Copy link
Copy Markdown

@gio3k gio3k commented May 21, 2026

This PR adds support for the FastRPC "subsystem" and the Qualcomm Sensor Core

When combined with the correct sensor data and hexagonrpc, this can provide accelerometer & gyroscope support to Snapdragon handhelds that use the SSC for that

Big changes, in no order:

  • libloading has been added as a dependency
  • libssc, glib and gobject are runtime dependencies (they don't need to be on the build machine or any targets that don't need it)
  • FastRPC has been added as an input source / "subsystem"
  • ssc has been added as a driver

I'm opening this as a draft as I have a couple concerns:

  • FastRPC devices show up in the "misc" subsystem - UdevDevice now checks for devices with the misc subsystem and fastrpc prefix, then fakes the subsystem
  • I'd like to see what other people think of the dylib loading at runtime, it's a bit weird code-wise but I'm not sure there's a better way here

Also, minor naming concern:

Maybe the ssc driver should be split into two, something like:

drivers/ssc/runtime.rs, drivers/ssc/bindings.rs
drivers/ssc_imu/driver.rs, drivers/ssc_imu/event.rs

This is because SSC can provide other sensor data in the future aside from gyro / accel.

Where would I put the drivers/ssc folder in that case - it seems out of place to have it there if it's just the core SSC stuff?

gio3k added 6 commits May 21, 2026 11:17
Adds a default value for MountMatrix (just an identity matrix)

Signed-off-by: Gianni Spadoni <me@gio.blue>
libloading will help us load dylibs, which we need for the libssc / FastRPC implementation

Signed-off-by: Gianni Spadoni <me@gio.blue>
This implements support for the Qualcomm Sensor Core (SSC), which provides accel and gyro to some Snapdragon based handhelds made in the past 8 years or so

This requires libssc as a runtime dependency, and requires libloading as a build time & runtime dependency

As FastRPC devices don't actually show up in a "fastrpc" subsystem, and instead use the "misc" subsystem, some logic has been added to udev/device.rs to check for fastrpc devices and fake the subsystem

Signed-off-by: Gianni Spadoni <me@gio.blue>
Based on IIOIMUDevice

Signed-off-by: Gianni Spadoni <me@gio.blue>
Signed-off-by: Gianni Spadoni <me@gio.blue>
Makes sure we don't get stuck trying to init the sensor if the subsystem isn't ready

Signed-off-by: Gianni Spadoni <me@gio.blue>
Also ups the gyro scaling from 14.0 -> 16.0

Signed-off-by: Gianni Spadoni <me@gio.blue>
Copy link
Copy Markdown
Contributor

@pastaq pastaq left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looking good so far. Understand this is a WIP so it isn't in a finished state. I'm asking for a bit of cleanup with the code comments, and one significant change to device discovery. I'm also not convinced we need a fastrpc specific config option.

Comment thread src/config/mod.rs
pub evdev: Option<Evdev>,
/// Devices that match the given fastrpc properties will be captured by InputPlumber
#[serde(skip_serializing_if = "Option::is_none")]
pub fastrpc: Option<FastRpc>,
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this new config interface add additional value? I would think that the udev config would be able to find these devices without the need for another protocol specific entry. evdev/hidraw/etc. are all legacy config options we'd ideally like to get away from.

Comment thread src/drivers/ssc/bindings.rs Outdated
@@ -0,0 +1,277 @@
pub mod glib {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This file contains a lot of C binding abstractions, but there is very little context to the purpose of each function or variable. Please go through it and add amplifying information such that we don't need to find & read the ssc documentation to have an understanding of the purpose of each. It doesn't need to be an exhaustive reproduction of the documentation, just enough to explain as an overview.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I reworked it and added comments around the externals. Let me know what you think

Comment thread src/drivers/ssc/bindings.rs Outdated
Comment thread src/drivers/ssc/driver.rs Outdated
Comment thread src/drivers/ssc/driver.rs
Ok(events)
}

/// Rotate the given axis data according to the mount matrix. This is used
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Any time we start duplicating code, it is a good idea to consider if a higher level utility file is beneficial. This could indicate we need a public IMU Utils file that each driver can import.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree, but iio_imu uses a different mount_matrix type than ssc does (the iio_imu one is deprecated)

#[deprecated(
since = "0.43.0",
note = "please use `<SourceDevice>.config.imu.mount_matrix` instead"
)]
#[serde(skip_serializing_if = "Option::is_none")]
pub mount_matrix: Option<MountMatrix>,

iio_imu isn't currently reading the new config.imu.mount_matrix key either, so I was thinking of fixing that in a subsequent PR

If you'd like I could do that in this PR, I'm just worried about it getting too big

Comment thread src/input/source/fastrpc/ssc_imu.rs Outdated
Comment thread src/udev/device.rs
};

let subsystem = match device.subsystem().map(|s| s.to_string_lossy().to_string()) {
// FastRPC has special behaviour, check the comment in "From<::udev::Device> for UdevDevice"
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please don't refer to other comments/files. Each section should be understandable within its own context.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah sorry this is bad I was planning to put this comment in the PR description but I forgot

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will fix this when I create the misc subsystem

Comment thread src/udev/device.rs
.unwrap_or(OsStr::new(""))
.to_string_lossy()
.to_string();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it would be better to fully support the "misc" subsystem, then determine a device is a fastrpc when searching for a driver. That will be more scalable in the future if we add additional "misc" devices as we won't need to add additional cases here or fake the subsystem.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In the same vein as the comment below, this file should be for "misc" subsystem, then it should identify a device as a fastrpc IMU here and load the driver. This will allow us to add more "misc" devices in the future if we need to without refactoring udev/manager again.

gio3k added 4 commits May 30, 2026 16:20
Signed-off-by: Gianni Spadoni <me@gio.blue>
Should this be docs(ssc) instead of refactor(ssc)?

Signed-off-by: Gianni Spadoni <me@gio.blue>
This is a rework of the whole driver side of this PR

Bunch more documentation / commenting, thread safety, code cleanup etc

Rewrote bindings.rs, made it a single struct for all dylibs & added documentation for all the bindings
Reworked SscRuntime to be wrapped in an Arc
Stopped passing pointers around all over the place

Signed-off-by: Gianni Spadoni <me@gio.blue>
Signed-off-by: Gianni Spadoni <me@gio.blue>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants