1use capsules_core::virtualizers::virtual_i2c::{I2CDevice, MuxI2C};
25use core::mem::MaybeUninit;
26use kernel::capabilities;
27use kernel::component::Component;
28use kernel::create_capability;
29use kernel::hil::i2c::{self, NoSMBus};
30
31#[macro_export]
33macro_rules! i2c_mux_component_static {
34 ($I:ty $(,)?) => {{
35 kernel::static_buf!(capsules_core::virtualizers::virtual_i2c::MuxI2C<'static, $I>)
36 };};
37 ($I:ty, $S:ty $(,)?) => {{
38 kernel::static_buf!(capsules::virtual_i2c::MuxI2C<'static, $I, $S>)
39 };};
40}
41
42#[macro_export]
43macro_rules! i2c_component_static {
44 ($I:ty $(,)?) => {{
45 kernel::static_buf!(capsules_core::virtualizers::virtual_i2c::I2CDevice<'static, $I>)
46 };};
47}
48
49#[macro_export]
50macro_rules! i2c_master_slave_component_static {
51 ($I:ty $(,)?) => {{
52 let i2c_master_buffer = kernel::static_buf!([u8; 32]);
53 let i2c_slave_buffer1 = kernel::static_buf!([u8; 32]);
54 let i2c_slave_buffer2 = kernel::static_buf!([u8; 32]);
55
56 let driver = kernel::static_buf!(
57 capsules_core::i2c_master_slave_driver::I2CMasterSlaveDriver<'static, $I>
58 );
59
60 (
61 driver,
62 i2c_master_buffer,
63 i2c_slave_buffer1,
64 i2c_slave_buffer2,
65 )
66 };};
67}
68
69pub struct I2CMuxComponent<
70 I: 'static + i2c::I2CMaster<'static>,
71 S: 'static + i2c::SMBusMaster<'static> = NoSMBus,
72> {
73 i2c: &'static I,
74 smbus: Option<&'static S>,
75}
76
77impl<I: 'static + i2c::I2CMaster<'static>, S: 'static + i2c::SMBusMaster<'static>>
78 I2CMuxComponent<I, S>
79{
80 pub fn new(i2c: &'static I, smbus: Option<&'static S>) -> Self {
81 I2CMuxComponent { i2c, smbus }
82 }
83}
84
85impl<I: 'static + i2c::I2CMaster<'static>, S: 'static + i2c::SMBusMaster<'static>> Component
86 for I2CMuxComponent<I, S>
87{
88 type StaticInput = &'static mut MaybeUninit<MuxI2C<'static, I, S>>;
89 type Output = &'static MuxI2C<'static, I, S>;
90
91 fn finalize(self, static_buffer: Self::StaticInput) -> Self::Output {
92 let mux_i2c = static_buffer.write(MuxI2C::new(self.i2c, self.smbus));
93 kernel::deferred_call::DeferredCallClient::register(mux_i2c);
94
95 self.i2c.set_master_client(mux_i2c);
96
97 mux_i2c
98 }
99}
100
101pub struct I2CComponent<I: 'static + i2c::I2CMaster<'static>> {
102 i2c_mux: &'static MuxI2C<'static, I>,
103 address: u8,
104}
105
106impl<I: 'static + i2c::I2CMaster<'static>> I2CComponent<I> {
107 pub fn new(mux: &'static MuxI2C<'static, I>, address: u8) -> Self {
108 I2CComponent {
109 i2c_mux: mux,
110 address,
111 }
112 }
113}
114
115impl<I: 'static + i2c::I2CMaster<'static>> Component for I2CComponent<I> {
116 type StaticInput = &'static mut MaybeUninit<I2CDevice<'static, I>>;
117 type Output = &'static I2CDevice<'static, I>;
118
119 fn finalize(self, static_buffer: Self::StaticInput) -> Self::Output {
120 let i2c_device = static_buffer.write(I2CDevice::new(self.i2c_mux, self.address));
121
122 i2c_device
123 }
124}
125
126pub struct I2CMasterSlaveDriverComponent<I: 'static + i2c::I2CMasterSlave<'static>> {
127 board_kernel: &'static kernel::Kernel,
128 driver_num: usize,
129 i2c: &'static I,
130}
131
132impl<I: 'static + i2c::I2CMasterSlave<'static>> I2CMasterSlaveDriverComponent<I> {
133 pub fn new(board_kernel: &'static kernel::Kernel, driver_num: usize, i2c: &'static I) -> Self {
134 I2CMasterSlaveDriverComponent {
135 board_kernel,
136 driver_num,
137 i2c,
138 }
139 }
140}
141
142impl<I: 'static + i2c::I2CMasterSlave<'static>> Component for I2CMasterSlaveDriverComponent<I> {
143 type StaticInput = (
144 &'static mut MaybeUninit<
145 capsules_core::i2c_master_slave_driver::I2CMasterSlaveDriver<'static, I>,
146 >,
147 &'static mut MaybeUninit<[u8; 32]>,
148 &'static mut MaybeUninit<[u8; 32]>,
149 &'static mut MaybeUninit<[u8; 32]>,
150 );
151 type Output = &'static capsules_core::i2c_master_slave_driver::I2CMasterSlaveDriver<'static, I>;
152
153 fn finalize(self, static_buffer: Self::StaticInput) -> Self::Output {
154 let grant_cap = create_capability!(capabilities::MemoryAllocationCapability);
155
156 let i2c_master_buffer = static_buffer.1.write([0; 32]);
157 let i2c_slave_buffer1 = static_buffer.2.write([0; 32]);
158 let i2c_slave_buffer2 = static_buffer.3.write([0; 32]);
159
160 let i2c_master_slave_driver = static_buffer.0.write(
161 capsules_core::i2c_master_slave_driver::I2CMasterSlaveDriver::new(
162 self.i2c,
163 i2c_master_buffer,
164 i2c_slave_buffer1,
165 i2c_slave_buffer2,
166 self.board_kernel.create_grant(self.driver_num, &grant_cap),
167 ),
168 );
169
170 self.i2c.set_master_client(i2c_master_slave_driver);
171 self.i2c.set_slave_client(i2c_master_slave_driver);
172
173 i2c_master_slave_driver
174 }
175}