xref: /linux/samples/rust/rust_driver_serdev.rs (revision 59e6295fac26b8e85c1ea859cdd89fa1e47519d7)
1 // SPDX-License-Identifier: GPL-2.0
2 
3 //! Rust Serial device bus device driver sample.
4 
5 use kernel::{
6     acpi,
7     device::{
8         Bound,
9         Core, //
10     },
11     of,
12     prelude::*,
13     serdev,
14     sync::aref::ARef, //
15 };
16 
17 struct SampleDriver {
18     sdev: ARef<serdev::Device>,
19 }
20 
21 kernel::of_device_table!(
22     OF_TABLE,
23     <SampleDriver as serdev::Driver>::IdInfo,
24     [(of::DeviceId::new(c"test,rust_driver_serdev"), ())]
25 );
26 
27 kernel::acpi_device_table!(
28     ACPI_TABLE,
29     <SampleDriver as serdev::Driver>::IdInfo,
30     [(acpi::DeviceId::new(c"LNUXBEEF"), ())]
31 );
32 
33 #[vtable]
34 impl serdev::Driver for SampleDriver {
35     type IdInfo = ();
36     type Data<'bound> = Self;
37     const OF_ID_TABLE: Option<of::IdTable<Self::IdInfo>> = Some(&OF_TABLE);
38     const ACPI_ID_TABLE: Option<acpi::IdTable<Self::IdInfo>> = Some(&ACPI_TABLE);
39 
40     fn probe<'bound>(
41         sdev: &'bound serdev::Device<Core<'_>>,
42         _info: Option<&'bound Self::IdInfo>,
43     ) -> impl PinInit<Self, Error> + 'bound {
44         let dev = sdev.as_ref();
45 
46         dev_dbg!(dev, "Probe Rust Serial device bus device driver sample.\n");
47 
48         if sdev
49             .set_baudrate(
50                 dev.fwnode()
51                     .and_then(|fwnode| fwnode.property_read(c"baudrate").optional())
52                     .unwrap_or(115200),
53             )
54             .is_err()
55         {
56             return Err(EINVAL);
57         }
58         sdev.set_flow_control(false);
59         sdev.set_parity(serdev::Parity::None)?;
60 
61         Ok(Self { sdev: sdev.into() })
62     }
63 
64     fn receive<'bound>(
65         sdev: &'bound serdev::Device<Bound>,
66         _this: Pin<&Self>,
67         data: &[u8],
68     ) -> usize {
69         sdev.write(data).unwrap_or_default() as usize
70     }
71 }
72 
73 impl Drop for SampleDriver {
74     fn drop(&mut self) {
75         dev_dbg!(
76             self.sdev.as_ref(),
77             "Remove Rust Serial device bus device driver sample.\n"
78         );
79     }
80 }
81 
82 kernel::module_serdev_device_driver! {
83     type: SampleDriver,
84     name: "rust_driver_serdev",
85     authors: ["Markus Probst"],
86     description: "Rust Serial device bus device driver",
87     license: "GPL v2",
88 }
89