drivers/pwm/pwm-max7360.c
Source file repositories/reference/linux-study-clean/drivers/pwm/pwm-max7360.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/pwm/pwm-max7360.c- Extension
.c- Size
- 5932 bytes
- Lines
- 211
- 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/bits.hlinux/dev_printk.hlinux/err.hlinux/math64.hlinux/mfd/max7360.hlinux/minmax.hlinux/mod_devicetable.hlinux/module.hlinux/platform_device.hlinux/pwm.hlinux/regmap.hlinux/time.hlinux/types.h
Detected Declarations
struct max7360_pwm_waveformfunction max7360_pwm_requestfunction max7360_pwm_round_waveform_tohwfunction max7360_pwm_round_waveform_fromhwfunction max7360_pwm_write_waveformfunction max7360_pwm_read_waveformfunction max7360_pwm_probe
Annotated Snippet
struct max7360_pwm_waveform {
u8 duty_steps;
bool enabled;
};
static int max7360_pwm_request(struct pwm_chip *chip, struct pwm_device *pwm)
{
struct regmap *regmap = pwmchip_get_drvdata(chip);
/*
* Make sure we use the individual PWM configuration register and not
* the global one.
* We never need to use the global one, so there is no need to revert
* that in the .free() callback.
*/
return regmap_write_bits(regmap, MAX7360_REG_PWMCFG(pwm->hwpwm),
MAX7360_PORT_CFG_COMMON_PWM, 0);
}
static int max7360_pwm_round_waveform_tohw(struct pwm_chip *chip,
struct pwm_device *pwm,
const struct pwm_waveform *wf,
void *_wfhw)
{
struct max7360_pwm_waveform *wfhw = _wfhw;
u64 duty_steps;
/*
* Ignore user provided values for period_length_ns and duty_offset_ns:
* we only support fixed period of MAX7360_PWM_PERIOD_NS and offset of 0.
* Values from 0 to 254 as duty_steps will provide duty cycles of 0/256
* to 254/256, while value 255 will provide a duty cycle of 100%.
*/
if (wf->duty_length_ns >= MAX7360_PWM_PERIOD_NS) {
duty_steps = MAX7360_PWM_MAX;
} else {
duty_steps = (u32)wf->duty_length_ns * MAX7360_PWM_STEPS / MAX7360_PWM_PERIOD_NS;
if (duty_steps == MAX7360_PWM_MAX)
duty_steps = MAX7360_PWM_MAX - 1;
}
wfhw->duty_steps = duty_steps;
wfhw->enabled = !!wf->period_length_ns;
if (wf->period_length_ns && wf->period_length_ns < MAX7360_PWM_PERIOD_NS)
return 1;
else
return 0;
}
static int max7360_pwm_round_waveform_fromhw(struct pwm_chip *chip, struct pwm_device *pwm,
const void *_wfhw, struct pwm_waveform *wf)
{
const struct max7360_pwm_waveform *wfhw = _wfhw;
wf->period_length_ns = wfhw->enabled ? MAX7360_PWM_PERIOD_NS : 0;
wf->duty_offset_ns = 0;
if (wfhw->enabled) {
if (wfhw->duty_steps == MAX7360_PWM_MAX)
wf->duty_length_ns = MAX7360_PWM_PERIOD_NS;
else
wf->duty_length_ns = DIV_ROUND_UP(wfhw->duty_steps * MAX7360_PWM_PERIOD_NS,
MAX7360_PWM_STEPS);
} else {
wf->duty_length_ns = 0;
}
return 0;
}
static int max7360_pwm_write_waveform(struct pwm_chip *chip,
struct pwm_device *pwm,
const void *_wfhw)
{
struct regmap *regmap = pwmchip_get_drvdata(chip);
const struct max7360_pwm_waveform *wfhw = _wfhw;
unsigned int val;
int ret;
if (wfhw->enabled) {
ret = regmap_write(regmap, MAX7360_REG_PWM(pwm->hwpwm), wfhw->duty_steps);
if (ret)
return ret;
}
val = wfhw->enabled ? BIT(pwm->hwpwm) : 0;
return regmap_write_bits(regmap, MAX7360_REG_GPIOCTRL, BIT(pwm->hwpwm), val);
}
Annotation
- Immediate include surface: `linux/bits.h`, `linux/dev_printk.h`, `linux/err.h`, `linux/math64.h`, `linux/mfd/max7360.h`, `linux/minmax.h`, `linux/mod_devicetable.h`, `linux/module.h`.
- Detected declarations: `struct max7360_pwm_waveform`, `function max7360_pwm_request`, `function max7360_pwm_round_waveform_tohw`, `function max7360_pwm_round_waveform_fromhw`, `function max7360_pwm_write_waveform`, `function max7360_pwm_read_waveform`, `function max7360_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.