From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mail-pf1-f170.google.com (mail-pf1-f170.google.com [209.85.210.170]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id CD2FC22578D for ; Sun, 19 Apr 2026 15:13:37 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.210.170 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1776611620; cv=none; b=Z5hU8n0c+Jf7jcl0l4N9WCys4s3mIoF++8FUy9HF9KryfHy4LkWZ0bR87xnvFV6IKeBpDtX7sUjn9moxLx8/iLWi77LLspMNpOQosmLhnyZ1r9NFy5uUxHDZF+K/nPg1LY9XtR0M+TVdUpblNTJU16qn4p65p8B+r42AgoKCqEg= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1776611620; c=relaxed/simple; bh=vDcIK+5js169U/jlxiXnZOwZX66iqRq/wHgzJ3IkbuM=; h=From:To:Cc:Subject:Date:Message-ID:MIME-Version; b=sxNJaG6NJNeGEz+4jpWo2EWzpSRk1NR50g2jf0yEPvBhhXA9aKL4XidpGPWovb5qhhqSa1TF4P8c4u1AFJFTLbGaMTwQaIlPvy0xGb70dh0LVfM0H0siqBj4a5DXENwMaGVO8mIHcLXgY94IfyTzrhizF86fFeePgM6RqIS1QuY= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=MouLzqpU; arc=none smtp.client-ip=209.85.210.170 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="MouLzqpU" Received: by mail-pf1-f170.google.com with SMTP id d2e1a72fcca58-82d0b68837aso1349838b3a.2 for ; Sun, 19 Apr 2026 08:13:37 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1776611617; x=1777216417; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:from:to:cc:subject:date:message-id:reply-to; bh=8fkjDIA2luV5mDODpq9a0VIYJU3zYUueNvtgaejrRgQ=; b=MouLzqpUvFJH28Dd30F15Pir5FXo2IPX8ie7hvIcKZaanuLxOMRo4Rmak4/diFmtPZ zLqWSeg8gzTplfIcnUeSpyHVIsQC+nnK+Rss6VJK1C1hrl/uuKIK57Z6pNai5xKG14dQ 8b7N6P0OwA825FvD/L9C4GVGSYkW0Zpltlxr94tcjzBZ8/ef9Q6rvmFqU010djK2YEGT cLFSDueG6z0QyGzEB9A9UfzU0tb+moPHL6ZSO0IvbP5MP/xTbfwiwOpsNelz6uhDX4Xe AbRXiA/gSZK6l34E2DpKfBj8S8AN++QL3E4QQkzQXLWYjZlt8f3vEbrfxDQ9uqXzu5jD KbVA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1776611617; x=1777216417; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:x-gm-gg:x-gm-message-state:from:to:cc:subject:date :message-id:reply-to; bh=8fkjDIA2luV5mDODpq9a0VIYJU3zYUueNvtgaejrRgQ=; b=RdvmFfHvW1LuxOtIqavMEpOTHDx2SO9k4KMG2Fhaay6+KUGoT8SP9c5fZHiXMo5Yy6 m06UhubxiNulFXeirU+KODHMaZwYq43ZFCws63pEeTCUI14gKBN/F/NcphRroXLsu0Vh B1yrs1fCnwoaYIIYn6qScPv+gXf/FMqpu/xtiGi3sFYu1eMfWLbIcYuScz9CMEq/NI0t 7+Ty1ADQSG5/czmF96ERzAiqq/4Rc0+yvTLMGSwjW5TFGg8huh34b3Ag1d6Nz9avhZi5 R23li7lcryvHzvk0QbFIbAkWScd7kX5hjmPk4KfBszl7Zr7fsE01TeSechHIAkuwAnwu m+lw== X-Forwarded-Encrypted: i=1; AFNElJ9hKw8PWhlvuzcuzgl5LtFKfgLS9FQqiuIkJGkDLCWXsAJovD9+Gvr2NPo4cNjwwgt526ZeeIEVHVyBXww=@vger.kernel.org X-Gm-Message-State: AOJu0YwZYww8+b8UhKWUELq1EZuwP9Za1Kh/K0IDps1eeLelCmXxlYvY OIJwWRnskBPm2XAxIT4/HDmqPQFr+BX2uwG+fjti+9f1yzpXnZHHvpWiDOKlDope X-Gm-Gg: AeBDietLh14nEvgIrI5fhZIzrkYrjznYDY5eLSoU013YUUNxzlC7dHUWfrzb2jK/2rQ 7fvybblk9w73PzLq+cY5ExOumNdunFc3+6un86LEPDT9LAfnn4EzVuSvgf1QaH8SRymTe6t0V/E +KObsd6jAYwc966smJn+IxWd2Km9s6i/noslq9LtF7EK8IpZ9aRFPoJ3XqzQ0f09wqMBYIzD6nL opNqc9FCbt7pb6LxNmyb/SQzwMBackd0DswII3mdp4LQ/BjUT3n9gdxUXQzBxu6FHM3jS6E5glz zYm7M+xMZa9edznW6myrKdcWQDZ/SuiDp51TbTtI8swa41b2SKakEgQTN69+2/tg6osZ8YAOMcd 6CZlvRTum7YWw/T1J/ev3yplgbJp3WAqdDcUNwfN5cvvN2OpJ0lmKoPNm5MlH84czH/Sm8WpqPt 914nLWUhoVlPSRmGKJe9KRAnjvrSbpwVpByZvmjlaOTqHVLELZBWuC0QDClWw0RFP1oDP9EYVrm XnCN+PtudqMd4g= X-Received: by 2002:a05:6a00:c8b:b0:82c:ec1b:9e12 with SMTP id d2e1a72fcca58-82f8c849042mr10372913b3a.21.1776611617129; Sun, 19 Apr 2026 08:13:37 -0700 (PDT) Received: from localhost.localdomain ([2001:448a:2002:a699:c062:7e7a:5ea3:cd14]) by smtp.gmail.com with ESMTPSA id d2e1a72fcca58-82f8ea02ef7sm7175560b3a.25.2026.04.19.08.13.34 (version=TLS1_3 cipher=TLS_CHACHA20_POLY1305_SHA256 bits=256/256); Sun, 19 Apr 2026 08:13:36 -0700 (PDT) From: Muchamad Coirul Anwar To: Jonathan Cameron , Lars-Peter Clausen , Miguel Ojeda Cc: Frank Zago , linux-iio@vger.kernel.org, rust-for-linux@vger.kernel.org, linux-kernel@vger.kernel.org, Muchamad Coirul Anwar Subject: [RFC PATCH] [RFC PATCH] iio: position: rust: add initial AS5600 driver Date: Sun, 19 Apr 2026 22:13:27 +0700 Message-ID: <20260419151327.26306-1-muchamadcoirulanwar@gmail.com> X-Mailer: git-send-email 2.50.0 Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit 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 --- 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 +//! 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, + ::IdInfo, + [(i2c::DeviceId::new(c"as5600"), ())] +); + +struct As5600 {} + +impl i2c::Driver for As5600 { + type IdInfo = (); + const I2C_ID_TABLE: Option> = Some(&I2C_TABLE); + + fn probe( + dev: &i2c::I2cClient, + _id_info: Option<&Self::IdInfo>, + ) -> impl PinInit { + 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, _this: Pin<&Self>) { + dev_info!(dev.as_ref(), "AS5600 Sensor Driver Unbound\n"); + } +} -- 2.50.0