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