drivers/iio/adc/cc10001_adc.c

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

File Facts

System
Linux kernel
Corpus path
drivers/iio/adc/cc10001_adc.c
Extension
.c
Size
10524 bytes
Lines
416
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 cc10001_adc_device {
	void __iomem *reg_base;
	struct clk *adc_clk;
	struct regulator *reg;
	u16 *buf;

	bool shared;
	struct mutex lock;
	unsigned int start_delay_ns;
	unsigned int eoc_delay_ns;
};

static inline void cc10001_adc_write_reg(struct cc10001_adc_device *adc_dev,
					 u32 reg, u32 val)
{
	writel(val, adc_dev->reg_base + reg);
}

static inline u32 cc10001_adc_read_reg(struct cc10001_adc_device *adc_dev,
				       u32 reg)
{
	return readl(adc_dev->reg_base + reg);
}

static void cc10001_adc_power_up(struct cc10001_adc_device *adc_dev)
{
	cc10001_adc_write_reg(adc_dev, CC10001_ADC_POWER_DOWN, 0);
	ndelay(adc_dev->start_delay_ns);
}

static void cc10001_adc_power_down(struct cc10001_adc_device *adc_dev)
{
	cc10001_adc_write_reg(adc_dev, CC10001_ADC_POWER_DOWN,
			      CC10001_ADC_POWER_DOWN_SET);
}

static void cc10001_adc_start(struct cc10001_adc_device *adc_dev,
			      unsigned int channel)
{
	u32 val;

	/* Channel selection and mode of operation */
	val = (channel & CC10001_ADC_CH_MASK) | CC10001_ADC_MODE_SINGLE_CONV;
	cc10001_adc_write_reg(adc_dev, CC10001_ADC_CONFIG, val);

	udelay(1);
	val = cc10001_adc_read_reg(adc_dev, CC10001_ADC_CONFIG);
	val = val | CC10001_ADC_START_CONV;
	cc10001_adc_write_reg(adc_dev, CC10001_ADC_CONFIG, val);
}

static u16 cc10001_adc_poll_done(struct iio_dev *indio_dev,
				 unsigned int channel,
				 unsigned int delay)
{
	struct cc10001_adc_device *adc_dev = iio_priv(indio_dev);
	unsigned int poll_count = 0;

	while (!(cc10001_adc_read_reg(adc_dev, CC10001_ADC_EOC) &
			CC10001_ADC_EOC_SET)) {

		ndelay(delay);
		if (poll_count++ == CC10001_MAX_POLL_COUNT)
			return CC10001_INVALID_SAMPLED;
	}

	poll_count = 0;
	while ((cc10001_adc_read_reg(adc_dev, CC10001_ADC_CHSEL_SAMPLED) &
			CC10001_ADC_CH_MASK) != channel) {

		ndelay(delay);
		if (poll_count++ == CC10001_MAX_POLL_COUNT)
			return CC10001_INVALID_SAMPLED;
	}

	/* Read the 10 bit output register */
	return cc10001_adc_read_reg(adc_dev, CC10001_ADC_DDATA_OUT) &
			       CC10001_ADC_DATA_MASK;
}

static irqreturn_t cc10001_adc_trigger_h(int irq, void *p)
{
	struct cc10001_adc_device *adc_dev;
	struct iio_poll_func *pf = p;
	struct iio_dev *indio_dev;
	unsigned int delay_ns;
	unsigned int channel;
	unsigned int scan_idx;
	bool sample_invalid;
	u16 *data;

Annotation

Implementation Notes