xref: /DragonOS/kernel/src/driver/input/serio/i8042/i8042_ports.rs (revision 4b0170bd6bb374d0e9699a0076cc23b976ad6db7)
1 use alloc::{
2     string::{String, ToString},
3     sync::{Arc, Weak},
4 };
5 use system_error::SystemError;
6 
7 use crate::{
8     driver::{
9         base::{
10             class::Class,
11             device::{bus::Bus, driver::Driver, Device, DeviceType, IdTable},
12             kobject::{KObjType, KObject, KObjectState, LockedKObjectState},
13             kset::KSet,
14         },
15         input::serio::serio_device::SerioDevice,
16     },
17     filesystem::kernfs::KernFSInode,
18     libs::{
19         rwlock::{RwLockReadGuard, RwLockWriteGuard},
20         spinlock::SpinLock,
21     },
22 };
23 
24 use super::{i8042_start, i8042_stop};
25 
26 #[derive(Debug)]
27 #[cast_to([sync] Device)]
28 pub struct I8042AuxPort {
29     inner: SpinLock<InnerI8042AuxPort>,
30     kobj_state: LockedKObjectState,
31 }
32 
33 #[derive(Debug)]
34 pub struct InnerI8042AuxPort {
35     bus: Option<Weak<dyn Bus>>,
36     class: Option<Weak<dyn Class>>,
37     driver: Option<Weak<dyn Driver>>,
38     kern_inode: Option<Arc<KernFSInode>>,
39     parent: Option<Weak<dyn KObject>>,
40     kset: Option<Arc<KSet>>,
41     kobj_type: Option<&'static dyn KObjType>,
42 }
43 
44 impl I8042AuxPort {
45     pub const NAME: &'static str = "serio1";
46     pub fn new() -> Self {
47         return Self {
48             inner: SpinLock::new(InnerI8042AuxPort {
49                 bus: None,
50                 class: None,
51                 driver: None,
52                 kern_inode: None,
53                 parent: None,
54                 kset: None,
55                 kobj_type: None,
56             }),
57             kobj_state: LockedKObjectState::new(None),
58         };
59     }
60 }
61 
62 impl Device for I8042AuxPort {
63     fn dev_type(&self) -> DeviceType {
64         DeviceType::Char
65     }
66 
67     fn id_table(&self) -> IdTable {
68         IdTable::new(self.name(), None)
69     }
70 
71     fn bus(&self) -> Option<Weak<dyn Bus>> {
72         self.inner.lock().bus.clone()
73     }
74 
75     fn set_bus(&self, bus: Option<Weak<dyn Bus>>) {
76         self.inner.lock().bus = bus;
77     }
78 
79     fn set_class(&self, class: Option<Weak<dyn Class>>) {
80         self.inner.lock().class = class;
81     }
82 
83     fn class(&self) -> Option<Arc<dyn Class>> {
84         let mut guard = self.inner.lock();
85         let r = guard.class.clone()?.upgrade();
86         if r.is_none() {
87             guard.class = None;
88         }
89         return r;
90     }
91 
92     fn driver(&self) -> Option<Arc<dyn Driver>> {
93         self.inner.lock().driver.clone()?.upgrade()
94     }
95 
96     fn set_driver(&self, driver: Option<Weak<dyn Driver>>) {
97         self.inner.lock().driver = driver;
98     }
99 
100     fn is_dead(&self) -> bool {
101         false
102     }
103 
104     fn can_match(&self) -> bool {
105         true
106     }
107 
108     fn set_can_match(&self, _can_match: bool) {}
109 
110     fn state_synced(&self) -> bool {
111         true
112     }
113 }
114 
115 impl KObject for I8042AuxPort {
116     fn as_any_ref(&self) -> &dyn core::any::Any {
117         self
118     }
119 
120     fn set_inode(&self, inode: Option<Arc<KernFSInode>>) {
121         self.inner.lock().kern_inode = inode;
122     }
123 
124     fn inode(&self) -> Option<Arc<KernFSInode>> {
125         self.inner.lock().kern_inode.clone()
126     }
127 
128     fn parent(&self) -> Option<Weak<dyn KObject>> {
129         self.inner.lock().parent.clone()
130     }
131 
132     fn set_parent(&self, parent: Option<Weak<dyn KObject>>) {
133         self.inner.lock().parent = parent;
134     }
135 
136     fn kset(&self) -> Option<Arc<KSet>> {
137         self.inner.lock().kset.clone()
138     }
139 
140     fn set_kset(&self, kset: Option<Arc<KSet>>) {
141         self.inner.lock().kset = kset;
142     }
143 
144     fn kobj_type(&self) -> Option<&'static dyn KObjType> {
145         self.inner.lock().kobj_type
146     }
147 
148     fn set_kobj_type(&self, ktype: Option<&'static dyn KObjType>) {
149         self.inner.lock().kobj_type = ktype;
150     }
151 
152     fn name(&self) -> String {
153         Self::NAME.to_string()
154     }
155 
156     fn set_name(&self, _name: String) {
157         // do nothing
158     }
159 
160     fn kobj_state(&self) -> RwLockReadGuard<KObjectState> {
161         self.kobj_state.read()
162     }
163 
164     fn kobj_state_mut(&self) -> RwLockWriteGuard<KObjectState> {
165         self.kobj_state.write()
166     }
167 
168     fn set_kobj_state(&self, state: KObjectState) {
169         *self.kobj_state.write() = state;
170     }
171 }
172 
173 impl SerioDevice for I8042AuxPort {
174     // TODO: https://code.dragonos.org.cn/xref/linux-6.1.9/drivers/input/serio/i8042.c#387
175     fn write(&self, _device: &Arc<dyn SerioDevice>, _data: u8) -> Result<(), SystemError> {
176         todo!()
177     }
178 
179     fn open(&self, _device: &Arc<dyn SerioDevice>) -> Result<(), SystemError> {
180         Ok(())
181     }
182 
183     fn close(&self, _device: &Arc<dyn SerioDevice>) -> Result<(), SystemError> {
184         Ok(())
185     }
186 
187     fn start(&self, device: &Arc<dyn SerioDevice>) -> Result<(), SystemError> {
188         i8042_start(device)
189     }
190 
191     fn stop(&self, device: &Arc<dyn SerioDevice>) -> Result<(), SystemError> {
192         i8042_stop(device)
193     }
194 }
195