drivers/pwm/pwm-stm32.c
Source file repositories/reference/linux-study-clean/drivers/pwm/pwm-stm32.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/pwm/pwm-stm32.c- Extension
.c- Size
- 25483 bytes
- Lines
- 940
- 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.
- Uses kernel synchronization; read lock ordering, sleepability, and interrupt context assumptions before translating.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/bitfield.hlinux/mfd/stm32-timers.hlinux/module.hlinux/of.hlinux/pinctrl/consumer.hlinux/platform_device.hlinux/pwm.h
Detected Declarations
struct stm32_breakinputstruct stm32_pwmstruct stm32_pwm_waveformfunction active_channelsfunction stm32_pwm_round_waveform_tohwfunction stm32_pwm_round_waveform_fromhwfunction stm32_pwm_read_waveformfunction stm32_pwm_write_waveformfunction stm32_pwm_raw_capturefunction stm32_pwm_capturefunction stm32_pwm_set_breakinputfunction stm32_pwm_apply_breakinputsfunction stm32_pwm_probe_breakinputsfunction stm32_pwm_detect_complementaryfunction stm32_pwm_detect_channelsfunction stm32_pwm_probefunction stm32_pwm_suspendfunction stm32_pwm_resume
Annotated Snippet
struct stm32_breakinput {
u32 index;
u32 level;
u32 filter;
};
struct stm32_pwm {
struct mutex lock; /* protect pwm config/enable */
struct clk *clk;
struct regmap *regmap;
u32 max_arr;
bool have_complementary_output;
struct stm32_breakinput breakinputs[MAX_BREAKINPUT];
unsigned int num_breakinputs;
u32 capture[4] ____cacheline_aligned; /* DMA'able buffer */
};
static inline struct stm32_pwm *to_stm32_pwm_dev(struct pwm_chip *chip)
{
return pwmchip_get_drvdata(chip);
}
static u32 active_channels(struct stm32_pwm *dev)
{
u32 ccer;
regmap_read(dev->regmap, TIM_CCER, &ccer);
return ccer & TIM_CCER_CCXE;
}
struct stm32_pwm_waveform {
u32 ccer;
u32 psc;
u32 arr;
u32 ccr;
};
static int stm32_pwm_round_waveform_tohw(struct pwm_chip *chip,
struct pwm_device *pwm,
const struct pwm_waveform *wf,
void *_wfhw)
{
struct stm32_pwm_waveform *wfhw = _wfhw;
struct stm32_pwm *priv = to_stm32_pwm_dev(chip);
unsigned int ch = pwm->hwpwm;
unsigned long rate;
u64 duty_ticks, offset_ticks;
int ret;
if (wf->period_length_ns == 0) {
*wfhw = (struct stm32_pwm_waveform){
.ccer = 0,
};
return 0;
}
ret = clk_enable(priv->clk);
if (ret)
return ret;
wfhw->ccer = TIM_CCER_CCxE(ch + 1);
if (priv->have_complementary_output)
wfhw->ccer |= TIM_CCER_CCxNE(ch + 1);
rate = clk_get_rate(priv->clk);
if (active_channels(priv) & ~TIM_CCER_CCxE(ch + 1)) {
u64 arr;
/*
* Other channels are already enabled, so the configured PSC and
* ARR must be used for this channel, too.
*/
ret = regmap_read(priv->regmap, TIM_PSC, &wfhw->psc);
if (ret)
goto out;
ret = regmap_read(priv->regmap, TIM_ARR, &wfhw->arr);
if (ret)
goto out;
arr = mul_u64_u64_div_u64(wf->period_length_ns, rate,
(u64)NSEC_PER_SEC * (wfhw->psc + 1));
if (arr <= wfhw->arr) {
/*
* requested period is smaller than the currently
* configured and unchangable period, report back the smallest
* possible period, i.e. the current state and return 1
Annotation
- Immediate include surface: `linux/bitfield.h`, `linux/mfd/stm32-timers.h`, `linux/module.h`, `linux/of.h`, `linux/pinctrl/consumer.h`, `linux/platform_device.h`, `linux/pwm.h`.
- Detected declarations: `struct stm32_breakinput`, `struct stm32_pwm`, `struct stm32_pwm_waveform`, `function active_channels`, `function stm32_pwm_round_waveform_tohw`, `function stm32_pwm_round_waveform_fromhw`, `function stm32_pwm_read_waveform`, `function stm32_pwm_write_waveform`, `function stm32_pwm_raw_capture`, `function stm32_pwm_capture`.
- Atlas domain: Driver Families / drivers/pwm.
- Implementation status: source implementation candidate.
- Synchronization appears in or near this file; preserve lock ordering, sleepability, and interrupt-context constraints.
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.