kobo_core/device/
config.rs1use crate::device::registry::DEVICES;
8
9#[derive(Debug, Clone, Copy, PartialEq, Eq)]
10pub enum SocFamily {
11 Mtk,
12 Nxp,
13 Sunxi,
14}
15
16#[derive(Debug, Clone, Copy, PartialEq, Eq)]
17pub enum TouchProtocol {
18 Snow,
19 Phoenix,
20 Legacy,
21}
22
23#[derive(Debug, Clone)]
24#[allow(dead_code)]
25pub struct FrontlightConfig {
26 pub brightness_path: String,
27 pub mixer_path: Option<String>,
28 pub nl_min: u32,
29 pub nl_max: u32,
30 pub nl_inverted: bool,
31}
32
33#[derive(Debug, Clone)]
34#[allow(dead_code)]
35pub struct DeviceConfig {
36 pub codename: &'static str,
37 pub model: &'static str,
38 pub soc: SocFamily,
39 pub display_dpi: u32,
40 pub has_color_screen: bool,
41 pub has_natural_light: bool,
42 pub has_bt: bool,
43 pub has_keys: bool,
44 pub has_gsensor: bool,
45 pub has_eclipse_wfm: bool,
46 pub is_smp: bool,
47 pub frontlight: FrontlightConfig,
48 pub battery_sysfs: String,
49 pub touch_protocol: TouchProtocol,
50 pub touch_switch_xy: bool,
51 pub touch_mirrored_x: bool,
52 pub touch_mirrored_y: bool,
53 pub standby_state: &'static str,
54 pub automagic_sysfs: bool,
55}
56
57impl Default for FrontlightConfig {
58 fn default() -> Self {
59 FrontlightConfig {
60 brightness_path: "/sys/class/backlight/mxc_msp430.0/brightness".into(),
61 mixer_path: None,
62 nl_min: 0,
63 nl_max: 10,
64 nl_inverted: true,
65 }
66 }
67}
68
69#[derive(Debug, Clone)]
70pub struct InputDevices {
71 pub touch_dev: String,
72 pub power_dev: String,
73}
74
75pub fn lookup_device(codename: &str) -> Option<&'static DeviceConfig> {
76 DEVICES.iter().find(|d| d.codename == codename)
77}
78
79pub fn detect_from_codename(codename: &str) -> &'static DeviceConfig {
82 lookup_device(codename).unwrap_or_else(|| {
83 DEVICES
84 .iter()
85 .find(|d| d.codename == "monza")
86 .expect("monza entry must exist in DEVICES")
87 })
88}
89
90pub fn parse_input_devices(content: &str) -> (Option<String>, Option<String>) {
94 let mut touch_path: Option<String> = None;
95 let mut power_path: Option<String> = None;
96 let mut current_handlers = Vec::new();
97 for line in content.lines() {
98 if let Some(handlers) = line.strip_prefix("H: Handlers=") {
99 current_handlers.clear();
100 current_handlers = handlers.split_whitespace().map(String::from).collect();
101 }
102 if let Some(dev) = line.strip_prefix("P: Phys=") {
103 let is_touch = current_handlers
104 .iter()
105 .any(|h| h.starts_with("event") && (dev.contains("touch") || dev.contains("ts")));
106 let is_power = current_handlers.iter().any(|h| {
107 h.starts_with("event")
108 && (dev.contains("gpio") || dev.contains("power") || dev.contains("keys"))
109 });
110 if is_touch && touch_path.is_none() {
111 for h in ¤t_handlers {
112 if h.starts_with("event") {
113 touch_path = Some(format!("/dev/input/{}", h));
114 break;
115 }
116 }
117 }
118 if is_power && power_path.is_none() {
119 for h in ¤t_handlers {
120 if h.starts_with("event") {
121 power_path = Some(format!("/dev/input/{}", h));
122 break;
123 }
124 }
125 }
126 }
127 }
128 (touch_path, power_path)
129}
130
131#[cfg(test)]
132mod tests {
133 use super::*;
134
135 #[test]
136 fn detect_from_codename_known() {
137 let d = detect_from_codename("monza");
138 assert_eq!(d.model, "Kobo Libra Colour");
139 assert_eq!(d.soc, SocFamily::Mtk);
140 }
141
142 #[test]
143 fn detect_from_codename_unknown_falls_back() {
144 let fallback = detect_from_codename("does-not-exist");
145 assert_eq!(
146 fallback.codename, "monza",
147 "unknown codename must fall back to monza"
148 );
149 assert!(lookup_device("does-not-exist").is_none());
150 }
151
152 #[test]
153 fn parse_input_devices_extracts_event_nodes() {
154 let sample = "\
155I: Bus=0018 Vendor=0000 Product=0000 Version=0000
156N: Name=\"cyttsp5_mt\"
157H: Handlers=event1 mouse0
158P: Phys=cyttsp5_mt/input0 touch\n\
159I: Bus=0019 Vendor=0001 Product=0001 Version=0100
160N: Name=\"gpio-keys\"
161H: Handlers=event2
162P: Phys=gpio-keys/power0 power\n";
163 let (touch, power) = parse_input_devices(sample);
164 assert_eq!(touch.as_deref(), Some("/dev/input/event1"));
165 assert_eq!(power.as_deref(), Some("/dev/input/event2"));
166 }
167}