157c5bd9aSIgor Korotin // SPDX-License-Identifier: GPL-2.0 257c5bd9aSIgor Korotin 357c5bd9aSIgor Korotin //! I2C Driver subsystem 457c5bd9aSIgor Korotin 557c5bd9aSIgor Korotin // I2C Driver abstractions. 657c5bd9aSIgor Korotin use crate::{ 757c5bd9aSIgor Korotin acpi, 857c5bd9aSIgor Korotin container_of, 957c5bd9aSIgor Korotin device, 1057c5bd9aSIgor Korotin device_id::{ 1157c5bd9aSIgor Korotin RawDeviceId, 1257c5bd9aSIgor Korotin RawDeviceIdIndex, // 1357c5bd9aSIgor Korotin }, 14f3cc26a4SIgor Korotin devres::Devres, 1557c5bd9aSIgor Korotin driver, 1657c5bd9aSIgor Korotin error::*, 1757c5bd9aSIgor Korotin of, 1857c5bd9aSIgor Korotin prelude::*, 1957c5bd9aSIgor Korotin types::{ 2057c5bd9aSIgor Korotin AlwaysRefCounted, 2157c5bd9aSIgor Korotin Opaque, // 2257c5bd9aSIgor Korotin }, // 2357c5bd9aSIgor Korotin }; 2457c5bd9aSIgor Korotin 2557c5bd9aSIgor Korotin use core::{ 2657c5bd9aSIgor Korotin marker::PhantomData, 27e4addc7cSMarkus Probst mem::offset_of, 28f3cc26a4SIgor Korotin ptr::{ 29f3cc26a4SIgor Korotin from_ref, 30f3cc26a4SIgor Korotin NonNull, // 31f3cc26a4SIgor Korotin }, // 3257c5bd9aSIgor Korotin }; 3357c5bd9aSIgor Korotin 34f3cc26a4SIgor Korotin use kernel::types::ARef; 35f3cc26a4SIgor Korotin 3657c5bd9aSIgor Korotin /// An I2C device id table. 3757c5bd9aSIgor Korotin #[repr(transparent)] 3857c5bd9aSIgor Korotin #[derive(Clone, Copy)] 3957c5bd9aSIgor Korotin pub struct DeviceId(bindings::i2c_device_id); 4057c5bd9aSIgor Korotin 4157c5bd9aSIgor Korotin impl DeviceId { 4257c5bd9aSIgor Korotin const I2C_NAME_SIZE: usize = 20; 4357c5bd9aSIgor Korotin 4457c5bd9aSIgor Korotin /// Create a new device id from an I2C 'id' string. 4557c5bd9aSIgor Korotin #[inline(always)] new(id: &'static CStr) -> Self4657c5bd9aSIgor Korotin pub const fn new(id: &'static CStr) -> Self { 47a762f883SMiguel Ojeda let src = id.to_bytes_with_nul(); 48a762f883SMiguel Ojeda build_assert!(src.len() <= Self::I2C_NAME_SIZE, "ID exceeds 20 bytes"); 4957c5bd9aSIgor Korotin let mut i2c: bindings::i2c_device_id = pin_init::zeroed(); 5057c5bd9aSIgor Korotin let mut i = 0; 5157c5bd9aSIgor Korotin while i < src.len() { 5257c5bd9aSIgor Korotin i2c.name[i] = src[i]; 5357c5bd9aSIgor Korotin i += 1; 5457c5bd9aSIgor Korotin } 5557c5bd9aSIgor Korotin 5657c5bd9aSIgor Korotin Self(i2c) 5757c5bd9aSIgor Korotin } 5857c5bd9aSIgor Korotin } 5957c5bd9aSIgor Korotin 6057c5bd9aSIgor Korotin // SAFETY: `DeviceId` is a `#[repr(transparent)]` wrapper of `i2c_device_id` and does not add 6157c5bd9aSIgor Korotin // additional invariants, so it's safe to transmute to `RawType`. 6257c5bd9aSIgor Korotin unsafe impl RawDeviceId for DeviceId { 6357c5bd9aSIgor Korotin type RawType = bindings::i2c_device_id; 6457c5bd9aSIgor Korotin } 6557c5bd9aSIgor Korotin 6657c5bd9aSIgor Korotin // SAFETY: `DRIVER_DATA_OFFSET` is the offset to the `driver_data` field. 6757c5bd9aSIgor Korotin unsafe impl RawDeviceIdIndex for DeviceId { 6857c5bd9aSIgor Korotin const DRIVER_DATA_OFFSET: usize = core::mem::offset_of!(bindings::i2c_device_id, driver_data); 6957c5bd9aSIgor Korotin index(&self) -> usize7057c5bd9aSIgor Korotin fn index(&self) -> usize { 7157c5bd9aSIgor Korotin self.0.driver_data 7257c5bd9aSIgor Korotin } 7357c5bd9aSIgor Korotin } 7457c5bd9aSIgor Korotin 7557c5bd9aSIgor Korotin /// IdTable type for I2C 7657c5bd9aSIgor Korotin pub type IdTable<T> = &'static dyn kernel::device_id::IdTable<DeviceId, T>; 7757c5bd9aSIgor Korotin 7857c5bd9aSIgor Korotin /// Create a I2C `IdTable` with its alias for modpost. 7957c5bd9aSIgor Korotin #[macro_export] 8057c5bd9aSIgor Korotin macro_rules! i2c_device_table { 8157c5bd9aSIgor Korotin ($table_name:ident, $module_table_name:ident, $id_info_type: ty, $table_data: expr) => { 8257c5bd9aSIgor Korotin const $table_name: $crate::device_id::IdArray< 8357c5bd9aSIgor Korotin $crate::i2c::DeviceId, 8457c5bd9aSIgor Korotin $id_info_type, 8557c5bd9aSIgor Korotin { $table_data.len() }, 8657c5bd9aSIgor Korotin > = $crate::device_id::IdArray::new($table_data); 8757c5bd9aSIgor Korotin 8857c5bd9aSIgor Korotin $crate::module_device_table!("i2c", $module_table_name, $table_name); 8957c5bd9aSIgor Korotin }; 9057c5bd9aSIgor Korotin } 9157c5bd9aSIgor Korotin 9257c5bd9aSIgor Korotin /// An adapter for the registration of I2C drivers. 9357c5bd9aSIgor Korotin pub struct Adapter<T: Driver>(T); 9457c5bd9aSIgor Korotin 950af1a9e4SDanilo Krummrich // SAFETY: 960af1a9e4SDanilo Krummrich // - `bindings::i2c_driver` is a C type declared as `repr(C)`. 972ad0f490SDanilo Krummrich // - `T` is the type of the driver's device private data. 98c1d4519eSDanilo Krummrich // - `struct i2c_driver` embeds a `struct device_driver`. 99c1d4519eSDanilo Krummrich // - `DEVICE_DRIVER_OFFSET` is the correct byte offset to the embedded `struct device_driver`. 1000af1a9e4SDanilo Krummrich unsafe impl<T: Driver + 'static> driver::DriverLayout for Adapter<T> { 1010af1a9e4SDanilo Krummrich type DriverType = bindings::i2c_driver; 1022ad0f490SDanilo Krummrich type DriverData = T; 103c1d4519eSDanilo Krummrich const DEVICE_DRIVER_OFFSET: usize = core::mem::offset_of!(Self::DriverType, driver); 1040af1a9e4SDanilo Krummrich } 1050af1a9e4SDanilo Krummrich 1060af1a9e4SDanilo Krummrich // SAFETY: A call to `unregister` for a given instance of `DriverType` is guaranteed to be valid if 10757c5bd9aSIgor Korotin // a preceding call to `register` has been successful. 10857c5bd9aSIgor Korotin unsafe impl<T: Driver + 'static> driver::RegistrationOps for Adapter<T> { register( idrv: &Opaque<Self::DriverType>, name: &'static CStr, module: &'static ThisModule, ) -> Result10957c5bd9aSIgor Korotin unsafe fn register( 1100af1a9e4SDanilo Krummrich idrv: &Opaque<Self::DriverType>, 11157c5bd9aSIgor Korotin name: &'static CStr, 11257c5bd9aSIgor Korotin module: &'static ThisModule, 11357c5bd9aSIgor Korotin ) -> Result { 11457c5bd9aSIgor Korotin build_assert!( 11557c5bd9aSIgor Korotin T::ACPI_ID_TABLE.is_some() || T::OF_ID_TABLE.is_some() || T::I2C_ID_TABLE.is_some(), 11657c5bd9aSIgor Korotin "At least one of ACPI/OF/Legacy tables must be present when registering an i2c driver" 11757c5bd9aSIgor Korotin ); 11857c5bd9aSIgor Korotin 11957c5bd9aSIgor Korotin let i2c_table = match T::I2C_ID_TABLE { 12057c5bd9aSIgor Korotin Some(table) => table.as_ptr(), 12157c5bd9aSIgor Korotin None => core::ptr::null(), 12257c5bd9aSIgor Korotin }; 12357c5bd9aSIgor Korotin 12457c5bd9aSIgor Korotin let of_table = match T::OF_ID_TABLE { 12557c5bd9aSIgor Korotin Some(table) => table.as_ptr(), 12657c5bd9aSIgor Korotin None => core::ptr::null(), 12757c5bd9aSIgor Korotin }; 12857c5bd9aSIgor Korotin 12957c5bd9aSIgor Korotin let acpi_table = match T::ACPI_ID_TABLE { 13057c5bd9aSIgor Korotin Some(table) => table.as_ptr(), 13157c5bd9aSIgor Korotin None => core::ptr::null(), 13257c5bd9aSIgor Korotin }; 13357c5bd9aSIgor Korotin 13457c5bd9aSIgor Korotin // SAFETY: It's safe to set the fields of `struct i2c_client` on initialization. 13557c5bd9aSIgor Korotin unsafe { 13657c5bd9aSIgor Korotin (*idrv.get()).driver.name = name.as_char_ptr(); 13757c5bd9aSIgor Korotin (*idrv.get()).probe = Some(Self::probe_callback); 13857c5bd9aSIgor Korotin (*idrv.get()).remove = Some(Self::remove_callback); 13957c5bd9aSIgor Korotin (*idrv.get()).shutdown = Some(Self::shutdown_callback); 14057c5bd9aSIgor Korotin (*idrv.get()).id_table = i2c_table; 14157c5bd9aSIgor Korotin (*idrv.get()).driver.of_match_table = of_table; 14257c5bd9aSIgor Korotin (*idrv.get()).driver.acpi_match_table = acpi_table; 14357c5bd9aSIgor Korotin } 14457c5bd9aSIgor Korotin 1450af1a9e4SDanilo Krummrich // SAFETY: `idrv` is guaranteed to be a valid `DriverType`. 14657c5bd9aSIgor Korotin to_result(unsafe { bindings::i2c_register_driver(module.0, idrv.get()) }) 14757c5bd9aSIgor Korotin } 14857c5bd9aSIgor Korotin unregister(idrv: &Opaque<Self::DriverType>)1490af1a9e4SDanilo Krummrich unsafe fn unregister(idrv: &Opaque<Self::DriverType>) { 1500af1a9e4SDanilo Krummrich // SAFETY: `idrv` is guaranteed to be a valid `DriverType`. 15157c5bd9aSIgor Korotin unsafe { bindings::i2c_del_driver(idrv.get()) } 15257c5bd9aSIgor Korotin } 15357c5bd9aSIgor Korotin } 15457c5bd9aSIgor Korotin 15557c5bd9aSIgor Korotin impl<T: Driver + 'static> Adapter<T> { probe_callback(idev: *mut bindings::i2c_client) -> kernel::ffi::c_int15657c5bd9aSIgor Korotin extern "C" fn probe_callback(idev: *mut bindings::i2c_client) -> kernel::ffi::c_int { 15757c5bd9aSIgor Korotin // SAFETY: The I2C bus only ever calls the probe callback with a valid pointer to a 15857c5bd9aSIgor Korotin // `struct i2c_client`. 15957c5bd9aSIgor Korotin // 16057c5bd9aSIgor Korotin // INVARIANT: `idev` is valid for the duration of `probe_callback()`. 16157c5bd9aSIgor Korotin let idev = unsafe { &*idev.cast::<I2cClient<device::CoreInternal>>() }; 16257c5bd9aSIgor Korotin 16357c5bd9aSIgor Korotin let info = 16457c5bd9aSIgor Korotin Self::i2c_id_info(idev).or_else(|| <Self as driver::Adapter>::id_info(idev.as_ref())); 16557c5bd9aSIgor Korotin 16657c5bd9aSIgor Korotin from_result(|| { 16757c5bd9aSIgor Korotin let data = T::probe(idev, info); 16857c5bd9aSIgor Korotin 16957c5bd9aSIgor Korotin idev.as_ref().set_drvdata(data)?; 17057c5bd9aSIgor Korotin Ok(0) 17157c5bd9aSIgor Korotin }) 17257c5bd9aSIgor Korotin } 17357c5bd9aSIgor Korotin remove_callback(idev: *mut bindings::i2c_client)17457c5bd9aSIgor Korotin extern "C" fn remove_callback(idev: *mut bindings::i2c_client) { 17557c5bd9aSIgor Korotin // SAFETY: `idev` is a valid pointer to a `struct i2c_client`. 17657c5bd9aSIgor Korotin let idev = unsafe { &*idev.cast::<I2cClient<device::CoreInternal>>() }; 17757c5bd9aSIgor Korotin 17857c5bd9aSIgor Korotin // SAFETY: `remove_callback` is only ever called after a successful call to 17957c5bd9aSIgor Korotin // `probe_callback`, hence it's guaranteed that `I2cClient::set_drvdata()` has been called 18057c5bd9aSIgor Korotin // and stored a `Pin<KBox<T>>`. 181*a995fe1aSDanilo Krummrich let data = unsafe { idev.as_ref().drvdata_borrow::<T>() }; 18257c5bd9aSIgor Korotin 183*a995fe1aSDanilo Krummrich T::unbind(idev, data); 18457c5bd9aSIgor Korotin } 18557c5bd9aSIgor Korotin shutdown_callback(idev: *mut bindings::i2c_client)18657c5bd9aSIgor Korotin extern "C" fn shutdown_callback(idev: *mut bindings::i2c_client) { 18757c5bd9aSIgor Korotin // SAFETY: `shutdown_callback` is only ever called for a valid `idev` 18857c5bd9aSIgor Korotin let idev = unsafe { &*idev.cast::<I2cClient<device::CoreInternal>>() }; 18957c5bd9aSIgor Korotin 19057c5bd9aSIgor Korotin // SAFETY: `shutdown_callback` is only ever called after a successful call to 19157c5bd9aSIgor Korotin // `probe_callback`, hence it's guaranteed that `Device::set_drvdata()` has been called 19257c5bd9aSIgor Korotin // and stored a `Pin<KBox<T>>`. 1934181acebSDanilo Krummrich let data = unsafe { idev.as_ref().drvdata_borrow::<T>() }; 19457c5bd9aSIgor Korotin 1954181acebSDanilo Krummrich T::shutdown(idev, data); 19657c5bd9aSIgor Korotin } 19757c5bd9aSIgor Korotin 19857c5bd9aSIgor Korotin /// The [`i2c::IdTable`] of the corresponding driver. i2c_id_table() -> Option<IdTable<<Self as driver::Adapter>::IdInfo>>19957c5bd9aSIgor Korotin fn i2c_id_table() -> Option<IdTable<<Self as driver::Adapter>::IdInfo>> { 20057c5bd9aSIgor Korotin T::I2C_ID_TABLE 20157c5bd9aSIgor Korotin } 20257c5bd9aSIgor Korotin 20357c5bd9aSIgor Korotin /// Returns the driver's private data from the matching entry in the [`i2c::IdTable`], if any. 20457c5bd9aSIgor Korotin /// 20557c5bd9aSIgor Korotin /// If this returns `None`, it means there is no match with an entry in the [`i2c::IdTable`]. i2c_id_info(dev: &I2cClient) -> Option<&'static <Self as driver::Adapter>::IdInfo>20657c5bd9aSIgor Korotin fn i2c_id_info(dev: &I2cClient) -> Option<&'static <Self as driver::Adapter>::IdInfo> { 20757c5bd9aSIgor Korotin let table = Self::i2c_id_table()?; 20857c5bd9aSIgor Korotin 20957c5bd9aSIgor Korotin // SAFETY: 21057c5bd9aSIgor Korotin // - `table` has static lifetime, hence it's valid for reads 21157c5bd9aSIgor Korotin // - `dev` is guaranteed to be valid while it's alive, and so is `dev.as_raw()`. 21257c5bd9aSIgor Korotin let raw_id = unsafe { bindings::i2c_match_id(table.as_ptr(), dev.as_raw()) }; 21357c5bd9aSIgor Korotin 21457c5bd9aSIgor Korotin if raw_id.is_null() { 21557c5bd9aSIgor Korotin return None; 21657c5bd9aSIgor Korotin } 21757c5bd9aSIgor Korotin 21857c5bd9aSIgor Korotin // SAFETY: `DeviceId` is a `#[repr(transparent)` wrapper of `struct i2c_device_id` and 21957c5bd9aSIgor Korotin // does not add additional invariants, so it's safe to transmute. 22057c5bd9aSIgor Korotin let id = unsafe { &*raw_id.cast::<DeviceId>() }; 22157c5bd9aSIgor Korotin 22257c5bd9aSIgor Korotin Some(table.info(<DeviceId as RawDeviceIdIndex>::index(id))) 22357c5bd9aSIgor Korotin } 22457c5bd9aSIgor Korotin } 22557c5bd9aSIgor Korotin 22657c5bd9aSIgor Korotin impl<T: Driver + 'static> driver::Adapter for Adapter<T> { 22757c5bd9aSIgor Korotin type IdInfo = T::IdInfo; 22857c5bd9aSIgor Korotin of_id_table() -> Option<of::IdTable<Self::IdInfo>>22957c5bd9aSIgor Korotin fn of_id_table() -> Option<of::IdTable<Self::IdInfo>> { 23057c5bd9aSIgor Korotin T::OF_ID_TABLE 23157c5bd9aSIgor Korotin } 23257c5bd9aSIgor Korotin acpi_id_table() -> Option<acpi::IdTable<Self::IdInfo>>23357c5bd9aSIgor Korotin fn acpi_id_table() -> Option<acpi::IdTable<Self::IdInfo>> { 23457c5bd9aSIgor Korotin T::ACPI_ID_TABLE 23557c5bd9aSIgor Korotin } 23657c5bd9aSIgor Korotin } 23757c5bd9aSIgor Korotin 23857c5bd9aSIgor Korotin /// Declares a kernel module that exposes a single i2c driver. 23957c5bd9aSIgor Korotin /// 24057c5bd9aSIgor Korotin /// # Examples 24157c5bd9aSIgor Korotin /// 24257c5bd9aSIgor Korotin /// ```ignore 24357c5bd9aSIgor Korotin /// kernel::module_i2c_driver! { 24457c5bd9aSIgor Korotin /// type: MyDriver, 24557c5bd9aSIgor Korotin /// name: "Module name", 24657c5bd9aSIgor Korotin /// authors: ["Author name"], 24757c5bd9aSIgor Korotin /// description: "Description", 24857c5bd9aSIgor Korotin /// license: "GPL v2", 24957c5bd9aSIgor Korotin /// } 25057c5bd9aSIgor Korotin /// ``` 25157c5bd9aSIgor Korotin #[macro_export] 25257c5bd9aSIgor Korotin macro_rules! module_i2c_driver { 25357c5bd9aSIgor Korotin ($($f:tt)*) => { 25457c5bd9aSIgor Korotin $crate::module_driver!(<T>, $crate::i2c::Adapter<T>, { $($f)* }); 25557c5bd9aSIgor Korotin }; 25657c5bd9aSIgor Korotin } 25757c5bd9aSIgor Korotin 25857c5bd9aSIgor Korotin /// The i2c driver trait. 25957c5bd9aSIgor Korotin /// 26057c5bd9aSIgor Korotin /// Drivers must implement this trait in order to get a i2c driver registered. 26157c5bd9aSIgor Korotin /// 26257c5bd9aSIgor Korotin /// # Example 26357c5bd9aSIgor Korotin /// 26457c5bd9aSIgor Korotin ///``` 26557c5bd9aSIgor Korotin /// # use kernel::{acpi, bindings, device::Core, i2c, of}; 26657c5bd9aSIgor Korotin /// 26757c5bd9aSIgor Korotin /// struct MyDriver; 26857c5bd9aSIgor Korotin /// 26957c5bd9aSIgor Korotin /// kernel::acpi_device_table!( 27057c5bd9aSIgor Korotin /// ACPI_TABLE, 27157c5bd9aSIgor Korotin /// MODULE_ACPI_TABLE, 27257c5bd9aSIgor Korotin /// <MyDriver as i2c::Driver>::IdInfo, 27357c5bd9aSIgor Korotin /// [ 27457c5bd9aSIgor Korotin /// (acpi::DeviceId::new(c"LNUXBEEF"), ()) 27557c5bd9aSIgor Korotin /// ] 27657c5bd9aSIgor Korotin /// ); 27757c5bd9aSIgor Korotin /// 27857c5bd9aSIgor Korotin /// kernel::i2c_device_table!( 27957c5bd9aSIgor Korotin /// I2C_TABLE, 28057c5bd9aSIgor Korotin /// MODULE_I2C_TABLE, 28157c5bd9aSIgor Korotin /// <MyDriver as i2c::Driver>::IdInfo, 28257c5bd9aSIgor Korotin /// [ 28357c5bd9aSIgor Korotin /// (i2c::DeviceId::new(c"rust_driver_i2c"), ()) 28457c5bd9aSIgor Korotin /// ] 28557c5bd9aSIgor Korotin /// ); 28657c5bd9aSIgor Korotin /// 28757c5bd9aSIgor Korotin /// kernel::of_device_table!( 28857c5bd9aSIgor Korotin /// OF_TABLE, 28957c5bd9aSIgor Korotin /// MODULE_OF_TABLE, 29057c5bd9aSIgor Korotin /// <MyDriver as i2c::Driver>::IdInfo, 29157c5bd9aSIgor Korotin /// [ 29257c5bd9aSIgor Korotin /// (of::DeviceId::new(c"test,device"), ()) 29357c5bd9aSIgor Korotin /// ] 29457c5bd9aSIgor Korotin /// ); 29557c5bd9aSIgor Korotin /// 29657c5bd9aSIgor Korotin /// impl i2c::Driver for MyDriver { 29757c5bd9aSIgor Korotin /// type IdInfo = (); 29857c5bd9aSIgor Korotin /// const I2C_ID_TABLE: Option<i2c::IdTable<Self::IdInfo>> = Some(&I2C_TABLE); 29957c5bd9aSIgor Korotin /// const OF_ID_TABLE: Option<of::IdTable<Self::IdInfo>> = Some(&OF_TABLE); 30057c5bd9aSIgor Korotin /// const ACPI_ID_TABLE: Option<acpi::IdTable<Self::IdInfo>> = Some(&ACPI_TABLE); 30157c5bd9aSIgor Korotin /// 30257c5bd9aSIgor Korotin /// fn probe( 30357c5bd9aSIgor Korotin /// _idev: &i2c::I2cClient<Core>, 30457c5bd9aSIgor Korotin /// _id_info: Option<&Self::IdInfo>, 30557c5bd9aSIgor Korotin /// ) -> impl PinInit<Self, Error> { 30657c5bd9aSIgor Korotin /// Err(ENODEV) 30757c5bd9aSIgor Korotin /// } 30857c5bd9aSIgor Korotin /// 30957c5bd9aSIgor Korotin /// fn shutdown(_idev: &i2c::I2cClient<Core>, this: Pin<&Self>) { 31057c5bd9aSIgor Korotin /// } 31157c5bd9aSIgor Korotin /// } 31257c5bd9aSIgor Korotin ///``` 31357c5bd9aSIgor Korotin pub trait Driver: Send { 31457c5bd9aSIgor Korotin /// The type holding information about each device id supported by the driver. 31557c5bd9aSIgor Korotin // TODO: Use `associated_type_defaults` once stabilized: 31657c5bd9aSIgor Korotin // 31757c5bd9aSIgor Korotin // ``` 31857c5bd9aSIgor Korotin // type IdInfo: 'static = (); 31957c5bd9aSIgor Korotin // ``` 32057c5bd9aSIgor Korotin type IdInfo: 'static; 32157c5bd9aSIgor Korotin 32257c5bd9aSIgor Korotin /// The table of device ids supported by the driver. 32357c5bd9aSIgor Korotin const I2C_ID_TABLE: Option<IdTable<Self::IdInfo>> = None; 32457c5bd9aSIgor Korotin 32557c5bd9aSIgor Korotin /// The table of OF device ids supported by the driver. 32657c5bd9aSIgor Korotin const OF_ID_TABLE: Option<of::IdTable<Self::IdInfo>> = None; 32757c5bd9aSIgor Korotin 32857c5bd9aSIgor Korotin /// The table of ACPI device ids supported by the driver. 32957c5bd9aSIgor Korotin const ACPI_ID_TABLE: Option<acpi::IdTable<Self::IdInfo>> = None; 33057c5bd9aSIgor Korotin 33157c5bd9aSIgor Korotin /// I2C driver probe. 33257c5bd9aSIgor Korotin /// 33357c5bd9aSIgor Korotin /// Called when a new i2c client is added or discovered. 33457c5bd9aSIgor Korotin /// Implementers should attempt to initialize the client here. probe( dev: &I2cClient<device::Core>, id_info: Option<&Self::IdInfo>, ) -> impl PinInit<Self, Error>33557c5bd9aSIgor Korotin fn probe( 33657c5bd9aSIgor Korotin dev: &I2cClient<device::Core>, 33757c5bd9aSIgor Korotin id_info: Option<&Self::IdInfo>, 33857c5bd9aSIgor Korotin ) -> impl PinInit<Self, Error>; 33957c5bd9aSIgor Korotin 34057c5bd9aSIgor Korotin /// I2C driver shutdown. 34157c5bd9aSIgor Korotin /// 34257c5bd9aSIgor Korotin /// Called by the kernel during system reboot or power-off to allow the [`Driver`] to bring the 34357c5bd9aSIgor Korotin /// [`I2cClient`] into a safe state. Implementing this callback is optional. 34457c5bd9aSIgor Korotin /// 34557c5bd9aSIgor Korotin /// Typical actions include stopping transfers, disabling interrupts, or resetting the hardware 34657c5bd9aSIgor Korotin /// to prevent undesired behavior during shutdown. 34757c5bd9aSIgor Korotin /// 34857c5bd9aSIgor Korotin /// This callback is distinct from final resource cleanup, as the driver instance remains valid 34957c5bd9aSIgor Korotin /// after it returns. Any deallocation or teardown of driver-owned resources should instead be 35057c5bd9aSIgor Korotin /// handled in `Self::drop`. shutdown(dev: &I2cClient<device::Core>, this: Pin<&Self>)35157c5bd9aSIgor Korotin fn shutdown(dev: &I2cClient<device::Core>, this: Pin<&Self>) { 35257c5bd9aSIgor Korotin let _ = (dev, this); 35357c5bd9aSIgor Korotin } 35457c5bd9aSIgor Korotin 35557c5bd9aSIgor Korotin /// I2C driver unbind. 35657c5bd9aSIgor Korotin /// 35757c5bd9aSIgor Korotin /// Called when the [`I2cClient`] is unbound from its bound [`Driver`]. Implementing this 35857c5bd9aSIgor Korotin /// callback is optional. 35957c5bd9aSIgor Korotin /// 36057c5bd9aSIgor Korotin /// This callback serves as a place for drivers to perform teardown operations that require a 36157c5bd9aSIgor Korotin /// `&Device<Core>` or `&Device<Bound>` reference. For instance, drivers may try to perform I/O 36257c5bd9aSIgor Korotin /// operations to gracefully tear down the device. 36357c5bd9aSIgor Korotin /// 36457c5bd9aSIgor Korotin /// Otherwise, release operations for driver resources should be performed in `Self::drop`. unbind(dev: &I2cClient<device::Core>, this: Pin<&Self>)36557c5bd9aSIgor Korotin fn unbind(dev: &I2cClient<device::Core>, this: Pin<&Self>) { 36657c5bd9aSIgor Korotin let _ = (dev, this); 36757c5bd9aSIgor Korotin } 36857c5bd9aSIgor Korotin } 36957c5bd9aSIgor Korotin 370f3cc26a4SIgor Korotin /// The i2c adapter representation. 371f3cc26a4SIgor Korotin /// 372f3cc26a4SIgor Korotin /// This structure represents the Rust abstraction for a C `struct i2c_adapter`. The 373f3cc26a4SIgor Korotin /// implementation abstracts the usage of an existing C `struct i2c_adapter` that 374f3cc26a4SIgor Korotin /// gets passed from the C side 375f3cc26a4SIgor Korotin /// 376f3cc26a4SIgor Korotin /// # Invariants 377f3cc26a4SIgor Korotin /// 378f3cc26a4SIgor Korotin /// A [`I2cAdapter`] instance represents a valid `struct i2c_adapter` created by the C portion of 379f3cc26a4SIgor Korotin /// the kernel. 380f3cc26a4SIgor Korotin #[repr(transparent)] 381f3cc26a4SIgor Korotin pub struct I2cAdapter<Ctx: device::DeviceContext = device::Normal>( 382f3cc26a4SIgor Korotin Opaque<bindings::i2c_adapter>, 383f3cc26a4SIgor Korotin PhantomData<Ctx>, 384f3cc26a4SIgor Korotin ); 385f3cc26a4SIgor Korotin 386f3cc26a4SIgor Korotin impl<Ctx: device::DeviceContext> I2cAdapter<Ctx> { as_raw(&self) -> *mut bindings::i2c_adapter387f3cc26a4SIgor Korotin fn as_raw(&self) -> *mut bindings::i2c_adapter { 388f3cc26a4SIgor Korotin self.0.get() 389f3cc26a4SIgor Korotin } 390f3cc26a4SIgor Korotin } 391f3cc26a4SIgor Korotin 392f3cc26a4SIgor Korotin impl I2cAdapter { 393f3cc26a4SIgor Korotin /// Returns the I2C Adapter index. 394f3cc26a4SIgor Korotin #[inline] index(&self) -> i32395f3cc26a4SIgor Korotin pub fn index(&self) -> i32 { 396f3cc26a4SIgor Korotin // SAFETY: `self.as_raw` is a valid pointer to a `struct i2c_adapter`. 397f3cc26a4SIgor Korotin unsafe { (*self.as_raw()).nr } 398f3cc26a4SIgor Korotin } 399f3cc26a4SIgor Korotin 400f3cc26a4SIgor Korotin /// Gets pointer to an `i2c_adapter` by index. get(index: i32) -> Result<ARef<Self>>401f3cc26a4SIgor Korotin pub fn get(index: i32) -> Result<ARef<Self>> { 402f3cc26a4SIgor Korotin // SAFETY: `index` must refer to a valid I2C adapter; the kernel 403f3cc26a4SIgor Korotin // guarantees that `i2c_get_adapter(index)` returns either a valid 404f3cc26a4SIgor Korotin // pointer or NULL. `NonNull::new` guarantees the correct check. 405f3cc26a4SIgor Korotin let adapter = NonNull::new(unsafe { bindings::i2c_get_adapter(index) }).ok_or(ENODEV)?; 406f3cc26a4SIgor Korotin 407f3cc26a4SIgor Korotin // SAFETY: `adapter` is non-null and points to a live `i2c_adapter`. 408f3cc26a4SIgor Korotin // `I2cAdapter` is #[repr(transparent)], so this cast is valid. 409f3cc26a4SIgor Korotin Ok(unsafe { (&*adapter.as_ptr().cast::<I2cAdapter<device::Normal>>()).into() }) 410f3cc26a4SIgor Korotin } 411f3cc26a4SIgor Korotin } 412f3cc26a4SIgor Korotin 413f3cc26a4SIgor Korotin // SAFETY: `I2cAdapter` is a transparent wrapper of a type that doesn't depend on 414f3cc26a4SIgor Korotin // `I2cAdapter`'s generic argument. 415f3cc26a4SIgor Korotin kernel::impl_device_context_deref!(unsafe { I2cAdapter }); 416f3cc26a4SIgor Korotin kernel::impl_device_context_into_aref!(I2cAdapter); 417f3cc26a4SIgor Korotin 418f3cc26a4SIgor Korotin // SAFETY: Instances of `I2cAdapter` are always reference-counted. 419f3cc26a4SIgor Korotin unsafe impl crate::types::AlwaysRefCounted for I2cAdapter { inc_ref(&self)420f3cc26a4SIgor Korotin fn inc_ref(&self) { 421f3cc26a4SIgor Korotin // SAFETY: The existence of a shared reference guarantees that the refcount is non-zero. 422f3cc26a4SIgor Korotin unsafe { bindings::i2c_get_adapter(self.index()) }; 423f3cc26a4SIgor Korotin } 424f3cc26a4SIgor Korotin dec_ref(obj: NonNull<Self>)425f3cc26a4SIgor Korotin unsafe fn dec_ref(obj: NonNull<Self>) { 426f3cc26a4SIgor Korotin // SAFETY: The safety requirements guarantee that the refcount is non-zero. 427f3cc26a4SIgor Korotin unsafe { bindings::i2c_put_adapter(obj.as_ref().as_raw()) } 428f3cc26a4SIgor Korotin } 429f3cc26a4SIgor Korotin } 430f3cc26a4SIgor Korotin 431f3cc26a4SIgor Korotin /// The i2c board info representation 432f3cc26a4SIgor Korotin /// 433f3cc26a4SIgor Korotin /// This structure represents the Rust abstraction for a C `struct i2c_board_info` structure, 434f3cc26a4SIgor Korotin /// which is used for manual I2C client creation. 435f3cc26a4SIgor Korotin #[repr(transparent)] 436f3cc26a4SIgor Korotin pub struct I2cBoardInfo(bindings::i2c_board_info); 437f3cc26a4SIgor Korotin 438f3cc26a4SIgor Korotin impl I2cBoardInfo { 439f3cc26a4SIgor Korotin const I2C_TYPE_SIZE: usize = 20; 440f3cc26a4SIgor Korotin /// Create a new [`I2cBoardInfo`] for a kernel driver. 441f3cc26a4SIgor Korotin #[inline(always)] new(type_: &'static CStr, addr: u16) -> Self442f3cc26a4SIgor Korotin pub const fn new(type_: &'static CStr, addr: u16) -> Self { 443a762f883SMiguel Ojeda let src = type_.to_bytes_with_nul(); 444a762f883SMiguel Ojeda build_assert!(src.len() <= Self::I2C_TYPE_SIZE, "Type exceeds 20 bytes"); 445f3cc26a4SIgor Korotin let mut i2c_board_info: bindings::i2c_board_info = pin_init::zeroed(); 446f3cc26a4SIgor Korotin let mut i: usize = 0; 447f3cc26a4SIgor Korotin while i < src.len() { 448f3cc26a4SIgor Korotin i2c_board_info.type_[i] = src[i]; 449f3cc26a4SIgor Korotin i += 1; 450f3cc26a4SIgor Korotin } 451f3cc26a4SIgor Korotin 452f3cc26a4SIgor Korotin i2c_board_info.addr = addr; 453f3cc26a4SIgor Korotin Self(i2c_board_info) 454f3cc26a4SIgor Korotin } 455f3cc26a4SIgor Korotin as_raw(&self) -> *const bindings::i2c_board_info456f3cc26a4SIgor Korotin fn as_raw(&self) -> *const bindings::i2c_board_info { 457f3cc26a4SIgor Korotin from_ref(&self.0) 458f3cc26a4SIgor Korotin } 459f3cc26a4SIgor Korotin } 460f3cc26a4SIgor Korotin 46157c5bd9aSIgor Korotin /// The i2c client representation. 46257c5bd9aSIgor Korotin /// 46357c5bd9aSIgor Korotin /// This structure represents the Rust abstraction for a C `struct i2c_client`. The 46457c5bd9aSIgor Korotin /// implementation abstracts the usage of an existing C `struct i2c_client` that 46557c5bd9aSIgor Korotin /// gets passed from the C side 46657c5bd9aSIgor Korotin /// 46757c5bd9aSIgor Korotin /// # Invariants 46857c5bd9aSIgor Korotin /// 46957c5bd9aSIgor Korotin /// A [`I2cClient`] instance represents a valid `struct i2c_client` created by the C portion of 47057c5bd9aSIgor Korotin /// the kernel. 47157c5bd9aSIgor Korotin #[repr(transparent)] 47257c5bd9aSIgor Korotin pub struct I2cClient<Ctx: device::DeviceContext = device::Normal>( 47357c5bd9aSIgor Korotin Opaque<bindings::i2c_client>, 47457c5bd9aSIgor Korotin PhantomData<Ctx>, 47557c5bd9aSIgor Korotin ); 47657c5bd9aSIgor Korotin 47757c5bd9aSIgor Korotin impl<Ctx: device::DeviceContext> I2cClient<Ctx> { as_raw(&self) -> *mut bindings::i2c_client47857c5bd9aSIgor Korotin fn as_raw(&self) -> *mut bindings::i2c_client { 47957c5bd9aSIgor Korotin self.0.get() 48057c5bd9aSIgor Korotin } 48157c5bd9aSIgor Korotin } 48257c5bd9aSIgor Korotin 483e4addc7cSMarkus Probst // SAFETY: `I2cClient` is a transparent wrapper of `struct i2c_client`. 484e4addc7cSMarkus Probst // The offset is guaranteed to point to a valid device field inside `I2cClient`. 485e4addc7cSMarkus Probst unsafe impl<Ctx: device::DeviceContext> device::AsBusDevice<Ctx> for I2cClient<Ctx> { 486e4addc7cSMarkus Probst const OFFSET: usize = offset_of!(bindings::i2c_client, dev); 487e4addc7cSMarkus Probst } 488e4addc7cSMarkus Probst 48957c5bd9aSIgor Korotin // SAFETY: `I2cClient` is a transparent wrapper of a type that doesn't depend on 49057c5bd9aSIgor Korotin // `I2cClient`'s generic argument. 49157c5bd9aSIgor Korotin kernel::impl_device_context_deref!(unsafe { I2cClient }); 49257c5bd9aSIgor Korotin kernel::impl_device_context_into_aref!(I2cClient); 49357c5bd9aSIgor Korotin 49457c5bd9aSIgor Korotin // SAFETY: Instances of `I2cClient` are always reference-counted. 49557c5bd9aSIgor Korotin unsafe impl AlwaysRefCounted for I2cClient { inc_ref(&self)49657c5bd9aSIgor Korotin fn inc_ref(&self) { 49757c5bd9aSIgor Korotin // SAFETY: The existence of a shared reference guarantees that the refcount is non-zero. 49857c5bd9aSIgor Korotin unsafe { bindings::get_device(self.as_ref().as_raw()) }; 49957c5bd9aSIgor Korotin } 50057c5bd9aSIgor Korotin dec_ref(obj: NonNull<Self>)50157c5bd9aSIgor Korotin unsafe fn dec_ref(obj: NonNull<Self>) { 50257c5bd9aSIgor Korotin // SAFETY: The safety requirements guarantee that the refcount is non-zero. 50357c5bd9aSIgor Korotin unsafe { bindings::put_device(&raw mut (*obj.as_ref().as_raw()).dev) } 50457c5bd9aSIgor Korotin } 50557c5bd9aSIgor Korotin } 50657c5bd9aSIgor Korotin 50757c5bd9aSIgor Korotin impl<Ctx: device::DeviceContext> AsRef<device::Device<Ctx>> for I2cClient<Ctx> { as_ref(&self) -> &device::Device<Ctx>50857c5bd9aSIgor Korotin fn as_ref(&self) -> &device::Device<Ctx> { 50957c5bd9aSIgor Korotin let raw = self.as_raw(); 51057c5bd9aSIgor Korotin // SAFETY: By the type invariant of `Self`, `self.as_raw()` is a pointer to a valid 51157c5bd9aSIgor Korotin // `struct i2c_client`. 51257c5bd9aSIgor Korotin let dev = unsafe { &raw mut (*raw).dev }; 51357c5bd9aSIgor Korotin 51457c5bd9aSIgor Korotin // SAFETY: `dev` points to a valid `struct device`. 51557c5bd9aSIgor Korotin unsafe { device::Device::from_raw(dev) } 51657c5bd9aSIgor Korotin } 51757c5bd9aSIgor Korotin } 51857c5bd9aSIgor Korotin 51957c5bd9aSIgor Korotin impl<Ctx: device::DeviceContext> TryFrom<&device::Device<Ctx>> for &I2cClient<Ctx> { 52057c5bd9aSIgor Korotin type Error = kernel::error::Error; 52157c5bd9aSIgor Korotin try_from(dev: &device::Device<Ctx>) -> Result<Self, Self::Error>52257c5bd9aSIgor Korotin fn try_from(dev: &device::Device<Ctx>) -> Result<Self, Self::Error> { 52357c5bd9aSIgor Korotin // SAFETY: By the type invariant of `Device`, `dev.as_raw()` is a valid pointer to a 52457c5bd9aSIgor Korotin // `struct device`. 52557c5bd9aSIgor Korotin if unsafe { bindings::i2c_verify_client(dev.as_raw()).is_null() } { 52657c5bd9aSIgor Korotin return Err(EINVAL); 52757c5bd9aSIgor Korotin } 52857c5bd9aSIgor Korotin 52957c5bd9aSIgor Korotin // SAFETY: We've just verified that the type of `dev` equals to 53057c5bd9aSIgor Korotin // `bindings::i2c_client_type`, hence `dev` must be embedded in a valid 53157c5bd9aSIgor Korotin // `struct i2c_client` as guaranteed by the corresponding C code. 53257c5bd9aSIgor Korotin let idev = unsafe { container_of!(dev.as_raw(), bindings::i2c_client, dev) }; 53357c5bd9aSIgor Korotin 53457c5bd9aSIgor Korotin // SAFETY: `idev` is a valid pointer to a `struct i2c_client`. 53557c5bd9aSIgor Korotin Ok(unsafe { &*idev.cast() }) 53657c5bd9aSIgor Korotin } 53757c5bd9aSIgor Korotin } 53857c5bd9aSIgor Korotin 53957c5bd9aSIgor Korotin // SAFETY: A `I2cClient` is always reference-counted and can be released from any thread. 54057c5bd9aSIgor Korotin unsafe impl Send for I2cClient {} 54157c5bd9aSIgor Korotin 54257c5bd9aSIgor Korotin // SAFETY: `I2cClient` can be shared among threads because all methods of `I2cClient` 54357c5bd9aSIgor Korotin // (i.e. `I2cClient<Normal>) are thread safe. 54457c5bd9aSIgor Korotin unsafe impl Sync for I2cClient {} 545f3cc26a4SIgor Korotin 546f3cc26a4SIgor Korotin /// The registration of an i2c client device. 547f3cc26a4SIgor Korotin /// 548f3cc26a4SIgor Korotin /// This type represents the registration of a [`struct i2c_client`]. When an instance of this 549f3cc26a4SIgor Korotin /// type is dropped, its respective i2c client device will be unregistered from the system. 550f3cc26a4SIgor Korotin /// 551f3cc26a4SIgor Korotin /// # Invariants 552f3cc26a4SIgor Korotin /// 553f3cc26a4SIgor Korotin /// `self.0` always holds a valid pointer to an initialized and registered 554f3cc26a4SIgor Korotin /// [`struct i2c_client`]. 555f3cc26a4SIgor Korotin #[repr(transparent)] 556f3cc26a4SIgor Korotin pub struct Registration(NonNull<bindings::i2c_client>); 557f3cc26a4SIgor Korotin 558f3cc26a4SIgor Korotin impl Registration { 559f3cc26a4SIgor Korotin /// The C `i2c_new_client_device` function wrapper for manual I2C client creation. new<'a>( i2c_adapter: &I2cAdapter, i2c_board_info: &I2cBoardInfo, parent_dev: &'a device::Device<device::Bound>, ) -> impl PinInit<Devres<Self>, Error> + 'a560f3cc26a4SIgor Korotin pub fn new<'a>( 561f3cc26a4SIgor Korotin i2c_adapter: &I2cAdapter, 562f3cc26a4SIgor Korotin i2c_board_info: &I2cBoardInfo, 563f3cc26a4SIgor Korotin parent_dev: &'a device::Device<device::Bound>, 564f3cc26a4SIgor Korotin ) -> impl PinInit<Devres<Self>, Error> + 'a { 565f3cc26a4SIgor Korotin Devres::new(parent_dev, Self::try_new(i2c_adapter, i2c_board_info)) 566f3cc26a4SIgor Korotin } 567f3cc26a4SIgor Korotin try_new(i2c_adapter: &I2cAdapter, i2c_board_info: &I2cBoardInfo) -> Result<Self>568f3cc26a4SIgor Korotin fn try_new(i2c_adapter: &I2cAdapter, i2c_board_info: &I2cBoardInfo) -> Result<Self> { 569f3cc26a4SIgor Korotin // SAFETY: the kernel guarantees that `i2c_new_client_device()` returns either a valid 570f3cc26a4SIgor Korotin // pointer or NULL. `from_err_ptr` separates errors. Following `NonNull::new` 571f3cc26a4SIgor Korotin // checks for NULL. 572f3cc26a4SIgor Korotin let raw_dev = from_err_ptr(unsafe { 573f3cc26a4SIgor Korotin bindings::i2c_new_client_device(i2c_adapter.as_raw(), i2c_board_info.as_raw()) 574f3cc26a4SIgor Korotin })?; 575f3cc26a4SIgor Korotin 576f3cc26a4SIgor Korotin let dev_ptr = NonNull::new(raw_dev).ok_or(ENODEV)?; 577f3cc26a4SIgor Korotin 578f3cc26a4SIgor Korotin Ok(Self(dev_ptr)) 579f3cc26a4SIgor Korotin } 580f3cc26a4SIgor Korotin } 581f3cc26a4SIgor Korotin 582f3cc26a4SIgor Korotin impl Drop for Registration { drop(&mut self)583f3cc26a4SIgor Korotin fn drop(&mut self) { 584f3cc26a4SIgor Korotin // SAFETY: `Drop` is only called for a valid `Registration`, which by invariant 585f3cc26a4SIgor Korotin // always contains a non-null pointer to an `i2c_client`. 586f3cc26a4SIgor Korotin unsafe { bindings::i2c_unregister_device(self.0.as_ptr()) } 587f3cc26a4SIgor Korotin } 588f3cc26a4SIgor Korotin } 589f3cc26a4SIgor Korotin 590f3cc26a4SIgor Korotin // SAFETY: A `Registration` of a `struct i2c_client` can be released from any thread. 591f3cc26a4SIgor Korotin unsafe impl Send for Registration {} 592f3cc26a4SIgor Korotin 593f3cc26a4SIgor Korotin // SAFETY: `Registration` offers no interior mutability (no mutation through &self 594f3cc26a4SIgor Korotin // and no mutable access is exposed) 595f3cc26a4SIgor Korotin unsafe impl Sync for Registration {} 596