drivers/pwm/pwm-tiecap.c
Source file repositories/reference/linux-study-clean/drivers/pwm/pwm-tiecap.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/pwm/pwm-tiecap.c- Extension
.c- Size
- 7837 bytes
- Lines
- 338
- 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/io.hlinux/err.hlinux/clk.hlinux/pm_runtime.hlinux/pwm.hlinux/of.h
Detected Declarations
struct ecap_contextstruct ecap_pwm_chipfunction ecap_pwm_configfunction ecap_pwm_set_polarityfunction ecap_pwm_enablefunction ecap_pwm_disablefunction ecap_pwm_applyfunction ecap_pwm_probefunction ecap_pwm_removefunction ecap_pwm_save_contextfunction ecap_pwm_restore_contextfunction ecap_pwm_suspendfunction ecap_pwm_resume
Annotated Snippet
struct ecap_context {
u32 cap3;
u32 cap4;
u16 ecctl2;
};
struct ecap_pwm_chip {
unsigned int clk_rate;
void __iomem *mmio_base;
struct ecap_context ctx;
};
static inline struct ecap_pwm_chip *to_ecap_pwm_chip(struct pwm_chip *chip)
{
return pwmchip_get_drvdata(chip);
}
/*
* period_ns = 10^9 * period_cycles / PWM_CLK_RATE
* duty_ns = 10^9 * duty_cycles / PWM_CLK_RATE
*/
static int ecap_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
int duty_ns, int period_ns, int enabled)
{
struct ecap_pwm_chip *pc = to_ecap_pwm_chip(chip);
u32 period_cycles, duty_cycles;
unsigned long long c;
u16 value;
c = pc->clk_rate;
c = c * period_ns;
do_div(c, NSEC_PER_SEC);
period_cycles = (u32)c;
if (period_cycles < 1) {
period_cycles = 1;
duty_cycles = 1;
} else {
c = pc->clk_rate;
c = c * duty_ns;
do_div(c, NSEC_PER_SEC);
duty_cycles = (u32)c;
}
pm_runtime_get_sync(pwmchip_parent(chip));
value = readw(pc->mmio_base + ECCTL2);
/* Configure APWM mode & disable sync option */
value |= ECCTL2_APWM_MODE | ECCTL2_SYNC_SEL_DISA;
writew(value, pc->mmio_base + ECCTL2);
if (!enabled) {
/* Update active registers if not running */
writel(duty_cycles, pc->mmio_base + CAP2);
writel(period_cycles, pc->mmio_base + CAP1);
} else {
/*
* Update shadow registers to configure period and
* compare values. This helps current PWM period to
* complete on reconfiguring
*/
writel(duty_cycles, pc->mmio_base + CAP4);
writel(period_cycles, pc->mmio_base + CAP3);
}
if (!enabled) {
value = readw(pc->mmio_base + ECCTL2);
/* Disable APWM mode to put APWM output Low */
value &= ~ECCTL2_APWM_MODE;
writew(value, pc->mmio_base + ECCTL2);
}
pm_runtime_put_sync(pwmchip_parent(chip));
return 0;
}
static int ecap_pwm_set_polarity(struct pwm_chip *chip, struct pwm_device *pwm,
enum pwm_polarity polarity)
{
struct ecap_pwm_chip *pc = to_ecap_pwm_chip(chip);
u16 value;
pm_runtime_get_sync(pwmchip_parent(chip));
value = readw(pc->mmio_base + ECCTL2);
if (polarity == PWM_POLARITY_INVERSED)
Annotation
- Immediate include surface: `linux/module.h`, `linux/platform_device.h`, `linux/io.h`, `linux/err.h`, `linux/clk.h`, `linux/pm_runtime.h`, `linux/pwm.h`, `linux/of.h`.
- Detected declarations: `struct ecap_context`, `struct ecap_pwm_chip`, `function ecap_pwm_config`, `function ecap_pwm_set_polarity`, `function ecap_pwm_enable`, `function ecap_pwm_disable`, `function ecap_pwm_apply`, `function ecap_pwm_probe`, `function ecap_pwm_remove`, `function ecap_pwm_save_context`.
- 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.