Friends, what are the measurement principles of the pulse sensors (PPG) and IMUs in smartwatches? How do you work with this type of hardware in the Linux kernel? Specifically, how are signals read through the input subsystem (APIs, eventX interfaces, sysfs values) in the kernel? If I were to attempt writing my own driver, which resources would be the most reliable? For example, where can I examine kernel docs, ABI specifications, or source codes from real projects?
How do smartwatches with Linux/Mesa (distance) hardware work?
👁️ 3 views💬 3 replies❤️ 0 likes
3 Replies
So you're diving into Linux, huh? 😅 I still can't find the power button on my phone, and you're writing sensor drivers by hand. But I guess connecting a sensor to the kernel is different from me trying to connect to WiFi. 🤯 You say there are docs? Lucky you, I'm using a Samsung— their support page just says "No temporary solution found for your issue." 😭
PPG sensors and IMUs were something I also looked into a while back, but honestly, it got a bit confusing. PPG sensors measure light reflection to provide heart rate data, while IMUs use accelerometers and gyroscopes to detect motion. On the Linux side, you can read raw data from `/dev/input/eventX` files via the kernel's input subsystem—for example, using the `evtest` command to see which event number corresponds to which sensor.
When it comes to drivers, the files in the kernel docs' `Documentation/input/` folder are pretty helpful. I also checked out a small project like https://github.com/nuulll/asus-ec-interface, which has code snippets on how HID-based sensors are defined. Pay attention to ABI stability across kernel versions, as there can be changes in the input subsystem, especially in the 6.x series.
The PPG (PhotoPlethysmoGraphy) sensors in smartwatches operate on a simple yet effective principle: a green, red, or IR LED shines light onto your skin, and a photodiode detects the light absorption. Changes in blood volume with each heartbeat modulate the light absorption, which is continuously detected as a signal (even when the LED isn’t blinking) and converted into numerical data. IMUs (Inertial Measurement Units) work by combining a 3-axis accelerometer, gyroscope, and sometimes a magnetometer to measure forces from gravity and motion. By integrating rotational speeds and acceleration, the device calculates its position and orientation—but the biggest challenge here is how well sensor fusion algorithms are optimized to correct sensor-based errors (like gyroscope drift).
In the Linux kernel, working with these sensors hinges on the **Input Subsystem** and the **IIO (Industrial I/O)** subsystem. PPG sensors typically send heart rate data via `input_event` (eventX interfaces), while IMUs usually appear under the IIO interface (e.g., `iio:deviceX`, where 3-axis accelerometer data can be read from sysfs files like `in_accel_x_raw`). The kernel docs in *Documentation/input/* and *Documentation/iio/* explain how to register sensors and read their data—but for now, the most reliable references are the actual driver implementations in upstream kernel projects. For example, kernel drivers for **Bosch BMI160** or **STM32L4**-based IMUs (like those in bspwm or stm32mp1 projects) are quite detailed.
If you're planning to write a custom driver, you’ll also need to consider **HID-over-I2C** or **SPI** communication protocols—most smartwatch sensors use these interfaces. Since ABI specifications highlight unstable parts of the kernel, your first priority should be using **stable kernel APIs**. For instance, structures like `iio_buffer` and `iio_trigger` in IIO are highly efficient for reading sensor data. Remember, developing a kernel driver requires far more caution than you might think—a small mistake can freeze the system or lead to incorrect measurements.