mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: Tristan de Cacqueray <tristan@midirus.com>
To: Takashi Iwai <tiwai@suse.de>, Miguel Ojeda <ojeda@kernel.org>
Cc: linux-sound@vger.kernel.org, rust-for-linux@vger.kernel.org,
	linux-kernel@vger.kernel.org,
	Tristan de Cacqueray <tristan@midirus.com>
Subject: [PATCH RFC 1/3] rust: snd: Add initial snd_card binding
Date: Sun, 11 Oct 2026 13:02:17 +0000	[thread overview]
Message-ID: <20261011-rust-snd-v1-1-7974ecdcd345@midirus.com> (raw)
In-Reply-To: <20261011-rust-snd-v1-0-7974ecdcd345@midirus.com>

Add minimal abstraction to create a snd_card in Rust.

Signed-off-by: Tristan de Cacqueray <tristan@midirus.com>
---
 rust/bindings/bindings_helper.h  |  1 +
 rust/kernel/lib.rs               |  2 ++
 rust/kernel/snd.rs               | 89 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 samples/rust/Kconfig             | 11 +++++++++++
 samples/rust/Makefile            |  1 +
 samples/rust/rust_midi_device.rs | 41 +++++++++++++++++++++++++++++++++++++++++
 6 files changed, 145 insertions(+)

diff --git a/rust/bindings/bindings_helper.h b/rust/bindings/bindings_helper.h
index c706dda5b5ca..c624f073db04 100644
--- a/rust/bindings/bindings_helper.h
+++ b/rust/bindings/bindings_helper.h
@@ -97,6 +97,7 @@
 #include <linux/xarray.h>
 #include <net/genetlink.h>
 #include <net/netlink.h>
+#include <sound/core.h>
 #include <trace/events/rust_sample.h>
 
 /*
diff --git a/rust/kernel/lib.rs b/rust/kernel/lib.rs
index 7225abc64084..974b3e5ce7ac 100644
--- a/rust/kernel/lib.rs
+++ b/rust/kernel/lib.rs
@@ -130,6 +130,8 @@
 #[cfg(CONFIG_RUST_SERIAL_DEV_BUS_ABSTRACTIONS)]
 pub mod serdev;
 pub mod sizes;
+#[cfg(CONFIG_SND)]
+pub mod snd;
 #[cfg(CONFIG_SOC_BUS)]
 pub mod soc;
 #[doc(hidden)]
diff --git a/rust/kernel/snd.rs b/rust/kernel/snd.rs
new file mode 100644
index 000000000000..aaffe942b360
--- /dev/null
+++ b/rust/kernel/snd.rs
@@ -0,0 +1,89 @@
+// SPDX-License-Identifier: GPL-2.0
+// SPDX-FileCopyrightText: Copyright (C) 2026 Tristan de Cacqueray
+
+//! Abstractions for the snd subsystem.
+//!
+//! This module provides bindings for working with ALSA in kernel modules.
+//!
+//! C header: [`include/sound/core.h`](srctree/include/sound/core.h)
+
+use kernel::{
+    bindings,
+    device::Device,
+    error::{Result},
+    prelude::*,
+};
+
+/// A sound card instance.
+pub struct SoundCard {
+    ptr: *mut bindings::snd_card,
+}
+
+impl SoundCard {
+    /// Creates a new sound card bound to a device lifecycle
+    pub fn new(dev: &Device, id: &CStr, module: &'static kernel::ThisModule) -> Result<Self> {
+        let mut card_ptr: *mut bindings::snd_card = core::ptr::null_mut();
+
+        // SAFETY: C helper copies the arguments.
+        let ret = unsafe {
+            bindings::snd_devm_card_new(
+                dev.as_raw(),
+                -1,
+                id.as_char_ptr(),
+                module.as_ptr(),
+                0,
+                &mut card_ptr,
+            )
+        };
+
+        if ret < 0 {
+            return Err(Error::from_errno(ret));
+        }
+
+        Ok(Self { ptr: card_ptr })
+    }
+
+    /// Sets the driver field of the sound card.
+    pub fn set_driver(&mut self, name: &CStr) -> Result<()> {
+        // SAFETY: `self.ptr` is valid and points to an initialized `snd_card`.
+        let card = unsafe { &mut *self.ptr };
+        copy_to_c_buf(&mut card.driver, name)
+    }
+
+    /// Sets the shortname field of the sound card.
+    pub fn set_shortname(&mut self, name: &CStr) -> Result<()> {
+        // SAFETY: `self.ptr` is valid and points to an initialized `snd_card`.
+        let card = unsafe { &mut *self.ptr };
+        copy_to_c_buf(&mut card.shortname, name)
+    }
+
+    /// Triggers registration of the card components to the user-space ALSA layers
+    pub fn register(self) -> Result<RegisteredSoundCard> {
+        // SAFETY: `self.ptr` is valid and points to an initialized `snd_card`.
+        let ret = unsafe { bindings::snd_card_register(self.ptr) };
+        if ret < 0 {
+            return Err(Error::from_errno(ret));
+        }
+        Ok(RegisteredSoundCard { _inner: self })
+    }
+}
+
+/// Helper to copy `src` (including its NUL) into the fixed-size C buffer `dest`.
+/// Returns `EINVAL` if `src` does not fit.
+fn copy_to_c_buf(dest: &mut [ffi::c_char], src: &CStr) -> Result<()> {
+    let bytes = src.to_bytes_with_nul();
+    if bytes.len() > dest.len() {
+        return Err(EINVAL);
+    }
+    let (used, rest) = dest.split_at_mut(bytes.len());
+    for (d, &b) in used.iter_mut().zip(bytes) {
+        *d = b as ffi::c_char;
+    }
+    rest.fill(0);
+    Ok(())
+}
+
+/// A sound card that is already registered.
+pub struct RegisteredSoundCard {
+    _inner: SoundCard,
+}
diff --git a/samples/rust/Kconfig b/samples/rust/Kconfig
index 31d62533ef25..1cf8cf18cd2d 100644
--- a/samples/rust/Kconfig
+++ b/samples/rust/Kconfig
@@ -31,6 +31,17 @@ config SAMPLE_RUST_MINIMAL
 
 	  If unsure, say N.
 
+config SAMPLE_RUST_MIDI_DEVICE
+	tristate "MIDI device"
+	depends on SND_RAWMIDI
+	help
+	  This option builds the Rust MIDI device.
+
+	  To compile this as a module, choose M here:
+	  the module will be called rust_midi_device.
+
+	  If unsure, say N.
+
 config SAMPLE_RUST_MISC_DEVICE
 	tristate "Misc device"
 	help
diff --git a/samples/rust/Makefile b/samples/rust/Makefile
index b986b681cde5..170b7e3e5590 100644
--- a/samples/rust/Makefile
+++ b/samples/rust/Makefile
@@ -2,6 +2,7 @@
 ccflags-y += -I$(src)				# needed for trace events
 
 obj-$(CONFIG_SAMPLE_RUST_MINIMAL)		+= rust_minimal.o
+obj-$(CONFIG_SAMPLE_RUST_MIDI_DEVICE)		+= rust_midi_device.o
 obj-$(CONFIG_SAMPLE_RUST_MISC_DEVICE)		+= rust_misc_device.o
 obj-$(CONFIG_SAMPLE_RUST_PRINT)			+= rust_print.o
 obj-$(CONFIG_SAMPLE_RUST_DEBUGFS)		+= rust_debugfs.o
diff --git a/samples/rust/rust_midi_device.rs b/samples/rust/rust_midi_device.rs
new file mode 100644
index 000000000000..5561a0437b59
--- /dev/null
+++ b/samples/rust/rust_midi_device.rs
@@ -0,0 +1,41 @@
+// SPDX-License-Identifier: GPL-2.0
+
+//! Rust MIDI minimal sample.
+
+use kernel::{
+    faux,
+    prelude::*,
+    snd,
+};
+
+impl kernel::Module for RustMidiDeviceModule {
+    fn init(_module: &'static ThisModule) -> Result<Self> {
+        pr_debug!("Initializing sound card\n");
+        let reg = faux::Registration::new(c"rust-midi-device", None)?;
+        let fdev = reg.as_ref();
+        let mut card = snd::SoundCard::new(
+            fdev.as_ref(),
+            c"RustMIDI",
+            kernel::module::this_module::<RustMidiDeviceModule>(),
+        )?;
+        card.set_driver(c"rust-midi")?;
+        card.set_shortname(c"RustMIDI")?;
+
+        // Register the sndcard to ALSA.
+        card.register()?;
+
+        Ok(Self { _reg: reg })
+    }
+}
+
+struct RustMidiDeviceModule {
+    _reg: faux::Registration,
+}
+
+module! {
+    type: RustMidiDeviceModule,
+    name: "rust_midi_device",
+    authors: ["Rust for Linux Contributors"],
+    description: "Rust MIDI device sample",
+    license: "GPL",
+}

-- 
2.56.0



  reply	other threads:[~2026-10-11 13:02 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-10-11 13:02 [PATCH RFC 0/3] rust: snd: Introduce experimental ALSA rawmidi abstractions Tristan de Cacqueray
2026-10-11 13:02 ` Tristan de Cacqueray [this message]
2026-10-11 13:02 ` [PATCH RFC 2/3] rust: snd: Add snd_rawmidi binding Tristan de Cacqueray
2026-10-11 13:02 ` [PATCH RFC 3/3] rust: snd: Add active rawmidi_substream helper Tristan de Cacqueray
2026-10-12 12:23 ` [PATCH RFC 0/3] rust: snd: Introduce experimental ALSA rawmidi abstractions Takashi Iwai

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=20261011-rust-snd-v1-1-7974ecdcd345@midirus.com \
    --to=tristan@midirus.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-sound@vger.kernel.org \
    --cc=ojeda@kernel.org \
    --cc=rust-for-linux@vger.kernel.org \
    --cc=tiwai@suse.de \
    /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

all inboxes | Powered by JetHome®