Skip to main content

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;