1use capsules_core::virtualizers::virtual_i2c::{I2CDevice, MuxI2C};
32use capsules_extra::lsm6dsoxtr::Lsm6dsoxtrI2C;
33use core::mem::MaybeUninit;
34use kernel::capabilities;
35use kernel::component::Component;
36use kernel::create_capability;
37use kernel::hil::i2c;
38
39#[macro_export]
41macro_rules! lsm6ds_i2c_component_static {
42    ($I:ty $(,)?) => {{
43        let buffer = kernel::static_buf!([u8; 8]);
44        let i2c_device =
45            kernel::static_buf!(capsules_core::virtualizers::virtual_i2c::I2CDevice<'static, $I>);
46        let lsm6dsoxtr = kernel::static_buf!(
47            capsules_extra::lsm6dsoxtr::Lsm6dsoxtrI2C<
48                'static,
49                capsules_core::virtualizers::virtual_i2c::I2CDevice<'static, $I>,
50            >
51        );
52
53        (i2c_device, buffer, lsm6dsoxtr)
54    };};
55}
56
57pub struct Lsm6dsoxtrI2CComponent<I: 'static + i2c::I2CMaster<'static>> {
58    i2c_mux: &'static MuxI2C<'static, I>,
59    i2c_address: u8,
60    board_kernel: &'static kernel::Kernel,
61    driver_num: usize,
62}
63
64impl<I: 'static + i2c::I2CMaster<'static>> Lsm6dsoxtrI2CComponent<I> {
65    pub fn new(
66        i2c_mux: &'static MuxI2C<'static, I>,
67        i2c_address: u8,
68        board_kernel: &'static kernel::Kernel,
69        driver_num: usize,
70    ) -> Lsm6dsoxtrI2CComponent<I> {
71        Lsm6dsoxtrI2CComponent {
72            i2c_mux,
73            i2c_address,
74            board_kernel,
75            driver_num,
76        }
77    }
78}
79
80impl<I: 'static + i2c::I2CMaster<'static>> Component for Lsm6dsoxtrI2CComponent<I> {
81    type StaticInput = (
82        &'static mut MaybeUninit<I2CDevice<'static, I>>,
83        &'static mut MaybeUninit<[u8; 8]>,
84        &'static mut MaybeUninit<Lsm6dsoxtrI2C<'static, I2CDevice<'static, I>>>,
85    );
86    type Output = &'static Lsm6dsoxtrI2C<'static, I2CDevice<'static, I>>;
87
88    fn finalize(self, static_buffer: Self::StaticInput) -> Self::Output {
89        let grant_cap = create_capability!(capabilities::MemoryAllocationCapability);
90        let grant = self.board_kernel.create_grant(self.driver_num, &grant_cap);
91
92        let lsm6dsox_i2c = static_buffer
93            .0
94            .write(I2CDevice::new(self.i2c_mux, self.i2c_address));
95        let buffer = static_buffer.1.write([0; 8]);
96
97        let lsm6dsox = static_buffer
98            .2
99            .write(Lsm6dsoxtrI2C::new(lsm6dsox_i2c, buffer, grant));
100        lsm6dsox_i2c.set_client(lsm6dsox);
101
102        lsm6dsox
103    }
104}