All of lore.kernel.org
 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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.