drivers/iio/adc/ad7766.c

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

File Facts

System
Linux kernel
Corpus path
drivers/iio/adc/ad7766.c
Extension
.c
Size
7631 bytes
Lines
310
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 ad7766_chip_info {
	unsigned int decimation_factor;
};

enum {
	AD7766_SUPPLY_AVDD = 0,
	AD7766_SUPPLY_DVDD = 1,
	AD7766_SUPPLY_VREF = 2,
	AD7766_NUM_SUPPLIES = 3
};

struct ad7766 {
	const struct ad7766_chip_info *chip_info;
	struct spi_device *spi;
	struct clk *mclk;
	struct gpio_desc *pd_gpio;
	struct regulator_bulk_data reg[AD7766_NUM_SUPPLIES];

	struct iio_trigger *trig;

	struct spi_transfer xfer;
	struct spi_message msg;

	/*
	 * DMA (thus cache coherency maintenance) may require the
	 * transfer buffers to live in their own cache lines.
	 * Make the buffer large enough for one 24 bit sample and one 64 bit
	 * aligned 64 bit timestamp.
	 */
	unsigned char data[ALIGN(3, sizeof(s64)) + sizeof(s64)]	__aligned(IIO_DMA_MINALIGN);
};

/*
 * AD7766 and AD7767 variations are interface compatible, the main difference is
 * analog performance. Both parts will use the same ID.
 */
enum ad7766_device_ids {
	ID_AD7766,
	ID_AD7766_1,
	ID_AD7766_2,
};

static irqreturn_t ad7766_trigger_handler(int irq, void *p)
{
	struct iio_poll_func *pf = p;
	struct iio_dev *indio_dev = pf->indio_dev;
	struct ad7766 *ad7766 = iio_priv(indio_dev);
	int ret;

	ret = spi_sync(ad7766->spi, &ad7766->msg);
	if (ret < 0)
		goto done;

	iio_push_to_buffers_with_timestamp(indio_dev, ad7766->data,
		pf->timestamp);
done:
	iio_trigger_notify_done(indio_dev->trig);

	return IRQ_HANDLED;
}

static int ad7766_preenable(struct iio_dev *indio_dev)
{
	struct ad7766 *ad7766 = iio_priv(indio_dev);
	int ret;

	ret = regulator_bulk_enable(ARRAY_SIZE(ad7766->reg), ad7766->reg);
	if (ret < 0) {
		dev_err(&ad7766->spi->dev, "Failed to enable supplies: %d\n",
			ret);
		return ret;
	}

	ret = clk_prepare_enable(ad7766->mclk);
	if (ret < 0) {
		dev_err(&ad7766->spi->dev, "Failed to enable MCLK: %d\n", ret);
		regulator_bulk_disable(ARRAY_SIZE(ad7766->reg), ad7766->reg);
		return ret;
	}

	gpiod_set_value(ad7766->pd_gpio, 0);

	return 0;
}

static int ad7766_postdisable(struct iio_dev *indio_dev)
{
	struct ad7766 *ad7766 = iio_priv(indio_dev);

	gpiod_set_value(ad7766->pd_gpio, 1);

Annotation

Implementation Notes