drivers/iio/adc/ti_am335x_adc.c

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

File Facts

System
Linux kernel
Corpus path
drivers/iio/adc/ti_am335x_adc.c
Extension
.c
Size
19201 bytes
Lines
754
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 tiadc_dma {
	struct dma_slave_config	conf;
	struct dma_chan		*chan;
	dma_addr_t		addr;
	dma_cookie_t		cookie;
	u8			*buf;
	int			current_period;
	int			period_size;
	u8			fifo_thresh;
};

struct tiadc_device {
	struct ti_tscadc_dev *mfd_tscadc;
	struct tiadc_dma dma;
	struct mutex fifo1_lock; /* to protect fifo access */
	int channels;
	int total_ch_enabled;
	u8 channel_line[8];
	u8 channel_step[8];
	int buffer_en_ch_steps;
	u16 data[8];
	u32 open_delay[8], sample_delay[8], step_avg[8];
};

static unsigned int tiadc_readl(struct tiadc_device *adc, unsigned int reg)
{
	return readl(adc->mfd_tscadc->tscadc_base + reg);
}

static void tiadc_writel(struct tiadc_device *adc, unsigned int reg,
			 unsigned int val)
{
	writel(val, adc->mfd_tscadc->tscadc_base + reg);
}

static u32 get_adc_step_mask(struct tiadc_device *adc_dev)
{
	u32 step_en;

	step_en = ((1 << adc_dev->channels) - 1);
	step_en <<= TOTAL_STEPS - adc_dev->channels + 1;
	return step_en;
}

static u32 get_adc_chan_step_mask(struct tiadc_device *adc_dev,
				  struct iio_chan_spec const *chan)
{
	int i;

	for (i = 0; i < ARRAY_SIZE(adc_dev->channel_step); i++) {
		if (chan->channel == adc_dev->channel_line[i]) {
			u32 step;

			step = adc_dev->channel_step[i];
			/* +1 for the charger */
			return 1 << (step + 1);
		}
	}
	WARN_ON(1);
	return 0;
}

static u32 get_adc_step_bit(struct tiadc_device *adc_dev, int chan)
{
	return 1 << adc_dev->channel_step[chan];
}

static int tiadc_wait_idle(struct tiadc_device *adc_dev)
{
	u32 val;

	return readl_poll_timeout(adc_dev->mfd_tscadc->tscadc_base + REG_ADCFSM,
				  val, !(val & SEQ_STATUS), 10,
				  IDLE_TIMEOUT_MS * 1000 * adc_dev->channels);
}

static void tiadc_step_config(struct iio_dev *indio_dev)
{
	struct tiadc_device *adc_dev = iio_priv(indio_dev);
	unsigned int stepconfig;
	int i, steps = 0;

	/*
	 * There are 16 configurable steps and 8 analog input
	 * lines available which are shared between Touchscreen and ADC.
	 *
	 * Steps forward, i.e. from 0 towards 16, are used by ADC
	 * depending on the number of input lines needed.
	 * Channel would represent which analog input
	 * needs to be given to ADC to digitize data.

Annotation

Implementation Notes