drivers/pwm/pwm-intel-lgm.c
Source file repositories/reference/linux-study-clean/drivers/pwm/pwm-intel-lgm.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/pwm/pwm-intel-lgm.c- Extension
.c- Size
- 6123 bytes
- Lines
- 235
- 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/module.hlinux/platform_device.hlinux/mod_devicetable.hlinux/pwm.hlinux/regmap.hlinux/reset.h
Detected Declarations
struct lgm_pwm_chipfunction lgm_pwm_enablefunction lgm_pwm_applyfunction lgm_pwm_get_statefunction lgm_pwm_initfunction lgm_clk_releasefunction lgm_clk_enablefunction lgm_reset_control_releasefunction lgm_reset_control_deassertfunction lgm_pwm_probe
Annotated Snippet
struct lgm_pwm_chip {
struct regmap *regmap;
u32 period;
};
static inline struct lgm_pwm_chip *to_lgm_pwm_chip(struct pwm_chip *chip)
{
return pwmchip_get_drvdata(chip);
}
static int lgm_pwm_enable(struct pwm_chip *chip, bool enable)
{
struct lgm_pwm_chip *pc = to_lgm_pwm_chip(chip);
struct regmap *regmap = pc->regmap;
return regmap_update_bits(regmap, LGM_PWM_FAN_CON0, LGM_PWM_FAN_EN_MSK,
enable ? LGM_PWM_FAN_EN_EN : LGM_PWM_FAN_EN_DIS);
}
static int lgm_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
const struct pwm_state *state)
{
struct lgm_pwm_chip *pc = to_lgm_pwm_chip(chip);
u32 duty_cycle, val;
int ret;
/* The hardware only supports normal polarity and fixed period. */
if (state->polarity != PWM_POLARITY_NORMAL || state->period < pc->period)
return -EINVAL;
if (!state->enabled)
return lgm_pwm_enable(chip, 0);
duty_cycle = min_t(u64, state->duty_cycle, pc->period);
val = duty_cycle * LGM_PWM_MAX_DUTY_CYCLE / pc->period;
ret = regmap_update_bits(pc->regmap, LGM_PWM_FAN_CON0, LGM_PWM_FAN_DC_MSK,
FIELD_PREP(LGM_PWM_FAN_DC_MSK, val));
if (ret)
return ret;
return lgm_pwm_enable(chip, 1);
}
static int lgm_pwm_get_state(struct pwm_chip *chip, struct pwm_device *pwm,
struct pwm_state *state)
{
struct lgm_pwm_chip *pc = to_lgm_pwm_chip(chip);
u32 duty, val;
state->enabled = regmap_test_bits(pc->regmap, LGM_PWM_FAN_CON0,
LGM_PWM_FAN_EN_EN);
state->polarity = PWM_POLARITY_NORMAL;
state->period = pc->period; /* fixed period */
regmap_read(pc->regmap, LGM_PWM_FAN_CON0, &val);
duty = FIELD_GET(LGM_PWM_FAN_DC_MSK, val);
state->duty_cycle = DIV_ROUND_UP(duty * pc->period, LGM_PWM_MAX_DUTY_CYCLE);
return 0;
}
static const struct pwm_ops lgm_pwm_ops = {
.get_state = lgm_pwm_get_state,
.apply = lgm_pwm_apply,
};
static void lgm_pwm_init(struct lgm_pwm_chip *pc)
{
struct regmap *regmap = pc->regmap;
u32 con0_val;
con0_val = FIELD_PREP(LGM_PWM_FAN_MODE_MSK, LGM_PWM_FAN_MODE_2WIRE);
pc->period = LGM_PWM_PERIOD_2WIRE_NS;
regmap_update_bits(regmap, LGM_PWM_FAN_CON1, LGM_PWM_FAN_MAX_RPM_MSK,
LGM_PWM_DEFAULT_RPM);
regmap_update_bits(regmap, LGM_PWM_FAN_CON0, LGM_PWM_FAN_MODE_MSK,
con0_val);
}
static const struct regmap_config lgm_pwm_regmap_config = {
.reg_bits = 32,
.reg_stride = 4,
.val_bits = 32,
};
static void lgm_clk_release(void *data)
{
struct clk *clk = data;
Annotation
- Immediate include surface: `linux/bitfield.h`, `linux/clk.h`, `linux/module.h`, `linux/platform_device.h`, `linux/mod_devicetable.h`, `linux/pwm.h`, `linux/regmap.h`, `linux/reset.h`.
- Detected declarations: `struct lgm_pwm_chip`, `function lgm_pwm_enable`, `function lgm_pwm_apply`, `function lgm_pwm_get_state`, `function lgm_pwm_init`, `function lgm_clk_release`, `function lgm_clk_enable`, `function lgm_reset_control_release`, `function lgm_reset_control_deassert`, `function lgm_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.