drivers/iio/resolver/ad2s1210.c

Source file repositories/reference/linux-study-clean/drivers/iio/resolver/ad2s1210.c

File Facts

System
Linux kernel
Corpus path
drivers/iio/resolver/ad2s1210.c
Extension
.c
Size
45198 bytes
Lines
1618
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 ad2s1210_state {
	struct mutex lock;
	struct spi_device *sdev;
	/** GPIO pin connected to SAMPLE line. */
	struct gpio_desc *sample_gpio;
	/** GPIO pins connected to A0 and A1 lines (optional). */
	struct gpio_descs *mode_gpios;
	/** Used to access config registers. */
	struct regmap *regmap;
	/** The external oscillator frequency in Hz. */
	unsigned long clkin_hz;
	/** Available raw hysteresis values based on resolution. */
	int hysteresis_available[2];
	/* adi,fixed-mode property - only valid when mode_gpios == NULL. */
	enum ad2s1210_mode fixed_mode;
	/** The selected resolution */
	enum ad2s1210_resolution resolution;
	/** Copy of fault register from the previous read. */
	u8 prev_fault_flags;
	/** For reading raw sample value via SPI. */
	struct {
		__be16 raw;
		u8 fault;
	} sample __aligned(IIO_DMA_MINALIGN);
	/** Scan buffer */
	struct {
		__be16 chan[2];
		/* Ensure timestamp is naturally aligned. */
		aligned_s64 timestamp;
	} scan;
	/** SPI transmit buffer. */
	u8 rx[2];
	/** SPI receive buffer. */
	u8 tx[2];
};

static int ad2s1210_set_mode(struct ad2s1210_state *st, enum ad2s1210_mode mode)
{
	struct gpio_descs *gpios = st->mode_gpios;
	DECLARE_BITMAP(bitmap, 2) = { };

	if (!gpios)
		return mode == st->fixed_mode ? 0 : -EOPNOTSUPP;

	bitmap_write(bitmap, mode, 0, 2);

	return gpiod_multi_set_value_cansleep(gpios, bitmap);
}

/*
 * Writes the given data to the given register address.
 *
 * If the mode is configurable, the device will first be placed in
 * configuration mode.
 */
static int ad2s1210_regmap_reg_write(void *context, unsigned int reg,
				     unsigned int val)
{
	struct ad2s1210_state *st = context;
	struct spi_transfer xfers[] = {
		{
			.len = 1,
			.rx_buf = &st->rx[0],
			.tx_buf = &st->tx[0],
			.cs_change = 1,
		}, {
			.len = 1,
			.rx_buf = &st->rx[1],
			.tx_buf = &st->tx[1],
		},
	};
	int ret;

	/* values can only be 7 bits, the MSB indicates an address */
	if (val & ~0x7F)
		return -EINVAL;

	st->tx[0] = reg;
	st->tx[1] = val;

	ret = ad2s1210_set_mode(st, MOD_CONFIG);
	if (ret < 0)
		return ret;

	ret = spi_sync_transfer(st->sdev, xfers, ARRAY_SIZE(xfers));
	if (ret < 0)
		return ret;

	/* soft reset also clears the fault register */
	if (reg == AD2S1210_REG_SOFT_RESET)

Annotation

Implementation Notes