drivers/pwm/pwm-mtk-disp.c
Source file repositories/reference/linux-study-clean/drivers/pwm/pwm-mtk-disp.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/pwm/pwm-mtk-disp.c- Extension
.c- Size
- 8532 bytes
- Lines
- 318
- 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/bitfield.hlinux/clk.hlinux/err.hlinux/io.hlinux/module.hlinux/of.hlinux/platform_device.hlinux/pwm.hlinux/slab.h
Detected Declarations
struct mtk_pwm_datastruct mtk_disp_pwmfunction mtk_disp_pwm_update_bitsfunction mtk_disp_pwm_applyfunction mtk_disp_pwm_get_statefunction mtk_disp_pwm_probe
Annotated Snippet
struct mtk_pwm_data {
u32 enable_mask;
unsigned int con0;
u32 con0_sel;
unsigned int con1;
bool has_commit;
unsigned int commit;
unsigned int commit_mask;
unsigned int bls_debug;
u32 bls_debug_mask;
};
struct mtk_disp_pwm {
const struct mtk_pwm_data *data;
struct clk *clk_main;
struct clk *clk_mm;
void __iomem *base;
bool enabled;
};
static inline struct mtk_disp_pwm *to_mtk_disp_pwm(struct pwm_chip *chip)
{
return pwmchip_get_drvdata(chip);
}
static void mtk_disp_pwm_update_bits(struct mtk_disp_pwm *mdp, u32 offset,
u32 mask, u32 data)
{
void __iomem *address = mdp->base + offset;
u32 value;
value = readl(address);
value &= ~mask;
value |= data;
writel(value, address);
}
static int mtk_disp_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
const struct pwm_state *state)
{
struct mtk_disp_pwm *mdp = to_mtk_disp_pwm(chip);
u32 clk_div, period, high_width, value;
u64 div, rate;
int err;
if (state->polarity != PWM_POLARITY_NORMAL)
return -EINVAL;
if (!state->enabled && mdp->enabled) {
mtk_disp_pwm_update_bits(mdp, DISP_PWM_EN,
mdp->data->enable_mask, 0x0);
clk_disable_unprepare(mdp->clk_mm);
clk_disable_unprepare(mdp->clk_main);
mdp->enabled = false;
return 0;
}
if (!mdp->enabled) {
err = clk_prepare_enable(mdp->clk_main);
if (err < 0) {
dev_err(pwmchip_parent(chip), "Can't enable mdp->clk_main: %pe\n",
ERR_PTR(err));
return err;
}
err = clk_prepare_enable(mdp->clk_mm);
if (err < 0) {
dev_err(pwmchip_parent(chip), "Can't enable mdp->clk_mm: %pe\n",
ERR_PTR(err));
clk_disable_unprepare(mdp->clk_main);
return err;
}
}
/*
* Find period, high_width and clk_div to suit duty_ns and period_ns.
* Calculate proper div value to keep period value in the bound.
*
* period_ns = 10^9 * (clk_div + 1) * (period + 1) / PWM_CLK_RATE
* duty_ns = 10^9 * (clk_div + 1) * high_width / PWM_CLK_RATE
*
* period = (PWM_CLK_RATE * period_ns) / (10^9 * (clk_div + 1)) - 1
* high_width = (PWM_CLK_RATE * duty_ns) / (10^9 * (clk_div + 1))
*/
rate = clk_get_rate(mdp->clk_main);
clk_div = mul_u64_u64_div_u64(state->period, rate, NSEC_PER_SEC) >>
PWM_PERIOD_BIT_WIDTH;
Annotation
- Immediate include surface: `linux/bitfield.h`, `linux/clk.h`, `linux/err.h`, `linux/io.h`, `linux/module.h`, `linux/of.h`, `linux/platform_device.h`, `linux/pwm.h`.
- Detected declarations: `struct mtk_pwm_data`, `struct mtk_disp_pwm`, `function mtk_disp_pwm_update_bits`, `function mtk_disp_pwm_apply`, `function mtk_disp_pwm_get_state`, `function mtk_disp_pwm_probe`.
- 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.