drivers/counter/ti-ecap-capture.c

Source file repositories/reference/linux-study-clean/drivers/counter/ti-ecap-capture.c

File Facts

System
Linux kernel
Corpus path
drivers/counter/ti-ecap-capture.c
Extension
.c
Size
16170 bytes
Lines
611
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.

Dependency Surface

Detected Declarations

Annotated Snippet

struct ecap_cnt_dev {
	bool enabled;
	struct mutex lock;
	struct clk *clk;
	struct regmap *regmap;
	atomic_t nb_ovf;
	struct {
		u8 ev_mode;
		u32 time_cntr;
	} pm_ctx;
};

static u8 ecap_cnt_capture_get_evmode(struct counter_device *counter)
{
	struct ecap_cnt_dev *ecap_dev = counter_priv(counter);
	unsigned int regval;

	pm_runtime_get_sync(counter->parent);
	regmap_read(ecap_dev->regmap, ECAP_ECCTL_REG, &regval);
	pm_runtime_put_sync(counter->parent);

	return regval;
}

static void ecap_cnt_capture_set_evmode(struct counter_device *counter, u8 ev_mode)
{
	struct ecap_cnt_dev *ecap_dev = counter_priv(counter);

	pm_runtime_get_sync(counter->parent);
	regmap_update_bits(ecap_dev->regmap, ECAP_ECCTL_REG, ECAP_EV_MODE_MASK, ev_mode);
	pm_runtime_put_sync(counter->parent);
}

static void ecap_cnt_capture_enable(struct counter_device *counter)
{
	struct ecap_cnt_dev *ecap_dev = counter_priv(counter);

	pm_runtime_get_sync(counter->parent);

	/* Enable interrupts on events */
	regmap_update_bits(ecap_dev->regmap, ECAP_ECINT_EN_FLG_REG,
			   ECAP_EVT_EN_MASK, ECAP_EVT_EN_MASK);

	/* Run counter */
	regmap_update_bits(ecap_dev->regmap, ECAP_ECCTL_REG, ECAP_ECCTL_CFG_MASK,
			   ECAP_SYNCO_DIS_MASK | ECAP_STOPVALUE_MASK | ECAP_ECCTL_EN_MASK);
}

static void ecap_cnt_capture_disable(struct counter_device *counter)
{
	struct ecap_cnt_dev *ecap_dev = counter_priv(counter);

	/* Stop counter */
	regmap_update_bits(ecap_dev->regmap, ECAP_ECCTL_REG, ECAP_ECCTL_EN_MASK, 0);

	/* Disable interrupts on events */
	regmap_update_bits(ecap_dev->regmap, ECAP_ECINT_EN_FLG_REG, ECAP_EVT_EN_MASK, 0);

	pm_runtime_put_sync(counter->parent);
}

static u32 ecap_cnt_count_get_val(struct counter_device *counter, unsigned int reg)
{
	struct ecap_cnt_dev *ecap_dev = counter_priv(counter);
	unsigned int regval;

	pm_runtime_get_sync(counter->parent);
	regmap_read(ecap_dev->regmap, reg, &regval);
	pm_runtime_put_sync(counter->parent);

	return regval;
}

static void ecap_cnt_count_set_val(struct counter_device *counter, unsigned int reg, u32 val)
{
	struct ecap_cnt_dev *ecap_dev = counter_priv(counter);

	pm_runtime_get_sync(counter->parent);
	regmap_write(ecap_dev->regmap, reg, val);
	pm_runtime_put_sync(counter->parent);
}

static int ecap_cnt_count_read(struct counter_device *counter,
			       struct counter_count *count, u64 *val)
{
	*val = ecap_cnt_count_get_val(counter, ECAP_TSCNT_REG);

	return 0;
}

Annotation

Implementation Notes