drivers/iio/adc/ti-ads1100.c

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

File Facts

System
Linux kernel
Corpus path
drivers/iio/adc/ti-ads1100.c
Extension
.c
Size
10748 bytes
Lines
433
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 ads1100_data {
	struct i2c_client *client;
	struct regulator *reg_vdd;
	struct mutex lock;
	int scale_avail[2 * 4]; /* 4 gain settings */
	u8 config;
	bool supports_data_rate; /* Only the ADS1100 can select the rate */
};

static const struct iio_chan_spec ads1100_channel = {
	.type = IIO_VOLTAGE,
	.info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
	.info_mask_shared_by_all =
	    BIT(IIO_CHAN_INFO_SCALE) | BIT(IIO_CHAN_INFO_SAMP_FREQ),
	.info_mask_shared_by_all_available =
	    BIT(IIO_CHAN_INFO_SCALE) | BIT(IIO_CHAN_INFO_SAMP_FREQ),
	.scan_type = {
		      .sign = 's',
		      .realbits = 16,
		      .storagebits = 16,
		      .endianness = IIO_CPU,
		       },
	.datasheet_name = "AIN",
};

static int ads1100_set_config_bits(struct ads1100_data *data, u8 mask, u8 value)
{
	int ret;
	u8 config = (data->config & ~mask) | (value & mask);

	if (data->config == config)
		return 0;	/* Already done */

	ret = i2c_master_send(data->client, &config, 1);
	if (ret < 0)
		return ret;

	data->config = config;

	return 0;
};

static int ads1100_data_bits(struct ads1100_data *data)
{
	return ads1100_data_rate_bits[FIELD_GET(ADS1100_DR_MASK, data->config)];
}

static int ads1100_get_adc_result(struct ads1100_data *data, int chan, int *val)
{
	int ret;
	__be16 buffer;
	s16 value;

	if (chan != 0)
		return -EINVAL;

	ret = pm_runtime_resume_and_get(&data->client->dev);
	if (ret < 0)
		return ret;

	ret = i2c_master_recv(data->client, (char *)&buffer, sizeof(buffer));

	pm_runtime_put_autosuspend(&data->client->dev);

	if (ret < 0) {
		dev_err(&data->client->dev, "I2C read fail: %d\n", ret);
		return ret;
	}

	/* Value is always 16-bit 2's complement */
	value = be16_to_cpu(buffer);

	/* Shift result to compensate for bit resolution vs. sample rate */
	value <<= 16 - ads1100_data_bits(data);

	*val = sign_extend32(value, 15);

	return 0;
}

static int ads1100_set_scale(struct ads1100_data *data, int val, int val2)
{
	int microvolts;
	int gain;

	/* With Vdd between 2.7 and 5V, the scale is always below 1 */
	if (val)
		return -EINVAL;

	if (!val2)

Annotation

Implementation Notes