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