drivers/pwm/pwm-tiehrpwm.c
Source file repositories/reference/linux-study-clean/drivers/pwm/pwm-tiehrpwm.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/pwm/pwm-tiehrpwm.c- Extension
.c- Size
- 14994 bytes
- Lines
- 579
- 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
linux/module.hlinux/platform_device.hlinux/pwm.hlinux/io.hlinux/err.hlinux/clk.hlinux/pm_runtime.hlinux/of.h
Detected Declarations
struct ehrpwm_contextstruct ehrpwm_pwm_chipfunction ehrpwm_readfunction ehrpwm_writefunction ehrpwm_modifyfunction set_prescale_divfunction ehrpwm_pwm_configfunction ehrpwm_pwm_enablefunction ehrpwm_pwm_disablefunction ehrpwm_pwm_freefunction ehrpwm_pwm_applyfunction ehrpwm_pwm_probefunction ehrpwm_pwm_removefunction ehrpwm_pwm_save_contextfunction ehrpwm_pwm_restore_contextfunction ehrpwm_pwm_suspendfunction ehrpwm_pwm_resume
Annotated Snippet
struct ehrpwm_context {
u16 tbctl;
u16 tbprd;
u16 cmpa;
u16 cmpb;
u16 aqctla;
u16 aqctlb;
u16 aqsfrc;
u16 aqcsfrc;
};
struct ehrpwm_pwm_chip {
unsigned long clk_rate;
void __iomem *mmio_base;
unsigned long period_cycles[NUM_PWM_CHANNEL];
struct clk *tbclk;
struct ehrpwm_context ctx;
};
static inline struct ehrpwm_pwm_chip *to_ehrpwm_pwm_chip(struct pwm_chip *chip)
{
return pwmchip_get_drvdata(chip);
}
static inline u16 ehrpwm_read(void __iomem *base, unsigned int offset)
{
return readw(base + offset);
}
static inline void ehrpwm_write(void __iomem *base, unsigned int offset,
u16 value)
{
writew(value, base + offset);
}
static void ehrpwm_modify(void __iomem *base, unsigned int offset, u16 mask,
u16 value)
{
unsigned short val;
val = readw(base + offset);
val &= ~mask;
val |= value & mask;
writew(val, base + offset);
}
/**
* set_prescale_div - Set up the prescaler divider function
* @rqst_prescaler: prescaler value min
* @prescale_div: prescaler value set
* @tb_clk_div: Time Base Control prescaler bits
*/
static int set_prescale_div(unsigned long rqst_prescaler, u16 *prescale_div,
u16 *tb_clk_div)
{
unsigned int clkdiv, hspclkdiv;
for (clkdiv = 0; clkdiv <= CLKDIV_MAX; clkdiv++) {
for (hspclkdiv = 0; hspclkdiv <= HSPCLKDIV_MAX; hspclkdiv++) {
/*
* calculations for prescaler value :
* prescale_div = HSPCLKDIVIDER * CLKDIVIDER.
* HSPCLKDIVIDER = 2 ** hspclkdiv
* CLKDIVIDER = (1), if clkdiv == 0 *OR*
* (2 * clkdiv), if clkdiv != 0
*
* Configure prescale_div value such that period
* register value is less than 65535.
*/
*prescale_div = (1 << clkdiv) *
(hspclkdiv ? (hspclkdiv * 2) : 1);
if (*prescale_div >= rqst_prescaler) {
*tb_clk_div = (clkdiv << TBCTL_CLKDIV_SHIFT) |
(hspclkdiv << TBCTL_HSPCLKDIV_SHIFT);
return 0;
}
}
}
return 1;
}
/*
* period_ns = 10^9 * (ps_divval * period_cycles) / PWM_CLK_RATE
* duty_ns = 10^9 * (ps_divval * duty_cycles) / PWM_CLK_RATE
*/
static int ehrpwm_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
u64 duty_ns, u64 period_ns, enum pwm_polarity polarity)
{
Annotation
- Immediate include surface: `linux/module.h`, `linux/platform_device.h`, `linux/pwm.h`, `linux/io.h`, `linux/err.h`, `linux/clk.h`, `linux/pm_runtime.h`, `linux/of.h`.
- Detected declarations: `struct ehrpwm_context`, `struct ehrpwm_pwm_chip`, `function ehrpwm_read`, `function ehrpwm_write`, `function ehrpwm_modify`, `function set_prescale_div`, `function ehrpwm_pwm_config`, `function ehrpwm_pwm_enable`, `function ehrpwm_pwm_disable`, `function ehrpwm_pwm_free`.
- 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.