Lines Matching +full:th1520 +full:- +full:pwm
1 // SPDX-License-Identifier: GPL-2.0
5 //! Rust T-HEAD TH1520 PWM driver
8 //! - The period and duty cycle are controlled by 32-bit hardware registers,
10 //! - The driver supports continuous output mode only; one-shot mode is not
12 //! - The controller hardware provides up to 6 PWM channels.
13 //! - Reconfiguration is glitch free - new period and duty cycle values are
15 //! - Polarity is handled via a simple hardware inversion bit; arbitrary
17 //! - Disabling a channel is achieved by configuring its duty cycle to zero to
32 pwm, time,
38 const fn th1520_pwm_chn_base(n: u32) -> usize { in th1520_pwm_chn_base()
42 const fn th1520_pwm_ctrl(n: u32) -> usize { in th1520_pwm_ctrl()
46 const fn th1520_pwm_per(n: u32) -> usize { in th1520_pwm_per()
50 const fn th1520_pwm_fp(n: u32) -> usize { in th1520_pwm_fp()
62 fn ns_to_cycles(ns: u64, rate_hz: u64) -> u64 { in ns_to_cycles()
71 fn cycles_to_ns(cycles: u64, rate_hz: u64) -> u64 { in cycles_to_ns()
78 .saturating_add(rate_hz - 1); in cycles_to_ns()
83 /// Hardware-specific waveform representation for TH1520.
106 // We can guarantee this because the PWM core synchronizes all callbacks, preventing concurrent
110 // SAFETY: The same reasoning applies as for `Send`. The PWM core's synchronization
115 impl pwm::PwmOps for Th1520PwmDriverData {
119 chip: &pwm::Chip<Self>, in round_waveform_tohw()
120 _pwm: &pwm::Device, in round_waveform_tohw()
121 wf: &pwm::Waveform, in round_waveform_tohw()
122 ) -> Result<pwm::RoundedWaveform<Self::WfHw>> { in round_waveform_tohw()
127 dev_dbg!(chip.device(), "Requested period is 0, disabling PWM.\n"); in round_waveform_tohw()
129 return Ok(pwm::RoundedWaveform { in round_waveform_tohw()
162 duty_cycles = period_cycles - duty_cycles; in round_waveform_tohw()
177 "Requested: {}/{} ns [+{} ns] -> HW: {}/{} cycles, ctrl 0x{:x}, rate {} Hz\n", in round_waveform_tohw()
187 Ok(pwm::RoundedWaveform { in round_waveform_tohw()
194 chip: &pwm::Chip<Self>, in round_waveform_fromhw()
195 _pwm: &pwm::Device, in round_waveform_fromhw()
197 wf: &mut pwm::Waveform, in round_waveform_fromhw()
198 ) -> Result { in round_waveform_fromhw()
207 *wf = pwm::Waveform::default(); in round_waveform_fromhw()
222 // For an inverted signal, `duty_length_ns` is the high time (period - low_time). in round_waveform_fromhw()
232 chip: &pwm::Chip<Self>, in read_waveform()
233 pwm: &pwm::Device, in read_waveform()
235 ) -> Result<Self::WfHw> { in read_waveform()
237 let hwpwm = pwm.hwpwm(); in read_waveform()
254 … "PWM-{}: read_waveform: Read hw state - period: {}, duty: {}, ctrl: 0x{:x}, enabled: {}", in read_waveform()
266 chip: &pwm::Chip<Self>, in write_waveform()
267 pwm: &pwm::Device, in write_waveform()
270 ) -> Result { in write_waveform()
272 let hwpwm = pwm.hwpwm(); in write_waveform()
279 dev_dbg!(chip.device(), "PWM-{}: Disabling channel.\n", hwpwm); in write_waveform()
307 "PWM-{}: Wrote {}/{} cycles", in write_waveform()
330 [(of::DeviceId::new(c_str!("thead,th1520-pwm")), ())]
340 ) -> impl PinInit<Self, Error> { in probe()
366 let chip = pwm::Chip::new( in probe()
370 iomem <- request.iomap_sized::<TH1520_PWM_REG_SIZE>(), in probe()
371 clk <- clk, in probe()
375 pwm::Registration::register(dev, chip)?; in probe()
383 name: "pwm-th1520",
385 description: "T-HEAD TH1520 PWM driver",