hdmi_hal_i2c_dev/phy.rs
1//! [`HdmiPhy`] stub implementation for userspace validation.
2//!
3//! [`HdmiPhy`]: hdmi_hal::phy::HdmiPhy
4
5use core::convert::Infallible;
6
7use display_types::cea861::hdmi_forum::HdmiForumFrl;
8use hdmi_hal::phy::{EqParams, FrlOutput, HdmiPhy, LanePatterns};
9
10/// A structured description of a single [`HdmiPhy`] method invocation.
11///
12/// Used as the callback argument for [`StubPhy`]. Match on variants to
13/// observe or assert specific PHY calls in tests and diagnostic tools.
14///
15/// This enum is `#[non_exhaustive]`: if [`HdmiPhy`] gains new methods,
16/// `PhyCall` gains new variants. Downstream match arms should include a
17/// wildcard (`_`) so they do not need to be updated for methods they do not
18/// care about.
19///
20/// [`HdmiPhy`]: hdmi_hal::phy::HdmiPhy
21#[derive(Debug, Clone, Copy, PartialEq, Eq)]
22#[non_exhaustive]
23pub enum PhyCall {
24 /// [`HdmiPhy::set_frl_rate`] was called with the given rate.
25 ///
26 /// [`HdmiPhy::set_frl_rate`]: hdmi_hal::phy::HdmiPhy::set_frl_rate
27 SetFrlRate(HdmiForumFrl),
28 /// [`HdmiPhy::send_ltp`] was called with the given per-lane pattern set.
29 ///
30 /// [`HdmiPhy::send_ltp`]: hdmi_hal::phy::HdmiPhy::send_ltp
31 SendLtp(LanePatterns),
32 /// [`HdmiPhy::set_frl_output`] was called with the given output mode.
33 ///
34 /// [`HdmiPhy::set_frl_output`]: hdmi_hal::phy::HdmiPhy::set_frl_output
35 SetFrlOutput(FrlOutput),
36 /// [`HdmiPhy::adjust_equalization`] was called with the given parameters.
37 ///
38 /// [`HdmiPhy::adjust_equalization`]: hdmi_hal::phy::HdmiPhy::adjust_equalization
39 AdjustEqualization(EqParams),
40 /// [`HdmiPhy::set_scrambling`] was called with the given flag.
41 ///
42 /// [`HdmiPhy::set_scrambling`]: hdmi_hal::phy::HdmiPhy::set_scrambling
43 SetScrambling(bool),
44}
45
46/// An [`HdmiPhy`] stub that forwards each call as a [`PhyCall`] event to a
47/// caller-supplied callback and unconditionally returns `Ok(())`.
48///
49/// `type Error = Infallible` is guaranteed by the design: the callback
50/// returns `()`, so `StubPhy` cannot fail regardless of what the callback
51/// does.
52///
53/// # Examples
54///
55/// No-op — discard all PHY calls:
56///
57/// ```
58/// use hdmi_hal_i2c_dev::phy::StubPhy;
59/// let _phy = StubPhy::new(|_| {});
60/// ```
61///
62/// Logging — print each call to stderr:
63///
64/// ```
65/// use hdmi_hal_i2c_dev::phy::StubPhy;
66/// let _phy = StubPhy::new(|call| eprintln!("{call:?}"));
67/// ```
68///
69/// [`HdmiPhy`]: hdmi_hal::phy::HdmiPhy
70pub struct StubPhy<F> {
71 on_call: F,
72}
73
74impl<F: FnMut(PhyCall)> StubPhy<F> {
75 /// Construct a `StubPhy` that forwards each PHY call to `on_call`.
76 pub fn new(on_call: F) -> Self {
77 Self { on_call }
78 }
79}
80
81impl<F: FnMut(PhyCall)> HdmiPhy for StubPhy<F> {
82 type Error = Infallible;
83
84 fn set_frl_rate(&mut self, rate: HdmiForumFrl) -> Result<(), Infallible> {
85 (self.on_call)(PhyCall::SetFrlRate(rate));
86 Ok(())
87 }
88
89 fn send_ltp(&mut self, patterns: LanePatterns) -> Result<(), Infallible> {
90 (self.on_call)(PhyCall::SendLtp(patterns));
91 Ok(())
92 }
93
94 fn set_frl_output(&mut self, output: FrlOutput) -> Result<(), Infallible> {
95 (self.on_call)(PhyCall::SetFrlOutput(output));
96 Ok(())
97 }
98
99 fn adjust_equalization(&mut self, params: EqParams) -> Result<(), Infallible> {
100 (self.on_call)(PhyCall::AdjustEqualization(params));
101 Ok(())
102 }
103
104 fn set_scrambling(&mut self, enabled: bool) -> Result<(), Infallible> {
105 (self.on_call)(PhyCall::SetScrambling(enabled));
106 Ok(())
107 }
108}
109
110#[cfg(test)]
111#[path = "phy_tests.rs"]
112mod tests;