Linux IIO development
 help / color / mirror / Atom feed
From: Jonathan Cameron <jic23@kernel.org>
To: Muchamad Coirul Anwar <muchamadcoirulanwar@gmail.com>
Cc: lars@metafoo.de, linux-iio@vger.kernel.org,
	linux-kernel@vger.kernel.org, linux-i2c@vger.kernel.org,
	andi.shyti@kernel.org, wsa+renesas@sang-engineering.com,
	ojeda@kernel.org, dakr@kernel.org, igor.korotin@linux.dev,
	branstj@gmail.com
Subject: Re: [RFC PATCH v4 3/3] iio: position: add Rust driver for ams AS5600
Date: Mon, 3 Aug 2026 02:13:04 +0100	[thread overview]
Message-ID: <20260803021304.60316f02@jic23-huawei> (raw)
In-Reply-To: <20260707151542.91997-4-muchamadcoirulanwar@gmail.com>

On Tue,  7 Jul 2026 22:15:42 +0700
Muchamad Coirul Anwar <muchamadcoirulanwar@gmail.com> wrote:

> Add a Rust driver for the ams AS5600 12-bit magnetic rotary position
> sensor. The driver exposes in_angl_raw and in_angl_scale via the IIO
> sysfs interface.
> 
> Features:
> - ARef<I2cClient> for safe refcounted I2C client access
> - Mutex-serialized status + angle read sequence
> - Static channel spec (module-level const)
> - No magnet validation at probe (deferred to read_raw per IIO convention)
> - Error propagation via ? operator (no recovery state machine)
> 
> The byte order for the AS5600's big-endian registers is handled via
> swap_bytes() in-driver. This is equivalent to C's
> i2c_smbus_read_word_swapped(). The long-term solution is regmap-rs
> where endianness is configured once at the transport level.
> 
> Tested on BeagleBone Black (AM335x) with AS5600 on i2c-2 (0x36).
> 
> Signed-off-by: Muchamad Coirul Anwar <muchamadcoirulanwar@gmail.com>

Sadly my rust remains very limited :(  So you both end up at the back
of my review queue and I can't provide much useful review!

> ---
>  drivers/iio/position/Kconfig   |  14 +++
>  drivers/iio/position/Makefile  |   1 +
>  drivers/iio/position/as5600.rs | 181 +++++++++++++++++++++++++++++++++
>  3 files changed, 196 insertions(+)
>  create mode 100644 drivers/iio/position/as5600.rs
> 
> diff --git a/drivers/iio/position/Kconfig b/drivers/iio/position/Kconfig
> index 1576a6380b53..573d241676bf 100644
> --- a/drivers/iio/position/Kconfig
> +++ b/drivers/iio/position/Kconfig
> @@ -6,6 +6,20 @@
>  
>  menu "Linear and angular position sensors"
>  
> +config AS5600
> +	tristate "ams AS5600 magnetic rotary position sensor"
> +	depends on I2C && IIO && RUST

The IIO dependence should be implicit given it is buried
deep in a menu gated on that.

> +	help
> +	  Say Y here to build support for the ams AS5600 12-bit

This Say Y language is odd as it sort of disagrees with the M
section below.  Start off with what it is then finish up with
any suggestions on Y vs M.

> +	  magnetic rotary position sensor with IIO channel support
> +	  (in_angl_raw and in_angl_scale).
> +
> +	  This is a Rust driver that exposes the 12-bit raw angle

I think the aim is that no one configuring the kernel should even
know what the language used.

> +	  and radian scale via the IIO subsystem.

I'd skip the IIO reference here given to get to this help typically
someone already navigated down into the IIO menus.

> +
> +	  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/as5600.rs b/drivers/iio/position/as5600.rs
> new file mode 100644
> index 000000000000..7445398c86b9
> --- /dev/null
> +++ b/drivers/iio/position/as5600.rs

> +
> +static AS5600_CHANNELS: As5600Channels = As5600Channels({
> +    // SAFETY: `iio_chan_spec` is a repr(C) struct where all-zeroes is valid
> +    // (integers default to 0, pointers to NULL).
> +    let mut chan: iio_chan_spec = unsafe { core::mem::zeroed() };
> +    chan.type_ = iio_chan_type_IIO_ANGL;
> +    // TODO: Use kernel::bits equivalent once bit_usize exists
> +    chan.info_mask_separate = (1usize << iio_chan_info_enum_IIO_CHAN_INFO_RAW)
> +        | (1usize << iio_chan_info_enum_IIO_CHAN_INFO_SCALE);

No nice BIT() equivalent?   Those names end up rather repetitive with
most of it coming twice.

I don't suppose there is any way to avoid that?

> +    [chan]
> +});
> +
> +impl IioDriver for As5600Priv {
> +    fn read_raw(&self, _chan: *const iio_chan_spec, mask: isize) -> Result<IioVal> {
> +        const INFO_RAW: isize = iio_chan_info_enum_IIO_CHAN_INFO_RAW as isize;
> +        const INFO_SCALE: isize = iio_chan_info_enum_IIO_CHAN_INFO_SCALE as isize;
> +        match mask {
> +            // IIO_CHAN_INFO_RAW: read the 12-bit raw angle value.
> +            INFO_RAW => {
> +                let hw = self.io_lock.lock();
> +
> +                // Read status register to verify magnet presence before
> +                // reading the angle.
> +                let status = hw.client.try_read8(AS5600_REG_STATUS as usize)?;
> +
> +                // Check magnet presence (MD bit). Without a magnet the angle
> +                // register contains stale/invalid data.
> +                if (status & AS5600_STATUS_MD) == 0 {
> +                    return Err(ENODATA);
> +                }
> +
> +                // Word read at register 0x0C: SMBus read_word_data returns LE,

That seems wrong.  It assumes LE data on the wire, but should return in
the CPU endianness.  Hence it's a swap in all cases, rather than an be16_to_cpu()
which would get it backwards on a big endian platform.


> +                // AS5600 stores angle big-endian, so swap_bytes() is needed.
> +                // Mutex ensures status + angle read is atomic.
> +                // NOTE: Equivalent to C's i2c_smbus_read_word_swapped().
> +                // Long-term, regmap-rs with val_format_endian=Big handles
> +                // this transparently at configuration level.
> +                let raw = hw.client.try_read16(AS5600_REG_RAW_ANGLE_H as usize)?;
> +                let angle = raw.swap_bytes() & AS5600_RAW_ANGLE_MASK;
> +                Ok(IioVal::Int(angle as i32))
> +            }
> +            // IIO_CHAN_INFO_SCALE: radians per LSB, 2*pi / 4096 = 0.001533981.
> +            INFO_SCALE => {
> +                Ok(IioVal::IntPlusNano(0, 1533981))
> +            }
> +            _ => Err(EINVAL),
> +        }
> +    }
> +
> +    fn channels(&self) -> &[iio_chan_spec] {
> +        &AS5600_CHANNELS.0
> +    }
> +}


  reply	other threads:[~2026-08-03  1:13 UTC|newest]

Thread overview: 25+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-07-07 15:15 [RFC PATCH v4 0/3] iio: position: add Rust driver for ams AS5600 Muchamad Coirul Anwar
2026-07-07 15:15 ` [RFC PATCH v4 1/3] i2c: rust: implement SMBus read abstraction via kernel::io::Io for I2cClient Muchamad Coirul Anwar
2026-07-11 10:05   ` Igor Korotin
2026-07-11 12:05     ` Danilo Krummrich
2026-07-14 16:08     ` Muchamad Coirul Anwar
2026-07-18  2:48       ` Bruce Robertson
2026-07-19 15:40         ` Muchamad Coirul Anwar
2026-07-19 23:02       ` Danilo Krummrich
2026-07-20  2:26         ` Muchamad Coirul Anwar
2026-07-11 12:08   ` Danilo Krummrich
2026-07-14 16:10     ` Muchamad Coirul Anwar
2026-08-03  0:53   ` Jonathan Cameron
2026-08-03  8:14     ` Muchamad Coirul Anwar
2026-07-07 15:15 ` [RFC PATCH v4 2/3] rust: add minimal IIO subsystem abstractions Muchamad Coirul Anwar
2026-07-11 12:12   ` Danilo Krummrich
2026-07-14 16:20     ` Muchamad Coirul Anwar
2026-08-03  0:43       ` Jonathan Cameron
2026-08-03  7:24         ` Muchamad Coirul Anwar
2026-07-07 15:15 ` [RFC PATCH v4 3/3] iio: position: add Rust driver for ams AS5600 Muchamad Coirul Anwar
2026-08-03  1:13   ` Jonathan Cameron [this message]
2026-08-06  1:54     ` Muchamad Coirul Anwar
2026-08-04 14:57   ` Nuno Sá
2026-08-06  2:51     ` Muchamad Coirul Anwar
2026-07-08 10:36 ` [RFC PATCH v4 0/3] " Miguel Ojeda
2026-07-08 12:37   ` Muchamad Coirul Anwar

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20260803021304.60316f02@jic23-huawei \
    --to=jic23@kernel.org \
    --cc=andi.shyti@kernel.org \
    --cc=branstj@gmail.com \
    --cc=dakr@kernel.org \
    --cc=igor.korotin@linux.dev \
    --cc=lars@metafoo.de \
    --cc=linux-i2c@vger.kernel.org \
    --cc=linux-iio@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=muchamadcoirulanwar@gmail.com \
    --cc=ojeda@kernel.org \
    --cc=wsa+renesas@sang-engineering.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox