drivers/iio/adc/intel_dc_ti_adc.c

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

File Facts

System
Linux kernel
Corpus path
drivers/iio/adc/intel_dc_ti_adc.c
Extension
.c
Size
8451 bytes
Lines
329
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 dc_ti_adc_info {
	struct mutex lock; /* Protects against concurrent accesses to the ADC */
	wait_queue_head_t wait;
	struct device *dev;
	struct regmap *regmap;
	int vbat_zse;
	int vbat_ge;
	bool conversion_done;
};

static const struct iio_chan_spec dc_ti_adc_channels[] = {
	{
		.indexed = 1,
		.type = IIO_VOLTAGE,
		.channel = DC_TI_ADC_VBAT,
		.address = DC_TI_ADC_DATA_REG_CH(0),
		.datasheet_name = "CH0",
		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
				      BIT(IIO_CHAN_INFO_SCALE) |
				      BIT(IIO_CHAN_INFO_PROCESSED),
	}, {
		.indexed = 1,
		.type = IIO_TEMP,
		.channel = DC_TI_ADC_PMICTEMP,
		.address = DC_TI_ADC_DATA_REG_CH(1),
		.datasheet_name = "CH1",
		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
	}, {
		.indexed = 1,
		.type = IIO_TEMP,
		.channel = DC_TI_ADC_BATTEMP,
		.address = DC_TI_ADC_DATA_REG_CH(2),
		.datasheet_name = "CH2",
		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
	}, {
		.indexed = 1,
		.type = IIO_TEMP,
		.channel = DC_TI_ADC_SYSTEMP0,
		.address = DC_TI_ADC_DATA_REG_CH(3),
		.datasheet_name = "CH3",
		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
	}
};

static struct iio_map dc_ti_adc_default_maps[] = {
	IIO_MAP("CH0", "chtdc_ti_battery", "VBAT"),
	IIO_MAP("CH1", "chtdc_ti_battery", "PMICTEMP"),
	IIO_MAP("CH2", "chtdc_ti_battery", "BATTEMP"),
	IIO_MAP("CH3", "chtdc_ti_battery", "SYSTEMP0"),
	{ }
};

static irqreturn_t dc_ti_adc_isr(int irq, void *data)
{
	struct dc_ti_adc_info *info = data;

	info->conversion_done = true;
	wake_up(&info->wait);
	return IRQ_HANDLED;
}

static int dc_ti_adc_scale(struct dc_ti_adc_info *info,
			   struct iio_chan_spec const *chan,
			   int *val, int *val2)
{
	if (chan->channel != DC_TI_ADC_VBAT)
		return -EINVAL;

	/* Vbat ADC scale is 4.6875 mV / unit */
	*val = 4;
	*val2 = 687500;

	return IIO_VAL_INT_PLUS_MICRO;
}

static int dc_ti_adc_raw_to_processed(struct dc_ti_adc_info *info,
				      struct iio_chan_spec const *chan,
				      int raw, int *val, int *val2)
{
	if (chan->channel != DC_TI_ADC_VBAT)
		return -EINVAL;

	/* Apply calibration */
	raw -= info->vbat_zse;
	raw = raw * (DC_TI_VBAT_GE_DIV - info->vbat_ge * DC_TI_VBAT_GE_STEP) /
	      DC_TI_VBAT_GE_DIV;
	/* Vbat ADC scale is 4.6875 mV / unit */
	raw *= 46875;

	/* raw is now in 10000 units / mV, convert to milli + milli/1e6 */

Annotation

Implementation Notes