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