drivers/staging/iio/adc/ad7816.c

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

File Facts

System
Linux kernel
Corpus path
drivers/staging/iio/adc/ad7816.c
Extension
.c
Size
10869 bytes
Lines
450
Domain
Driver Families
Bucket
drivers/staging
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 ad7816_chip_info {
	kernel_ulong_t id;
	struct spi_device *spi_dev;
	struct gpio_desc *rdwr_pin;
	struct gpio_desc *convert_pin;
	struct gpio_desc *busy_pin;
	u8  oti_data[AD7816_CS_MAX + 1];
	u8  channel_id;	/* 0 always be temperature */
	u8  mode;
};

enum ad7816_type {
	ID_AD7816,
	ID_AD7817,
	ID_AD7818,
};

/*
 * ad7816 data access by SPI
 */
static int ad7816_spi_read(struct ad7816_chip_info *chip, u16 *data)
{
	struct spi_device *spi_dev = chip->spi_dev;
	int ret;
	__be16 buf;

	gpiod_set_value(chip->rdwr_pin, 1);
	gpiod_set_value(chip->rdwr_pin, 0);
	ret = spi_write(spi_dev, &chip->channel_id, sizeof(chip->channel_id));
	if (ret < 0) {
		dev_err(&spi_dev->dev, "SPI channel setting error\n");
		return ret;
	}
	gpiod_set_value(chip->rdwr_pin, 1);

	if (chip->mode == AD7816_PD) { /* operating mode 2 */
		gpiod_set_value(chip->convert_pin, 1);
		gpiod_set_value(chip->convert_pin, 0);
	} else { /* operating mode 1 */
		gpiod_set_value(chip->convert_pin, 0);
		gpiod_set_value(chip->convert_pin, 1);
	}

	if (chip->id == ID_AD7816 || chip->id == ID_AD7817) {
		while (gpiod_get_value(chip->busy_pin))
			cpu_relax();
	}

	gpiod_set_value(chip->rdwr_pin, 0);
	gpiod_set_value(chip->rdwr_pin, 1);
	ret = spi_read(spi_dev, &buf, sizeof(*data));
	if (ret < 0) {
		dev_err(&spi_dev->dev, "SPI data read error\n");
		return ret;
	}

	*data = be16_to_cpu(buf);

	return ret;
}

static int ad7816_spi_write(struct ad7816_chip_info *chip, u8 data)
{
	struct spi_device *spi_dev = chip->spi_dev;
	int ret;

	gpiod_set_value(chip->rdwr_pin, 1);
	gpiod_set_value(chip->rdwr_pin, 0);
	ret = spi_write(spi_dev, &data, sizeof(data));
	if (ret < 0)
		dev_err(&spi_dev->dev, "SPI oti data write error\n");

	return ret;
}

static ssize_t ad7816_show_mode(struct device *dev,
				struct device_attribute *attr,
				char *buf)
{
	struct iio_dev *indio_dev = dev_to_iio_dev(dev);
	struct ad7816_chip_info *chip = iio_priv(indio_dev);

	if (chip->mode)
		return sysfs_emit(buf, "power-save\n");
	return sysfs_emit(buf, "full\n");
}

static ssize_t ad7816_store_mode(struct device *dev,
				 struct device_attribute *attr,
				 const char *buf,

Annotation

Implementation Notes