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