drivers/iio/adc/npcm_adc.c

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

File Facts

System
Linux kernel
Corpus path
drivers/iio/adc/npcm_adc.c
Extension
.c
Size
8743 bytes
Lines
343
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 npcm_adc_info {
	u32 data_mask;
	u32 internal_vref;
	u32 res_bits;
};

struct npcm_adc {
	bool int_status;
	u32 adc_sample_hz;
	struct device *dev;
	void __iomem *regs;
	struct clk *adc_clk;
	wait_queue_head_t wq;
	struct regulator *vref;
	struct reset_control *reset;
	/*
	 * Lock to protect the device state during a potential concurrent
	 * read access from userspace. Reading a raw value requires a sequence
	 * of register writes, then a wait for a event and finally a register
	 * read, during which userspace could issue another read request.
	 * This lock protects a read access from occurring before another one
	 * has finished.
	 */
	struct mutex lock;
	const struct npcm_adc_info *data;
};

/* ADC registers */
#define NPCM_ADCCON	 0x00
#define NPCM_ADCDATA	 0x04

/* ADCCON Register Bits */
#define NPCM_ADCCON_ADC_INT_EN		BIT(21)
#define NPCM_ADCCON_REFSEL		BIT(19)
#define NPCM_ADCCON_ADC_INT_ST		BIT(18)
#define NPCM_ADCCON_ADC_EN		BIT(17)
#define NPCM_ADCCON_ADC_RST		BIT(16)
#define NPCM_ADCCON_ADC_CONV		BIT(13)

#define NPCM_ADCCON_CH_MASK		GENMASK(27, 24)
#define NPCM_ADCCON_CH(x)		((x) << 24)
#define NPCM_ADCCON_DIV_SHIFT		1
#define NPCM_ADCCON_DIV_MASK		GENMASK(8, 1)

#define NPCM_ADC_ENABLE		(NPCM_ADCCON_ADC_EN | NPCM_ADCCON_ADC_INT_EN)

/* ADC General Definition */
static const struct npcm_adc_info npxm7xx_adc_info = {
	.data_mask = GENMASK(9, 0),
	.internal_vref = 2048,
	.res_bits = 10,
};

static const struct npcm_adc_info npxm8xx_adc_info = {
	.data_mask = GENMASK(11, 0),
	.internal_vref = 1229,
	.res_bits = 12,
};

#define NPCM_ADC_CHAN(ch) {					\
	.type = IIO_VOLTAGE,					\
	.indexed = 1,						\
	.channel = ch,						\
	.info_mask_separate = BIT(IIO_CHAN_INFO_RAW),		\
	.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE) |	\
				BIT(IIO_CHAN_INFO_SAMP_FREQ),	\
}

static const struct iio_chan_spec npcm_adc_iio_channels[] = {
	NPCM_ADC_CHAN(0),
	NPCM_ADC_CHAN(1),
	NPCM_ADC_CHAN(2),
	NPCM_ADC_CHAN(3),
	NPCM_ADC_CHAN(4),
	NPCM_ADC_CHAN(5),
	NPCM_ADC_CHAN(6),
	NPCM_ADC_CHAN(7),
};

static irqreturn_t npcm_adc_isr(int irq, void *data)
{
	u32 regtemp;
	struct iio_dev *indio_dev = data;
	struct npcm_adc *info = iio_priv(indio_dev);

	regtemp = ioread32(info->regs + NPCM_ADCCON);
	if (regtemp & NPCM_ADCCON_ADC_INT_ST) {
		iowrite32(regtemp, info->regs + NPCM_ADCCON);
		wake_up_interruptible(&info->wq);
		info->int_status = true;

Annotation

Implementation Notes