drivers/pwm/pwm_th1520.rs
Source file repositories/reference/linux-study-clean/drivers/pwm/pwm_th1520.rs
File Facts
- System
- Linux kernel
- Corpus path
drivers/pwm/pwm_th1520.rs- Extension
.rs- Size
- 11077 bytes
- Lines
- 367
- Domain
- Driver Families
- Bucket
- drivers/pwm
- Inferred role
- Driver Families: implementation source
- Status
- source implementation candidate
Why This File Exists
Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.
- Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
- No C-style include directives detected by the generator.
Detected Declarations
struct Th1520WfHwstruct Th1520PwmDriverDatastruct Th1520PwmPlatformDriverfunction Ok
Annotated Snippet
struct Th1520WfHw {
period_cycles: u32,
duty_cycles: u32,
ctrl_val: u32,
enabled: bool,
}
/// The driver's private data struct. It holds all necessary devres managed resources.
#[pin_data(PinnedDrop)]
struct Th1520PwmDriverData {
#[pin]
iomem: devres::Devres<IoMem<'static, TH1520_PWM_REG_SIZE>>,
clk: Clk,
}
impl pwm::PwmOps for Th1520PwmDriverData {
type WfHw = Th1520WfHw;
fn round_waveform_tohw(
chip: &pwm::Chip<Self>,
_pwm: &pwm::Device,
wf: &pwm::Waveform,
) -> Result<pwm::RoundedWaveform<Self::WfHw>> {
let data = chip.drvdata();
let mut status = 0;
if wf.period_length_ns == 0 {
dev_dbg!(chip.device(), "Requested period is 0, disabling PWM.\n");
return Ok(pwm::RoundedWaveform {
status: 0,
hardware_waveform: Th1520WfHw {
enabled: false,
..Default::default()
},
});
}
let rate_hz = data.clk.rate().as_hz() as u64;
let mut period_cycles = ns_to_cycles(wf.period_length_ns, rate_hz).min(u64::from(u32::MAX));
if period_cycles == 0 {
dev_dbg!(
chip.device(),
"Requested period {} ns is too small for clock rate {} Hz, rounding up.\n",
wf.period_length_ns,
rate_hz
);
period_cycles = 1;
status = 1;
}
let mut duty_cycles = ns_to_cycles(wf.duty_length_ns, rate_hz).min(u64::from(u32::MAX));
let mut ctrl_val = TH1520_PWM_CONTINUOUS_MODE;
let is_inversed = wf.duty_length_ns > 0
&& wf.duty_offset_ns > 0
&& wf.duty_offset_ns >= wf.period_length_ns.saturating_sub(wf.duty_length_ns);
if is_inversed {
duty_cycles = period_cycles - duty_cycles;
} else {
ctrl_val |= TH1520_PWM_FPOUT;
}
let wfhw = Th1520WfHw {
// The cast is safe because the value was clamped with `.min(u64::from(u32::MAX))`.
period_cycles: period_cycles as u32,
duty_cycles: duty_cycles as u32,
ctrl_val,
enabled: true,
};
dev_dbg!(
chip.device(),
"Requested: {}/{} ns [+{} ns] -> HW: {}/{} cycles, ctrl 0x{:x}, rate {} Hz\n",
wf.duty_length_ns,
wf.period_length_ns,
wf.duty_offset_ns,
wfhw.duty_cycles,
wfhw.period_cycles,
wfhw.ctrl_val,
rate_hz
);
Ok(pwm::RoundedWaveform {
status,
hardware_waveform: wfhw,
Annotation
- Detected declarations: `struct Th1520WfHw`, `struct Th1520PwmDriverData`, `struct Th1520PwmPlatformDriver`, `function Ok`.
- Atlas domain: Driver Families / drivers/pwm.
- Implementation status: source implementation candidate.
Implementation Notes
- This generated page is the file-by-file coverage layer; curated subsystem chapters should link here when they synthesize a multi-file control flow.
- Core OS pages should be promoted from atlas-only to deep-reviewed when they explain data structures, invariants, locking, lifecycle, and C implementation snippets.
- Driver-family pages are intentionally pattern-oriented unless they are part of the selected PCIe/NVMe representative device path.