drivers/counter/microchip-tcb-capture.c
Source file repositories/reference/linux-study-clean/drivers/counter/microchip-tcb-capture.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/counter/microchip-tcb-capture.c- Extension
.c- Size
- 16082 bytes
- Lines
- 609
- Domain
- Driver Families
- Bucket
- drivers/counter
- 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.
- Touches IRQ or DMA behavior; this matters for the representative real-device path.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/clk.hlinux/counter.hlinux/interrupt.hlinux/mfd/syscon.hlinux/module.hlinux/mutex.hlinux/of.hlinux/of_irq.hlinux/platform_device.hlinux/regmap.huapi/linux/counter/microchip-tcb-capture.hsoc/at91/atmel_tcb.h
Detected Declarations
struct mchp_tc_datafunction mchp_tc_count_function_readfunction mchp_tc_count_function_writefunction mchp_tc_count_signal_readfunction mchp_tc_count_action_readfunction mchp_tc_count_action_writefunction mchp_tc_count_readfunction mchp_tc_count_cap_readfunction mchp_tc_count_cap_writefunction mchp_tc_count_compare_readfunction mchp_tc_count_compare_writefunction mchp_tc_watch_validatefunction mchp_tc_isrfunction mchp_tc_irq_removefunction mchp_tc_irq_enablefunction mchp_tc_clk_removefunction mchp_tc_probe
Annotated Snippet
struct mchp_tc_data {
const struct atmel_tcb_config *tc_cfg;
struct regmap *regmap;
int qdec_mode;
int num_channels;
int channel[2];
};
static const enum counter_function mchp_tc_count_functions[] = {
COUNTER_FUNCTION_INCREASE,
COUNTER_FUNCTION_QUADRATURE_X4,
};
static const enum counter_synapse_action mchp_tc_synapse_actions[] = {
COUNTER_SYNAPSE_ACTION_NONE,
COUNTER_SYNAPSE_ACTION_RISING_EDGE,
COUNTER_SYNAPSE_ACTION_FALLING_EDGE,
COUNTER_SYNAPSE_ACTION_BOTH_EDGES,
};
static struct counter_signal mchp_tc_count_signals[] = {
{
.id = 0,
.name = "Channel A",
},
{
.id = 1,
.name = "Channel B",
}
};
static struct counter_synapse mchp_tc_count_synapses[] = {
{
.actions_list = mchp_tc_synapse_actions,
.num_actions = ARRAY_SIZE(mchp_tc_synapse_actions),
.signal = &mchp_tc_count_signals[0]
},
{
.actions_list = mchp_tc_synapse_actions,
.num_actions = ARRAY_SIZE(mchp_tc_synapse_actions),
.signal = &mchp_tc_count_signals[1]
}
};
static int mchp_tc_count_function_read(struct counter_device *counter,
struct counter_count *count,
enum counter_function *function)
{
struct mchp_tc_data *const priv = counter_priv(counter);
if (priv->qdec_mode)
*function = COUNTER_FUNCTION_QUADRATURE_X4;
else
*function = COUNTER_FUNCTION_INCREASE;
return 0;
}
static int mchp_tc_count_function_write(struct counter_device *counter,
struct counter_count *count,
enum counter_function function)
{
struct mchp_tc_data *const priv = counter_priv(counter);
u32 bmr, cmr;
regmap_read(priv->regmap, ATMEL_TC_BMR, &bmr);
regmap_read(priv->regmap, ATMEL_TC_REG(priv->channel[0], CMR), &cmr);
/* Set capture mode */
cmr &= ~ATMEL_TC_WAVE;
switch (function) {
case COUNTER_FUNCTION_INCREASE:
priv->qdec_mode = 0;
/* Set highest rate based on whether soc has gclk or not */
bmr &= ~(ATMEL_TC_QDEN | ATMEL_TC_POSEN);
if (!priv->tc_cfg->has_gclk)
cmr |= ATMEL_TC_TIMER_CLOCK2;
else
cmr |= ATMEL_TC_TIMER_CLOCK1;
/* Setup the period capture mode */
cmr |= ATMEL_TC_CMR_MASK;
cmr &= ~(ATMEL_TC_ABETRG | ATMEL_TC_XC0);
break;
case COUNTER_FUNCTION_QUADRATURE_X4:
if (!priv->tc_cfg->has_qdec)
return -EINVAL;
/* In QDEC mode settings both channels 0 and 1 are required */
if (priv->num_channels < 2 || priv->channel[0] != 0 ||
priv->channel[1] != 1) {
Annotation
- Immediate include surface: `linux/clk.h`, `linux/counter.h`, `linux/interrupt.h`, `linux/mfd/syscon.h`, `linux/module.h`, `linux/mutex.h`, `linux/of.h`, `linux/of_irq.h`.
- Detected declarations: `struct mchp_tc_data`, `function mchp_tc_count_function_read`, `function mchp_tc_count_function_write`, `function mchp_tc_count_signal_read`, `function mchp_tc_count_action_read`, `function mchp_tc_count_action_write`, `function mchp_tc_count_read`, `function mchp_tc_count_cap_read`, `function mchp_tc_count_cap_write`, `function mchp_tc_count_compare_read`.
- Atlas domain: Driver Families / drivers/counter.
- Implementation status: source implementation candidate.
- IRQ or DMA behavior appears here, which is relevant to the selected PCIe/NVMe device path.
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.