drivers/iio/adc/xilinx-ams.c

Source file repositories/reference/linux-study-clean/drivers/iio/adc/xilinx-ams.c

File Facts

System
Linux kernel
Corpus path
drivers/iio/adc/xilinx-ams.c
Extension
.c
Size
39339 bytes
Lines
1451
Domain
Driver Families
Bucket
drivers/iio
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 ams {
	void __iomem *base;
	void __iomem *ps_base;
	void __iomem *pl_base;
	struct clk *clk;
	struct device *dev;
	struct mutex lock;
	spinlock_t intr_lock;
	unsigned int alarm_mask;
	unsigned int current_masked_alarm;
	u64 intr_mask;
	struct delayed_work ams_unmask_work;
};

static inline void ams_ps_update_reg(struct ams *ams, unsigned int offset,
				     u32 mask, u32 data)
{
	u32 val, regval;

	val = readl(ams->ps_base + offset);
	regval = (val & ~mask) | (data & mask);
	writel(regval, ams->ps_base + offset);
}

static inline void ams_pl_update_reg(struct ams *ams, unsigned int offset,
				     u32 mask, u32 data)
{
	u32 val, regval;

	val = readl(ams->pl_base + offset);
	regval = (val & ~mask) | (data & mask);
	writel(regval, ams->pl_base + offset);
}

static void ams_update_intrmask(struct ams *ams, u64 mask, u64 val)
{
	u32 regval;

	ams->intr_mask = (ams->intr_mask & ~mask) | (val & mask);

	regval = ~(ams->intr_mask | ams->current_masked_alarm);
	writel(regval, ams->base + AMS_IER_0);

	regval = ~(FIELD_GET(AMS_ISR1_INTR_MASK, ams->intr_mask));
	writel(regval, ams->base + AMS_IER_1);

	regval = ams->intr_mask | ams->current_masked_alarm;
	writel(regval, ams->base + AMS_IDR_0);

	regval = FIELD_GET(AMS_ISR1_INTR_MASK, ams->intr_mask);
	writel(regval, ams->base + AMS_IDR_1);
}

static void ams_disable_all_alarms(struct ams *ams)
{
	/* disable PS module alarm */
	if (ams->ps_base) {
		ams_ps_update_reg(ams, AMS_REG_CONFIG1, AMS_REGCFG1_ALARM_MASK,
				  AMS_REGCFG1_ALARM_MASK);
		ams_ps_update_reg(ams, AMS_REG_CONFIG3, AMS_REGCFG3_ALARM_MASK,
				  AMS_REGCFG3_ALARM_MASK);
	}

	/* disable PL module alarm */
	if (ams->pl_base) {
		ams_pl_update_reg(ams, AMS_REG_CONFIG1, AMS_REGCFG1_ALARM_MASK,
				  AMS_REGCFG1_ALARM_MASK);
		ams_pl_update_reg(ams, AMS_REG_CONFIG3, AMS_REGCFG3_ALARM_MASK,
				  AMS_REGCFG3_ALARM_MASK);
	}
}

static void ams_update_ps_alarm(struct ams *ams, unsigned long alarm_mask)
{
	u32 cfg;
	u32 val;

	val = FIELD_GET(AMS_ISR0_ALARM_2_TO_0_MASK, alarm_mask);
	cfg = ~(FIELD_PREP(AMS_CONF1_ALARM_2_TO_0_MASK, val));

	val = FIELD_GET(AMS_ISR0_ALARM_6_TO_3_MASK, alarm_mask);
	cfg &= ~(FIELD_PREP(AMS_CONF1_ALARM_6_TO_3_MASK, val));

	ams_ps_update_reg(ams, AMS_REG_CONFIG1, AMS_REGCFG1_ALARM_MASK, cfg);

	val = FIELD_GET(AMS_ISR0_ALARM_12_TO_7_MASK, alarm_mask);
	cfg = ~(FIELD_PREP(AMS_CONF1_ALARM_12_TO_7_MASK, val));
	ams_ps_update_reg(ams, AMS_REG_CONFIG3, AMS_REGCFG3_ALARM_MASK, cfg);
}

Annotation

Implementation Notes