Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

samples: rust: add Rust I2C client registration sample

Add a new `rust_i2c_client` sample, showing how to create a new
i2c client using `i2c::Registration`

Acked-by: Wolfram Sang <wsa+renesas@sang-engineering.com>
Signed-off-by: Igor Korotin <igor.korotin.linux@gmail.com>
Link: https://patch.msgid.link/20251116162210.171542-1-igor.korotin.linux@gmail.com
[ * Remove dependency to I2C_CHARDEV, depend on I2C=y.
* Remove unnecessary impl Drop for SampleDriver.
* Rename i2c::Registration, import Devres.
* Fixup module description.
* Add new source file to MAINTAINERS.
- Danilo ]
Signed-off-by: Danilo Krummrich <dakr@kernel.org>

authored by

Igor Korotin and committed by
Danilo Krummrich
13ae55e2 d05b8e97

+161
+1
MAINTAINERS
··· 11751 11751 S: Maintained 11752 11752 F: rust/kernel/i2c.rs 11753 11753 F: samples/rust/rust_driver_i2c.rs 11754 + F: samples/rust/rust_i2c_client.rs 11754 11755 11755 11756 I2C SUBSYSTEM HOST DRIVERS 11756 11757 M: Andi Shyti <andi.shyti@kernel.org>
+12
samples/rust/Kconfig
··· 95 95 96 96 If unsure, say N. 97 97 98 + config SAMPLE_RUST_I2C_CLIENT 99 + tristate "I2C Client Registration" 100 + depends on I2C=y 101 + help 102 + This option builds the Rust I2C client manual creation 103 + sample. 104 + 105 + To compile this as a module, choose M here: 106 + the module will be called rust_i2c_client. 107 + 108 + If unsure, say N. 109 + 98 110 config SAMPLE_RUST_DRIVER_PCI 99 111 tristate "PCI Driver" 100 112 depends on PCI
+1
samples/rust/Makefile
··· 8 8 obj-$(CONFIG_SAMPLE_RUST_DEBUGFS_SCOPED) += rust_debugfs_scoped.o 9 9 obj-$(CONFIG_SAMPLE_RUST_DMA) += rust_dma.o 10 10 obj-$(CONFIG_SAMPLE_RUST_DRIVER_I2C) += rust_driver_i2c.o 11 + obj-$(CONFIG_SAMPLE_RUST_I2C_CLIENT) += rust_i2c_client.o 11 12 obj-$(CONFIG_SAMPLE_RUST_DRIVER_PCI) += rust_driver_pci.o 12 13 obj-$(CONFIG_SAMPLE_RUST_DRIVER_PLATFORM) += rust_driver_platform.o 13 14 obj-$(CONFIG_SAMPLE_RUST_DRIVER_USB) += rust_driver_usb.o
+147
samples/rust/rust_i2c_client.rs
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + 3 + //! Rust I2C client registration sample. 4 + //! 5 + //! An I2C client in Rust cannot exist on its own. To register a new I2C client, 6 + //! it must be bound to a parent device. In this sample driver, a platform device 7 + //! is used as the parent. 8 + //! 9 + 10 + //! ACPI match table test 11 + //! 12 + //! This demonstrates how to test an ACPI-based Rust I2C client registration driver 13 + //! using QEMU with a custom SSDT. 14 + //! 15 + //! Steps: 16 + //! 17 + //! 1. **Create an SSDT source file** (`ssdt.dsl`) with the following content: 18 + //! 19 + //! ```asl 20 + //! DefinitionBlock ("", "SSDT", 2, "TEST", "VIRTACPI", 0x00000001) 21 + //! { 22 + //! Scope (\_SB) 23 + //! { 24 + //! Device (T432) 25 + //! { 26 + //! Name (_HID, "LNUXBEEF") // ACPI hardware ID to match 27 + //! Name (_UID, 1) 28 + //! Name (_STA, 0x0F) // Device present, enabled 29 + //! Name (_CRS, ResourceTemplate () 30 + //! { 31 + //! Memory32Fixed (ReadWrite, 0xFED00000, 0x1000) 32 + //! }) 33 + //! } 34 + //! } 35 + //! } 36 + //! ``` 37 + //! 38 + //! 2. **Compile the table**: 39 + //! 40 + //! ```sh 41 + //! iasl -tc ssdt.dsl 42 + //! ``` 43 + //! 44 + //! This generates `ssdt.aml` 45 + //! 46 + //! 3. **Run QEMU** with the compiled AML file: 47 + //! 48 + //! ```sh 49 + //! qemu-system-x86_64 -m 512M \ 50 + //! -enable-kvm \ 51 + //! -kernel path/to/bzImage \ 52 + //! -append "root=/dev/sda console=ttyS0" \ 53 + //! -hda rootfs.img \ 54 + //! -serial stdio \ 55 + //! -acpitable file=ssdt.aml 56 + //! ``` 57 + //! 58 + //! Requirements: 59 + //! - The `rust_driver_platform` must be present either: 60 + //! - built directly into the kernel (`bzImage`), or 61 + //! - available as a `.ko` file and loadable from `rootfs.img` 62 + //! 63 + //! 4. **Verify it worked** by checking `dmesg`: 64 + //! 65 + //! ``` 66 + //! rust_driver_platform LNUXBEEF:00: Probed with info: '0'. 67 + //! ``` 68 + //! 69 + 70 + use kernel::{ 71 + acpi, 72 + c_str, 73 + device, 74 + devres::Devres, 75 + i2c, 76 + of, 77 + platform, 78 + prelude::*, 79 + sync::aref::ARef, // 80 + }; 81 + 82 + #[pin_data] 83 + struct SampleDriver { 84 + parent_dev: ARef<platform::Device>, 85 + #[pin] 86 + _reg: Devres<i2c::Registration>, 87 + } 88 + 89 + kernel::of_device_table!( 90 + OF_TABLE, 91 + MODULE_OF_TABLE, 92 + <SampleDriver as platform::Driver>::IdInfo, 93 + [(of::DeviceId::new(c_str!("test,rust-device")), ())] 94 + ); 95 + 96 + kernel::acpi_device_table!( 97 + ACPI_TABLE, 98 + MODULE_ACPI_TABLE, 99 + <SampleDriver as platform::Driver>::IdInfo, 100 + [(acpi::DeviceId::new(c_str!("LNUXBEEF")), ())] 101 + ); 102 + 103 + const SAMPLE_I2C_CLIENT_ADDR: u16 = 0x30; 104 + const SAMPLE_I2C_ADAPTER_INDEX: i32 = 0; 105 + const BOARD_INFO: i2c::I2cBoardInfo = 106 + i2c::I2cBoardInfo::new(c_str!("rust_driver_i2c"), SAMPLE_I2C_CLIENT_ADDR); 107 + 108 + impl platform::Driver for SampleDriver { 109 + type IdInfo = (); 110 + const OF_ID_TABLE: Option<of::IdTable<Self::IdInfo>> = Some(&OF_TABLE); 111 + const ACPI_ID_TABLE: Option<acpi::IdTable<Self::IdInfo>> = Some(&ACPI_TABLE); 112 + 113 + fn probe( 114 + pdev: &platform::Device<device::Core>, 115 + _info: Option<&Self::IdInfo>, 116 + ) -> impl PinInit<Self, Error> { 117 + dev_info!( 118 + pdev.as_ref(), 119 + "Probe Rust I2C Client registration sample.\n" 120 + ); 121 + 122 + kernel::try_pin_init!( Self { 123 + parent_dev: pdev.into(), 124 + 125 + _reg <- { 126 + let adapter = i2c::I2cAdapter::get(SAMPLE_I2C_ADAPTER_INDEX)?; 127 + 128 + i2c::Registration::new(&adapter, &BOARD_INFO, pdev.as_ref()) 129 + } 130 + }) 131 + } 132 + 133 + fn unbind(pdev: &platform::Device<device::Core>, _this: Pin<&Self>) { 134 + dev_info!( 135 + pdev.as_ref(), 136 + "Unbind Rust I2C Client registration sample.\n" 137 + ); 138 + } 139 + } 140 + 141 + kernel::module_platform_driver! { 142 + type: SampleDriver, 143 + name: "rust_device_i2c", 144 + authors: ["Danilo Krummrich", "Igor Korotin"], 145 + description: "Rust I2C client registration", 146 + license: "GPL v2", 147 + }