public inbox for linux-iio@vger.kernel.org
 help / color / mirror / Atom feed
* [RFC PATCH] [RFC PATCH] iio: position: rust: add initial AS5600 driver
@ 2026-04-19 15:13 Muchamad Coirul Anwar
  2026-04-20 18:33 ` Jonathan Cameron
  0 siblings, 1 reply; 3+ messages in thread
From: Muchamad Coirul Anwar @ 2026-04-19 15:13 UTC (permalink / raw)
  To: Jonathan Cameron, Lars-Peter Clausen, Miguel Ojeda
  Cc: Frank Zago, linux-iio, rust-for-linux, linux-kernel,
	Muchamad Coirul Anwar

This RFC introduces an initial Rust implementation for the ams OSRAM AS5600 magnetic rotary position sensor. The current scope covers I2C communication, device probing, and strict parsing of the AGC (Automatic Gain Control) hardware status.

For context, a C-based driver was proposed by Frank Zago in 2021 (Link: https://lore.kernel.org/linux-iio/20211216202651.120172-1-frank@zago.net/), but it was not merged. This fresh Rust implementation takes a stricter approach to probing by enforcing mandatory validation of the STATUS (0x0B) register. It gracefully aborts with -ENODEV if a valid diametrical magnet is not detected.

I have intentionally deferred exposing the IIO channels (in_angl_raw and scale) to avoid writing raw unsafe C FFI bindings. Full sysfs support will be added in a V2 once the safe Rust IIO abstractions land upstream.

Testing was performed on kernel v7.0.0-rc3 using a BeagleBone Black (AM335x) on i2c-2 (0x36) operating at 3.3V.

Testing logs verifying probe behavior and AGC logic via sysfs bind/unbind:

No magnet or magnetic field out of range:
$ echo 2-0036 > /sys/bus/i2c/drivers/as5600/bind
[ 1928.138249] as5600 2-0036: AS5600: No magnet detected

(Probe aborted, safely returns -ENODEV)
Magnet pushed too far (weak field):
$ echo 2-0036 > /sys/bus/i2c/drivers/as5600/bind
[ 1966.130616] as5600 2-0036: AS5600: Magnet too weak
[ 1966.135628] as5600 2-0036: AS5600: Sensor probed, driver ready

Magnet placed too close (strong field):
$ echo 2-0036 > /sys/bus/i2c/drivers/as5600/bind
[ 1988.541979] as5600 2-0036: AS5600: Magnet too strong
[ 1988.547183] as5600 2-0036: AS5600: Sensor probed, driver ready

Optimal diametrical spot:
$ echo 2-0036 > /sys/bus/i2c/drivers/as5600/bind
[ 1977.527490] as5600 2-0036: AS5600: Sensor probed, driver ready

Signed-off-by: Muchamad Coirul Anwar <muchamadcoirulanwar@gmail.com>
---
 drivers/iio/position/Kconfig   | 13 +++++++
 drivers/iio/position/Makefile  |  1 +
 drivers/iio/position/as5600.rs | 64 ++++++++++++++++++++++++++++++++++
 3 files changed, 78 insertions(+)
 create mode 100644 drivers/iio/position/as5600.rs

diff --git a/drivers/iio/position/Kconfig b/drivers/iio/position/Kconfig
index 1576a6380b53..9d2611a71e33 100644
--- a/drivers/iio/position/Kconfig
+++ b/drivers/iio/position/Kconfig
@@ -6,6 +6,19 @@
 
 menu "Linear and angular position sensors"
 
+config AS5600
+	tristate "ams AS5600 magnetic rotary position sensor"
+	depends on I2C && RUST
+	help	  
+	  Say Y here to build support for the ams AS5600 12-bit
+	  magnetic rotary position sensor.
+
+	  This driver provides hardware validation and I2C probing
+	  in Rust for the AS5600.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called as5600.
+
 config IQS624_POS
 	tristate "Azoteq IQS624/625 angular position sensors"
 	depends on MFD_IQS62X || COMPILE_TEST
diff --git a/drivers/iio/position/Makefile b/drivers/iio/position/Makefile
index d70902f2979d..2d26f6d6ace3 100644
--- a/drivers/iio/position/Makefile
+++ b/drivers/iio/position/Makefile
@@ -4,5 +4,6 @@
 
 # When adding new entries keep the list in alphabetical order
 
+obj-$(CONFIG_AS5600) += as5600.o
 obj-$(CONFIG_HID_SENSOR_CUSTOM_INTEL_HINGE) += hid-sensor-custom-intel-hinge.o
 obj-$(CONFIG_IQS624_POS)	+= iqs624-pos.o
diff --git a/drivers/iio/position/as5600.rs b/drivers/iio/position/as5600.rs
new file mode 100644
index 000000000000..c5aab2230acf
--- /dev/null
+++ b/drivers/iio/position/as5600.rs
@@ -0,0 +1,64 @@
+// SPDX-License-Identifier: GPL-2.0-only
+// Copyright (C) 2026 Muchamad Coirul Anwar <muchamadcoirulanwar@gmail.com>
+//! Driver for ams AS5600 12-bit magnetic rotary position sensor.
+//!
+//! Datasheet: https://ams.com/documents/20143/36005/AS5600_DS000365_5-00.pdf
+
+use kernel::device::Core;
+use kernel::i2c;
+use kernel::module_i2c_driver;
+use kernel::prelude::*;
+
+// AS5600 register addresses (from datasheet v1.06)
+const AS5600_REG_STATUS: u8 = 0x0B;
+const AS5600_REG_RAW_ANGLE_H: u8 = 0x0C; // High nibble [11:8] in bits [3:0]
+const AS5600_REG_RAW_ANGLE_L: u8 = 0x0D; // Low byte [7:0]
+
+// STATUS register bit masks
+const AS5600_STATUS_MH: u8 = 0x08; // Magnet too strong (AGC minimum gain overflow)
+const AS5600_STATUS_ML: u8 = 0x10; // Magnet too weak (AGC maximum gain overflow)
+const AS5600_STATUS_MD: u8 = 0x20; // Magnet detected
+
+module_i2c_driver! {
+    type: As5600,
+    name: "as5600",
+    authors: ["Muchamad Coirul Anwar"],
+    description: "I2C Driver for ams OSRAM AS5600 Magnetic Rotary Position Sensor",
+    license: "GPL",
+}
+
+kernel::i2c_device_table!(
+    I2C_TABLE,
+    MODULE_I2C_TABLE,
+    <As5600 as i2c::Driver>::IdInfo,
+    [(i2c::DeviceId::new(c"as5600"), ())]
+);
+
+struct As5600 {}
+
+impl i2c::Driver for As5600 {
+    type IdInfo = ();
+    const I2C_ID_TABLE: Option<i2c::IdTable<Self::IdInfo>> = Some(&I2C_TABLE);
+
+    fn probe(
+        dev: &i2c::I2cClient<Core>,
+        _id_info: Option<&Self::IdInfo>,
+    ) -> impl PinInit<Self, Error> {
+        let status = dev.smbus_read_byte_data(AS5600_REG_STATUS)?;
+        if (status & AS5600_STATUS_MD) == 0 {
+            dev_err!(dev.as_ref(), "AS5600: No magnet detected\n");
+            return Err(ENODEV);
+        } else if (status & AS5600_STATUS_MH) != 0 {
+            dev_warn!(dev.as_ref(), "AS5600: Magnet too strong\n");
+        } else if (status & AS5600_STATUS_ML) != 0 {
+            dev_warn!(dev.as_ref(), "AS5600: Magnet too weak\n");
+        }
+
+        dev_info!(dev.as_ref(), "AS5600: Sensor probed, driver ready\n");
+        Ok::<_, Error>(As5600 {})
+    }
+
+    fn unbind(dev: &i2c::I2cClient<Core>, _this: Pin<&Self>) {
+        dev_info!(dev.as_ref(), "AS5600 Sensor Driver Unbound\n");
+    }
+}
-- 
2.50.0


^ permalink raw reply related	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2026-04-21  9:49 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-04-19 15:13 [RFC PATCH] [RFC PATCH] iio: position: rust: add initial AS5600 driver Muchamad Coirul Anwar
2026-04-20 18:33 ` Jonathan Cameron
2026-04-21  9:49   ` Miguel Ojeda

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox