drivers/iio/adc/ti-ads7924.c

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

File Facts

System
Linux kernel
Corpus path
drivers/iio/adc/ti-ads7924.c
Extension
.c
Size
12395 bytes
Lines
469
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 ads7924_data {
	struct device *dev;
	struct regmap *regmap;
	struct regulator *vref_reg;

	/* GPIO descriptor for device hard-reset pin. */
	struct gpio_desc *reset_gpio;

	/*
	 * Protects ADC ops, e.g: concurrent sysfs/buffered
	 * data reads, configuration updates
	 */
	struct mutex lock;

	/*
	 * Set to true when the ADC is switched to the continuous-conversion
	 * mode and exits from a power-down state. This flag is used to avoid
	 * getting the stale result from the conversion register.
	 */
	bool conv_invalid;
};

static bool ads7924_is_writeable_reg(struct device *dev, unsigned int reg)
{
	switch (reg) {
	case ADS7924_MODECNTRL_REG:
	case ADS7924_INTCNTRL_REG:
	case ADS7924_ULR0_REG:
	case ADS7924_LLR0_REG:
	case ADS7924_ULR1_REG:
	case ADS7924_LLR1_REG:
	case ADS7924_ULR2_REG:
	case ADS7924_LLR2_REG:
	case ADS7924_ULR3_REG:
	case ADS7924_LLR3_REG:
	case ADS7924_INTCONFIG_REG:
	case ADS7924_SLPCONFIG_REG:
	case ADS7924_ACQCONFIG_REG:
	case ADS7924_PWRCONFIG_REG:
	case ADS7924_RESET_REG:
		return true;
	default:
		return false;
	}
}

static const struct regmap_config ads7924_regmap_config = {
	.reg_bits = 8,
	.val_bits = 8,
	.max_register = ADS7924_RESET_REG,
	.writeable_reg = ads7924_is_writeable_reg,
};

static const struct iio_chan_spec ads7924_channels[] = {
	ADS7924_V_CHAN(0, ADS7924_DATA0_U_REG),
	ADS7924_V_CHAN(1, ADS7924_DATA1_U_REG),
	ADS7924_V_CHAN(2, ADS7924_DATA2_U_REG),
	ADS7924_V_CHAN(3, ADS7924_DATA3_U_REG),
};

static int ads7924_get_adc_result(struct ads7924_data *data,
				  struct iio_chan_spec const *chan, int *val)
{
	int ret;
	__be16 be_val;

	if (chan->channel < 0 || chan->channel >= ADS7924_CHANNELS)
		return -EINVAL;

	if (data->conv_invalid) {
		int conv_time;

		conv_time = ADS7924_TOTAL_CONVTIME_US;
		/* Allow 10% for internal clock inaccuracy. */
		conv_time += conv_time / 10;
		usleep_range(conv_time, conv_time + 1);
		data->conv_invalid = false;
	}

	ret = regmap_raw_read(data->regmap, ADS7924_AUTO_INCREMENT_BIT |
			      chan->address, &be_val, sizeof(be_val));
	if (ret)
		return ret;

	*val = be16_to_cpu(be_val) >> ADS7924_DATA_SHIFT;

	return 0;
}

static int ads7924_read_raw(struct iio_dev *indio_dev,

Annotation

Implementation Notes