drivers/pwm/pwm-airoha.c
Source file repositories/reference/linux-study-clean/drivers/pwm/pwm-airoha.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/pwm/pwm-airoha.c- Extension
.c- Size
- 19014 bytes
- Lines
- 623
- 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/array_size.hlinux/bitfield.hlinux/bitmap.hlinux/err.hlinux/io.hlinux/iopoll.hlinux/math64.hlinux/mfd/syscon.hlinux/module.hlinux/mod_devicetable.hlinux/platform_device.hlinux/pwm.hlinux/regmap.hlinux/types.h
Detected Declarations
struct airoha_pwm_bucketstruct airoha_pwmfunction airoha_pwm_get_flash_map_addr_and_shiftfunction airoha_pwm_get_period_ticks_from_nsfunction airoha_pwm_get_duty_ticks_from_nsfunction airoha_pwm_get_period_ns_from_ticksfunction airoha_pwm_get_duty_ns_from_ticksfunction airoha_pwm_get_bucketfunction airoha_pwm_get_generatorfunction airoha_pwm_release_bucket_configfunction airoha_pwm_apply_bucket_configfunction airoha_pwm_consume_generatorfunction airoha_pwm_sipo_initfunction airoha_pwm_config_flash_mapfunction airoha_pwm_configfunction disabledfunction airoha_pwm_disablefunction airoha_pwm_applyfunction airoha_pwm_get_statefunction airoha_pwm_probe
Annotated Snippet
struct airoha_pwm_bucket {
/* Concurrent access protected by PWM core */
int used;
u32 period_ticks;
u32 duty_ticks;
};
struct airoha_pwm {
struct regmap *regmap;
DECLARE_BITMAP(initialized, AIROHA_PWM_MAX_CHANNELS);
struct airoha_pwm_bucket buckets[AIROHA_PWM_NUM_BUCKETS];
/* Cache bucket used by each pwm channel */
u8 channel_bucket[AIROHA_PWM_MAX_CHANNELS];
};
/* The PWM hardware supports periods between 4 ms and 1 s */
#define AIROHA_PWM_PERIOD_TICK_NS (4 * NSEC_PER_MSEC)
#define AIROHA_PWM_PERIOD_MAX_NS (1 * NSEC_PER_SEC)
/* It is represented internally as 1/250 s between 1 and 250. Unit is ticks. */
#define AIROHA_PWM_PERIOD_MIN 1
#define AIROHA_PWM_PERIOD_MAX 250
/* Duty cycle is relative with 255 corresponding to 100% */
#define AIROHA_PWM_DUTY_FULL 255
static void airoha_pwm_get_flash_map_addr_and_shift(unsigned int hwpwm,
u32 *addr, u32 *shift)
{
unsigned int offset, hwpwm_bit;
if (hwpwm >= AIROHA_PWM_NUM_GPIO) {
unsigned int sipohwpwm = hwpwm - AIROHA_PWM_NUM_GPIO;
offset = sipohwpwm / AIROHA_PWM_PINS_PER_FLASH_MAP;
hwpwm_bit = sipohwpwm % AIROHA_PWM_PINS_PER_FLASH_MAP;
/* One FLASH_MAP register handles 8 pins */
*shift = AIROHA_PWM_REG_GPIO_FLASH_MAP_SHIFT(hwpwm_bit);
*addr = AIROHA_PWM_REG_SIPO_FLASH_MAP(offset);
} else {
offset = hwpwm / AIROHA_PWM_PINS_PER_FLASH_MAP;
hwpwm_bit = hwpwm % AIROHA_PWM_PINS_PER_FLASH_MAP;
/* One FLASH_MAP register handles 8 pins */
*shift = AIROHA_PWM_REG_GPIO_FLASH_MAP_SHIFT(hwpwm_bit);
*addr = AIROHA_PWM_REG_GPIO_FLASH_MAP(offset);
}
}
static u32 airoha_pwm_get_period_ticks_from_ns(u32 period_ns)
{
return period_ns / AIROHA_PWM_PERIOD_TICK_NS;
}
static u32 airoha_pwm_get_duty_ticks_from_ns(u32 period_ns, u32 duty_ns)
{
return mul_u64_u32_div(duty_ns, AIROHA_PWM_DUTY_FULL, period_ns);
}
static u32 airoha_pwm_get_period_ns_from_ticks(u32 period_tick)
{
return period_tick * AIROHA_PWM_PERIOD_TICK_NS;
}
static u32 airoha_pwm_get_duty_ns_from_ticks(u32 period_tick, u32 duty_tick)
{
u32 period_ns = period_tick * AIROHA_PWM_PERIOD_TICK_NS;
/*
* Overflow can't occur in multiplication as duty_tick is just 8 bit
* and period_ns is clamped to AIROHA_PWM_PERIOD_MAX_NS and fit in a
* u64.
*/
return DIV_U64_ROUND_UP(duty_tick * period_ns, AIROHA_PWM_DUTY_FULL);
}
static int airoha_pwm_get_bucket(struct airoha_pwm *pc, int bucket,
u64 *period_ns, u64 *duty_ns)
{
struct regmap *map = pc->regmap;
u32 period_tick, duty_tick;
unsigned int offset;
u32 shift, val;
int ret;
offset = bucket / AIROHA_PWM_BUCKET_PER_CYCLE_CFG;
shift = bucket % AIROHA_PWM_BUCKET_PER_CYCLE_CFG;
shift = AIROHA_PWM_REG_CYCLE_CFG_SHIFT(shift);
Annotation
- Immediate include surface: `linux/array_size.h`, `linux/bitfield.h`, `linux/bitmap.h`, `linux/err.h`, `linux/io.h`, `linux/iopoll.h`, `linux/math64.h`, `linux/mfd/syscon.h`.
- Detected declarations: `struct airoha_pwm_bucket`, `struct airoha_pwm`, `function airoha_pwm_get_flash_map_addr_and_shift`, `function airoha_pwm_get_period_ticks_from_ns`, `function airoha_pwm_get_duty_ticks_from_ns`, `function airoha_pwm_get_period_ns_from_ticks`, `function airoha_pwm_get_duty_ns_from_ticks`, `function airoha_pwm_get_bucket`, `function airoha_pwm_get_generator`, `function airoha_pwm_release_bucket_config`.
- 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.