drivers/iio/trigger/stm32-timer-trigger.c
Source file repositories/reference/linux-study-clean/drivers/iio/trigger/stm32-timer-trigger.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/iio/trigger/stm32-timer-trigger.c- Extension
.c- Size
- 23421 bytes
- Lines
- 943
- Domain
- Driver Families
- Bucket
- drivers/iio
- Inferred role
- Driver Families: exported/initcall integration point
- Status
- integration 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.
- Exports symbols or registers init work; inspect boot/module ordering and who consumes the exported contract.
- Uses kernel synchronization; read lock ordering, sleepability, and interrupt context assumptions before translating.
- Allocates kernel memory; connect allocation flags and lifetime to context constraints.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/export.hlinux/iio/iio.hlinux/iio/sysfs.hlinux/iio/timer/stm32-timer-trigger.hlinux/iio/trigger.hlinux/mfd/stm32-timers.hlinux/mod_devicetable.hlinux/module.hlinux/platform_device.hlinux/property.h
Detected Declarations
struct stm32_timer_trigger_regsstruct stm32_timer_triggerstruct stm32_timer_trigger_cfgfunction stm32_timer_is_trgo2_namefunction stm32_timer_is_trgo_namefunction stm32_timer_startfunction stm32_timer_stopfunction stm32_tt_store_frequencyfunction stm32_tt_read_frequencyfunction stm32_tt_show_master_modefunction stm32_tt_store_master_modefunction stm32_tt_show_master_mode_availfunction stm32_unregister_iio_triggersfunction stm32_register_iio_triggersfunction stm32_counter_read_rawfunction stm32_counter_write_rawfunction stm32_counter_validate_triggerfunction stm32_set_trigger_modefunction stm32_get_trigger_modefunction stm32_enable_mode2smsfunction stm32_set_enable_modefunction stm32_sms2enable_modefunction stm32_get_enable_modefunction stm32_count_get_presetfunction stm32_count_set_presetfunction is_stm32_timer_triggerfunction stm32_timer_detect_trgo2function stm32_timer_trigger_probefunction stm32_timer_trigger_removefunction stm32_timer_trigger_suspendfunction stm32_timer_trigger_resumeexport is_stm32_timer_trigger
Annotated Snippet
struct stm32_timer_trigger_regs {
u32 cr1;
u32 cr2;
u32 psc;
u32 arr;
u32 cnt;
u32 smcr;
};
struct stm32_timer_trigger {
struct device *dev;
struct regmap *regmap;
struct clk *clk;
bool enabled;
u32 max_arr;
const void *triggers;
const void *valids;
bool has_trgo2;
struct mutex lock; /* concurrent sysfs configuration */
struct list_head tr_list;
struct stm32_timer_trigger_regs bak;
};
struct stm32_timer_trigger_cfg {
const void *(*valids_table)[MAX_VALIDS];
const unsigned int num_valids_table;
};
static bool stm32_timer_is_trgo2_name(const char *name)
{
return !!strstr(name, "trgo2");
}
static bool stm32_timer_is_trgo_name(const char *name)
{
return (!!strstr(name, "trgo") && !strstr(name, "trgo2"));
}
static int stm32_timer_start(struct stm32_timer_trigger *priv,
struct iio_trigger *trig,
unsigned int frequency)
{
unsigned long long prd, div;
int prescaler = 0, ret;
u32 ccer;
/* Period and prescaler values depends of clock rate */
div = (unsigned long long)clk_get_rate(priv->clk);
do_div(div, frequency);
prd = div;
/*
* Increase prescaler value until we get a result that fit
* with auto reload register maximum value.
*/
while (div > priv->max_arr) {
prescaler++;
div = prd;
do_div(div, (prescaler + 1));
}
prd = div;
if (prescaler > MAX_TIM_PSC) {
dev_err(priv->dev, "prescaler exceeds the maximum value\n");
return -EINVAL;
}
/* Check if nobody else use the timer */
regmap_read(priv->regmap, TIM_CCER, &ccer);
if (ccer & TIM_CCER_CCXE)
return -EBUSY;
guard(mutex)(&priv->lock);
if (!priv->enabled) {
priv->enabled = true;
ret = clk_enable(priv->clk);
if (ret)
return ret;
}
regmap_write(priv->regmap, TIM_PSC, prescaler);
regmap_write(priv->regmap, TIM_ARR, prd - 1);
regmap_set_bits(priv->regmap, TIM_CR1, TIM_CR1_ARPE);
/* Force master mode to update mode */
if (stm32_timer_is_trgo2_name(trig->name))
regmap_update_bits(priv->regmap, TIM_CR2, TIM_CR2_MMS2,
0x2 << TIM_CR2_MMS2_SHIFT);
Annotation
- Immediate include surface: `linux/export.h`, `linux/iio/iio.h`, `linux/iio/sysfs.h`, `linux/iio/timer/stm32-timer-trigger.h`, `linux/iio/trigger.h`, `linux/mfd/stm32-timers.h`, `linux/mod_devicetable.h`, `linux/module.h`.
- Detected declarations: `struct stm32_timer_trigger_regs`, `struct stm32_timer_trigger`, `struct stm32_timer_trigger_cfg`, `function stm32_timer_is_trgo2_name`, `function stm32_timer_is_trgo_name`, `function stm32_timer_start`, `function stm32_timer_stop`, `function stm32_tt_store_frequency`, `function stm32_tt_read_frequency`, `function stm32_tt_show_master_mode`.
- Atlas domain: Driver Families / drivers/iio.
- Implementation status: integration implementation candidate.
- Synchronization appears in or near this file; preserve lock ordering, sleepability, and interrupt-context constraints.
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.