drivers/iio/adc/ad9467.c

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

File Facts

System
Linux kernel
Corpus path
drivers/iio/adc/ad9467.c
Extension
.c
Size
37795 bytes
Lines
1435
Domain
Driver Families
Bucket
drivers/iio
Inferred role
Driver Families: operation-table or driver-model contract
Status
pattern 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

static const struct file_operations ad9467_chan_test_mode_fops = {
	.open = simple_open,
	.read = ad9467_chan_test_mode_read,
	.write = ad9467_chan_test_mode_write,
	.llseek = default_llseek,
	.owner = THIS_MODULE,
};

static ssize_t ad9467_dump_calib_table(struct file *file,
				       char __user *userbuf,
				       size_t count, loff_t *ppos)
{
	struct ad9467_state *st = file->private_data;
	unsigned int bit;
	/* +2 for the newline and +1 for the string termination */
	unsigned char map[AD9647_MAX_TEST_POINTS * 2 + 3];
	ssize_t len = 0;

	guard(mutex)(&st->lock);
	if (*ppos)
		goto out_read;

	for (bit = 0; bit < st->calib_map_size; bit++) {
		if (AD9467_CAN_INVERT(st) && bit == st->calib_map_size / 2)
			len += scnprintf(map + len, sizeof(map) - len, "\n");

		len += scnprintf(map + len, sizeof(map) - len, "%c",
				 test_bit(bit, st->calib_map) ? 'x' : 'o');
	}

	len += scnprintf(map + len, sizeof(map) - len, "\n");
out_read:
	return simple_read_from_buffer(userbuf, count, ppos, map, len);
}

static const struct file_operations ad9467_calib_table_fops = {
	.open = simple_open,
	.read = ad9467_dump_calib_table,
	.llseek = default_llseek,
	.owner = THIS_MODULE,
};

static void ad9467_debugfs_init(struct iio_dev *indio_dev)
{
	struct dentry *d = iio_get_debugfs_dentry(indio_dev);
	struct ad9467_state *st = iio_priv(indio_dev);
	char attr_name[32];
	unsigned int chan;

	if (!IS_ENABLED(CONFIG_DEBUG_FS))
		return;

	st->chan_test = devm_kcalloc(&st->spi->dev, st->info->num_channels,
				     sizeof(*st->chan_test), GFP_KERNEL);
	if (!st->chan_test)
		return;

	if (iio_backend_has_caps(st->back, IIO_BACKEND_CAP_CALIBRATION))
		debugfs_create_file("calibration_table_dump", 0400, d, st,
				    &ad9467_calib_table_fops);

	for (chan = 0; chan < st->info->num_channels; chan++) {
		snprintf(attr_name, sizeof(attr_name), "in_voltage%u_test_mode",
			 chan);
		st->chan_test[chan].idx = chan;
		st->chan_test[chan].st = st;
		debugfs_create_file(attr_name, 0600, d, &st->chan_test[chan],
				    &ad9467_chan_test_mode_fops);
	}

	debugfs_create_file("in_voltage_test_mode_available", 0400, d, st,
			    &ad9467_test_mode_available_fops);

	iio_backend_debugfs_add(st->back, indio_dev);
}

static int ad9467_probe(struct spi_device *spi)
{
	struct device *dev = &spi->dev;
	struct iio_dev *indio_dev;
	struct ad9467_state *st;
	unsigned int id;
	int ret;

	indio_dev = devm_iio_device_alloc(dev, sizeof(*st));
	if (!indio_dev)
		return -ENOMEM;

	st = iio_priv(indio_dev);
	st->spi = spi;

Annotation

Implementation Notes