1use crate::{
2 raw::v2::*, utils::*, Active, AsValuesMut, Bias, Direction, Drive, Edge, EdgeDetect, Event,
3 LineId, LineInfo, LineMap, Result, Values,
4};
5
6pub type RawEvent = GpioLineEvent;
8
9impl GpioLineInfo {
10 pub fn as_info(&self) -> Result<LineInfo> {
11 let direction = if is_set(self.flags, GPIO_LINE_FLAG_OUTPUT) {
12 Direction::Output
13 } else {
14 Direction::Input
15 };
16
17 let active = if is_set(self.flags, GPIO_LINE_FLAG_ACTIVE_LOW) {
18 Active::Low
19 } else {
20 Active::High
21 };
22
23 let edge = match (
24 is_set(self.flags, GPIO_LINE_FLAG_EDGE_RISING),
25 is_set(self.flags, GPIO_LINE_FLAG_EDGE_FALLING),
26 ) {
27 (true, false) => EdgeDetect::Rising,
28 (false, true) => EdgeDetect::Falling,
29 (true, true) => EdgeDetect::Both,
30 _ => EdgeDetect::Disable,
31 };
32
33 let used = is_set(self.flags, GPIO_LINE_FLAG_USED);
34
35 let bias = match (
36 is_set(self.flags, GPIO_LINE_FLAG_BIAS_PULL_UP),
37 is_set(self.flags, GPIO_LINE_FLAG_BIAS_PULL_DOWN),
38 ) {
39 (true, false) => Bias::PullUp,
40 (false, true) => Bias::PullDown,
41 _ => Bias::Disable,
42 };
43
44 let drive = match (
45 is_set(self.flags, GPIO_LINE_FLAG_OPEN_DRAIN),
46 is_set(self.flags, GPIO_LINE_FLAG_OPEN_SOURCE),
47 ) {
48 (true, false) => Drive::OpenDrain,
49 (false, true) => Drive::OpenSource,
50 _ => Drive::PushPull,
51 };
52 let name = safe_get_str(&self.name)?.into();
53 let consumer = safe_get_str(&self.consumer)?.into();
54
55 Ok(LineInfo {
56 direction,
57 active,
58 edge,
59 used,
60 bias,
61 drive,
62 name,
63 consumer,
64 })
65 }
66}
67
68impl AsMut<GpioLineValues> for Values {
69 fn as_mut(&mut self) -> &mut GpioLineValues {
70 unsafe { &mut *(self as *mut _ as *mut _) }
72 }
73}
74
75impl GpioLineRequest {
76 #[allow(clippy::too_many_arguments)]
77 pub fn new(
78 lines: &[LineId],
79 direction: Direction,
80 active: Active,
81 edge: Option<EdgeDetect>,
82 bias: Option<Bias>,
83 drive: Option<Drive>,
84 values: Option<Values>,
85 consumer: &str,
86 ) -> Result<Self> {
87 let mut request = GpioLineRequest::default();
88
89 check_len(lines, &request.offsets)?;
90
91 request.num_lines = lines.len() as _;
92
93 request.offsets[..lines.len()].copy_from_slice(lines);
94
95 let config = &mut request.config;
96
97 config.flags |= match direction {
98 Direction::Input => GPIO_LINE_FLAG_INPUT,
99 Direction::Output => GPIO_LINE_FLAG_OUTPUT,
102 };
103
104 if matches!(active, Active::Low) {
105 config.flags |= GPIO_LINE_FLAG_ACTIVE_LOW;
106 }
107
108 if matches!(direction, Direction::Input) {
109 if let Some(edge) = edge {
112 match edge {
113 EdgeDetect::Rising => config.flags |= GPIO_LINE_FLAG_EDGE_RISING,
114 EdgeDetect::Falling => config.flags |= GPIO_LINE_FLAG_EDGE_FALLING,
115 EdgeDetect::Both => config.flags |= GPIO_LINE_FLAG_EDGE_BOTH,
116 _ => {}
117 }
118 }
119 }
120
121 if let Some(bias) = bias {
122 config.flags |= match bias {
123 Bias::PullUp => GPIO_LINE_FLAG_BIAS_PULL_UP,
124 Bias::PullDown => GPIO_LINE_FLAG_BIAS_PULL_DOWN,
125 Bias::Disable => GPIO_LINE_FLAG_BIAS_DISABLED,
126 }
127 }
128
129 if matches!(direction, Direction::Output) {
130 if let Some(drive) = drive {
133 match drive {
134 Drive::OpenDrain => config.flags |= GPIO_LINE_FLAG_OPEN_DRAIN,
135 Drive::OpenSource => config.flags |= GPIO_LINE_FLAG_OPEN_SOURCE,
136 _ => (),
137 }
138 }
139
140 if let Some(mut values) = values {
141 values.truncate(lines.len() as _);
142
143 config.num_attrs = 1;
144 let attr = &mut config.attrs[0];
145 attr.attr.id = GPIO_LINE_ATTR_ID_OUTPUT_VALUES;
146 attr.mask = values.mask;
147 attr.attr.val.values = values.bits;
148 }
149 }
150
151 safe_set_str(&mut request.consumer, consumer)?;
152
153 Ok(request)
154 }
155}
156
157impl GpioLineEvent {
158 pub fn as_event(&self, line_map: &LineMap) -> Result<Event> {
159 let line = line_map.get(self.offset)?;
160
161 let edge = match self.id {
162 GPIO_LINE_EVENT_RISING_EDGE => Edge::Rising,
163 GPIO_LINE_EVENT_FALLING_EDGE => Edge::Falling,
164 _ => return Err(invalid_data("Unknown edge")),
165 };
166
167 let time = time_from_nanos(self.timestamp_ns);
168
169 Ok(Event { line, edge, time })
170 }
171}